sqlew 3.5.3 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +247 -1772
- package/README.md +70 -304
- package/assets/config.example.toml +97 -0
- package/dist/adapters/index.d.ts +11 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +21 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/mysql-adapter.d.ts +31 -0
- package/dist/adapters/mysql-adapter.d.ts.map +1 -0
- package/dist/adapters/mysql-adapter.js +63 -0
- package/dist/adapters/mysql-adapter.js.map +1 -0
- package/dist/adapters/postgresql-adapter.d.ts +31 -0
- package/dist/adapters/postgresql-adapter.d.ts.map +1 -0
- package/dist/adapters/postgresql-adapter.js +63 -0
- package/dist/adapters/postgresql-adapter.js.map +1 -0
- package/dist/adapters/sqlite-adapter.d.ts +37 -0
- package/dist/adapters/sqlite-adapter.d.ts.map +1 -0
- package/dist/adapters/sqlite-adapter.js +129 -0
- package/dist/adapters/sqlite-adapter.js.map +1 -0
- package/dist/adapters/types.d.ts +33 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/adapters/types.js +2 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/cli.js +55 -54
- package/dist/cli.js.map +1 -1
- package/dist/config/example-generator.d.ts +11 -0
- package/dist/config/example-generator.d.ts.map +1 -0
- package/dist/config/example-generator.js +48 -0
- package/dist/config/example-generator.js.map +1 -0
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +4 -0
- package/dist/config/loader.js.map +1 -1
- package/dist/config/types.d.ts +9 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js.map +1 -1
- package/dist/database.d.ts +44 -122
- package/dist/database.d.ts.map +1 -1
- package/dist/database.js +145 -416
- package/dist/database.js.map +1 -1
- package/dist/index.js +215 -185
- package/dist/index.js.map +1 -1
- package/dist/knexfile.d.ts +6 -0
- package/dist/knexfile.d.ts.map +1 -0
- package/dist/knexfile.js +85 -0
- package/dist/knexfile.js.map +1 -0
- package/dist/migrations/add-help-system-tables.d.ts +35 -0
- package/dist/migrations/add-help-system-tables.d.ts.map +1 -0
- package/dist/migrations/add-help-system-tables.js +206 -0
- package/dist/migrations/add-help-system-tables.js.map +1 -0
- package/dist/migrations/add-token-tracking.d.ts +28 -0
- package/dist/migrations/add-token-tracking.d.ts.map +1 -0
- package/dist/migrations/add-token-tracking.js +108 -0
- package/dist/migrations/add-token-tracking.js.map +1 -0
- package/dist/migrations/index.d.ts +25 -12
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +147 -20
- package/dist/migrations/index.js.map +1 -1
- package/dist/migrations/knex/20251025020452_create_master_tables.d.ts +4 -0
- package/dist/migrations/knex/20251025020452_create_master_tables.d.ts.map +1 -0
- package/dist/migrations/knex/20251025020452_create_master_tables.js +65 -0
- package/dist/migrations/knex/20251025020452_create_master_tables.js.map +1 -0
- package/dist/migrations/knex/20251025021152_create_transaction_tables.d.ts +4 -0
- package/dist/migrations/knex/20251025021152_create_transaction_tables.d.ts.map +1 -0
- package/dist/migrations/knex/20251025021152_create_transaction_tables.js +235 -0
- package/dist/migrations/knex/20251025021152_create_transaction_tables.js.map +1 -0
- package/dist/migrations/knex/20251025021351_create_indexes.d.ts +4 -0
- package/dist/migrations/knex/20251025021351_create_indexes.d.ts.map +1 -0
- package/dist/migrations/knex/20251025021351_create_indexes.js +62 -0
- package/dist/migrations/knex/20251025021351_create_indexes.js.map +1 -0
- package/dist/migrations/knex/20251025021416_seed_master_data.d.ts +4 -0
- package/dist/migrations/knex/20251025021416_seed_master_data.d.ts.map +1 -0
- package/dist/migrations/knex/20251025021416_seed_master_data.js +58 -0
- package/dist/migrations/knex/20251025021416_seed_master_data.js.map +1 -0
- package/dist/migrations/knex/20251025070349_create_views.d.ts +4 -0
- package/dist/migrations/knex/20251025070349_create_views.d.ts.map +1 -0
- package/dist/migrations/knex/20251025070349_create_views.js +143 -0
- package/dist/migrations/knex/20251025070349_create_views.js.map +1 -0
- package/dist/migrations/knex/20251025081221_add_link_type_to_task_decision_links.d.ts +4 -0
- package/dist/migrations/knex/20251025081221_add_link_type_to_task_decision_links.d.ts.map +1 -0
- package/dist/migrations/knex/20251025081221_add_link_type_to_task_decision_links.js +15 -0
- package/dist/migrations/knex/20251025081221_add_link_type_to_task_decision_links.js.map +1 -0
- package/dist/migrations/knex/20251025082220_fix_task_dependencies_columns.d.ts +8 -0
- package/dist/migrations/knex/20251025082220_fix_task_dependencies_columns.d.ts.map +1 -0
- package/dist/migrations/knex/20251025082220_fix_task_dependencies_columns.js +12 -0
- package/dist/migrations/knex/20251025082220_fix_task_dependencies_columns.js.map +1 -0
- package/dist/migrations/knex/20251025090000_create_help_system_tables.d.ts +19 -0
- package/dist/migrations/knex/20251025090000_create_help_system_tables.d.ts.map +1 -0
- package/dist/migrations/knex/20251025090000_create_help_system_tables.js +115 -0
- package/dist/migrations/knex/20251025090000_create_help_system_tables.js.map +1 -0
- package/dist/migrations/knex/20251025090100_seed_help_categories_and_use_cases.d.ts +13 -0
- package/dist/migrations/knex/20251025090100_seed_help_categories_and_use_cases.d.ts.map +1 -0
- package/dist/migrations/knex/20251025090100_seed_help_categories_and_use_cases.js +377 -0
- package/dist/migrations/knex/20251025090100_seed_help_categories_and_use_cases.js.map +1 -0
- package/dist/migrations/knex/20251025100000_seed_help_metadata.d.ts +15 -0
- package/dist/migrations/knex/20251025100000_seed_help_metadata.d.ts.map +1 -0
- package/dist/migrations/knex/20251025100000_seed_help_metadata.js +253 -0
- package/dist/migrations/knex/20251025100000_seed_help_metadata.js.map +1 -0
- package/dist/migrations/knex/20251025100100_seed_remaining_use_cases.d.ts +16 -0
- package/dist/migrations/knex/20251025100100_seed_remaining_use_cases.d.ts.map +1 -0
- package/dist/migrations/knex/20251025100100_seed_remaining_use_cases.js +276 -0
- package/dist/migrations/knex/20251025100100_seed_remaining_use_cases.js.map +1 -0
- package/dist/migrations/knex/20251025120000_add_cascade_to_task_dependencies.d.ts +8 -0
- package/dist/migrations/knex/20251025120000_add_cascade_to_task_dependencies.d.ts.map +1 -0
- package/dist/migrations/knex/20251025120000_add_cascade_to_task_dependencies.js +64 -0
- package/dist/migrations/knex/20251025120000_add_cascade_to_task_dependencies.js.map +1 -0
- package/dist/migrations/seed-help-data.d.ts +48 -0
- package/dist/migrations/seed-help-data.d.ts.map +1 -0
- package/dist/migrations/seed-help-data.js +1466 -0
- package/dist/migrations/seed-help-data.js.map +1 -0
- package/dist/migrations/seed-tool-metadata.d.ts +24 -0
- package/dist/migrations/seed-tool-metadata.d.ts.map +1 -0
- package/dist/migrations/seed-tool-metadata.js +392 -0
- package/dist/migrations/seed-tool-metadata.js.map +1 -0
- package/dist/migrations/v3.6.0-help-system-refactor.d.ts +46 -0
- package/dist/migrations/v3.6.0-help-system-refactor.d.ts.map +1 -0
- package/dist/migrations/v3.6.0-help-system-refactor.js +223 -0
- package/dist/migrations/v3.6.0-help-system-refactor.js.map +1 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +2 -0
- package/dist/schema.js.map +1 -1
- package/dist/tests/git-aware-completion.test.js +89 -70
- package/dist/tests/git-aware-completion.test.js.map +1 -1
- package/dist/tests/help-system.test.d.ts +23 -0
- package/dist/tests/help-system.test.d.ts.map +1 -0
- package/dist/tests/help-system.test.js +374 -0
- package/dist/tests/help-system.test.js.map +1 -0
- package/dist/tests/tasks.auto-pruning-decision-link.test.js +92 -78
- package/dist/tests/tasks.auto-pruning-decision-link.test.js.map +1 -1
- package/dist/tests/tasks.auto-pruning-partial.test.js +106 -95
- package/dist/tests/tasks.auto-pruning-partial.test.js.map +1 -1
- package/dist/tests/tasks.auto-pruning-persistence.test.js +115 -97
- package/dist/tests/tasks.auto-pruning-persistence.test.js.map +1 -1
- package/dist/tests/tasks.auto-pruning-safety.test.js +124 -103
- package/dist/tests/tasks.auto-pruning-safety.test.js.map +1 -1
- package/dist/tests/tasks.dependencies.test.js +338 -307
- package/dist/tests/tasks.dependencies.test.js.map +1 -1
- package/dist/tests/tasks.link-file-backward-compat.test.js +116 -104
- package/dist/tests/tasks.link-file-backward-compat.test.js.map +1 -1
- package/dist/tests/tasks.watch-files-action.test.js +122 -101
- package/dist/tests/tasks.watch-files-action.test.js.map +1 -1
- package/dist/tests/tasks.watch-files-parameter.test.js +105 -94
- package/dist/tests/tasks.watch-files-parameter.test.js.map +1 -1
- package/dist/tests/two-step-git-completion.test.js +176 -133
- package/dist/tests/two-step-git-completion.test.js.map +1 -1
- package/dist/tests/vcs-staging.test.js +1 -1
- package/dist/tests/vcs-staging.test.js.map +1 -1
- package/dist/tools/config.d.ts +9 -6
- package/dist/tools/config.d.ts.map +1 -1
- package/dist/tools/config.js +16 -14
- package/dist/tools/config.js.map +1 -1
- package/dist/tools/constraints.d.ts +10 -7
- package/dist/tools/constraints.d.ts.map +1 -1
- package/dist/tools/constraints.js +66 -48
- package/dist/tools/constraints.js.map +1 -1
- package/dist/tools/context.d.ts +36 -33
- package/dist/tools/context.d.ts.map +1 -1
- package/dist/tools/context.js +374 -330
- package/dist/tools/context.js.map +1 -1
- package/dist/tools/files.d.ts +12 -9
- package/dist/tools/files.d.ts.map +1 -1
- package/dist/tools/files.js +173 -95
- package/dist/tools/files.js.map +1 -1
- package/dist/tools/help-queries.d.ts +130 -0
- package/dist/tools/help-queries.d.ts.map +1 -0
- package/dist/tools/help-queries.js +393 -0
- package/dist/tools/help-queries.js.map +1 -0
- package/dist/tools/messaging.d.ts +14 -11
- package/dist/tools/messaging.d.ts.map +1 -1
- package/dist/tools/messaging.js +217 -133
- package/dist/tools/messaging.js.map +1 -1
- package/dist/tools/tasks.d.ts +18 -16
- package/dist/tools/tasks.d.ts.map +1 -1
- package/dist/tools/tasks.js +513 -439
- package/dist/tools/tasks.js.map +1 -1
- package/dist/tools/utils.d.ts +14 -11
- package/dist/tools/utils.d.ts.map +1 -1
- package/dist/tools/utils.js +86 -121
- package/dist/tools/utils.js.map +1 -1
- package/dist/utils/activity-logging.d.ts +114 -0
- package/dist/utils/activity-logging.d.ts.map +1 -0
- package/dist/utils/activity-logging.js +162 -0
- package/dist/utils/activity-logging.js.map +1 -0
- package/dist/utils/batch.d.ts +2 -2
- package/dist/utils/batch.d.ts.map +1 -1
- package/dist/utils/batch.js +8 -8
- package/dist/utils/batch.js.map +1 -1
- package/dist/utils/cleanup.d.ts +21 -13
- package/dist/utils/cleanup.d.ts.map +1 -1
- package/dist/utils/cleanup.js +31 -24
- package/dist/utils/cleanup.js.map +1 -1
- package/dist/utils/debug-logger.d.ts +44 -0
- package/dist/utils/debug-logger.d.ts.map +1 -0
- package/dist/utils/debug-logger.js +116 -0
- package/dist/utils/debug-logger.js.map +1 -0
- package/dist/utils/help-tracking.d.ts +55 -0
- package/dist/utils/help-tracking.d.ts.map +1 -0
- package/dist/utils/help-tracking.js +88 -0
- package/dist/utils/help-tracking.js.map +1 -0
- package/dist/utils/retention.d.ts +7 -7
- package/dist/utils/retention.d.ts.map +1 -1
- package/dist/utils/retention.js +12 -12
- package/dist/utils/retention.js.map +1 -1
- package/dist/utils/task-stale-detection.d.ts +15 -13
- package/dist/utils/task-stale-detection.d.ts.map +1 -1
- package/dist/utils/task-stale-detection.js +100 -302
- package/dist/utils/task-stale-detection.js.map +1 -1
- package/dist/utils/token-estimation.d.ts +72 -0
- package/dist/utils/token-estimation.d.ts.map +1 -0
- package/dist/utils/token-estimation.js +71 -0
- package/dist/utils/token-estimation.js.map +1 -0
- package/dist/utils/token-logging.d.ts +48 -0
- package/dist/utils/token-logging.d.ts.map +1 -0
- package/dist/utils/token-logging.js +112 -0
- package/dist/utils/token-logging.js.map +1 -0
- package/dist/utils/view-queries.d.ts +34 -0
- package/dist/utils/view-queries.d.ts.map +1 -0
- package/dist/utils/view-queries.js +192 -0
- package/dist/utils/view-queries.js.map +1 -0
- package/dist/watcher/file-watcher.d.ts.map +1 -1
- package/dist/watcher/file-watcher.js +25 -11
- package/dist/watcher/file-watcher.js.map +1 -1
- package/docs/BEST_PRACTICES.md +56 -448
- package/docs/MIGRATION_v3.6.0.md +170 -0
- package/docs/SHARED_CONCEPTS.md +63 -208
- package/docs/TASK_OVERVIEW.md +2 -2
- package/docs/TOOL_SELECTION.md +41 -248
- package/package.json +16 -4
|
@@ -4,10 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { describe, it, beforeEach, afterEach } from 'node:test';
|
|
6
6
|
import assert from 'node:assert/strict';
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
import { runAllMigrations } from '../migrations/index.js';
|
|
10
|
-
import { getOrCreateAgent, transaction } from '../database.js';
|
|
7
|
+
import { initializeDatabase, closeDatabase } from '../database.js';
|
|
8
|
+
import { getOrCreateAgent } from '../database.js';
|
|
11
9
|
/**
|
|
12
10
|
* Test database instance
|
|
13
11
|
*/
|
|
@@ -15,41 +13,54 @@ let testDb;
|
|
|
15
13
|
/**
|
|
16
14
|
* Create an in-memory test database with schema and migrations
|
|
17
15
|
*/
|
|
18
|
-
function createTestDatabase() {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
16
|
+
async function createTestDatabase() {
|
|
17
|
+
const adapter = await initializeDatabase({
|
|
18
|
+
databaseType: 'sqlite',
|
|
19
|
+
connection: {
|
|
20
|
+
filename: ':memory:',
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
// Enable foreign keys for SQLite
|
|
24
|
+
const knex = adapter.getKnex();
|
|
25
|
+
await knex.raw('PRAGMA foreign_keys = ON');
|
|
26
|
+
return adapter;
|
|
25
27
|
}
|
|
26
28
|
/**
|
|
27
29
|
* Helper: Create a test task in 'done' status (ready to archive)
|
|
28
30
|
*/
|
|
29
|
-
function createTestTask(
|
|
30
|
-
const
|
|
31
|
+
async function createTestTask(adapter, title) {
|
|
32
|
+
const knex = adapter.getKnex();
|
|
33
|
+
const agentId = await getOrCreateAgent(adapter, 'test-agent');
|
|
31
34
|
const statusId = 5; // done (ready to archive)
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
const [taskId] = await knex('t_tasks').insert({
|
|
36
|
+
title,
|
|
37
|
+
status_id: statusId,
|
|
38
|
+
priority: 2,
|
|
39
|
+
created_by_agent_id: agentId,
|
|
40
|
+
assigned_agent_id: agentId,
|
|
41
|
+
});
|
|
42
|
+
return taskId;
|
|
37
43
|
}
|
|
38
44
|
/**
|
|
39
45
|
* Helper: Create a pruned file record in audit table
|
|
40
46
|
*/
|
|
41
|
-
function createPrunedFileRecord(
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
async function createPrunedFileRecord(adapter, taskId, filePath) {
|
|
48
|
+
const knex = adapter.getKnex();
|
|
49
|
+
const [id] = await knex('t_task_pruned_files').insert({
|
|
50
|
+
task_id: taskId,
|
|
51
|
+
file_path: filePath,
|
|
52
|
+
pruned_ts: knex.raw('unixepoch()'),
|
|
53
|
+
});
|
|
54
|
+
return id;
|
|
47
55
|
}
|
|
48
56
|
/**
|
|
49
57
|
* Helper: Get task status by ID
|
|
50
58
|
*/
|
|
51
|
-
function getTaskStatus(
|
|
52
|
-
const
|
|
59
|
+
async function getTaskStatus(adapter, taskId) {
|
|
60
|
+
const knex = adapter.getKnex();
|
|
61
|
+
const row = await knex('t_tasks')
|
|
62
|
+
.where({ id: taskId })
|
|
63
|
+
.first('status_id');
|
|
53
64
|
if (!row) {
|
|
54
65
|
throw new Error(`Task not found: ${taskId}`);
|
|
55
66
|
}
|
|
@@ -58,21 +69,26 @@ function getTaskStatus(db, taskId) {
|
|
|
58
69
|
/**
|
|
59
70
|
* Helper: Count pruned file records for a task
|
|
60
71
|
*/
|
|
61
|
-
function countPrunedFiles(
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
72
|
+
async function countPrunedFiles(adapter, taskId) {
|
|
73
|
+
const knex = adapter.getKnex();
|
|
74
|
+
const row = await knex('t_task_pruned_files')
|
|
75
|
+
.where({ task_id: taskId })
|
|
76
|
+
.count('* as count')
|
|
77
|
+
.first();
|
|
78
|
+
return row?.count || 0;
|
|
66
79
|
}
|
|
67
80
|
/**
|
|
68
81
|
* Helper: Archive a task (test version)
|
|
69
82
|
*/
|
|
70
|
-
function archiveTask(
|
|
83
|
+
async function archiveTask(adapter, taskId) {
|
|
71
84
|
const TASK_STATUS_DONE = 5;
|
|
72
85
|
const TASK_STATUS_ARCHIVED = 6;
|
|
73
|
-
|
|
86
|
+
const knex = adapter.getKnex();
|
|
87
|
+
return await knex.transaction(async (trx) => {
|
|
74
88
|
// Check if task is in 'done' status
|
|
75
|
-
const taskRow =
|
|
89
|
+
const taskRow = await trx('t_tasks')
|
|
90
|
+
.where({ id: taskId })
|
|
91
|
+
.first('status_id');
|
|
76
92
|
if (!taskRow) {
|
|
77
93
|
throw new Error(`Task with id ${taskId} not found`);
|
|
78
94
|
}
|
|
@@ -80,20 +96,21 @@ function archiveTask(db, taskId) {
|
|
|
80
96
|
throw new Error(`Task ${taskId} must be in 'done' status to archive`);
|
|
81
97
|
}
|
|
82
98
|
// Update to archived
|
|
83
|
-
|
|
99
|
+
await trx('t_tasks')
|
|
100
|
+
.where({ id: taskId })
|
|
101
|
+
.update({ status_id: TASK_STATUS_ARCHIVED });
|
|
84
102
|
return { success: true, task_id: taskId };
|
|
85
103
|
});
|
|
86
104
|
}
|
|
87
105
|
/**
|
|
88
106
|
* Helper: Get pruned files for a task (test version)
|
|
89
107
|
*/
|
|
90
|
-
function getPrunedFiles(
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
`).all(taskId);
|
|
108
|
+
async function getPrunedFiles(adapter, taskId) {
|
|
109
|
+
const knex = adapter.getKnex();
|
|
110
|
+
const rows = await knex('t_task_pruned_files')
|
|
111
|
+
.where({ task_id: taskId })
|
|
112
|
+
.select('file_path', 'pruned_ts')
|
|
113
|
+
.orderBy('pruned_ts', 'desc');
|
|
97
114
|
return {
|
|
98
115
|
success: true,
|
|
99
116
|
count: rows.length,
|
|
@@ -101,37 +118,37 @@ function getPrunedFiles(db, taskId) {
|
|
|
101
118
|
};
|
|
102
119
|
}
|
|
103
120
|
describe('Auto-pruning: Audit trail persistence after archival', () => {
|
|
104
|
-
beforeEach(() => {
|
|
105
|
-
testDb = createTestDatabase();
|
|
121
|
+
beforeEach(async () => {
|
|
122
|
+
testDb = await createTestDatabase();
|
|
106
123
|
});
|
|
107
|
-
afterEach(() => {
|
|
108
|
-
|
|
124
|
+
afterEach(async () => {
|
|
125
|
+
await closeDatabase();
|
|
109
126
|
});
|
|
110
|
-
it('should preserve audit trail after task archival', () => {
|
|
127
|
+
it('should preserve audit trail after task archival', async () => {
|
|
111
128
|
// 1. Setup: Create task with pruned files
|
|
112
|
-
const taskId = createTestTask(testDb, 'Task with pruned files');
|
|
129
|
+
const taskId = await createTestTask(testDb, 'Task with pruned files');
|
|
113
130
|
// Create multiple pruned file records
|
|
114
131
|
const prunedFileIds = [
|
|
115
|
-
createPrunedFileRecord(testDb, taskId, '/tmp/file1.ts'),
|
|
116
|
-
createPrunedFileRecord(testDb, taskId, '/tmp/file2.ts'),
|
|
117
|
-
createPrunedFileRecord(testDb, taskId, '/tmp/file3.ts')
|
|
132
|
+
await createPrunedFileRecord(testDb, taskId, '/tmp/file1.ts'),
|
|
133
|
+
await createPrunedFileRecord(testDb, taskId, '/tmp/file2.ts'),
|
|
134
|
+
await createPrunedFileRecord(testDb, taskId, '/tmp/file3.ts')
|
|
118
135
|
];
|
|
119
136
|
assert.equal(prunedFileIds.length, 3, 'Should create 3 pruned file records');
|
|
120
137
|
// 2. Verify pruned files exist before archival
|
|
121
|
-
const beforeCount = countPrunedFiles(testDb, taskId);
|
|
138
|
+
const beforeCount = await countPrunedFiles(testDb, taskId);
|
|
122
139
|
assert.equal(beforeCount, 3, 'Should have 3 pruned file records before archival');
|
|
123
140
|
// 3. Archive the task
|
|
124
|
-
const archiveResult = archiveTask(testDb, taskId);
|
|
141
|
+
const archiveResult = await archiveTask(testDb, taskId);
|
|
125
142
|
assert.ok(archiveResult.success, 'Task archival should succeed');
|
|
126
143
|
assert.equal(archiveResult.task_id, taskId);
|
|
127
144
|
// 4. Verify task is archived
|
|
128
|
-
const taskStatus = getTaskStatus(testDb, taskId);
|
|
145
|
+
const taskStatus = await getTaskStatus(testDb, taskId);
|
|
129
146
|
assert.equal(taskStatus, 6, 'Task should be archived (status_id 6)');
|
|
130
147
|
// 5. Verify pruned files still exist (NOT cascade deleted)
|
|
131
|
-
const afterCount = countPrunedFiles(testDb, taskId);
|
|
148
|
+
const afterCount = await countPrunedFiles(testDb, taskId);
|
|
132
149
|
assert.equal(afterCount, 3, 'Should still have 3 pruned file records after archival');
|
|
133
150
|
// 6. Verify get_pruned_files works for archived tasks
|
|
134
|
-
const getPrunedResult = getPrunedFiles(testDb, taskId);
|
|
151
|
+
const getPrunedResult = await getPrunedFiles(testDb, taskId);
|
|
135
152
|
assert.ok(getPrunedResult.success, 'get_pruned_files should work for archived tasks');
|
|
136
153
|
assert.equal(getPrunedResult.count, 3, 'Should return count of 3 pruned files');
|
|
137
154
|
assert.equal(getPrunedResult.pruned_files.length, 3, 'Should return all 3 pruned files');
|
|
@@ -141,43 +158,43 @@ describe('Auto-pruning: Audit trail persistence after archival', () => {
|
|
|
141
158
|
assert.ok(filePaths.includes('/tmp/file2.ts'), 'Should include file2.ts');
|
|
142
159
|
assert.ok(filePaths.includes('/tmp/file3.ts'), 'Should include file3.ts');
|
|
143
160
|
});
|
|
144
|
-
it('should maintain foreign key integrity after archival', () => {
|
|
145
|
-
const taskId = createTestTask(testDb, 'Task for FK test');
|
|
146
|
-
createPrunedFileRecord(testDb, taskId, '/tmp/test.ts');
|
|
161
|
+
it('should maintain foreign key integrity after archival', async () => {
|
|
162
|
+
const taskId = await createTestTask(testDb, 'Task for FK test');
|
|
163
|
+
await createPrunedFileRecord(testDb, taskId, '/tmp/test.ts');
|
|
147
164
|
// Archive task
|
|
148
|
-
const archiveResult = archiveTask(testDb, taskId);
|
|
165
|
+
const archiveResult = await archiveTask(testDb, taskId);
|
|
149
166
|
assert.ok(archiveResult.success, 'Task archival should succeed');
|
|
150
167
|
// Verify foreign key still valid (can JOIN successfully)
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
168
|
+
const knex = testDb.getKnex();
|
|
169
|
+
const result = await knex('t_task_pruned_files as tpf')
|
|
170
|
+
.join('t_tasks as t', 'tpf.task_id', 't.id')
|
|
171
|
+
.where('tpf.task_id', taskId)
|
|
172
|
+
.select('tpf.id', 'tpf.task_id', 't.status_id')
|
|
173
|
+
.first();
|
|
157
174
|
assert.ok(result, 'Foreign key join should succeed');
|
|
158
175
|
assert.equal(result.task_id, taskId, 'Task ID should match');
|
|
159
176
|
assert.equal(result.status_id, 6, 'Task status should be archived (6)');
|
|
160
177
|
});
|
|
161
|
-
it('should handle zero pruned files for archived task', () => {
|
|
162
|
-
const taskId = createTestTask(testDb, 'Task with no pruned files');
|
|
178
|
+
it('should handle zero pruned files for archived task', async () => {
|
|
179
|
+
const taskId = await createTestTask(testDb, 'Task with no pruned files');
|
|
163
180
|
// Archive without any pruned files
|
|
164
|
-
const archiveResult = archiveTask(testDb, taskId);
|
|
181
|
+
const archiveResult = await archiveTask(testDb, taskId);
|
|
165
182
|
assert.ok(archiveResult.success);
|
|
166
183
|
// Query pruned files - should return empty array
|
|
167
|
-
const getPrunedResult = getPrunedFiles(testDb, taskId);
|
|
184
|
+
const getPrunedResult = await getPrunedFiles(testDb, taskId);
|
|
168
185
|
assert.ok(getPrunedResult.success);
|
|
169
186
|
assert.equal(getPrunedResult.count, 0);
|
|
170
187
|
assert.equal(getPrunedResult.pruned_files.length, 0);
|
|
171
188
|
});
|
|
172
|
-
it('should preserve pruned file timestamps after archival', () => {
|
|
173
|
-
const taskId = createTestTask(testDb, 'Task for timestamp test');
|
|
189
|
+
it('should preserve pruned file timestamps after archival', async () => {
|
|
190
|
+
const taskId = await createTestTask(testDb, 'Task for timestamp test');
|
|
174
191
|
// Create pruned file with explicit timestamp check
|
|
175
192
|
const beforeTs = Math.floor(Date.now() / 1000);
|
|
176
|
-
createPrunedFileRecord(testDb, taskId, '/tmp/timestamped.ts');
|
|
193
|
+
await createPrunedFileRecord(testDb, taskId, '/tmp/timestamped.ts');
|
|
177
194
|
// Archive task
|
|
178
|
-
archiveTask(testDb, taskId);
|
|
195
|
+
await archiveTask(testDb, taskId);
|
|
179
196
|
// Get pruned files and verify timestamp
|
|
180
|
-
const getPrunedResult = getPrunedFiles(testDb, taskId);
|
|
197
|
+
const getPrunedResult = await getPrunedFiles(testDb, taskId);
|
|
181
198
|
assert.equal(getPrunedResult.pruned_files.length, 1);
|
|
182
199
|
const prunedFile = getPrunedResult.pruned_files[0];
|
|
183
200
|
assert.ok(prunedFile.pruned_ts, 'Should have pruned_ts timestamp');
|
|
@@ -187,44 +204,45 @@ describe('Auto-pruning: Audit trail persistence after archival', () => {
|
|
|
187
204
|
assert.ok(prunedAt >= beforeTs, 'Timestamp should be after or equal to test start');
|
|
188
205
|
assert.ok(prunedAt <= beforeTs + 5, 'Timestamp should be within 5 seconds');
|
|
189
206
|
});
|
|
190
|
-
it('should handle multiple archived tasks with pruned files', () => {
|
|
207
|
+
it('should handle multiple archived tasks with pruned files', async () => {
|
|
191
208
|
// Create multiple tasks with pruned files
|
|
192
|
-
const task1Id = createTestTask(testDb, 'Task 1');
|
|
193
|
-
const task2Id = createTestTask(testDb, 'Task 2');
|
|
194
|
-
const task3Id = createTestTask(testDb, 'Task 3');
|
|
195
|
-
createPrunedFileRecord(testDb, task1Id, '/tmp/task1-file1.ts');
|
|
196
|
-
createPrunedFileRecord(testDb, task1Id, '/tmp/task1-file2.ts');
|
|
197
|
-
createPrunedFileRecord(testDb, task2Id, '/tmp/task2-file1.ts');
|
|
198
|
-
createPrunedFileRecord(testDb, task3Id, '/tmp/task3-file1.ts');
|
|
199
|
-
createPrunedFileRecord(testDb, task3Id, '/tmp/task3-file2.ts');
|
|
200
|
-
createPrunedFileRecord(testDb, task3Id, '/tmp/task3-file3.ts');
|
|
209
|
+
const task1Id = await createTestTask(testDb, 'Task 1');
|
|
210
|
+
const task2Id = await createTestTask(testDb, 'Task 2');
|
|
211
|
+
const task3Id = await createTestTask(testDb, 'Task 3');
|
|
212
|
+
await createPrunedFileRecord(testDb, task1Id, '/tmp/task1-file1.ts');
|
|
213
|
+
await createPrunedFileRecord(testDb, task1Id, '/tmp/task1-file2.ts');
|
|
214
|
+
await createPrunedFileRecord(testDb, task2Id, '/tmp/task2-file1.ts');
|
|
215
|
+
await createPrunedFileRecord(testDb, task3Id, '/tmp/task3-file1.ts');
|
|
216
|
+
await createPrunedFileRecord(testDb, task3Id, '/tmp/task3-file2.ts');
|
|
217
|
+
await createPrunedFileRecord(testDb, task3Id, '/tmp/task3-file3.ts');
|
|
201
218
|
// Archive all tasks
|
|
202
|
-
archiveTask(testDb, task1Id);
|
|
203
|
-
archiveTask(testDb, task2Id);
|
|
204
|
-
archiveTask(testDb, task3Id);
|
|
219
|
+
await archiveTask(testDb, task1Id);
|
|
220
|
+
await archiveTask(testDb, task2Id);
|
|
221
|
+
await archiveTask(testDb, task3Id);
|
|
205
222
|
// Verify each task's pruned files are isolated and preserved
|
|
206
|
-
const task1Pruned = getPrunedFiles(testDb, task1Id);
|
|
223
|
+
const task1Pruned = await getPrunedFiles(testDb, task1Id);
|
|
207
224
|
assert.equal(task1Pruned.count, 2, 'Task 1 should have 2 pruned files');
|
|
208
|
-
const task2Pruned = getPrunedFiles(testDb, task2Id);
|
|
225
|
+
const task2Pruned = await getPrunedFiles(testDb, task2Id);
|
|
209
226
|
assert.equal(task2Pruned.count, 1, 'Task 2 should have 1 pruned file');
|
|
210
|
-
const task3Pruned = getPrunedFiles(testDb, task3Id);
|
|
227
|
+
const task3Pruned = await getPrunedFiles(testDb, task3Id);
|
|
211
228
|
assert.equal(task3Pruned.count, 3, 'Task 3 should have 3 pruned files');
|
|
212
229
|
// Verify file paths are isolated (no cross-contamination)
|
|
213
230
|
const task1Paths = task1Pruned.pruned_files.map((f) => f.file_path);
|
|
214
231
|
assert.ok(!task1Paths.includes('/tmp/task2-file1.ts'), 'Task 1 should not include Task 2 files');
|
|
215
232
|
assert.ok(!task1Paths.includes('/tmp/task3-file1.ts'), 'Task 1 should not include Task 3 files');
|
|
216
233
|
});
|
|
217
|
-
it('should verify CASCADE constraint when task is deleted (not archived)', () => {
|
|
234
|
+
it('should verify CASCADE constraint when task is deleted (not archived)', async () => {
|
|
218
235
|
// This test verifies the ON DELETE CASCADE behavior
|
|
219
|
-
const taskId = createTestTask(testDb, 'Task for deletion test');
|
|
220
|
-
createPrunedFileRecord(testDb, taskId, '/tmp/cascade-test.ts');
|
|
236
|
+
const taskId = await createTestTask(testDb, 'Task for deletion test');
|
|
237
|
+
await createPrunedFileRecord(testDb, taskId, '/tmp/cascade-test.ts');
|
|
221
238
|
// Verify pruned file exists
|
|
222
|
-
const beforeCount = countPrunedFiles(testDb, taskId);
|
|
239
|
+
const beforeCount = await countPrunedFiles(testDb, taskId);
|
|
223
240
|
assert.equal(beforeCount, 1);
|
|
224
241
|
// DELETE task (not archive) - should cascade delete pruned files
|
|
225
|
-
|
|
242
|
+
const knex = testDb.getKnex();
|
|
243
|
+
await knex('t_tasks').where({ id: taskId }).delete();
|
|
226
244
|
// Verify pruned file was cascade deleted
|
|
227
|
-
const afterCount = countPrunedFiles(testDb, taskId);
|
|
245
|
+
const afterCount = await countPrunedFiles(testDb, taskId);
|
|
228
246
|
assert.equal(afterCount, 0, 'Pruned files should be CASCADE deleted when task is deleted');
|
|
229
247
|
});
|
|
230
248
|
console.log('\n✅ All auto-pruning persistence tests passed!\n');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks.auto-pruning-persistence.test.js","sourceRoot":"","sources":["../../src/tests/tasks.auto-pruning-persistence.test.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,
|
|
1
|
+
{"version":3,"file":"tasks.auto-pruning-persistence.test.js","sourceRoot":"","sources":["../../src/tests/tasks.auto-pruning-persistence.test.ts"],"names":[],"mappings":"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"}
|