feat: add annotations, undo system, and schema updates
Add annotations as JSON column on tasks table with Annotate/Denotate methods and CLI commands. Add undo system backed by change_log with lightweight undo_stack table (capped at 10 entries). All mutating CLI commands (add, done, delete, modify, start, stop) now record undo entries. Undo restores prior task state from change_log data. Schema changes (in v1 migration): - annotations TEXT column on tasks - undo_stack table - annotations field in change_log triggers Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -112,7 +112,8 @@ func runMigrations() error {
|
||||
|
||||
recurrence_duration INTEGER,
|
||||
parent_uuid TEXT,
|
||||
|
||||
annotations TEXT DEFAULT NULL,
|
||||
|
||||
FOREIGN KEY (parent_uuid) REFERENCES tasks(uuid) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
@@ -209,6 +210,15 @@ func runMigrations() error {
|
||||
CREATE INDEX idx_refresh_tokens_hash ON refresh_tokens(token_hash);
|
||||
CREATE INDEX idx_refresh_tokens_user ON refresh_tokens(user_id);
|
||||
|
||||
-- Undo stack (local-only, references change_log entries)
|
||||
CREATE TABLE undo_stack (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
created_at INTEGER NOT NULL,
|
||||
op_type TEXT NOT NULL,
|
||||
task_uuid TEXT NOT NULL,
|
||||
change_log_id INTEGER NOT NULL
|
||||
);
|
||||
|
||||
-- Triggers to populate change_log
|
||||
CREATE TRIGGER track_task_create AFTER INSERT ON tasks
|
||||
BEGIN
|
||||
@@ -241,10 +251,11 @@ func runMigrations() error {
|
||||
CASE WHEN NEW.until_date IS NOT NULL THEN 'until: ' || NEW.until_date || CHAR(10) ELSE '' END ||
|
||||
CASE WHEN NEW.recurrence_duration IS NOT NULL THEN 'recurrence: ' || NEW.recurrence_duration || CHAR(10) ELSE '' END ||
|
||||
CASE WHEN NEW.parent_uuid IS NOT NULL THEN 'parent_uuid: ' || NEW.parent_uuid || CHAR(10) ELSE '' END ||
|
||||
(SELECT CASE WHEN COUNT(*) > 0
|
||||
CASE WHEN NEW.annotations IS NOT NULL THEN 'annotations: ' || NEW.annotations || CHAR(10) ELSE '' END ||
|
||||
(SELECT CASE WHEN COUNT(*) > 0
|
||||
THEN 'tags: ' || GROUP_CONCAT(tag, ',') || CHAR(10)
|
||||
ELSE ''
|
||||
END
|
||||
ELSE ''
|
||||
END
|
||||
FROM (SELECT tag FROM tags WHERE task_id = NEW.id ORDER BY tag))
|
||||
);
|
||||
END;
|
||||
@@ -280,10 +291,11 @@ func runMigrations() error {
|
||||
CASE WHEN NEW.until_date IS NOT NULL THEN 'until: ' || NEW.until_date || CHAR(10) ELSE '' END ||
|
||||
CASE WHEN NEW.recurrence_duration IS NOT NULL THEN 'recurrence: ' || NEW.recurrence_duration || CHAR(10) ELSE '' END ||
|
||||
CASE WHEN NEW.parent_uuid IS NOT NULL THEN 'parent_uuid: ' || NEW.parent_uuid || CHAR(10) ELSE '' END ||
|
||||
(SELECT CASE WHEN COUNT(*) > 0
|
||||
CASE WHEN NEW.annotations IS NOT NULL THEN 'annotations: ' || NEW.annotations || CHAR(10) ELSE '' END ||
|
||||
(SELECT CASE WHEN COUNT(*) > 0
|
||||
THEN 'tags: ' || GROUP_CONCAT(tag, ',') || CHAR(10)
|
||||
ELSE ''
|
||||
END
|
||||
ELSE ''
|
||||
END
|
||||
FROM (SELECT tag FROM tags WHERE task_id = NEW.id ORDER BY tag))
|
||||
);
|
||||
END;
|
||||
|
||||
Reference in New Issue
Block a user