feat(client): persist digital governance events
This commit is contained in:
@@ -66,6 +66,7 @@ export interface DigitalEmployeeSyncFailure {
|
||||
id: string;
|
||||
entityType: string;
|
||||
entityId: string;
|
||||
entitySummary: DigitalEmployeeSyncEntitySummary | null;
|
||||
operation: string;
|
||||
attempts: number;
|
||||
lastAttemptAt: string | null;
|
||||
@@ -78,6 +79,12 @@ export interface DigitalEmployeeSyncFailure {
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface DigitalEmployeeSyncEntitySummary {
|
||||
title: string | null;
|
||||
status: string | null;
|
||||
summary: string | null;
|
||||
}
|
||||
|
||||
interface SyncAck {
|
||||
outbox_id?: string;
|
||||
id?: string;
|
||||
@@ -580,6 +587,7 @@ function readRecentFailures(
|
||||
id: row.id,
|
||||
entityType: row.entity_type,
|
||||
entityId: row.entity_id,
|
||||
entitySummary: readEntitySummary(row.entity_type, row.entity_id),
|
||||
operation: row.operation,
|
||||
attempts: row.attempts,
|
||||
lastAttemptAt: row.last_attempt_at,
|
||||
@@ -594,6 +602,58 @@ function readRecentFailures(
|
||||
});
|
||||
}
|
||||
|
||||
function readEntitySummary(
|
||||
entityType: string,
|
||||
entityId: string,
|
||||
): DigitalEmployeeSyncEntitySummary | null {
|
||||
const table = entityTable(entityType);
|
||||
const db = getDigitalEmployeeDb();
|
||||
if (!db || !table) return null;
|
||||
const select = entitySummarySelect(entityType);
|
||||
if (!select) return null;
|
||||
const row = db.prepare(select).get(entityId) as Record<string, unknown> | undefined;
|
||||
if (!row) return null;
|
||||
const payload = parsePayload(String(row.payload ?? "{}"));
|
||||
const payloadSummary = payload && typeof payload === "object" && !Array.isArray(payload)
|
||||
? payload as Record<string, unknown>
|
||||
: {};
|
||||
return {
|
||||
title: stringField(row.title) || stringField(payloadSummary.title) || null,
|
||||
status: stringField(row.status) || stringField(payloadSummary.status) || null,
|
||||
summary:
|
||||
stringField(row.summary) ||
|
||||
stringField(row.objective) ||
|
||||
stringField(row.message) ||
|
||||
stringField(payloadSummary.objective) ||
|
||||
stringField(payloadSummary.message) ||
|
||||
stringField(payloadSummary.summary) ||
|
||||
null,
|
||||
};
|
||||
}
|
||||
|
||||
function entitySummarySelect(entityType: string): string | null {
|
||||
switch (entityType) {
|
||||
case "plan":
|
||||
return "SELECT title, status, objective, payload FROM digital_plans WHERE id = ?";
|
||||
case "task":
|
||||
return "SELECT title, status, NULL AS objective, payload FROM digital_tasks WHERE id = ?";
|
||||
case "run":
|
||||
return "SELECT id AS title, status, NULL AS objective, payload FROM digital_runs WHERE id = ?";
|
||||
case "event":
|
||||
return "SELECT kind AS title, kind AS status, message, payload FROM digital_events WHERE id = ?";
|
||||
case "artifact":
|
||||
return "SELECT name AS title, kind AS status, uri AS summary, payload FROM digital_artifacts WHERE id = ?";
|
||||
case "approval":
|
||||
return "SELECT title, status, NULL AS objective, payload FROM digital_approvals WHERE id = ?";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function stringField(value: unknown): string {
|
||||
return typeof value === "string" && value.trim() ? value.trim() : "";
|
||||
}
|
||||
|
||||
function readAttemptHistory(
|
||||
outboxId: string,
|
||||
limit = 5,
|
||||
|
||||
Reference in New Issue
Block a user