feat(client): summarize digital sync failures
This commit is contained in:
@@ -45,6 +45,18 @@ export interface DigitalEmployeeSyncAttempt {
|
||||
finishedAt: string;
|
||||
}
|
||||
|
||||
export interface DigitalEmployeeSyncFailureGroup {
|
||||
entityType: string;
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface DigitalEmployeeSyncFailureSummary {
|
||||
total: number;
|
||||
dueForRetry: number;
|
||||
backoff: number;
|
||||
byEntityType: DigitalEmployeeSyncFailureGroup[];
|
||||
}
|
||||
|
||||
export interface DigitalEmployeeSyncFailure {
|
||||
id: string;
|
||||
entityType: string;
|
||||
@@ -87,6 +99,7 @@ export interface DigitalEmployeeSyncStatus {
|
||||
failed: number;
|
||||
lastSyncAt: string | null;
|
||||
lastSyncError: string | null;
|
||||
failureSummary: DigitalEmployeeSyncFailureSummary;
|
||||
recentFailures: DigitalEmployeeSyncFailure[];
|
||||
}
|
||||
|
||||
@@ -123,6 +136,7 @@ export function getDigitalEmployeeSyncStatus(): DigitalEmployeeSyncStatus {
|
||||
failed: countOutbox("failed"),
|
||||
lastSyncAt,
|
||||
lastSyncError,
|
||||
failureSummary: readFailureSummary(),
|
||||
recentFailures: readRecentFailures(config),
|
||||
};
|
||||
}
|
||||
@@ -467,6 +481,43 @@ function countOutbox(status: string): number {
|
||||
return row?.count ?? 0;
|
||||
}
|
||||
|
||||
function readFailureSummary(): DigitalEmployeeSyncFailureSummary {
|
||||
const db = getDb();
|
||||
if (!db) return { total: 0, dueForRetry: 0, backoff: 0, byEntityType: [] };
|
||||
const rows = db
|
||||
.prepare(
|
||||
`
|
||||
SELECT entity_type, attempts, last_attempt_at
|
||||
FROM digital_sync_outbox
|
||||
WHERE status = 'failed'
|
||||
`,
|
||||
)
|
||||
.all() as Array<{
|
||||
entity_type: string;
|
||||
attempts: number;
|
||||
last_attempt_at: string | null;
|
||||
}>;
|
||||
const groups = new Map<string, number>();
|
||||
let dueForRetry = 0;
|
||||
|
||||
for (const row of rows) {
|
||||
groups.set(row.entity_type, (groups.get(row.entity_type) || 0) + 1);
|
||||
const nextRetryAt = nextRetryAtForFailure(row.last_attempt_at, row.attempts);
|
||||
if (!nextRetryAt || Date.now() >= Date.parse(nextRetryAt)) {
|
||||
dueForRetry += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
total: rows.length,
|
||||
dueForRetry,
|
||||
backoff: rows.length - dueForRetry,
|
||||
byEntityType: Array.from(groups.entries())
|
||||
.map(([entityType, count]) => ({ entityType, count }))
|
||||
.sort((left, right) => right.count - left.count),
|
||||
};
|
||||
}
|
||||
|
||||
function readRecentFailures(
|
||||
config: DigitalEmployeeSyncConfig,
|
||||
limit = 3,
|
||||
|
||||
Reference in New Issue
Block a user