Implementa o MVP do Adaptador de Planilhas no Elo Pro.
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>
This commit is contained in:
commit
6e23f1533b
144 files changed
+19060
No files matched your search
@@ -0,0 +1,63 @@
|
||||
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);
|
||||
Reference in new issue
Block a user