feat(FN-2456): persist task token usage on task records

- Add schema v44 migration to persist task-level token usage totals and first/last usage timestamps on tasks
- Extend core task types, store create/update flows, and exports to round-trip token usage data
- Add migration and TaskStore regression tests for token usage persistence, null clearing, and reinitialization behavior
- Update dashboard async handling and tests to prevent post-unmount state updates and reduce flaky assertion timing
This commit is contained in:
Fusion
2026-04-24 09:44:44 -07:00
committed by gsxdsm
parent d37cb519d3
commit e7a8a952b7
17 changed files with 312 additions and 44 deletions

View File

@@ -86,7 +86,7 @@ export function probeFts5(db: DatabaseSync): boolean {
// ── Schema Definition ────────────────────────────────────────────────
const SCHEMA_VERSION = 43;
const SCHEMA_VERSION = 44;
function normalizeTaskComments(
steeringComments: SteeringComment[] | undefined,
@@ -180,6 +180,12 @@ CREATE TABLE IF NOT EXISTS tasks (
summary TEXT,
thinkingLevel TEXT,
executionMode TEXT DEFAULT 'standard',
tokenUsageInputTokens INTEGER,
tokenUsageOutputTokens INTEGER,
tokenUsageCachedTokens INTEGER,
tokenUsageTotalTokens INTEGER,
tokenUsageFirstUsedAt TEXT,
tokenUsageLastUsedAt TEXT,
createdAt TEXT NOT NULL,
updatedAt TEXT NOT NULL,
columnMovedAt TEXT,
@@ -1714,6 +1720,21 @@ export class Database {
});
}
// Task-level token usage aggregate contract (FN-2456)
// Persists durable token totals and first/last usage timestamps on each task row.
// Existing rows are left null-compatible so legacy tasks deserialize without
// synthesizing usage data.
if (version < 44) {
this.applyMigration(44, () => {
this.addColumnIfMissing("tasks", "tokenUsageInputTokens", "INTEGER");
this.addColumnIfMissing("tasks", "tokenUsageOutputTokens", "INTEGER");
this.addColumnIfMissing("tasks", "tokenUsageCachedTokens", "INTEGER");
this.addColumnIfMissing("tasks", "tokenUsageTotalTokens", "INTEGER");
this.addColumnIfMissing("tasks", "tokenUsageFirstUsedAt", "TEXT");
this.addColumnIfMissing("tasks", "tokenUsageLastUsedAt", "TEXT");
});
}
}
/**