Skip to content

feat: add deleteTask method with CASCADE cleanup verification#19

Merged
blackms merged 2 commits intomainfrom
feat/task-deletion-cleanup
Jan 29, 2026
Merged

feat: add deleteTask method with CASCADE cleanup verification#19
blackms merged 2 commits intomainfrom
feat/task-deletion-cleanup

Conversation

@blackms
Copy link
Owner

@blackms blackms commented Jan 29, 2026

Summary

  • Add deleteTask() method to SQLiteStore for removing tasks and associated data
  • Create comprehensive integration tests verifying CASCADE deletion behavior
  • Add unit tests for the new deleteTask() method

Changes

File Change
src/memory/sqlite-store.ts Add deleteTask() method
tests/integration/task-cleanup.test.ts New file - 8 integration tests
tests/unit/sqlite-store.test.ts Add 3 unit tests for deleteTask()

CASCADE Behavior Verified

Table CASCADE? Behavior
task_embeddings YES Auto-deleted when task deleted
task_relationships YES Auto-deleted (both directions)
drift_detection_events NO Intentionally persists for metrics

Test plan

  • Unit tests pass (npm run test:unit)
  • Integration tests pass (npm run test:integration)
  • New deleteTask() method properly removes tasks
  • CASCADE deletion verified for task_embeddings
  • CASCADE deletion verified for task_relationships
  • drift_detection_events confirmed to persist after task deletion (by design)

Closes #14

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added task deletion with automatic cleanup of related data while preserving metric/history records for audit
  • Tests

    • Added integration tests verifying cascading removals and preservation of metrics
    • Added extensive unit tests covering deletion behaviors, relationships, embeddings, namespaces, and related edge cases

✏️ Tip: You can customize this high-level summary in your review settings.

Add deleteTask() method to SQLiteStore and comprehensive tests to verify
proper cleanup of task-related data via CASCADE constraints.

Closes #14

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Jan 29, 2026

📝 Walkthrough

Walkthrough

Added a public deleteTask(id: string) method to SQLiteStore that deletes a task row and returns whether a row was removed. Extensive unit and integration tests were added to verify CASCADE cleanup of embeddings and relationships, preservation of drift detection events, and various edge cases.

Changes

Cohort / File(s) Summary
Database Method
src/memory/sqlite-store.ts
Added deleteTask(id: string): boolean which executes DELETE FROM tasks WHERE id = ? and returns true if a row was deleted; comment notes related-data cleanup relies on FK CASCADE.
Integration Tests
tests/integration/task-cleanup.test.ts
New integration tests that insert tasks, embeddings, relationships, and drift events via SQL, then verify deletions cascade for task_embeddings and task_relationships while drift_detection_events persist; covers non-existent and multi-task edge cases.
Unit Tests
tests/unit/sqlite-store.test.ts
Expanded unit test suite with broad coverage across memory, namespace, tags, relationships, tasks, projects, sessions, embeddings, metrics, checkpoints, and more; validates behavior around deletion, cascading, and related queries.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nibbled code and found a task,
I waved a DELETE—no need to ask,
Embeddings fell and links unmade,
Metrics linger in the shade,
Hop! The database tidies fast. 🥕✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding a deleteTask method with CASCADE cleanup verification, which aligns with the primary objective.
Linked Issues check ✅ Passed The PR addresses all coding requirements from issue #14: deleteTask method implementation, integration tests verifying CASCADE cleanup of task_embeddings and task_relationships, and verification of drift_detection_events persistence.
Out of Scope Changes check ✅ Passed The addTag bugfix (getById instead of get) is a minor incidental fix outside issue #14 scope, but extensive unit tests cover the new deleteTask method and existing functionality without modifying application logic.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/memory/sqlite-store.ts`:
- Around line 1340-1347: The deleteTask method currently fails when the task is
a parent because tasks.parent_task_id has no ON DELETE action; modify deleteTask
to handle child rows first by wrapping operations in a transaction: begin a
transaction, run an UPDATE on the tasks table to SET parent_task_id = NULL WHERE
parent_task_id = id (or reparent as desired), then DELETE FROM tasks WHERE id =
?, commit the transaction, and ensure the function returns a boolean based on
the delete result; alternatively, update the schema to define
tasks.parent_task_id with ON DELETE SET NULL/ CASCADE and adjust deleteTask
accordingly.

Comment on lines +1340 to +1347
/**
* Delete a task and all associated data
* CASCADE constraints automatically clean up task_embeddings and task_relationships
*/
deleteTask(id: string): boolean {
const result = this.db.prepare('DELETE FROM tasks WHERE id = ?').run(id);
return result.changes > 0;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

fd -t f "schema\|create\|migrate" src/memory

Repository: blackms/aistack

Length of output: 41


🏁 Script executed:

git ls-files src/memory/

Repository: blackms/aistack

Length of output: 187


🏁 Script executed:

cat -n src/memory/sqlite-store.ts | head -100

Repository: blackms/aistack

Length of output: 3428


🏁 Script executed:

grep -n "CREATE TABLE.*tasks" src/memory/sqlite-store.ts

Repository: blackms/aistack

Length of output: 144


🏁 Script executed:

sed -n '100,500p' src/memory/sqlite-store.ts | cat -n

Repository: blackms/aistack

Length of output: 16691


🏁 Script executed:

sed -n '1340,1347p' src/memory/sqlite-store.ts | cat -n

Repository: blackms/aistack

Length of output: 405


🏁 Script executed:

sed -n '1320,1360p' src/memory/sqlite-store.ts | cat -n

Repository: blackms/aistack

Length of output: 1396


🏁 Script executed:

rg "deleteTask" src/memory/sqlite-store.ts -B 2 -A 2

Repository: blackms/aistack

Length of output: 296


🏁 Script executed:

rg "transaction" src/memory/sqlite-store.ts | head -20

Repository: blackms/aistack

Length of output: 481


Handle parent/child FK constraint before deleting tasks.

tasks.parent_task_id has a foreign key with no ON DELETE action. When deleting a task that is a parent of other tasks, the FK constraint will throw an exception, causing deleteTask to fail and violate the boolean return contract. Explicitly handle children before deletion using a transaction, or update the schema to include ON DELETE SET NULL / CASCADE.

One possible fix (nullify children before delete)
-  deleteTask(id: string): boolean {
-    const result = this.db.prepare('DELETE FROM tasks WHERE id = ?').run(id);
-    return result.changes > 0;
-  }
+  deleteTask(id: string): boolean {
+    return this.transaction((db) => {
+      db.prepare('UPDATE tasks SET parent_task_id = NULL WHERE parent_task_id = ?').run(id);
+      const result = db.prepare('DELETE FROM tasks WHERE id = ?').run(id);
+      return result.changes > 0;
+    });
+  }
🤖 Prompt for AI Agents
In `@src/memory/sqlite-store.ts` around lines 1340 - 1347, The deleteTask method
currently fails when the task is a parent because tasks.parent_task_id has no ON
DELETE action; modify deleteTask to handle child rows first by wrapping
operations in a transaction: begin a transaction, run an UPDATE on the tasks
table to SET parent_task_id = NULL WHERE parent_task_id = id (or reparent as
desired), then DELETE FROM tasks WHERE id = ?, commit the transaction, and
ensure the function returns a boolean based on the delete result; alternatively,
update the schema to define tasks.parent_task_id with ON DELETE SET NULL/
CASCADE and adjust deleteTask accordingly.

Add comprehensive unit tests covering all major methods:
- Namespace operations (deleteByNamespace)
- Tag operations (addTag, removeTag, getAllTags, searchByTags)
- Relationship operations (createRelationship, getRelationships, etc.)
- Version operations (getVersionHistory, restoreVersion)
- Project operations (CRUD for projects, tasks, specifications)
- Active agent operations (save, load, delete, update status)
- Review loop operations (save, load, delete)
- Agent identity operations (create, update, list, audit)
- Resource metrics and deliverable checkpoints
- Consensus checkpoint operations

Also fix bug in addTag() - was using get() instead of getById()

Coverage results:
- Statements: 95.15%
- Functions: 100%
- Lines: 95.15%

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@blackms blackms merged commit e0d66a1 into main Jan 29, 2026
6 checks passed
@blackms blackms deleted the feat/task-deletion-cleanup branch January 29, 2026 14:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: Verify embedding cleanup on task deletion

1 participant