terminal plugin, card edit history, bump script

Terminal: in-app command line with 22 commands (Shift+T toggle).
Navigation, CRUD, search, view toggles, tab completion, history.

Card history: card_history table tracks field changes on every PATCH.
GET /api/cards/{id}/history endpoint. Terminal `history` command.

bump.sh: standalone version bump for config.php, electron/package.json,
website footer. dist.sh no longer bumps.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
thandClaude Opus 4.6 committed 2026-04-13 14:10:43 +02:00
1 parent b9bd294c90
commit 2169c1de1b
11 files changed
+707 -1

No files matched your search

+22
View File
@@ -293,8 +293,30 @@ if (str_starts_with($route, '/api/')) {
echo json_encode(['ok' => true]); exit;
}
if (preg_match('#^/api/cards/(\d+)/history$#', $route, $m) && $method === 'GET') {
$stmt = $db->prepare('SELECT field, old_value, new_value, changed_at FROM card_history WHERE card_id = :id ORDER BY changed_at DESC LIMIT 100');
$stmt->execute(['id' => $m[1]]);
echo json_encode($stmt->fetchAll()); exit;
}
if (preg_match('#^/api/cards/(\d+)$#', $route, $m) && $method === 'PATCH') {
$input = json_decode(file_get_contents('php://input'), true);
// Snapshot changed fields before update
$tracked = ['title', 'body', 'color', 'bucket_id', 'due_date'];
$changedTracked = array_intersect($tracked, array_keys($input));
if ($changedTracked) {
$old = $db->prepare('SELECT * FROM cards WHERE id = :id'); $old->execute(['id' => $m[1]]); $old = $old->fetch();
if ($old) {
$histStmt = $db->prepare('INSERT INTO card_history (card_id, field, old_value, new_value) VALUES (:cid, :f, :o, :n)');
foreach ($changedTracked as $f) {
$oldVal = $old[$f] ?? null; $newVal = $input[$f] ?? null;
if ($f === 'body') { $oldVal = mb_substr($oldVal ?? '', 0, 500); $newVal = mb_substr($newVal ?? '', 0, 500); }
if ((string)$oldVal !== (string)$newVal) {
$histStmt->execute(['cid' => $m[1], 'f' => $f, 'o' => $oldVal, 'n' => $newVal]);
}
}
}
}
$fields = []; $params = ['id' => $m[1]];
foreach (['title', 'body', 'color', 'position', 'bucket_id', 'parent_id', 'due_date'] as $f) {
if (array_key_exists($f, $input)) { $fields[] = "$f = :$f"; $params[$f] = $input[$f]; }