perf(dashboard): index tasks.column/updatedAt and debounce detail fetches

Speeds up task-list load and interaction for projects with 100+ tasks.

- Migration 59 adds idxTasksColumn and idxTasksUpdatedAt; listTasks()
  filters by "column" on every board load and SSE/refresh paths sort by
  updatedAt, so each query was previously a full table scan plus a temp
  B-tree sort.
- Debounce handleEmbeddedOpenDetail in ListView so rapid keyboard/mouse
  navigation no longer fires a heavy /tasks/:id (log + comments) per
  selection; stale-target requests short-circuit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-05-03 01:06:18 -07:00
parent 2ce4351724
commit 8dcf25c53a
9 changed files with 86 additions and 32 deletions

View File

@@ -88,7 +88,7 @@ export function probeFts5(db: DatabaseSync): boolean {
// ── Schema Definition ────────────────────────────────────────────────
const SCHEMA_VERSION = 58;
const SCHEMA_VERSION = 59;
function normalizeTaskComments(
steeringComments: SteeringComment[] | undefined,
@@ -2246,6 +2246,17 @@ export class Database {
});
}
// Dashboard load performance for projects with 100+ tasks.
// listTasks() filters by "column" and the SSE/refresh paths sort by
// updatedAt; neither column had an index, so each board load did a
// full table scan + temp B-tree sort.
if (version < 59) {
this.applyMigration(59, () => {
this.db.exec(`CREATE INDEX IF NOT EXISTS idxTasksColumn ON tasks("column")`);
this.db.exec(`CREATE INDEX IF NOT EXISTS idxTasksUpdatedAt ON tasks(updatedAt DESC)`);
});
}
}
/**