diff --git a/bridge/src/index.ts b/bridge/src/index.ts index 9f10f37..f2c8eb4 100644 --- a/bridge/src/index.ts +++ b/bridge/src/index.ts @@ -57,13 +57,22 @@ export async function buildApp(): Promise> { async function main() { const config = loadConfig(); - // BASEROW_DATABASE_ID requis pour resolveTableIds. Cf .env + // Soit BASEROW_TABLE_IDS={"personne":609,...} (preferred — DB tokens n'ont pas + // acces a /api/database/tables/database/:id/), soit BASEROW_DATABASE_ID + un JWT + // user (Phase 3+). Cf doc 19 §5. + const tableIdsRaw = process.env.BASEROW_TABLE_IDS; const databaseIdRaw = process.env.BASEROW_DATABASE_ID; - const databaseId = databaseIdRaw ? Number.parseInt(databaseIdRaw, 10) : undefined; - if (!databaseId || Number.isNaN(databaseId)) { - throw new Error('BASEROW_DATABASE_ID env var requis pour resolve table ids'); + let initOpts: Parameters[0]; + if (tableIdsRaw) { + initOpts = { config, tableIds: JSON.parse(tableIdsRaw) }; + } else { + const databaseId = databaseIdRaw ? Number.parseInt(databaseIdRaw, 10) : undefined; + if (!databaseId || Number.isNaN(databaseId)) { + throw new Error('BASEROW_TABLE_IDS ou BASEROW_DATABASE_ID requis'); + } + initOpts = { config, databaseId }; } - await initContainer({ config, databaseId }); + await initContainer(initOpts); const app = await buildApp(); serve({ fetch: app.fetch, port: config.port }, (info) => { diff --git a/bridge/src/repos/baserow-repo.ts b/bridge/src/repos/baserow-repo.ts index cf42b6a..27c4d91 100644 --- a/bridge/src/repos/baserow-repo.ts +++ b/bridge/src/repos/baserow-repo.ts @@ -131,7 +131,13 @@ abstract class BaseRepo { async list(opts: BaserowListOptions = {}): Promise<{ items: TDomain[]; - meta: { page: number; per_page: number; total: number; total_pages: number }; + meta: { + page: number; + per_page: number; + total: number; + total_pages: number; + skipped?: number; + }; }> { const page = opts.page ?? 1; const size = Math.min(opts.size ?? 50, 200); @@ -140,7 +146,22 @@ abstract class BaseRepo { page, size, }); - const items = res.results.map((row) => this.toDomain(row)); + // Skip rows that fail domain validation (split != 100, etc.) plutot que + // de casser la liste entiere. La row corrompue est loguee pour investigation + // manuelle. cf doc 19 §10 : robustness vs visibility. + const items: TDomain[] = []; + let skipped = 0; + for (const row of res.results) { + try { + items.push(this.toDomain(row)); + } catch (err) { + skipped++; + this.logger.warn( + { rowId: row.id, err: err instanceof Error ? err.message : String(err) }, + 'row skipped — invalid domain mapping', + ); + } + } return { items, meta: { @@ -148,6 +169,7 @@ abstract class BaseRepo { per_page: size, total: res.count, total_pages: Math.max(1, Math.ceil(res.count / size)), + ...(skipped > 0 ? { skipped } : {}), }, }; }