feat(FN-3546): add approval request persistence layer with SQLite store and

Merged branches introduce an approval-request persistence layer (FN-3546) with a new `ApprovalRequestStore` in core, schema v68 with audit history support, and updated dashboard task/API tests, alongside a minor task-schema extension (FN-3429) adding `branch`/`baseBranch` fields to the task model an

Fusion-Task-Id: FN-3546
This commit is contained in:
Fusion
2026-05-07 13:01:42 -07:00
committed by gsxdsm
parent dcead400c9
commit 3f7aedd4fd
13 changed files with 675 additions and 31 deletions

View File

@@ -88,7 +88,7 @@ export function probeFts5(db: DatabaseSync): boolean {
// ── Schema Definition ────────────────────────────────────────────────
const SCHEMA_VERSION = 67;
const SCHEMA_VERSION = 68;
function normalizeTaskComments(
steeringComments: SteeringComment[] | undefined,
@@ -2683,6 +2683,51 @@ export class Database {
});
}
if (version < 68) {
this.applyMigration(68, () => {
this.db.exec(`
CREATE TABLE IF NOT EXISTS approval_requests (
id TEXT PRIMARY KEY,
status TEXT NOT NULL,
requesterActorId TEXT NOT NULL,
requesterActorType TEXT NOT NULL,
requesterActorName TEXT NOT NULL,
targetActionCategory TEXT NOT NULL,
targetActionOperation TEXT NOT NULL,
targetActionSummary TEXT NOT NULL,
targetResourceType TEXT NOT NULL,
targetResourceId TEXT NOT NULL,
targetContext TEXT,
taskId TEXT,
runId TEXT,
requestedAt TEXT NOT NULL,
decidedAt TEXT,
completedAt TEXT,
createdAt TEXT NOT NULL,
updatedAt TEXT NOT NULL
)
`);
this.db.exec(`CREATE INDEX IF NOT EXISTS idxApprovalRequestsStatusCreatedAt ON approval_requests(status, createdAt)`);
this.db.exec(`CREATE INDEX IF NOT EXISTS idxApprovalRequestsRequesterCreatedAt ON approval_requests(requesterActorId, createdAt)`);
this.db.exec(`CREATE INDEX IF NOT EXISTS idxApprovalRequestsTaskCreatedAt ON approval_requests(taskId, createdAt)`);
this.db.exec(`
CREATE TABLE IF NOT EXISTS approval_request_audit_events (
id TEXT PRIMARY KEY,
requestId TEXT NOT NULL,
eventType TEXT NOT NULL,
actorId TEXT NOT NULL,
actorType TEXT NOT NULL,
actorName TEXT NOT NULL,
note TEXT,
createdAt TEXT NOT NULL,
FOREIGN KEY (requestId) REFERENCES approval_requests(id) ON DELETE CASCADE
)
`);
this.db.exec(`CREATE INDEX IF NOT EXISTS idxApprovalRequestAuditRequestCreatedAt ON approval_request_audit_events(requestId, createdAt, id)`);
});
}
}
/**