Files
AgentCompany/src/main/bootstrap/recover-scheduled-posts.ts
T
ZacharyZhang-NY a2a90f00e6 refactor(bootstrap): extract bootstrap-application into orchestrator + modules
Splits the 391-line bootstrapApplication god function into a thin
orchestrator plus 7 focused modules under src/main/bootstrap/:
prepare-logger, prepare-database, prepare-services (service graph +
ipc wiring), wire-api-server (14-callback dictionary), recover-
scheduled-posts, run-startup-health-checks, recover-interrupted-tasks
(crash notification + clean-shutdown task resumption). Original
startup order, before-quit cleanup, and error handling are preserved;
the entry file drops to 153 lines.
2026-04-16 23:34:13 -04:00

46 lines
1.8 KiB
TypeScript

import type { AppDatabase } from "../database";
interface Logger {
info: (...args: unknown[]) => void;
warn: (...args: unknown[]) => void;
}
export interface RecoverScheduledPostsDeps {
db: AppDatabase;
logger: Logger;
isQuittingRef: { current: boolean };
getBrowserActionService: () => { dispatchBrowserAction: (actionId: string, companyId: string) => Promise<void> } | null;
}
export function recoverScheduledPosts(deps: RecoverScheduledPostsDeps): Set<ReturnType<typeof setTimeout>> {
const timers = new Set<ReturnType<typeof setTimeout>>();
try {
const snapshot = deps.db.listSnapshot();
for (const company of snapshot.companies) {
const queuedActions = deps.db.listBrowserActions(company.id, { status: "queued" });
for (const action of queuedActions) {
if (!action.payloadJson) continue;
try {
const payload = JSON.parse(action.payloadJson) as { scheduledAt?: string };
if (!payload.scheduledAt) continue;
const delay = new Date(payload.scheduledAt).getTime() - Date.now();
if (delay <= 0) continue;
const timer = setTimeout(() => {
timers.delete(timer);
if (deps.isQuittingRef.current) return;
const browserActions = deps.getBrowserActionService();
if (browserActions) {
void browserActions.dispatchBrowserAction(action.id, company.id);
}
}, delay);
timers.add(timer);
deps.logger.info(`[bootstrap] Re-registered scheduled post timer: action ${action.id} in ${Math.round(delay / 1000)}s`);
} catch { /* ignore malformed payload */ }
}
}
} catch (error) {
deps.logger.warn(`[bootstrap] Failed to re-register scheduled post timers: ${error instanceof Error ? error.message : String(error)}`);
}
return timers;
}