O módulo usa a identidade Supabase, isola cada workspace e registra storage, TTL, runner e biblioteca XLSX como decisões ainda abertas. Co-authored-by: Cursor <cursoragent@cursor.com>
64 lines
2.8 KiB
TypeScript
64 lines
2.8 KiB
TypeScript
import path from "node:path";
|
|
import { createFileDb } from "../src/infra/db/pglite";
|
|
import { createPostgresDb } from "../src/infra/db/postgres";
|
|
import { createCoordinator } from "../src/infra/redis";
|
|
import { createStorage } from "../src/infra/storage";
|
|
import { migrate } from "../src/infra/db/migrate";
|
|
import { cleanupExpired, listQueuedJobIds, readJobForWorker, recoverStaleJobs, runProcess } from "../src/server/spreadsheet-adapter/process-job";
|
|
import { asJson } from "../src/server/spreadsheet-adapter/db-utils";
|
|
import type { JobProgress, RequestContext, Role } from "../src/domain/spreadsheet-adapter/types";
|
|
|
|
const databaseUrl = process.env.DATABASE_URL;
|
|
if (!databaseUrl && process.env.NODE_ENV === "production") {
|
|
throw new Error("DATABASE_URL é obrigatório para o worker.");
|
|
}
|
|
const db = databaseUrl ? createPostgresDb(databaseUrl) : await createFileDb(path.join(process.cwd(), ".data", "pglite"));
|
|
await migrate(db);
|
|
const deps = { db, storage: createStorage(), coordinator: createCoordinator() };
|
|
|
|
async function tick() {
|
|
await recoverStaleJobs(deps);
|
|
await cleanupExpired(deps);
|
|
for (const jobId of await listQueuedJobIds(deps)) {
|
|
const rows = await readJobForWorker(deps, jobId);
|
|
const row = rows[0];
|
|
if (!row) continue;
|
|
const progress = asJson<JobProgress | null>(row.progress, null);
|
|
if (!progress?.sourceId) continue;
|
|
const profile = await db.withService((query) =>
|
|
query.query<{ display_name: string; is_superadmin: boolean; role: Role; workspace_name: string; module_enabled: boolean; allow_upload: boolean }>(
|
|
`select p.display_name, p.is_superadmin, w.name as workspace_name, m.role,
|
|
coalesce(f.enabled, false) as module_enabled,
|
|
coalesce(s.allow_non_admin_model_upload, false) as allow_upload
|
|
from public.profiles p
|
|
join public.workspace_members m on m.user_id = p.id and m.workspace_id = $2
|
|
join public.workspaces w on w.id = $2
|
|
left join public.workspace_module_flags f on f.workspace_id = w.id and f.module_key = 'spreadsheet_adapter'
|
|
left join public.spreadsheet_adapter_settings s on s.workspace_id = w.id
|
|
where p.id = $1`,
|
|
[row.user_id, row.workspace_id],
|
|
),
|
|
);
|
|
const found = profile[0];
|
|
if (!found) continue;
|
|
const ctx: RequestContext = {
|
|
userId: row.user_id,
|
|
displayName: found.display_name,
|
|
isSuperadmin: found.is_superadmin,
|
|
workspaceId: row.workspace_id,
|
|
workspaceName: found.workspace_name,
|
|
role: found.role,
|
|
moduleEnabled: found.module_enabled,
|
|
allowNonAdminModelUpload: found.allow_upload,
|
|
};
|
|
await runProcess(deps, ctx, jobId, progress.sourceId).catch((error) => {
|
|
console.error("worker", error instanceof Error ? error.name : "error");
|
|
});
|
|
}
|
|
}
|
|
|
|
await tick();
|
|
setInterval(() => {
|
|
void tick();
|
|
}, 2000);
|