import { writeFile } from "node:fs/promises";
import { call, download, waitRun } from "./retriever.mjs";
const batchId = "crm-enrich-2026-09-15"; // identifiant stable, choisi par vous
const crmAccounts = [
{ name: "Acme", domain: "acme.example" },
{ name: "Beta", domain: "beta.example" },
];
// 1. Workspace et import (à ne faire qu'une fois par lot : stockez les ids)
const ws = await call("/v1/workspaces", { method: "POST", body: { name: `Enrichissement ${batchId}` } });
const table = await call(`/v1/workspaces/${ws.id}/tables`, {
method: "POST",
body: {
name: "Comptes CRM",
columns: [
{ key: "name", name: "Entreprise" },
{ key: "domain", name: "Domaine" },
],
// n'envoyer que les champs déclarés en colonnes
rows: crmAccounts.map(({ name, domain }) => ({ name, domain })),
},
});
// 2. Run ciblé. La clé d'idempotence dépend du lot, pas d'un id généré à chaque exécution.
const run = await call("/v1/runs", {
method: "POST",
headers: { "Idempotency-Key": `${batchId}:run` },
body: {
workspace_id: ws.id,
prompt: `Pour chaque entreprise de la table ${table.id}, trouve le nom du CEO et l'URL de son profil LinkedIn. Publie une ligne par entreprise.`,
output: {
type: "tables",
tables: [{
key: "contacts",
row_schema: {
type: "object",
required: ["domain", "ceo_name", "ceo_linkedin_url"],
properties: {
domain: { type: "string" },
ceo_name: { type: ["string", "null"] },
ceo_linkedin_url: { type: ["string", "null"] },
},
},
}],
},
},
});
const done = await waitRun(run.id);
if (done.status !== "completed") throw new Error(done.error?.message ?? done.status);
// 3. Export CSV de la table figée
const exp = await call(`/v1/runs/${run.id}/exports`, { method: "POST", body: { table_key: "contacts", format: "csv" } });
await writeFile("contacts.csv", await download(exp.links.self));