@danielarndt0/cnpj-db-loader 2.4.0-beta.1 → 2.4.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/errors/app-error.ts","../src/core/errors/service-error.ts","../src/core/errors/validation-error.ts","../src/core/utils/filesystem.ts","../src/core/utils/format.ts","../src/core/utils/string.ts","../src/core/utils/path.ts","../src/core/utils/os.ts","../src/config/config-path.ts","../src/services/config.service.ts","../src/services/database.service.ts","../src/services/import/schema-validation.ts","../src/services/import/checkpoints.ts","../src/services/import/materialization-checkpoints.ts","../src/services/import/plan-store.ts","../src/services/import/targets.ts","../src/services/import/staging-schema.ts","../src/dictionary/layouts/companies.layout.ts","../src/dictionary/layouts/domain.layout.ts","../src/dictionary/layouts/establishments.layout.ts","../src/dictionary/layouts/partners.layout.ts","../src/dictionary/layouts/simples.layout.ts","../src/services/import/types.ts","../src/services/database/cleanup.ts","../src/services/dictionary.service.ts","../src/services/doctor.service.ts","../src/services/inspect.service.ts","../src/services/schema.service.ts","../src/services/schema/control.ts","../src/services/schema/shared.ts","../src/services/schema/domain.ts","../src/services/schema/indexes.ts","../src/services/schema/operational.ts","../src/services/schema/staging.ts","../src/services/schema/builders.ts","../src/services/schema/types.ts","../src/services/validate.service.ts","../src/services/extract.service.ts","../src/services/input-mode.service.ts","../src/services/logging.service.ts","../src/services/logging/types.ts","../src/services/logging/entry.ts","../src/services/import/runner.ts","../src/services/import/finalizer.ts","../src/services/import/file-import.ts","../src/services/import/checkpoint-manager.ts","../src/services/import/transform.ts","../src/services/import/parser.ts","../src/services/import/sql.ts","../src/services/import/normalizer.ts","../src/services/import/planning.ts","../src/services/import/source-reader.ts","../src/services/import/copy-from.ts","../src/services/import/staging-writer.ts","../src/services/import/quarantine.ts","../src/services/import/quarantine-writer.ts","../src/services/import/materializer.ts","../src/services/import/materialization-sql.ts","../src/services/import/materialization-lookups.ts","../src/services/import/planner.ts","../src/services/import/schema-capabilities.ts","../src/services/import.service.ts","../src/services/quarantine.service.ts","../src/services/quarantine/queries.ts","../src/services/federal-revenue/client.ts","../src/services/federal-revenue/download.ts","../src/services/federal-revenue/manifest.ts","../src/services/federal-revenue/status.ts","../src/services/federal-revenue/clean.ts","../src/services/federal-revenue/lock.ts","../src/services/sanitize.service.ts","../src/services/sanitize/types.ts","../src/services/sanitize/runner.ts","../src/services/federal-revenue/sync.ts","../src/services/postgres-direct/exporter.ts","../src/services/postgres-direct/csv.ts","../src/services/postgres-direct/script.ts","../src/services/postgres-direct/generator.ts"],"sourcesContent":["export class AppError extends Error {\n public readonly code: string;\n public readonly details?: unknown;\n\n constructor(message: string, code = \"APP_ERROR\", details?: unknown) {\n super(message);\n this.name = \"AppError\";\n this.code = code;\n this.details = details;\n }\n}\n","import { AppError } from \"./app-error.js\";\n\nexport class ServiceError extends AppError {\n constructor(message: string, details?: unknown) {\n super(message, \"SERVICE_ERROR\", details);\n this.name = \"ServiceError\";\n }\n}\n","import { AppError } from \"./app-error.js\";\n\nexport class ValidationError extends AppError {\n constructor(message: string, details?: unknown) {\n super(message, \"VALIDATION_ERROR\", details);\n this.name = \"ValidationError\";\n }\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nexport async function ensureDirectory(filePath: string): Promise<void> {\n await mkdir(dirname(filePath), { recursive: true });\n}\n\nexport async function safeReadText(\n filePath: string,\n): Promise<string | undefined> {\n try {\n return await readFile(filePath, \"utf8\");\n } catch {\n return undefined;\n }\n}\n\nexport async function safeWriteText(\n filePath: string,\n content: string,\n): Promise<void> {\n await ensureDirectory(filePath);\n await writeFile(filePath, content, \"utf8\");\n}\n","export function prettyJson(value: unknown): string {\n return JSON.stringify(value, null, 2);\n}\n","export function toTitleCase(value: string): string {\n return value\n .trim()\n .split(/\\s+/)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())\n .join(\" \");\n}\n","import path from \"node:path\";\n\nexport function defaultExtractedOutputPath(inputPath: string): string {\n return path.join(inputPath, \"extracted\");\n}\n","import os from \"node:os\";\n\nexport type SupportedOs = \"windows\" | \"macos\" | \"linux\" | \"unknown\";\n\nexport function detectOs(): SupportedOs {\n const platform = os.platform();\n\n if (platform === \"win32\") {\n return \"windows\";\n }\n\n if (platform === \"darwin\") {\n return \"macos\";\n }\n\n if (platform === \"linux\") {\n return \"linux\";\n }\n\n return \"unknown\";\n}\n","import os from \"node:os\";\nimport path from \"node:path\";\n\nexport function getConfigFilePath(): string {\n if (process.platform === \"win32\") {\n const appData =\n process.env.APPDATA ?? path.join(os.homedir(), \"AppData\", \"Roaming\");\n return path.join(appData, \"cnpj-db-loader\", \"config.json\");\n }\n\n return path.join(os.homedir(), \".config\", \"cnpj-db-loader\", \"config.json\");\n}\n","import { ValidationError } from \"../core/errors/index.js\";\nimport type { DatabaseConfig } from \"../core/types/index.js\";\nimport { safeReadText, safeWriteText } from \"../core/utils/index.js\";\nimport { getConfigFilePath } from \"../config/config-path.js\";\n\nexport async function readDatabaseConfig(): Promise<DatabaseConfig> {\n const raw = await safeReadText(getConfigFilePath());\n if (!raw) {\n return {};\n }\n\n return JSON.parse(raw) as DatabaseConfig;\n}\n\nexport async function writeDatabaseConfig(\n config: DatabaseConfig,\n): Promise<void> {\n await safeWriteText(getConfigFilePath(), JSON.stringify(config, null, 2));\n}\n\nexport function assertPostgresUrl(url: string): void {\n let parsed: URL;\n\n try {\n parsed = new URL(url);\n } catch {\n throw new ValidationError(\"The provided database URL is not a valid URL.\", {\n url,\n });\n }\n\n if (![\"postgres:\", \"postgresql:\"].includes(parsed.protocol)) {\n throw new ValidationError(\n \"The database URL must use the postgres or postgresql protocol.\",\n { url },\n );\n }\n}\n\nexport async function setDefaultDbUrl(url: string): Promise<void> {\n assertPostgresUrl(url);\n await writeDatabaseConfig({ defaultDbUrl: url });\n}\n\nexport async function resetDefaultDbUrl(): Promise<void> {\n await writeDatabaseConfig({});\n}\n","import { Client } from \"pg\";\n\nimport { ServiceError, ValidationError } from \"../core/errors/index.js\";\nimport { readDatabaseConfig } from \"./config.service.js\";\nimport {\n cleanupDatabaseCheckpoints,\n cleanupDatabaseMaterializedTables,\n cleanupDatabasePlans,\n cleanupDatabaseStaging,\n type CheckpointCleanupPhase,\n type DatabaseCleanupSummary,\n} from \"./database/cleanup.js\";\nimport type { ImportDatasetType } from \"./import/types.js\";\n\nexport type { CheckpointCleanupPhase, DatabaseCleanupSummary };\n\nexport async function resolveDatabaseUrl(override?: string): Promise<string> {\n if (override) {\n return override;\n }\n\n const config = await readDatabaseConfig();\n\n if (!config.defaultDbUrl) {\n throw new ValidationError(\n 'No database connection is configured. Use \"cnpj-db-loader database config set <postgres-url>\" or pass \"--db-url\".',\n );\n }\n\n return config.defaultDbUrl;\n}\n\nexport async function testDatabaseConnection(url: string): Promise<void> {\n const client = new Client({ connectionString: url });\n\n try {\n await client.connect();\n await client.query(\"select 1\");\n } catch (error) {\n throw new ServiceError(\"The PostgreSQL connection test failed.\", error);\n } finally {\n await client.end().catch(() => undefined);\n }\n}\n\nasync function withDatabaseClient<T>(\n dbUrl: string,\n operation: (client: Client) => Promise<T>,\n): Promise<T> {\n const client = new Client({ connectionString: dbUrl });\n await client.connect();\n\n try {\n return await operation(client);\n } catch (error) {\n throw new ServiceError(\"The database maintenance operation failed.\", error);\n } finally {\n await client.end().catch(() => undefined);\n }\n}\n\nexport async function cleanupDatabaseStagingData(\n options: {\n dbUrl?: string;\n dataset?: ImportDatasetType | undefined;\n validatedPath?: string | undefined;\n } = {},\n): Promise<DatabaseCleanupSummary> {\n const dbUrl = await resolveDatabaseUrl(options.dbUrl);\n return withDatabaseClient(dbUrl, async (client) =>\n cleanupDatabaseStaging(client, {\n dbUrl,\n dataset: options.dataset,\n validatedPath: options.validatedPath,\n }),\n );\n}\n\nexport async function cleanupDatabaseMaterializedData(\n options: {\n dbUrl?: string;\n dataset?: ImportDatasetType | undefined;\n } = {},\n): Promise<DatabaseCleanupSummary> {\n const dbUrl = await resolveDatabaseUrl(options.dbUrl);\n return withDatabaseClient(dbUrl, async (client) =>\n cleanupDatabaseMaterializedTables(client, {\n dbUrl,\n dataset: options.dataset,\n }),\n );\n}\n\nexport async function cleanupDatabaseCheckpointsData(\n options: {\n dbUrl?: string;\n phase?: CheckpointCleanupPhase | undefined;\n dataset?: ImportDatasetType | undefined;\n validatedPath?: string | undefined;\n planId?: number | undefined;\n } = {},\n): Promise<DatabaseCleanupSummary> {\n const phase = options.phase ?? \"all\";\n if (![\"load\", \"materialization\", \"all\"].includes(phase)) {\n throw new ValidationError(\n `Unsupported checkpoint cleanup phase: ${phase}. Use load, materialization, or all.`,\n );\n }\n\n const dbUrl = await resolveDatabaseUrl(options.dbUrl);\n return withDatabaseClient(dbUrl, async (client) =>\n cleanupDatabaseCheckpoints(client, {\n dbUrl,\n phase,\n dataset: options.dataset,\n validatedPath: options.validatedPath,\n planId: options.planId,\n }),\n );\n}\n\nexport async function cleanupDatabasePlansData(\n options: {\n dbUrl?: string;\n validatedPath?: string | undefined;\n planId?: number | undefined;\n } = {},\n): Promise<DatabaseCleanupSummary> {\n const dbUrl = await resolveDatabaseUrl(options.dbUrl);\n return withDatabaseClient(dbUrl, async (client) =>\n cleanupDatabasePlans(client, {\n dbUrl,\n validatedPath: options.validatedPath,\n planId: options.planId,\n }),\n );\n}\n\nexport async function resolveDbUrl(override?: string): Promise<string> {\n return resolveDatabaseUrl(override);\n}\n","import type { Client } from \"pg\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\n\nasync function tableExists(\n client: Client,\n tableName: string,\n): Promise<boolean> {\n const result = await client.query<{ exists: string | null }>(\n \"select to_regclass(current_schema() || '.' || $1) as exists\",\n [tableName],\n );\n\n return Boolean(result.rows[0]?.exists);\n}\n\nasync function readColumnNames(\n client: Client,\n tableName: string,\n): Promise<Set<string>> {\n const result = await client.query<{ column_name: string }>(\n `select column_name\n from information_schema.columns\n where table_schema = current_schema()\n and table_name = $1`,\n [tableName],\n );\n\n return new Set(result.rows.map((row) => row.column_name));\n}\n\nexport async function ensureTableShape(\n client: Client,\n input: {\n tableName: string;\n requiredColumns: readonly string[];\n helpMessage: string;\n },\n): Promise<void> {\n const exists = await tableExists(client, input.tableName);\n\n if (!exists) {\n throw new ValidationError(\n `${input.helpMessage} Missing table: ${input.tableName}.`,\n );\n }\n\n const availableColumns = await readColumnNames(client, input.tableName);\n const missingColumns = input.requiredColumns.filter(\n (columnName) => !availableColumns.has(columnName),\n );\n\n if (missingColumns.length > 0) {\n throw new ValidationError(\n `${input.helpMessage} Table ${input.tableName} is missing required columns: ${missingColumns.join(\", \")}.`,\n );\n }\n}\n","import { Client } from \"pg\";\n\nimport { ensureTableShape } from \"./schema-validation.js\";\nimport type {\n ImportCheckpointRecord,\n ImportCheckpointStatus,\n ImportDatasetPlan,\n} from \"./types.js\";\n\nexport async function ensureCheckpointTable(client: Client): Promise<void> {\n await ensureTableShape(client, {\n tableName: \"import_checkpoints\",\n requiredColumns: [\n \"dataset\",\n \"file_path\",\n \"file_size\",\n \"file_mtime\",\n \"byte_offset\",\n \"rows_committed\",\n \"status\",\n \"last_error\",\n \"updated_at\",\n ],\n helpMessage:\n 'The import checkpoint schema is required. Run \"cnpj-db-loader schema generate --profile full\" and apply the SQL before importing.',\n });\n}\n\nexport async function readCheckpoint(\n client: Client,\n dataset: ImportCheckpointRecord[\"dataset\"],\n filePath: string,\n fileSize: number,\n fileMtime: Date,\n): Promise<ImportCheckpointRecord> {\n const existing = await client.query<{\n file_size: string;\n file_mtime: Date;\n byte_offset: string;\n rows_committed: string;\n status: ImportCheckpointStatus;\n last_error: string | null;\n }>(\n `select file_size, file_mtime, byte_offset, rows_committed, status, last_error\n from import_checkpoints\n where dataset = $1 and file_path = $2`,\n [dataset, filePath],\n );\n\n const baseRecord: ImportCheckpointRecord = {\n dataset,\n filePath,\n fileSize,\n fileMtime,\n byteOffset: 0,\n rowsCommitted: 0,\n status: \"pending\",\n lastError: null,\n };\n\n if (existing.rowCount === 0) {\n return baseRecord;\n }\n\n const row = existing.rows[0]!;\n const checkpoint: ImportCheckpointRecord = {\n dataset,\n filePath,\n fileSize: Number.parseInt(row.file_size, 10),\n fileMtime: new Date(row.file_mtime),\n byteOffset: Number.parseInt(row.byte_offset, 10),\n rowsCommitted: Number.parseInt(row.rows_committed, 10),\n status: row.status,\n lastError: row.last_error,\n };\n\n const sameMetadata =\n checkpoint.fileSize === fileSize &&\n checkpoint.fileMtime.getTime() === fileMtime.getTime();\n\n if (!sameMetadata) {\n return baseRecord;\n }\n\n return checkpoint;\n}\n\nexport async function writeCheckpoint(\n client: Client,\n checkpoint: ImportCheckpointRecord,\n): Promise<void> {\n await client.query(\n `insert into import_checkpoints (\n dataset,\n file_path,\n file_size,\n file_mtime,\n byte_offset,\n rows_committed,\n status,\n last_error,\n updated_at\n ) values ($1, $2, $3, $4, $5, $6, $7, $8, now())\n on conflict (dataset, file_path)\n do update set\n file_size = excluded.file_size,\n file_mtime = excluded.file_mtime,\n byte_offset = excluded.byte_offset,\n rows_committed = excluded.rows_committed,\n status = excluded.status,\n last_error = excluded.last_error,\n updated_at = now()`,\n [\n checkpoint.dataset,\n checkpoint.filePath,\n checkpoint.fileSize,\n checkpoint.fileMtime,\n checkpoint.byteOffset,\n checkpoint.rowsCommitted,\n checkpoint.status,\n checkpoint.lastError ?? null,\n ],\n );\n}\n\nexport async function markCheckpointFailed(\n client: Client,\n checkpoint: ImportCheckpointRecord,\n errorMessage: string,\n): Promise<void> {\n await writeCheckpoint(client, {\n ...checkpoint,\n status: \"failed\",\n lastError: errorMessage,\n });\n}\n\nexport async function hydratePlanWithCheckpoints(\n client: Client,\n datasets: ImportDatasetPlan[],\n batchSize: number,\n): Promise<{\n committedRows: number;\n committedBatches: number;\n completedFiles: number;\n resumedFiles: number;\n skippedCompletedFiles: number;\n}> {\n let committedRows = 0;\n let committedBatches = 0;\n let completedFiles = 0;\n let resumedFiles = 0;\n let skippedCompletedFiles = 0;\n\n for (const datasetPlan of datasets) {\n for (const filePlan of datasetPlan.files) {\n const checkpoint = await readCheckpoint(\n client,\n datasetPlan.dataset,\n filePlan.absolutePath,\n filePlan.fileSize,\n filePlan.fileMtime,\n );\n filePlan.checkpoint = checkpoint;\n\n if (checkpoint.rowsCommitted > 0) {\n committedRows += checkpoint.rowsCommitted;\n committedBatches += Math.min(\n filePlan.totalBatches,\n Math.ceil(checkpoint.rowsCommitted / batchSize),\n );\n }\n\n if (\n checkpoint.status === \"completed\" &&\n checkpoint.byteOffset >= filePlan.fileSize\n ) {\n completedFiles += 1;\n skippedCompletedFiles += 1;\n } else if (checkpoint.byteOffset > 0 || checkpoint.rowsCommitted > 0) {\n resumedFiles += 1;\n }\n }\n }\n\n return {\n committedRows,\n committedBatches,\n completedFiles,\n resumedFiles,\n skippedCompletedFiles,\n };\n}\n","import type { Client } from \"pg\";\n\nimport { ensureTableShape } from \"./schema-validation.js\";\nimport type { ImportPhaseStatus } from \"./types.js\";\n\nexport type MaterializationCheckpointRecord = {\n planId: number;\n dataset: string;\n targetTable: string;\n status: ImportPhaseStatus;\n rowsMaterialized: number;\n lastStagingId: number;\n chunksCompleted: number;\n lastError: string | null;\n startedAt: Date | null;\n completedAt: Date | null;\n updatedAt: Date;\n stagingRowCountVerified: number | null;\n stagingMaxStagingIdVerified: number | null;\n stagingValidatedAt: Date | null;\n lookupReconciliationStatus: ImportPhaseStatus;\n lookupReconciliationRowCountVerified: number | null;\n lookupReconciliationMaxStagingIdVerified: number | null;\n lookupReconciliationCompletedAt: Date | null;\n lastChunkFirstStagingId: number;\n lastChunkLastStagingId: number;\n lastChunkRows: number;\n};\n\ntype MaterializationCheckpointRow = {\n plan_id: string;\n dataset: string;\n target_table: string;\n status: ImportPhaseStatus;\n rows_materialized: string;\n last_staging_id: string;\n chunks_completed: string;\n last_error: string | null;\n started_at: Date | null;\n completed_at: Date | null;\n updated_at: Date;\n staging_row_count_verified: string | null;\n staging_max_staging_id_verified: string | null;\n staging_validated_at: Date | null;\n lookup_reconciliation_status: ImportPhaseStatus | null;\n lookup_reconciliation_row_count_verified: string | null;\n lookup_reconciliation_max_staging_id_verified: string | null;\n lookup_reconciliation_completed_at: Date | null;\n last_chunk_first_staging_id: string | null;\n last_chunk_last_staging_id: string | null;\n last_chunk_rows: string | null;\n};\n\nfunction parseNullableInt(value: string | null): number | null {\n return value === null ? null : Number.parseInt(value, 10);\n}\n\nfunction mapCheckpointRow(\n row: MaterializationCheckpointRow,\n): MaterializationCheckpointRecord {\n return {\n planId: Number.parseInt(row.plan_id, 10),\n dataset: row.dataset,\n targetTable: row.target_table,\n status: row.status,\n rowsMaterialized: Number.parseInt(row.rows_materialized, 10),\n lastStagingId: Number.parseInt(row.last_staging_id, 10),\n chunksCompleted: Number.parseInt(row.chunks_completed, 10),\n lastError: row.last_error,\n startedAt: row.started_at ? new Date(row.started_at) : null,\n completedAt: row.completed_at ? new Date(row.completed_at) : null,\n updatedAt: new Date(row.updated_at),\n stagingRowCountVerified: parseNullableInt(row.staging_row_count_verified),\n stagingMaxStagingIdVerified: parseNullableInt(\n row.staging_max_staging_id_verified,\n ),\n stagingValidatedAt: row.staging_validated_at\n ? new Date(row.staging_validated_at)\n : null,\n lookupReconciliationStatus: row.lookup_reconciliation_status ?? \"pending\",\n lookupReconciliationRowCountVerified: parseNullableInt(\n row.lookup_reconciliation_row_count_verified,\n ),\n lookupReconciliationMaxStagingIdVerified: parseNullableInt(\n row.lookup_reconciliation_max_staging_id_verified,\n ),\n lookupReconciliationCompletedAt: row.lookup_reconciliation_completed_at\n ? new Date(row.lookup_reconciliation_completed_at)\n : null,\n lastChunkFirstStagingId: Number.parseInt(\n row.last_chunk_first_staging_id ?? \"0\",\n 10,\n ),\n lastChunkLastStagingId: Number.parseInt(\n row.last_chunk_last_staging_id ?? \"0\",\n 10,\n ),\n lastChunkRows: Number.parseInt(row.last_chunk_rows ?? \"0\", 10),\n };\n}\n\nexport async function ensureMaterializationCheckpointTable(\n client: Client,\n): Promise<void> {\n await ensureTableShape(client, {\n tableName: \"import_materialization_checkpoints\",\n requiredColumns: [\n \"plan_id\",\n \"dataset\",\n \"target_table\",\n \"status\",\n \"rows_materialized\",\n \"last_staging_id\",\n \"chunks_completed\",\n \"last_error\",\n \"started_at\",\n \"completed_at\",\n \"updated_at\",\n \"staging_row_count_verified\",\n \"staging_max_staging_id_verified\",\n \"staging_validated_at\",\n \"lookup_reconciliation_status\",\n \"lookup_reconciliation_row_count_verified\",\n \"lookup_reconciliation_max_staging_id_verified\",\n \"lookup_reconciliation_completed_at\",\n \"last_chunk_first_staging_id\",\n \"last_chunk_last_staging_id\",\n \"last_chunk_rows\",\n ],\n helpMessage:\n 'The materialization checkpoint schema is required. Run \"cnpj-db-loader schema generate --profile full\" and apply the SQL before importing.',\n });\n}\n\nexport async function readMaterializationCheckpoint(\n client: Client,\n planId: number,\n dataset: string,\n targetTable: string,\n): Promise<MaterializationCheckpointRecord> {\n const result = await client.query<MaterializationCheckpointRow>(\n `select\n plan_id,\n dataset,\n target_table,\n status,\n rows_materialized,\n last_staging_id,\n chunks_completed,\n last_error,\n started_at,\n completed_at,\n updated_at,\n staging_row_count_verified,\n staging_max_staging_id_verified,\n staging_validated_at,\n lookup_reconciliation_status,\n lookup_reconciliation_row_count_verified,\n lookup_reconciliation_max_staging_id_verified,\n lookup_reconciliation_completed_at,\n last_chunk_first_staging_id,\n last_chunk_last_staging_id,\n last_chunk_rows\n from import_materialization_checkpoints\n where plan_id = $1 and dataset = $2`,\n [planId, dataset],\n );\n\n if (result.rowCount === 0) {\n return {\n planId,\n dataset,\n targetTable,\n status: \"pending\",\n rowsMaterialized: 0,\n lastStagingId: 0,\n chunksCompleted: 0,\n lastError: null,\n startedAt: null,\n completedAt: null,\n updatedAt: new Date(),\n stagingRowCountVerified: null,\n stagingMaxStagingIdVerified: null,\n stagingValidatedAt: null,\n lookupReconciliationStatus: \"pending\",\n lookupReconciliationRowCountVerified: null,\n lookupReconciliationMaxStagingIdVerified: null,\n lookupReconciliationCompletedAt: null,\n lastChunkFirstStagingId: 0,\n lastChunkLastStagingId: 0,\n lastChunkRows: 0,\n };\n }\n\n return mapCheckpointRow(result.rows[0]!);\n}\n\nexport async function writeMaterializationCheckpoint(\n client: Client,\n checkpoint: MaterializationCheckpointRecord,\n): Promise<void> {\n await client.query(\n `insert into import_materialization_checkpoints (\n plan_id,\n dataset,\n target_table,\n status,\n rows_materialized,\n last_staging_id,\n chunks_completed,\n last_error,\n started_at,\n completed_at,\n updated_at,\n staging_row_count_verified,\n staging_max_staging_id_verified,\n staging_validated_at,\n lookup_reconciliation_status,\n lookup_reconciliation_row_count_verified,\n lookup_reconciliation_max_staging_id_verified,\n lookup_reconciliation_completed_at,\n last_chunk_first_staging_id,\n last_chunk_last_staging_id,\n last_chunk_rows\n ) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, now(), $11, $12, $13, $14, $15, $16, $17, $18, $19, $20)\n on conflict (plan_id, dataset)\n do update set\n target_table = excluded.target_table,\n status = excluded.status,\n rows_materialized = excluded.rows_materialized,\n last_staging_id = excluded.last_staging_id,\n chunks_completed = excluded.chunks_completed,\n last_error = excluded.last_error,\n started_at = excluded.started_at,\n completed_at = excluded.completed_at,\n updated_at = now(),\n staging_row_count_verified = excluded.staging_row_count_verified,\n staging_max_staging_id_verified = excluded.staging_max_staging_id_verified,\n staging_validated_at = excluded.staging_validated_at,\n lookup_reconciliation_status = excluded.lookup_reconciliation_status,\n lookup_reconciliation_row_count_verified = excluded.lookup_reconciliation_row_count_verified,\n lookup_reconciliation_max_staging_id_verified = excluded.lookup_reconciliation_max_staging_id_verified,\n lookup_reconciliation_completed_at = excluded.lookup_reconciliation_completed_at,\n last_chunk_first_staging_id = excluded.last_chunk_first_staging_id,\n last_chunk_last_staging_id = excluded.last_chunk_last_staging_id,\n last_chunk_rows = excluded.last_chunk_rows`,\n [\n checkpoint.planId,\n checkpoint.dataset,\n checkpoint.targetTable,\n checkpoint.status,\n checkpoint.rowsMaterialized,\n checkpoint.lastStagingId,\n checkpoint.chunksCompleted,\n checkpoint.lastError,\n checkpoint.startedAt,\n checkpoint.completedAt,\n checkpoint.stagingRowCountVerified,\n checkpoint.stagingMaxStagingIdVerified,\n checkpoint.stagingValidatedAt,\n checkpoint.lookupReconciliationStatus,\n checkpoint.lookupReconciliationRowCountVerified,\n checkpoint.lookupReconciliationMaxStagingIdVerified,\n checkpoint.lookupReconciliationCompletedAt,\n checkpoint.lastChunkFirstStagingId,\n checkpoint.lastChunkLastStagingId,\n checkpoint.lastChunkRows,\n ],\n );\n}\n\nexport async function writeMaterializationCheckpointProgress(\n client: Client,\n checkpoint: MaterializationCheckpointRecord,\n): Promise<void> {\n await client.query(\n `update import_materialization_checkpoints\n set status = $3,\n rows_materialized = $4,\n last_staging_id = $5,\n chunks_completed = $6,\n last_error = $7,\n started_at = $8,\n completed_at = $9,\n updated_at = now(),\n last_chunk_first_staging_id = $10,\n last_chunk_last_staging_id = $11,\n last_chunk_rows = $12\n where plan_id = $1 and dataset = $2`,\n [\n checkpoint.planId,\n checkpoint.dataset,\n checkpoint.status,\n checkpoint.rowsMaterialized,\n checkpoint.lastStagingId,\n checkpoint.chunksCompleted,\n checkpoint.lastError,\n checkpoint.startedAt,\n checkpoint.completedAt,\n checkpoint.lastChunkFirstStagingId,\n checkpoint.lastChunkLastStagingId,\n checkpoint.lastChunkRows,\n ],\n );\n}\n\nexport async function resetMaterializationCheckpoints(\n client: Client,\n planId: number,\n): Promise<void> {\n await client.query(\n `delete from import_materialization_checkpoints where plan_id = $1`,\n [planId],\n );\n}\n","import { Client } from \"pg\";\n\nimport { ensureTableShape } from \"./schema-validation.js\";\nimport type {\n ImportDatasetPlan,\n ImportDatasetType,\n ImportPhaseStatus,\n ImportPlanRecord,\n ImportPlanStatus,\n} from \"./types.js\";\n\nexport async function ensureImportPlanTables(client: Client): Promise<void> {\n await ensureTableShape(client, {\n tableName: \"import_plans\",\n requiredColumns: [\n \"source_fingerprint\",\n \"input_path\",\n \"validated_path\",\n \"batch_size\",\n \"target_database\",\n \"total_datasets\",\n \"total_files\",\n \"total_rows\",\n \"total_batches\",\n \"execution_order\",\n \"status\",\n \"load_status\",\n \"materialization_status\",\n \"last_phase\",\n \"last_error\",\n \"created_at\",\n \"updated_at\",\n \"last_used_at\",\n ],\n helpMessage:\n 'The import plan schema is required. Run \"cnpj-db-loader schema generate --profile full\" and apply the SQL before importing.',\n });\n\n await ensureTableShape(client, {\n tableName: \"import_plan_files\",\n requiredColumns: [\n \"plan_id\",\n \"dataset\",\n \"dataset_index\",\n \"file_index\",\n \"file_path\",\n \"file_display_path\",\n \"file_size\",\n \"file_mtime\",\n \"total_rows\",\n \"total_batches\",\n ],\n helpMessage:\n 'The import plan schema is required. Run \"cnpj-db-loader schema generate --profile full\" and apply the SQL before importing.',\n });\n}\n\ntype ImportPlanRow = {\n id: string;\n source_fingerprint: string;\n input_path: string;\n validated_path: string;\n batch_size: string;\n target_database: string;\n total_datasets: string;\n total_files: string;\n total_rows: string;\n total_batches: string;\n execution_order: ImportDatasetType[];\n status: ImportPlanStatus;\n load_status: ImportPhaseStatus;\n materialization_status: ImportPhaseStatus;\n last_phase: string | null;\n last_error: string | null;\n created_at: Date;\n updated_at: Date;\n last_used_at: Date;\n};\n\ntype ImportPlanFileRow = {\n dataset: ImportDatasetType;\n file_path: string;\n file_display_path: string;\n file_size: string;\n file_mtime: Date;\n total_rows: string;\n total_batches: string;\n dataset_index: string;\n file_index: string;\n};\n\nfunction mapImportPlanRow(row: ImportPlanRow): ImportPlanRecord {\n return {\n id: Number.parseInt(row.id, 10),\n sourceFingerprint: row.source_fingerprint,\n inputPath: row.input_path,\n validatedPath: row.validated_path,\n batchSize: Number.parseInt(row.batch_size, 10),\n targetDatabase: row.target_database,\n totalDatasets: Number.parseInt(row.total_datasets, 10),\n totalFiles: Number.parseInt(row.total_files, 10),\n totalRows: Number.parseInt(row.total_rows, 10),\n totalBatches: Number.parseInt(row.total_batches, 10),\n executionOrder: row.execution_order,\n status: row.status,\n loadStatus: row.load_status,\n materializationStatus: row.materialization_status,\n lastPhase: row.last_phase,\n lastError: row.last_error,\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n lastUsedAt: new Date(row.last_used_at),\n };\n}\n\nasync function readPlanDatasets(\n client: Client,\n plan: ImportPlanRecord,\n): Promise<ImportDatasetPlan[]> {\n const filesResult = await client.query<ImportPlanFileRow>(\n `select\n dataset,\n file_path,\n file_display_path,\n file_size,\n file_mtime,\n total_rows,\n total_batches,\n dataset_index,\n file_index\n from import_plan_files\n where plan_id = $1\n order by dataset_index asc, file_index asc`,\n [plan.id],\n );\n\n const grouped = new Map<ImportDatasetType, ImportDatasetPlan>();\n\n for (const row of filesResult.rows) {\n const current = grouped.get(row.dataset) ?? {\n dataset: row.dataset,\n files: [],\n totalRows: 0,\n totalBatches: 0,\n };\n\n const fileTotalRows = Number.parseInt(row.total_rows, 10);\n const fileTotalBatches = Number.parseInt(row.total_batches, 10);\n\n current.files.push({\n dataset: row.dataset,\n absolutePath: row.file_path,\n displayPath: row.file_display_path,\n fileSize: Number.parseInt(row.file_size, 10),\n fileMtime: new Date(row.file_mtime),\n totalRows: fileTotalRows,\n totalBatches: fileTotalBatches,\n });\n current.totalRows += fileTotalRows;\n current.totalBatches += fileTotalBatches;\n grouped.set(row.dataset, current);\n }\n\n return plan.executionOrder\n .map((dataset) => grouped.get(dataset))\n .filter((item): item is ImportDatasetPlan => item !== undefined);\n}\n\nasync function readPlanRecordByQuery(\n client: Client,\n query: string,\n values: readonly unknown[],\n): Promise<{\n plan: ImportPlanRecord;\n datasets: ImportDatasetPlan[];\n} | null> {\n const planResult = await client.query<ImportPlanRow>(query, [...values]);\n\n if (planResult.rowCount === 0) {\n return null;\n }\n\n const plan = mapImportPlanRow(planResult.rows[0]!);\n const datasets = await readPlanDatasets(client, plan);\n\n await client.query(\n `update import_plans set last_used_at = now(), updated_at = now() where id = $1`,\n [plan.id],\n );\n\n return { plan, datasets };\n}\n\nexport async function readSavedImportPlan(\n client: Client,\n sourceFingerprint: string,\n): Promise<{\n plan: ImportPlanRecord;\n datasets: ImportDatasetPlan[];\n} | null> {\n return readPlanRecordByQuery(\n client,\n `select\n id,\n source_fingerprint,\n input_path,\n validated_path,\n batch_size,\n target_database,\n total_datasets,\n total_files,\n total_rows,\n total_batches,\n execution_order,\n status,\n load_status,\n materialization_status,\n last_phase,\n last_error,\n created_at,\n updated_at,\n last_used_at\n from import_plans\n where source_fingerprint = $1`,\n [sourceFingerprint],\n );\n}\n\nexport async function readLatestImportPlanForValidatedPath(\n client: Client,\n validatedPath: string,\n targetDatabase: string,\n): Promise<{\n plan: ImportPlanRecord;\n datasets: ImportDatasetPlan[];\n} | null> {\n return readPlanRecordByQuery(\n client,\n `select\n id,\n source_fingerprint,\n input_path,\n validated_path,\n batch_size,\n target_database,\n total_datasets,\n total_files,\n total_rows,\n total_batches,\n execution_order,\n status,\n load_status,\n materialization_status,\n last_phase,\n last_error,\n created_at,\n updated_at,\n last_used_at\n from import_plans\n where validated_path = $1\n and target_database = $2\n order by last_used_at desc, updated_at desc, id desc\n limit 1`,\n [validatedPath, targetDatabase],\n );\n}\n\nexport async function saveImportPlan(\n client: Client,\n input: {\n sourceFingerprint: string;\n inputPath: string;\n validatedPath: string;\n batchSize: number;\n targetDatabase: string;\n datasets: ImportDatasetPlan[];\n totalFiles: number;\n totalRows: number;\n totalBatches: number;\n },\n): Promise<ImportPlanRecord> {\n await client.query(\"begin\");\n try {\n const existing = await client.query<{ id: string }>(\n `select id from import_plans where source_fingerprint = $1`,\n [input.sourceFingerprint],\n );\n\n if ((existing.rowCount ?? 0) > 0) {\n await client.query(`delete from import_plan_files where plan_id = $1`, [\n existing.rows[0]!.id,\n ]);\n }\n\n const planResult = await client.query<ImportPlanRow>(\n `insert into import_plans (\n source_fingerprint,\n input_path,\n validated_path,\n batch_size,\n target_database,\n total_datasets,\n total_files,\n total_rows,\n total_batches,\n execution_order,\n status,\n load_status,\n materialization_status,\n last_phase,\n last_error,\n created_at,\n updated_at,\n last_used_at\n ) values (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10::jsonb, 'planned', 'pending', 'pending', 'planning', null, now(), now(), now()\n )\n on conflict (source_fingerprint)\n do update set\n input_path = excluded.input_path,\n validated_path = excluded.validated_path,\n batch_size = excluded.batch_size,\n target_database = excluded.target_database,\n total_datasets = excluded.total_datasets,\n total_files = excluded.total_files,\n total_rows = excluded.total_rows,\n total_batches = excluded.total_batches,\n execution_order = excluded.execution_order,\n status = 'planned',\n load_status = 'pending',\n materialization_status = 'pending',\n last_phase = 'planning',\n last_error = null,\n updated_at = now(),\n last_used_at = now()\n returning\n id,\n source_fingerprint,\n input_path,\n validated_path,\n batch_size,\n target_database,\n total_datasets,\n total_files,\n total_rows,\n total_batches,\n execution_order,\n status,\n load_status,\n materialization_status,\n last_phase,\n last_error,\n created_at,\n updated_at,\n last_used_at`,\n [\n input.sourceFingerprint,\n input.inputPath,\n input.validatedPath,\n input.batchSize,\n input.targetDatabase,\n input.datasets.length,\n input.totalFiles,\n input.totalRows,\n input.totalBatches,\n JSON.stringify(input.datasets.map((item) => item.dataset)),\n ],\n );\n\n const plan = mapImportPlanRow(planResult.rows[0]!);\n\n let fileIndex = 0;\n for (const [datasetIndex, datasetPlan] of input.datasets.entries()) {\n for (const filePlan of datasetPlan.files) {\n fileIndex += 1;\n await client.query(\n `insert into import_plan_files (\n plan_id,\n dataset,\n dataset_index,\n file_index,\n file_path,\n file_display_path,\n file_size,\n file_mtime,\n total_rows,\n total_batches\n ) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)\n on conflict (plan_id, file_path)\n do update set\n dataset = excluded.dataset,\n dataset_index = excluded.dataset_index,\n file_index = excluded.file_index,\n file_display_path = excluded.file_display_path,\n file_size = excluded.file_size,\n file_mtime = excluded.file_mtime,\n total_rows = excluded.total_rows,\n total_batches = excluded.total_batches`,\n [\n plan.id,\n datasetPlan.dataset,\n datasetIndex + 1,\n fileIndex,\n filePlan.absolutePath,\n filePlan.displayPath,\n filePlan.fileSize,\n filePlan.fileMtime,\n filePlan.totalRows,\n filePlan.totalBatches,\n ],\n );\n }\n }\n\n await client.query(\"commit\");\n return plan;\n } catch (error) {\n await client.query(\"rollback\");\n throw error;\n }\n}\n\nexport async function updateImportPlanStatus(\n client: Client,\n planId: number,\n status: ImportPlanStatus,\n): Promise<void> {\n await client.query(\n `update import_plans\n set status = $2,\n updated_at = now(),\n last_used_at = now()\n where id = $1`,\n [planId, status],\n );\n}\n\nexport async function updateImportPlanPhaseState(\n client: Client,\n input: {\n planId: number;\n loadStatus?: ImportPhaseStatus;\n materializationStatus?: ImportPhaseStatus;\n lastPhase?: string | null;\n lastError?: string | null;\n },\n): Promise<void> {\n const assignments: string[] = [\"updated_at = now()\", \"last_used_at = now()\"];\n const values: unknown[] = [input.planId];\n let nextIndex = 2;\n\n if (input.loadStatus !== undefined) {\n assignments.push(`load_status = $${nextIndex}`);\n values.push(input.loadStatus);\n nextIndex += 1;\n }\n\n if (input.materializationStatus !== undefined) {\n assignments.push(`materialization_status = $${nextIndex}`);\n values.push(input.materializationStatus);\n nextIndex += 1;\n }\n\n if (input.lastPhase !== undefined) {\n assignments.push(`last_phase = $${nextIndex}`);\n values.push(input.lastPhase);\n nextIndex += 1;\n }\n\n if (input.lastError !== undefined) {\n assignments.push(`last_error = $${nextIndex}`);\n values.push(input.lastError);\n nextIndex += 1;\n }\n\n await client.query(\n `update import_plans set ${assignments.join(\", \")} where id = $1`,\n values,\n );\n}\n","import type { ImportDatasetType, ImportWriteTarget } from \"./types.js\";\n\nexport const STAGED_IMPORT_DATASETS: ReadonlySet<ImportDatasetType> = new Set([\n \"companies\",\n \"establishments\",\n \"partners\",\n \"simples_options\",\n]);\n\nconst STAGING_TABLE_BY_DATASET: Partial<Record<ImportDatasetType, string>> = {\n companies: \"staging_companies\",\n establishments: \"staging_establishments\",\n partners: \"staging_partners\",\n simples_options: \"staging_simples_options\",\n};\n\nexport function usesStagingWriteTarget(dataset: ImportDatasetType): boolean {\n return STAGED_IMPORT_DATASETS.has(dataset);\n}\n\nexport function resolveImportWriteTarget(\n dataset: ImportDatasetType,\n): ImportWriteTarget {\n return usesStagingWriteTarget(dataset) ? \"staging\" : \"final\";\n}\n\nexport function getTargetTableName(dataset: ImportDatasetType): string {\n return STAGING_TABLE_BY_DATASET[dataset] ?? dataset;\n}\n\nexport function getSecondaryTargetTableName(\n dataset: ImportDatasetType,\n): string | null {\n void dataset;\n return null;\n}\n\nexport function collectRequiredStagingTables(\n datasets: readonly ImportDatasetType[],\n): string[] {\n const tableNames = new Set<string>();\n\n for (const dataset of datasets) {\n if (!usesStagingWriteTarget(dataset)) {\n continue;\n }\n\n tableNames.add(getTargetTableName(dataset));\n }\n\n return [...tableNames];\n}\n\nconst FINAL_TABLE_BY_DATASET: Partial<Record<ImportDatasetType, string>> = {\n companies: \"companies\",\n establishments: \"establishments\",\n partners: \"partners\",\n simples_options: \"simples_options\",\n};\n\nexport function getFinalTargetTableName(dataset: ImportDatasetType): string {\n return FINAL_TABLE_BY_DATASET[dataset] ?? dataset;\n}\n","import type { Client } from \"pg\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport type { ImportDatasetType } from \"./types.js\";\nimport { collectRequiredStagingTables } from \"./targets.js\";\n\nconst LEGACY_STAGING_TABLES = [\n \"staging_establishment_secondary_cnaes\",\n] as const;\n\nasync function tableExists(\n client: Client,\n tableName: string,\n): Promise<boolean> {\n const result = await client.query<{ exists: string | null }>(\n \"select to_regclass(current_schema() || '.' || $1) as exists\",\n [tableName],\n );\n\n return Boolean(result.rows[0]?.exists);\n}\n\nasync function collectResettableStagingTables(\n client: Client,\n datasets: readonly ImportDatasetType[],\n): Promise<string[]> {\n const tableNames = new Set(collectRequiredStagingTables(datasets));\n\n if (datasets.includes(\"establishments\")) {\n for (const tableName of LEGACY_STAGING_TABLES) {\n if (await tableExists(client, tableName)) {\n tableNames.add(tableName);\n }\n }\n }\n\n return [...tableNames];\n}\n\nexport async function ensureStagingSchemaSupport(\n client: Client,\n datasets: readonly ImportDatasetType[],\n): Promise<void> {\n const requiredTables = collectRequiredStagingTables(datasets);\n\n if (requiredTables.length === 0) {\n return;\n }\n\n const missingTables: string[] = [];\n const invalidTables: string[] = [];\n\n for (const tableName of requiredTables) {\n if (!(await tableExists(client, tableName))) {\n missingTables.push(tableName);\n continue;\n }\n\n const stagingIdResult = await client.query<{ exists: boolean }>(\n `select exists (\n select 1\n from information_schema.columns\n where table_schema = current_schema()\n and table_name = $1\n and column_name = 'staging_id'\n ) as exists`,\n [tableName],\n );\n\n if (!stagingIdResult.rows[0]?.exists) {\n invalidTables.push(tableName);\n }\n }\n\n if (missingTables.length > 0) {\n throw new ValidationError(\n `The staging schema is required for the selected bulk-load datasets. Missing tables: ${missingTables.join(\", \")}. Run \"cnpj-db-loader schema generate --profile full\" or \"cnpj-db-loader schema generate --profile staging\" and apply the SQL before importing.`,\n );\n }\n\n if (invalidTables.length > 0) {\n throw new ValidationError(\n `The staging schema is outdated for chunked materialization. Recreate or migrate these tables so they include the staging_id column: ${invalidTables.join(\", \")}.`,\n );\n }\n}\n\nexport async function resetStagingTablesForFreshPlan(\n client: Client,\n datasets: readonly ImportDatasetType[],\n): Promise<string[]> {\n const tableNames = await collectResettableStagingTables(client, datasets);\n\n if (tableNames.length === 0) {\n return [];\n }\n\n await client.query(`truncate ${tableNames.join(\", \")}`);\n return tableNames;\n}\n","import type { TableLayout } from \"./types.js\";\n\nexport const companiesLayout: TableLayout = {\n key: \"companies\",\n tableName: \"companies\",\n sourceName: \"EMPRESAS\",\n description: \"Main company registration block.\",\n fields: [\n { sourceLabel: \"CNPJ BÁSICO\", columnName: \"cnpj_root\", dataType: \"text\" },\n {\n sourceLabel: \"RAZÃO SOCIAL / NOME EMPRESARIAL\",\n columnName: \"company_name\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"NATUREZA JURÍDICA\",\n columnName: \"legal_nature_code\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"QUALIFICAÇÃO DO RESPONSÁVEL\",\n columnName: \"responsible_qualification_code\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"CAPITAL SOCIAL DA EMPRESA\",\n columnName: \"share_capital\",\n dataType: \"numeric\",\n },\n {\n sourceLabel: \"PORTE DA EMPRESA\",\n columnName: \"company_size_code\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"ENTE FEDERATIVO RESPONSÁVEL\",\n columnName: \"responsible_federative_entity\",\n dataType: \"text\",\n nullable: true,\n },\n ],\n};\n","import type { TableLayout } from \"./types.js\";\n\nexport const countriesLayout: TableLayout = {\n key: \"countries\",\n tableName: \"countries\",\n sourceName: \"PAÍSES\",\n description: \"Country domain table.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n\nexport const citiesLayout: TableLayout = {\n key: \"cities\",\n tableName: \"cities\",\n sourceName: \"MUNICÍPIOS\",\n description: \"City domain table.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n\nexport const partnerQualificationsLayout: TableLayout = {\n key: \"partner_qualifications\",\n tableName: \"partner_qualifications\",\n sourceName: \"QUALIFICAÇÕES DE SÓCIOS\",\n description: \"Partner qualification domain table.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n\nexport const legalNaturesLayout: TableLayout = {\n key: \"legal_natures\",\n tableName: \"legal_natures\",\n sourceName: \"NATUREZAS JURÍDICAS\",\n description: \"Legal nature domain table.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n\nexport const cnaesLayout: TableLayout = {\n key: \"cnaes\",\n tableName: \"cnaes\",\n sourceName: \"CNAEs\",\n description: \"Economic activity domain table.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n\nexport const reasonsLayout: TableLayout = {\n key: \"reasons\",\n tableName: \"reasons\",\n sourceName: \"MOTIVOS\",\n description: \"Registration status reason domain table.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n\nexport const companySizesLayout: TableLayout = {\n key: \"company_sizes\",\n tableName: \"company_sizes\",\n sourceName: \"INTERNAL COMPANY SIZE LOOKUP\",\n description:\n \"Internal lookup table for company size codes defined by the Receita layout.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n\nexport const branchTypesLayout: TableLayout = {\n key: \"branch_types\",\n tableName: \"branch_types\",\n sourceName: \"INTERNAL BRANCH TYPE LOOKUP\",\n description:\n \"Internal lookup table for matriz/filial codes defined by the Receita layout.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n\nexport const registrationStatusesLayout: TableLayout = {\n key: \"registration_statuses\",\n tableName: \"registration_statuses\",\n sourceName: \"INTERNAL REGISTRATION STATUS LOOKUP\",\n description:\n \"Internal lookup table for establishment registration status codes defined by the Receita layout.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n\nexport const partnerTypesLayout: TableLayout = {\n key: \"partner_types\",\n tableName: \"partner_types\",\n sourceName: \"INTERNAL PARTNER TYPE LOOKUP\",\n description:\n \"Internal lookup table for partner identifier codes defined by the Receita layout.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n\nexport const ageGroupsLayout: TableLayout = {\n key: \"age_groups\",\n tableName: \"age_groups\",\n sourceName: \"INTERNAL AGE GROUP LOOKUP\",\n description:\n \"Internal lookup table for partner age group codes defined by the Receita layout.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n","import type { TableLayout } from \"./types.js\";\n\nexport const establishmentsLayout: TableLayout = {\n key: \"establishments\",\n tableName: \"establishments\",\n sourceName: \"ESTABELECIMENTOS\",\n description: \"Establishment registration block.\",\n fields: [\n { sourceLabel: \"CNPJ BÁSICO\", columnName: \"cnpj_root\", dataType: \"text\" },\n { sourceLabel: \"CNPJ ORDEM\", columnName: \"cnpj_order\", dataType: \"text\" },\n {\n sourceLabel: \"CNPJ DV\",\n columnName: \"cnpj_check_digits\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"IDENTIFICADOR MATRIZ/FILIAL\",\n columnName: \"branch_type_code\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"NOME FANTASIA\",\n columnName: \"trade_name\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"SITUAÇÃO CADASTRAL\",\n columnName: \"registration_status_code\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"DATA SITUAÇÃO CADASTRAL\",\n columnName: \"registration_status_date\",\n dataType: \"date\",\n nullable: true,\n },\n {\n sourceLabel: \"MOTIVO SITUAÇÃO CADASTRAL\",\n columnName: \"registration_status_reason_code\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"NOME DA CIDADE NO EXTERIOR\",\n columnName: \"foreign_city_name\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"PAIS\",\n columnName: \"country_code\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"DATA DE INÍCIO ATIVIDADE\",\n columnName: \"activity_start_date\",\n dataType: \"date\",\n nullable: true,\n },\n {\n sourceLabel: \"CNAE FISCAL PRINCIPAL\",\n columnName: \"main_cnae_code\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"CNAE FISCAL SECUNDÁRIA\",\n columnName: \"secondary_cnaes_raw\",\n dataType: \"text\",\n nullable: true,\n notes: \"Comma-separated occurrences in the source file.\",\n },\n {\n sourceLabel: \"TIPO DE LOGRADOURO\",\n columnName: \"street_type\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"LOGRADOURO\",\n columnName: \"street_name\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"NÚMERO\",\n columnName: \"street_number\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"COMPLEMENTO\",\n columnName: \"address_complement\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"BAIRRO\",\n columnName: \"district\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"CEP\",\n columnName: \"postal_code\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"UF\",\n columnName: \"state_code\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"MUNICÍPIO\",\n columnName: \"city_code\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"DDD 1\",\n columnName: \"phone_area_code_1\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"TELEFONE 1\",\n columnName: \"phone_number_1\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"DDD 2\",\n columnName: \"phone_area_code_2\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"TELEFONE 2\",\n columnName: \"phone_number_2\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"DDD DO FAX\",\n columnName: \"fax_area_code\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"FAX\",\n columnName: \"fax_number\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"CORREIO ELETRÔNICO\",\n columnName: \"email\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"SITUAÇÃO ESPECIAL\",\n columnName: \"special_status\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"DATA DA SITUAÇÃO ESPECIAL\",\n columnName: \"special_status_date\",\n dataType: \"date\",\n nullable: true,\n },\n ],\n};\n","import type { TableLayout } from \"./types.js\";\n\nexport const partnersLayout: TableLayout = {\n key: \"partners\",\n tableName: \"partners\",\n sourceName: \"SÓCIOS\",\n description:\n \"Partners block, including masked CPF/CNPJ fields according to the official layout.\",\n fields: [\n { sourceLabel: \"CNPJ BÁSICO\", columnName: \"cnpj_root\", dataType: \"text\" },\n {\n sourceLabel: \"IDENTIFICADOR DE SÓCIO\",\n columnName: \"partner_type_code\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"NOME DO SÓCIO / RAZÃO SOCIAL\",\n columnName: \"partner_name\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"CNPJ/CPF DO SÓCIO\",\n columnName: \"partner_document\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"QUALIFICAÇÃO DO SÓCIO\",\n columnName: \"partner_qualification_code\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"DATA DE ENTRADA SOCIEDADE\",\n columnName: \"entry_date\",\n dataType: \"date\",\n nullable: true,\n },\n {\n sourceLabel: \"PAIS\",\n columnName: \"country_code\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"REPRESENTANTE LEGAL\",\n columnName: \"legal_representative_document\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"NOME DO REPRESENTANTE\",\n columnName: \"legal_representative_name\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"QUALIFICAÇÃO DO REPRESENTANTE LEGAL\",\n columnName: \"legal_representative_qualification_code\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"FAIXA ETÁRIA\",\n columnName: \"age_group_code\",\n dataType: \"text\",\n nullable: true,\n },\n ],\n};\n","import type { TableLayout } from \"./types.js\";\n\nexport const simplesLayout: TableLayout = {\n key: \"simples_options\",\n tableName: \"simples_options\",\n sourceName: \"DADOS DO SIMPLES\",\n description: \"Simples Nacional and MEI option block.\",\n fields: [\n { sourceLabel: \"CNPJ BÁSICO\", columnName: \"cnpj_root\", dataType: \"text\" },\n {\n sourceLabel: \"OPÇÃO PELO SIMPLES\",\n columnName: \"simples_option_flag\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"DATA DE OPÇÃO PELO SIMPLES\",\n columnName: \"simples_option_date\",\n dataType: \"date\",\n nullable: true,\n },\n {\n sourceLabel: \"DATA DE EXCLUSÃO DO SIMPLES\",\n columnName: \"simples_exclusion_date\",\n dataType: \"date\",\n nullable: true,\n },\n {\n sourceLabel: \"OPÇÃO PELO MEI\",\n columnName: \"mei_option_flag\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"DATA DE OPÇÃO PELO MEI\",\n columnName: \"mei_option_date\",\n dataType: \"date\",\n nullable: true,\n },\n {\n sourceLabel: \"DATA DE EXCLUSÃO DO MEI\",\n columnName: \"mei_exclusion_date\",\n dataType: \"date\",\n nullable: true,\n },\n ],\n};\n","import type { TableLayout } from \"../../dictionary/layouts/index.js\";\nimport {\n citiesLayout,\n cnaesLayout,\n companiesLayout,\n countriesLayout,\n establishmentsLayout,\n legalNaturesLayout,\n partnerQualificationsLayout,\n partnersLayout,\n reasonsLayout,\n simplesLayout,\n} from \"../../dictionary/layouts/index.js\";\nimport type { DatasetType } from \"../inspect.service.js\";\n\nexport type ImportDatasetType = Exclude<DatasetType, \"zip-archive\" | \"unknown\">;\n\nexport type ImportCheckpointStatus =\n | \"pending\"\n | \"in_progress\"\n | \"completed\"\n | \"failed\";\n\nexport type ImportCheckpointRecord = {\n dataset: ImportDatasetType;\n filePath: string;\n fileSize: number;\n fileMtime: Date;\n byteOffset: number;\n rowsCommitted: number;\n status: ImportCheckpointStatus;\n lastError?: string | null;\n};\n\nexport type ImportFilePlan = {\n dataset: ImportDatasetType;\n absolutePath: string;\n displayPath: string;\n fileSize: number;\n fileMtime: Date;\n totalRows: number;\n totalBatches: number;\n checkpoint?: ImportCheckpointRecord;\n};\n\nexport type ImportSourceFile = {\n dataset: ImportDatasetType;\n absolutePath: string;\n relativePath: string;\n displayPath: string;\n fileSize: number;\n fileMtime: Date;\n};\n\nexport type BatchRow = {\n values: unknown[];\n rawLine: string;\n nextOffset: number;\n sourceRowNumber: number;\n secondaryRows: Array<[string, string, number]>;\n};\n\nexport type ImportDatasetPlan = {\n dataset: ImportDatasetType;\n files: ImportFilePlan[];\n totalRows: number;\n totalBatches: number;\n};\n\nexport type ImportPlanStatus =\n | \"planned\"\n | \"in_progress\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\";\n\nexport type ImportPhaseStatus =\n | \"pending\"\n | \"in_progress\"\n | \"completed\"\n | \"failed\";\n\nexport type ImportPlanRecord = {\n id: number;\n sourceFingerprint: string;\n inputPath: string;\n validatedPath: string;\n batchSize: number;\n targetDatabase: string;\n totalDatasets: number;\n totalFiles: number;\n totalRows: number;\n totalBatches: number;\n executionOrder: ImportDatasetType[];\n status: ImportPlanStatus;\n loadStatus: ImportPhaseStatus;\n materializationStatus: ImportPhaseStatus;\n lastPhase: string | null;\n lastError: string | null;\n createdAt: Date;\n updatedAt: Date;\n lastUsedAt: Date;\n};\n\nexport type ImportWriteTarget = \"final\" | \"staging\";\n\nexport type ImportSchemaCapabilities = {\n includeEstablishmentCnpjFullInInsert: boolean;\n includeEstablishmentSecondaryCnaesTable: boolean;\n includePartnerDedupeKeyInInsert: boolean;\n requiresLookupReconciliation: boolean;\n};\n\nexport type ImportDatasetPerformanceSummary = {\n dataset: ImportDatasetType;\n files: number;\n plannedRows: number;\n importedRows: number;\n plannedBatches: number;\n committedBatches: number;\n resumedFiles: number;\n skippedCompletedFiles: number;\n retriedRows: number;\n retriedBatches: number;\n quarantinedRows: number;\n scanDurationMs: number;\n importDurationMs: number;\n insertDurationMs: number;\n retryDurationMs: number;\n quarantineDurationMs: number;\n materializationDurationMs: number;\n rowsPerSecond: number;\n batchesPerMinute: number;\n};\n\nexport type ImportPerformanceSummary = {\n planReused: boolean;\n totalDurationMs: number;\n scanDurationMs: number;\n executionDurationMs: number;\n lookupLoadDurationMs: number;\n insertDurationMs: number;\n retryDurationMs: number;\n quarantineDurationMs: number;\n materializationDurationMs: number;\n rowsPerSecond: number;\n batchesPerMinute: number;\n datasets: ImportDatasetPerformanceSummary[];\n};\n\nexport type ImportProgressEvent =\n | {\n kind: \"preparing_start\";\n inputPath: string;\n validatedPath: string;\n totalDatasets: number;\n totalFiles: number;\n batchSize: number;\n loadBatchSize?: number;\n materializeBatchSize?: number;\n targetDatabase: string;\n }\n | {\n kind: \"preparing_progress\";\n scannedFiles: number;\n totalFiles: number;\n countedRows: number;\n currentFileDisplayPath: string;\n }\n | {\n kind: \"plan_ready\";\n totalDatasets: number;\n totalFiles: number;\n batchSize: number;\n loadBatchSize?: number;\n materializeBatchSize?: number;\n totalRows: number;\n totalBatches: number;\n targetDatabase: string;\n executionOrder: ImportDatasetType[];\n reused: boolean;\n planId: number | null;\n }\n | {\n kind: \"start\";\n inputPath: string;\n validatedPath: string;\n totalDatasets: number;\n totalFiles: number;\n targetDatabase: string;\n totalRows: number;\n totalBatches: number;\n committedRows: number;\n committedBatches: number;\n }\n | {\n kind: \"progress\";\n dataset: ImportDatasetType;\n datasetIndex: number;\n totalDatasets: number;\n currentFilePath: string;\n currentFileDisplayPath: string;\n fileIndex: number;\n completedFiles: number;\n totalFiles: number;\n currentFileRowsCommitted: number;\n currentFileRowsTotal: number;\n committedRows: number;\n committedBatches: number;\n totalBatches: number;\n currentBatch: number;\n batchSize: number;\n checkpointOffset: number;\n currentFileSize: number;\n verboseProgress: boolean;\n }\n | {\n kind: \"materialization_start\";\n totalDatasets: number;\n datasets: ImportDatasetType[];\n completedFiles: number;\n totalFiles: number;\n processedRows: number;\n totalRows: number;\n committedBatches: number;\n totalBatches: number;\n }\n | {\n kind: \"materialization_progress\";\n dataset: ImportDatasetType;\n datasetIndex: number;\n totalDatasets: number;\n completedDatasets: number;\n targetTable: string;\n stepLabel: string;\n completedFiles: number;\n totalFiles: number;\n processedRows: number;\n totalRows: number;\n committedBatches: number;\n totalBatches: number;\n elapsedMs?: number;\n reason?: string;\n chunkSize?: number;\n rowsMaterialized?: number;\n datasetRowCount?: number;\n chunksCompleted?: number;\n estimatedChunks?: number;\n lastStagingId?: number;\n }\n | {\n kind: \"materialization_finish\";\n totalDatasets: number;\n completedDatasets: number;\n }\n | {\n kind: \"finish\";\n totalDatasets: number;\n totalFiles: number;\n completedFiles: number;\n processedRows: number;\n totalRows: number;\n committedBatches: number;\n totalBatches: number;\n quarantinedRows: number;\n };\n\nexport type ImportProgressListener = (event: ImportProgressEvent) => void;\n\nexport type ImportOptions = {\n dbUrl?: string;\n dataset?: ImportDatasetType | undefined;\n batchSize?: number | undefined;\n loadBatchSize?: number | undefined;\n materializeBatchSize?: number | undefined;\n verboseProgress?: boolean | undefined;\n onProgress?: ImportProgressListener | undefined;\n};\n\nexport type ImportExecutionMode = \"full\" | \"load\" | \"materialize\";\n\nexport type ImportSummary = {\n executionMode: ImportExecutionMode;\n inputPath: string;\n validatedPath: string;\n targetDatabase: string;\n importPlanId: number | null;\n reusedImportPlan: boolean;\n importedDatasets: ImportDatasetType[];\n importedFiles: number;\n processedRows: number;\n plannedRows: number;\n committedBatches: number;\n plannedBatches: number;\n quarantinedRows: number;\n resumedFiles: number;\n skippedCompletedFiles: number;\n datasetSummaries: Array<{\n dataset: ImportDatasetType;\n files: number;\n rows: number;\n }>;\n performance: ImportPerformanceSummary;\n warnings: string[];\n progressLogPath: string;\n};\n\nexport const IMPORT_ORDER: ImportDatasetType[] = [\n \"partner_qualifications\",\n \"legal_natures\",\n \"countries\",\n \"cities\",\n \"reasons\",\n \"cnaes\",\n \"companies\",\n \"establishments\",\n \"partners\",\n \"simples_options\",\n];\n\nexport const DATASET_LAYOUTS: Record<ImportDatasetType, TableLayout> = {\n companies: companiesLayout,\n establishments: establishmentsLayout,\n partners: partnersLayout,\n simples_options: simplesLayout,\n countries: countriesLayout,\n cities: citiesLayout,\n partner_qualifications: partnerQualificationsLayout,\n legal_natures: legalNaturesLayout,\n cnaes: cnaesLayout,\n reasons: reasonsLayout,\n};\n\nexport type LookupTableName =\n | \"partner_qualifications\"\n | \"legal_natures\"\n | \"company_sizes\"\n | \"branch_types\"\n | \"registration_statuses\"\n | \"reasons\"\n | \"countries\"\n | \"cnaes\"\n | \"cities\"\n | \"partner_types\"\n | \"age_groups\";\n\nexport type LookupCacheMap = Map<LookupTableName, Set<string>>;\n\nexport const LOOKUP_TABLES: LookupTableName[] = [\n \"partner_qualifications\",\n \"legal_natures\",\n \"company_sizes\",\n \"branch_types\",\n \"registration_statuses\",\n \"reasons\",\n \"countries\",\n \"cnaes\",\n \"cities\",\n \"partner_types\",\n \"age_groups\",\n];\n\nexport const LOOKUP_PLACEHOLDER_LABEL: Record<LookupTableName, string> = {\n partner_qualifications: \"Imported placeholder qualification\",\n legal_natures: \"Imported placeholder legal nature\",\n company_sizes: \"Imported placeholder company size\",\n branch_types: \"Imported placeholder branch type\",\n registration_statuses: \"Imported placeholder registration status\",\n reasons: \"Imported placeholder registration reason\",\n countries: \"Imported placeholder country\",\n cnaes: \"Imported placeholder CNAE\",\n cities: \"Imported placeholder city\",\n partner_types: \"Imported placeholder partner type\",\n age_groups: \"Imported placeholder age group\",\n};\n\nexport function isImportDatasetType(value: string): value is ImportDatasetType {\n return IMPORT_ORDER.includes(value as ImportDatasetType);\n}\n\nexport function maskDatabaseLabel(url: string): string {\n try {\n const parsed = new URL(url);\n const databaseName = parsed.pathname.replace(/^\\//, \"\") || \"database\";\n return `${parsed.hostname}/${databaseName}`;\n } catch {\n return \"configured database\";\n }\n}\n","import type { Client } from \"pg\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport type { ImportDatasetType } from \"../import/types.js\";\nimport { ensureCheckpointTable } from \"../import/checkpoints.js\";\nimport { ensureMaterializationCheckpointTable } from \"../import/materialization-checkpoints.js\";\nimport { ensureImportPlanTables } from \"../import/plan-store.js\";\nimport { resetStagingTablesForFreshPlan } from \"../import/staging-schema.js\";\nimport { isImportDatasetType, maskDatabaseLabel } from \"../import/types.js\";\n\nexport type DatabaseCleanupScope =\n | \"staging\"\n | \"materialized\"\n | \"checkpoints\"\n | \"plans\";\n\nexport type CheckpointCleanupPhase = \"load\" | \"materialization\" | \"all\";\n\nexport type DatabaseCleanupSummary = {\n scope: DatabaseCleanupScope;\n targetDatabase: string;\n dataset?: ImportDatasetType | undefined;\n phase?: CheckpointCleanupPhase | undefined;\n validatedPath?: string | undefined;\n planId?: number | undefined;\n truncatedTables: string[];\n deletedLoadCheckpoints: number;\n deletedMaterializationCheckpoints: number;\n deletedPlans: number;\n notes: string[];\n};\n\nconst MATERIALIZED_DATASET_TABLES: Readonly<\n Partial<Record<ImportDatasetType, readonly string[]>>\n> = {\n companies: [\n \"simples_options\",\n \"partners\",\n \"establishment_secondary_cnaes\",\n \"establishments\",\n \"companies\",\n ],\n establishments: [\"establishment_secondary_cnaes\", \"establishments\"],\n partners: [\"partners\"],\n simples_options: [\"simples_options\"],\n} as const;\n\nfunction assertSupportedCleanupDataset(\n dataset: string | undefined,\n scopes: readonly DatabaseCleanupScope[],\n): asserts dataset is ImportDatasetType | undefined {\n if (dataset === undefined) {\n return;\n }\n\n if (!isImportDatasetType(dataset)) {\n throw new ValidationError(`Unsupported dataset type: ${dataset}.`);\n }\n\n if (scopes.includes(\"staging\") || scopes.includes(\"materialized\")) {\n const supported = Object.keys(\n MATERIALIZED_DATASET_TABLES,\n ) as ImportDatasetType[];\n if (!supported.includes(dataset)) {\n throw new ValidationError(\n `Dataset ${dataset} is not supported for this cleanup scope. Supported datasets: ${supported.join(\", \")}.`,\n );\n }\n }\n}\n\nfunction createBaseSummary(\n input: Pick<\n DatabaseCleanupSummary,\n | \"scope\"\n | \"targetDatabase\"\n | \"dataset\"\n | \"phase\"\n | \"validatedPath\"\n | \"planId\"\n >,\n): DatabaseCleanupSummary {\n return {\n ...input,\n truncatedTables: [],\n deletedLoadCheckpoints: 0,\n deletedMaterializationCheckpoints: 0,\n deletedPlans: 0,\n notes: [],\n };\n}\n\nfunction collectMaterializedTables(dataset?: ImportDatasetType): string[] {\n if (dataset) {\n return [...(MATERIALIZED_DATASET_TABLES[dataset] ?? [])];\n }\n\n const orderedTables = new Set<string>();\n for (const tableNames of Object.values(MATERIALIZED_DATASET_TABLES)) {\n for (const tableName of tableNames ?? []) {\n orderedTables.add(tableName);\n }\n }\n\n return [...orderedTables];\n}\n\nasync function tableExists(\n client: Client,\n tableName: string,\n): Promise<boolean> {\n const result = await client.query<{ exists: string | null }>(\n \"select to_regclass(current_schema() || '.' || $1) as exists\",\n [tableName],\n );\n\n return Boolean(result.rows[0]?.exists);\n}\n\nasync function filterExistingTables(\n client: Client,\n tableNames: readonly string[],\n): Promise<string[]> {\n const existingTables: string[] = [];\n\n for (const tableName of tableNames) {\n if (await tableExists(client, tableName)) {\n existingTables.push(tableName);\n }\n }\n\n return existingTables;\n}\n\nasync function deleteLoadCheckpoints(\n client: Client,\n dataset?: ImportDatasetType,\n): Promise<number> {\n await ensureCheckpointTable(client);\n\n const result = dataset\n ? await client.query(`delete from import_checkpoints where dataset = $1`, [\n dataset,\n ])\n : await client.query(`delete from import_checkpoints`);\n\n return result.rowCount ?? 0;\n}\n\nasync function resolvePlanIdsForCleanup(\n client: Client,\n input: {\n targetDatabase: string;\n planId?: number | undefined;\n validatedPath?: string | undefined;\n },\n): Promise<number[]> {\n await ensureImportPlanTables(client);\n\n if (input.planId !== undefined) {\n return [input.planId];\n }\n\n if (!input.validatedPath) {\n const result = await client.query<{ id: string }>(\n `select id from import_plans order by id asc`,\n );\n return result.rows.map((row) => Number.parseInt(row.id, 10));\n }\n\n const result = await client.query<{ id: string }>(\n `select id\n from import_plans\n where validated_path = $1\n and target_database = $2\n order by id asc`,\n [input.validatedPath, input.targetDatabase],\n );\n\n return result.rows.map((row) => Number.parseInt(row.id, 10));\n}\n\nasync function deleteMaterializationCheckpoints(\n client: Client,\n input: {\n targetDatabase: string;\n planId?: number | undefined;\n validatedPath?: string | undefined;\n dataset?: ImportDatasetType | undefined;\n },\n): Promise<number> {\n await ensureMaterializationCheckpointTable(client);\n const planIds = await resolvePlanIdsForCleanup(client, input);\n\n if (planIds.length === 0) {\n return 0;\n }\n\n if (input.dataset) {\n const result = await client.query(\n `delete from import_materialization_checkpoints\n where plan_id = any($1::bigint[])\n and dataset = $2`,\n [planIds, input.dataset],\n );\n return result.rowCount ?? 0;\n }\n\n const result = await client.query(\n `delete from import_materialization_checkpoints\n where plan_id = any($1::bigint[])`,\n [planIds],\n );\n return result.rowCount ?? 0;\n}\n\nasync function deleteImportPlans(\n client: Client,\n input: {\n targetDatabase: string;\n planId?: number | undefined;\n validatedPath?: string | undefined;\n },\n): Promise<number> {\n await ensureImportPlanTables(client);\n\n if (input.planId !== undefined) {\n const result = await client.query(\n `delete from import_plans where id = $1`,\n [input.planId],\n );\n return result.rowCount ?? 0;\n }\n\n if (input.validatedPath) {\n const result = await client.query(\n `delete from import_plans\n where validated_path = $1\n and target_database = $2`,\n [input.validatedPath, input.targetDatabase],\n );\n return result.rowCount ?? 0;\n }\n\n const result = await client.query(`delete from import_plans`);\n return result.rowCount ?? 0;\n}\n\nexport async function cleanupDatabaseStaging(\n client: Client,\n input: {\n dbUrl: string;\n dataset?: ImportDatasetType | undefined;\n validatedPath?: string | undefined;\n },\n): Promise<DatabaseCleanupSummary> {\n assertSupportedCleanupDataset(input.dataset, [\"staging\"]);\n\n const targetDatabase = maskDatabaseLabel(input.dbUrl);\n const summary = createBaseSummary({\n scope: \"staging\",\n targetDatabase,\n dataset: input.dataset,\n validatedPath: input.validatedPath,\n });\n\n const datasets: ImportDatasetType[] = input.dataset\n ? [input.dataset]\n : [\"companies\", \"establishments\", \"partners\", \"simples_options\"];\n\n summary.truncatedTables = await resetStagingTablesForFreshPlan(\n client,\n datasets,\n );\n\n if (input.validatedPath) {\n summary.deletedMaterializationCheckpoints =\n await deleteMaterializationCheckpoints(client, {\n targetDatabase,\n validatedPath: input.validatedPath,\n dataset: input.dataset,\n });\n summary.notes.push(\n \"Materialization checkpoints for the selected validated path were cleared so the next materialization can restart cleanly.\",\n );\n }\n\n return summary;\n}\n\nexport async function cleanupDatabaseMaterializedTables(\n client: Client,\n input: {\n dbUrl: string;\n dataset?: ImportDatasetType | undefined;\n },\n): Promise<DatabaseCleanupSummary> {\n assertSupportedCleanupDataset(input.dataset, [\"materialized\"]);\n\n const targetDatabase = maskDatabaseLabel(input.dbUrl);\n const summary = createBaseSummary({\n scope: \"materialized\",\n targetDatabase,\n dataset: input.dataset,\n });\n\n const tableNames = await filterExistingTables(\n client,\n collectMaterializedTables(input.dataset),\n );\n if (tableNames.length > 0) {\n await client.query(`truncate ${tableNames.join(\", \")}`);\n }\n summary.truncatedTables = tableNames;\n summary.notes.push(\n \"Simplified final materialized tables were truncated in safe order for the current schema. Clear materialization checkpoints separately if you want the import plan to rebuild these tables from scratch.\",\n );\n\n return summary;\n}\n\nexport async function cleanupDatabaseCheckpoints(\n client: Client,\n input: {\n dbUrl: string;\n phase: CheckpointCleanupPhase;\n dataset?: ImportDatasetType | undefined;\n validatedPath?: string | undefined;\n planId?: number | undefined;\n },\n): Promise<DatabaseCleanupSummary> {\n assertSupportedCleanupDataset(input.dataset, []);\n\n if (input.planId !== undefined && input.planId <= 0) {\n throw new ValidationError(\"The plan id must be a positive integer.\");\n }\n\n const targetDatabase = maskDatabaseLabel(input.dbUrl);\n const summary = createBaseSummary({\n scope: \"checkpoints\",\n targetDatabase,\n dataset: input.dataset,\n phase: input.phase,\n validatedPath: input.validatedPath,\n planId: input.planId,\n });\n\n if (input.phase === \"load\" || input.phase === \"all\") {\n summary.deletedLoadCheckpoints = await deleteLoadCheckpoints(\n client,\n input.dataset,\n );\n }\n\n if (input.phase === \"materialization\" || input.phase === \"all\") {\n summary.deletedMaterializationCheckpoints =\n await deleteMaterializationCheckpoints(client, {\n targetDatabase,\n planId: input.planId,\n validatedPath: input.validatedPath,\n dataset: input.dataset,\n });\n }\n\n if (\n input.phase !== \"load\" &&\n input.planId === undefined &&\n input.validatedPath === undefined\n ) {\n summary.notes.push(\n \"Without --plan-id or --validated-path, materialization checkpoint cleanup affects all saved import plans for this database.\",\n );\n }\n\n return summary;\n}\n\nexport async function cleanupDatabasePlans(\n client: Client,\n input: {\n dbUrl: string;\n validatedPath?: string | undefined;\n planId?: number | undefined;\n },\n): Promise<DatabaseCleanupSummary> {\n if (input.planId !== undefined && input.planId <= 0) {\n throw new ValidationError(\"The plan id must be a positive integer.\");\n }\n\n const targetDatabase = maskDatabaseLabel(input.dbUrl);\n const summary = createBaseSummary({\n scope: \"plans\",\n targetDatabase,\n validatedPath: input.validatedPath,\n planId: input.planId,\n });\n\n summary.deletedPlans = await deleteImportPlans(client, {\n targetDatabase,\n validatedPath: input.validatedPath,\n planId: input.planId,\n });\n summary.notes.push(\n \"Deleting import plans also removes linked plan files and materialization checkpoints through database cascades.\",\n );\n\n return summary;\n}\n","import {\n ageGroupsLayout,\n branchTypesLayout,\n cnaesLayout,\n citiesLayout,\n companiesLayout,\n companySizesLayout,\n countriesLayout,\n establishmentsLayout,\n legalNaturesLayout,\n partnerQualificationsLayout,\n partnerTypesLayout,\n partnersLayout,\n reasonsLayout,\n registrationStatusesLayout,\n simplesLayout,\n type TableLayout,\n} from \"../dictionary/layouts/index.js\";\n\nconst layouts: TableLayout[] = [\n companiesLayout,\n establishmentsLayout,\n partnersLayout,\n simplesLayout,\n countriesLayout,\n citiesLayout,\n partnerQualificationsLayout,\n legalNaturesLayout,\n cnaesLayout,\n reasonsLayout,\n companySizesLayout,\n branchTypesLayout,\n registrationStatusesLayout,\n partnerTypesLayout,\n ageGroupsLayout,\n];\n\nexport function getAllLayouts(): TableLayout[] {\n return layouts;\n}\n\nexport function getLayoutSummary(): Array<\n Pick<TableLayout, \"key\" | \"tableName\" | \"sourceName\">\n> {\n return layouts.map(({ key, tableName, sourceName }) => ({\n key,\n tableName,\n sourceName,\n }));\n}\n","import { access } from \"node:fs/promises\";\n\nimport {\n resolveDatabaseUrl,\n testDatabaseConnection,\n} from \"./database.service.js\";\n\nexport async function runDoctor(\n inputPath?: string,\n dbUrl?: string,\n): Promise<string[]> {\n const report: string[] = [];\n\n if (inputPath) {\n try {\n await access(inputPath);\n report.push(`Input path reachable: ${inputPath}`);\n } catch {\n report.push(`Input path not reachable: ${inputPath}`);\n }\n }\n\n try {\n const resolvedDbUrl = await resolveDatabaseUrl(dbUrl);\n await testDatabaseConnection(resolvedDbUrl);\n report.push(\"Database connection succeeded.\");\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n report.push(`Database check failed: ${message}`);\n }\n\n return report;\n}\n","import { readdir, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport type DatasetType =\n | \"companies\"\n | \"establishments\"\n | \"partners\"\n | \"simples_options\"\n | \"countries\"\n | \"cities\"\n | \"partner_qualifications\"\n | \"legal_natures\"\n | \"cnaes\"\n | \"reasons\"\n | \"zip-archive\"\n | \"unknown\";\n\nexport type InputDetectionMode =\n | \"zip-archives-only\"\n | \"extracted-tree\"\n | \"mixed\"\n | \"empty\";\n\nexport type FileInspection = {\n relativePath: string;\n entryName: string;\n entryKind: \"file\" | \"directory\";\n size: number;\n inferredType: DatasetType;\n requiresExtraction: boolean;\n};\n\nexport type InspectSummary = {\n inputPath: string;\n detectedInputMode: InputDetectionMode;\n totalEntries: number;\n zipArchivesFound: number;\n extractedEntriesFound: number;\n recognizedByType: Record<string, number>;\n recognizedDatasets: Partial<Record<DatasetType, number>>;\n warnings: string[];\n nextStep?: string | undefined;\n entries: FileInspection[];\n};\n\nconst DATASET_TYPES: DatasetType[] = [\n \"companies\",\n \"establishments\",\n \"partners\",\n \"simples_options\",\n \"countries\",\n \"cities\",\n \"partner_qualifications\",\n \"legal_natures\",\n \"cnaes\",\n \"reasons\",\n];\n\nconst DATASET_ALIASES: Record<string, DatasetType> = {\n empresas: \"companies\",\n estabelecimentos: \"establishments\",\n socios: \"partners\",\n simples: \"simples_options\",\n paises: \"countries\",\n municipios: \"cities\",\n qualificacoes: \"partner_qualifications\",\n naturezas: \"legal_natures\",\n cnaes: \"cnaes\",\n motivos: \"reasons\",\n emprecsv: \"companies\",\n estabelece: \"establishments\",\n sociocsv: \"partners\",\n simplescsv: \"simples_options\",\n paiscsv: \"countries\",\n municcsv: \"cities\",\n qualscsv: \"partner_qualifications\",\n natjucsv: \"legal_natures\",\n cnaecsv: \"cnaes\",\n moticsv: \"reasons\",\n};\n\nfunction normalizeEntryName(name: string): string {\n return name\n .normalize(\"NFD\")\n .replace(/[̀-ͯ]/g, \"\")\n .toLowerCase()\n .replace(/\\.zip$/i, \"\")\n .replace(/[\\\\/]/g, \"\")\n .replace(/[\\s._-]+/g, \"\")\n .replace(/\\d+$/g, \"\");\n}\n\nfunction inferDatasetAlias(name: string): DatasetType | undefined {\n const normalized = normalizeEntryName(name);\n\n if (DATASET_ALIASES[normalized]) {\n return DATASET_ALIASES[normalized];\n }\n\n if (normalized.startsWith(\"empresas\")) return \"companies\";\n if (normalized.startsWith(\"estabelecimentos\")) return \"establishments\";\n if (normalized.startsWith(\"socios\")) return \"partners\";\n if (normalized.startsWith(\"simples\")) return \"simples_options\";\n if (normalized.startsWith(\"paises\")) return \"countries\";\n if (normalized.startsWith(\"municipios\")) return \"cities\";\n if (normalized.startsWith(\"qualificacoes\")) return \"partner_qualifications\";\n if (normalized.startsWith(\"naturezas\")) return \"legal_natures\";\n if (normalized.startsWith(\"cnaes\")) return \"cnaes\";\n if (normalized.startsWith(\"motivos\")) return \"reasons\";\n\n if (normalized.includes(\"emprecsv\")) return \"companies\";\n if (normalized.includes(\"estabele\")) return \"establishments\";\n if (normalized.includes(\"sociocsv\")) return \"partners\";\n if (normalized.includes(\"simplescsv\")) return \"simples_options\";\n if (normalized.includes(\"paiscsv\")) return \"countries\";\n if (normalized.includes(\"municcsv\")) return \"cities\";\n if (normalized.includes(\"qualscsv\")) return \"partner_qualifications\";\n if (normalized.includes(\"natjucsv\")) return \"legal_natures\";\n if (normalized.includes(\"cnaecsv\")) return \"cnaes\";\n if (normalized.includes(\"moticsv\")) return \"reasons\";\n\n return undefined;\n}\n\nfunction inferType(relativePath: string, name: string): DatasetType {\n if (name.toLowerCase().endsWith(\".zip\")) {\n return \"zip-archive\";\n }\n\n const alias = inferDatasetAlias(relativePath) ?? inferDatasetAlias(name);\n if (alias) {\n return alias;\n }\n\n return \"unknown\";\n}\n\nasync function walk(\n rootPath: string,\n currentPath = rootPath,\n): Promise<FileInspection[]> {\n const entries = await readdir(currentPath, { withFileTypes: true });\n const inspections: FileInspection[] = [];\n\n for (const entry of entries) {\n const fullPath = path.join(currentPath, entry.name);\n const entryStat = await stat(fullPath);\n const relativePath = path.relative(rootPath, fullPath) || entry.name;\n const inferredType = inferType(relativePath, entry.name);\n\n inspections.push({\n relativePath,\n entryName: entry.name,\n entryKind: entry.isDirectory() ? \"directory\" : \"file\",\n size: entryStat.size,\n inferredType,\n requiresExtraction:\n entry.isFile() && entry.name.toLowerCase().endsWith(\".zip\"),\n });\n\n if (entry.isDirectory()) {\n inspections.push(...(await walk(rootPath, fullPath)));\n }\n }\n\n return inspections;\n}\n\nfunction detectInputMode(\n entries: FileInspection[],\n zipArchivesFound: number,\n extractedEntriesFound: number,\n): InputDetectionMode {\n if (entries.length === 0) {\n return \"empty\";\n }\n\n if (zipArchivesFound > 0 && extractedEntriesFound === 0) {\n return \"zip-archives-only\";\n }\n\n if (zipArchivesFound === 0 && extractedEntriesFound > 0) {\n return \"extracted-tree\";\n }\n\n return \"mixed\";\n}\n\nfunction inferNextStep(\n inputPath: string,\n mode: InputDetectionMode,\n): string | undefined {\n const normalized = inputPath.replace(/\\\\/g, \"/\");\n\n if (mode === \"zip-archives-only\") {\n return `cnpj-db-loader extract ${normalized}`;\n }\n\n if (mode === \"extracted-tree\") {\n return `cnpj-db-loader validate ${normalized}`;\n }\n\n if (mode === \"mixed\") {\n return `cnpj-db-loader validate ${normalized}`;\n }\n\n return undefined;\n}\n\nexport async function inspectFiles(inputPath: string): Promise<InspectSummary> {\n const resolvedInputPath = path.resolve(inputPath);\n const entries = await walk(resolvedInputPath);\n const zipArchivesFound = entries.filter((entry) =>\n entry.entryName.toLowerCase().endsWith(\".zip\"),\n ).length;\n const extractedEntriesFound = entries.filter(\n (entry) =>\n entry.inferredType !== \"zip-archive\" && entry.inferredType !== \"unknown\",\n ).length;\n\n const detectedInputMode = detectInputMode(\n entries,\n zipArchivesFound,\n extractedEntriesFound,\n );\n\n const recognizedByType = entries.reduce<Record<string, number>>(\n (accumulator, entry) => {\n accumulator[entry.inferredType] =\n (accumulator[entry.inferredType] ?? 0) + 1;\n return accumulator;\n },\n {},\n );\n\n const recognizedDatasets = DATASET_TYPES.reduce<\n Partial<Record<DatasetType, number>>\n >((accumulator, datasetType) => {\n const count = entries.filter(\n (entry) => entry.inferredType === datasetType,\n ).length;\n\n if (count > 0) {\n accumulator[datasetType] = count;\n }\n\n return accumulator;\n }, {});\n\n const warnings: string[] = [];\n\n if (detectedInputMode === \"zip-archives-only\") {\n for (const expectedType of DATASET_TYPES) {\n const expectedPrefixFound = entries.some(\n (entry) => inferDatasetAlias(entry.relativePath) === expectedType,\n );\n\n if (!expectedPrefixFound) {\n warnings.push(`Expected ZIP dataset block not found: ${expectedType}.`);\n }\n }\n\n if (zipArchivesFound > 0) {\n warnings.push(\n `Input contains ${zipArchivesFound} ZIP archive(s). Extract them before running validation on the dataset contents.`,\n );\n }\n } else {\n for (const expectedType of DATASET_TYPES) {\n if (!entries.some((entry) => entry.inferredType === expectedType)) {\n warnings.push(\n `Expected extracted dataset block not found: ${expectedType}.`,\n );\n }\n }\n\n if (detectedInputMode === \"mixed\") {\n warnings.push(\n \"Input contains both ZIP archives and extracted content. Consider using a clean extracted directory.\",\n );\n }\n }\n\n return {\n inputPath: resolvedInputPath,\n detectedInputMode,\n totalEntries: entries.length,\n zipArchivesFound,\n extractedEntriesFound,\n recognizedByType,\n recognizedDatasets,\n warnings,\n nextStep: inferNextStep(resolvedInputPath, detectedInputMode),\n entries,\n };\n}\n","import { writeFile } from \"node:fs/promises\";\n\nimport { generateSchemaParts } from \"./schema/builders.js\";\nimport {\n normalizeSchemaProfile,\n type SchemaGenerationOptions,\n type SchemaProfile,\n} from \"./schema/types.js\";\n\nexport function generateSchemaSql(options?: SchemaGenerationOptions): string {\n const profile = options?.profile ?? \"full\";\n return generateSchemaParts(profile).join(\"\\n\\n\");\n}\n\nexport async function writeSchemaFile(\n outFile: string,\n options?: SchemaGenerationOptions,\n): Promise<void> {\n await writeFile(outFile, `${generateSchemaSql(options)}\\n`, \"utf8\");\n}\n\nexport function resolveSchemaProfile(profile?: string): SchemaProfile {\n return normalizeSchemaProfile(profile);\n}\n\nexport type { SchemaGenerationOptions, SchemaProfile } from \"./schema/types.js\";\n","export function createImportPlansSql(): string {\n return [\n \"create table if not exists import_plans (\",\n \" id bigserial primary key,\",\n \" source_fingerprint text not null unique,\",\n \" input_path text not null,\",\n \" validated_path text not null,\",\n \" batch_size integer not null,\",\n \" target_database text not null,\",\n \" total_datasets integer not null,\",\n \" total_files integer not null,\",\n \" total_rows bigint not null,\",\n \" total_batches bigint not null,\",\n \" execution_order jsonb not null,\",\n \" status text not null default 'planned',\",\n \" load_status text not null default 'pending',\",\n \" materialization_status text not null default 'pending',\",\n \" last_phase text,\",\n \" last_error text,\",\n \" created_at timestamp with time zone not null default now(),\",\n \" updated_at timestamp with time zone not null default now(),\",\n \" last_used_at timestamp with time zone not null default now()\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createImportPlanFilesSql(): string {\n return [\n \"create table if not exists import_plan_files (\",\n \" id bigserial primary key,\",\n \" plan_id bigint not null references import_plans (id) on delete cascade,\",\n \" dataset text not null,\",\n \" dataset_index integer not null,\",\n \" file_index integer not null,\",\n \" file_path text not null,\",\n \" file_display_path text not null,\",\n \" file_size bigint not null,\",\n \" file_mtime timestamp with time zone not null,\",\n \" total_rows bigint not null,\",\n \" total_batches bigint not null,\",\n \" unique (plan_id, file_path)\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createImportCheckpointsSql(): string {\n return [\n \"create table if not exists import_checkpoints (\",\n \" id bigserial primary key,\",\n \" dataset text not null,\",\n \" file_path text not null,\",\n \" file_size bigint not null,\",\n \" file_mtime timestamp with time zone not null,\",\n \" byte_offset bigint not null default 0,\",\n \" rows_committed bigint not null default 0,\",\n \" status text not null default 'pending',\",\n \" last_error text,\",\n \" updated_at timestamp with time zone not null default now(),\",\n \" unique (dataset, file_path)\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createImportMaterializationCheckpointsSql(): string {\n return [\n \"create table if not exists import_materialization_checkpoints (\",\n \" id bigserial primary key,\",\n \" plan_id bigint not null references import_plans (id) on delete cascade,\",\n \" dataset text not null,\",\n \" target_table text not null,\",\n \" status text not null default 'pending',\",\n \" rows_materialized bigint not null default 0,\",\n \" last_staging_id bigint not null default 0,\",\n \" chunks_completed bigint not null default 0,\",\n \" last_error text,\",\n \" started_at timestamp with time zone,\",\n \" completed_at timestamp with time zone,\",\n \" updated_at timestamp with time zone not null default now(),\",\n \" staging_row_count_verified bigint,\",\n \" staging_max_staging_id_verified bigint,\",\n \" staging_validated_at timestamp with time zone,\",\n \" lookup_reconciliation_status text not null default 'pending',\",\n \" lookup_reconciliation_row_count_verified bigint,\",\n \" lookup_reconciliation_max_staging_id_verified bigint,\",\n \" lookup_reconciliation_completed_at timestamp with time zone,\",\n \" last_chunk_first_staging_id bigint not null default 0,\",\n \" last_chunk_last_staging_id bigint not null default 0,\",\n \" last_chunk_rows bigint not null default 0,\",\n \" unique (plan_id, dataset)\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createImportQuarantineSql(): string {\n return [\n \"create table if not exists import_quarantine (\",\n \" id bigserial primary key,\",\n \" dataset text not null,\",\n \" file_path text not null,\",\n \" row_number bigint,\",\n \" checkpoint_offset bigint,\",\n \" error_code text,\",\n \" error_category text,\",\n \" error_stage text,\",\n \" error_message text not null,\",\n \" raw_line text not null,\",\n \" parsed_payload jsonb,\",\n \" sanitizations_applied jsonb,\",\n \" retry_count integer not null default 0,\",\n \" can_retry_later boolean not null default false,\",\n \" created_at timestamp with time zone not null default now()\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createControlSchemaParts(): string[] {\n return [\n \"-- Import control tables\",\n createImportPlansSql(),\n createImportPlanFilesSql(),\n createImportCheckpointsSql(),\n createImportMaterializationCheckpointsSql(),\n createImportQuarantineSql(),\n ];\n}\n","import type {\n FieldDefinition,\n TableLayout,\n} from \"../../dictionary/layouts/index.js\";\n\nexport function mapType(dataType: FieldDefinition[\"dataType\"]): string {\n switch (dataType) {\n case \"integer\":\n return \"integer\";\n case \"numeric\":\n return \"numeric(18,2)\";\n case \"date\":\n return \"date\";\n case \"boolean\":\n return \"boolean\";\n default:\n return \"text\";\n }\n}\n\nexport function createColumnSql(field: FieldDefinition): string {\n return ` ${field.columnName} ${mapType(field.dataType)}${field.nullable ? \"\" : \" not null\"}`;\n}\n\nexport function createSimpleDomainTableSql(layout: TableLayout): string {\n const columns = layout.fields.map(createColumnSql).join(\",\\n\");\n return [\n `create table if not exists ${layout.tableName} (`,\n columns + \",\",\n \" primary key (code)\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createLookupSeedSql(\n tableName: string,\n rows: Array<[string, string]>,\n): string {\n const values = rows\n .map(\n ([code, description]) =>\n ` ('${code.replace(/'/g, \"''\")}', '${description.replace(/'/g, \"''\")}')`,\n )\n .join(\",\\n\");\n\n return [\n `insert into ${tableName} (code, description) values`,\n values,\n \"on conflict (code) do update set description = excluded.description;\",\n ].join(\"\\n\");\n}\n","import {\n ageGroupsLayout,\n branchTypesLayout,\n citiesLayout,\n cnaesLayout,\n companySizesLayout,\n countriesLayout,\n legalNaturesLayout,\n partnerQualificationsLayout,\n partnerTypesLayout,\n reasonsLayout,\n registrationStatusesLayout,\n} from \"../../dictionary/layouts/index.js\";\nimport { createLookupSeedSql, createSimpleDomainTableSql } from \"./shared.js\";\n\nconst domainTables = [\n countriesLayout,\n citiesLayout,\n partnerQualificationsLayout,\n legalNaturesLayout,\n cnaesLayout,\n reasonsLayout,\n companySizesLayout,\n branchTypesLayout,\n registrationStatusesLayout,\n partnerTypesLayout,\n ageGroupsLayout,\n];\n\nexport function createDomainSchemaParts(): string[] {\n return [\"-- Domain tables\", ...domainTables.map(createSimpleDomainTableSql)];\n}\n\nexport function createDomainSeedParts(): string[] {\n return [\n \"-- Domain seed data\",\n createLookupSeedSql(\"company_sizes\", [\n [\"00\", \"Not informed\"],\n [\"01\", \"Micro company\"],\n [\"03\", \"Small business\"],\n [\"05\", \"Other\"],\n ]),\n createLookupSeedSql(\"branch_types\", [\n [\"1\", \"Headquarters\"],\n [\"2\", \"Branch\"],\n ]),\n createLookupSeedSql(\"registration_statuses\", [\n [\"01\", \"Null\"],\n [\"2\", \"Active\"],\n [\"3\", \"Suspended\"],\n [\"4\", \"Inactive\"],\n [\"08\", \"Closed\"],\n ]),\n createLookupSeedSql(\"partner_types\", [\n [\"1\", \"Legal entity\"],\n [\"2\", \"Natural person\"],\n [\"3\", \"Foreign person/entity\"],\n ]),\n createLookupSeedSql(\"age_groups\", [\n [\"0\", \"Not applicable\"],\n [\"1\", \"0 to 12 years\"],\n [\"2\", \"13 to 20 years\"],\n [\"3\", \"21 to 30 years\"],\n [\"4\", \"31 to 40 years\"],\n [\"5\", \"41 to 50 years\"],\n [\"6\", \"51 to 60 years\"],\n [\"7\", \"61 to 70 years\"],\n [\"8\", \"71 to 80 years\"],\n [\"9\", \"Over 80 years\"],\n ]),\n ];\n}\n","export function createIndexesSql(): string {\n return [\n \"-- Operational indexes\",\n \"create index if not exists idx_establishments_cnpj_root on establishments (cnpj_root);\",\n \"create index if not exists idx_establishment_secondary_cnaes_cnae_code on establishment_secondary_cnaes (cnae_code);\",\n \"create index if not exists idx_partners_cnpj_root on partners (cnpj_root);\",\n \"create index if not exists idx_import_plans_status on import_plans (status);\",\n \"create index if not exists idx_import_plans_load_status on import_plans (load_status);\",\n \"create index if not exists idx_import_plans_materialization_status on import_plans (materialization_status);\",\n \"create index if not exists idx_import_plan_files_plan_id on import_plan_files (plan_id);\",\n \"create index if not exists idx_import_plan_files_dataset on import_plan_files (dataset);\",\n \"create index if not exists idx_import_checkpoints_status on import_checkpoints (status);\",\n \"create index if not exists idx_import_materialization_checkpoints_status on import_materialization_checkpoints (status);\",\n \"create index if not exists idx_import_materialization_checkpoints_plan_id on import_materialization_checkpoints (plan_id);\",\n \"create index if not exists idx_import_materialization_checkpoints_dataset on import_materialization_checkpoints (dataset);\",\n \"create index if not exists idx_import_checkpoints_dataset on import_checkpoints (dataset);\",\n \"create index if not exists idx_import_quarantine_dataset on import_quarantine (dataset);\",\n \"create index if not exists idx_import_quarantine_file_path on import_quarantine (file_path);\",\n \"create index if not exists idx_import_quarantine_error_category on import_quarantine (error_category);\",\n \"create index if not exists idx_import_quarantine_can_retry_later on import_quarantine (can_retry_later);\",\n ].join(\"\\n\");\n}\n","import {\n companiesLayout,\n establishmentsLayout,\n partnersLayout,\n simplesLayout,\n} from \"../../dictionary/layouts/index.js\";\nimport { createColumnSql } from \"./shared.js\";\n\nexport function createCompaniesSql(): string {\n return [\n \"create table if not exists companies (\",\n companiesLayout.fields.map(createColumnSql).join(\",\\n\") + \",\",\n \" created_at timestamp without time zone not null default now(),\",\n \" updated_at timestamp without time zone not null default now(),\",\n \" primary key (cnpj_root)\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createEstablishmentsSql(): string {\n const baseColumns = establishmentsLayout.fields\n .map(createColumnSql)\n .join(\",\\n\");\n\n return [\n \"create table if not exists establishments (\",\n baseColumns + \",\",\n \" cnpj_full text not null,\",\n \" created_at timestamp without time zone not null default now(),\",\n \" updated_at timestamp without time zone not null default now(),\",\n \" primary key (cnpj_full)\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createPartnersSql(): string {\n return [\n \"create table if not exists partners (\",\n \" id bigserial primary key,\",\n partnersLayout.fields.map(createColumnSql).join(\",\\n\") + \",\",\n \" partner_dedupe_key text not null,\",\n \" created_at timestamp without time zone not null default now(),\",\n \" updated_at timestamp without time zone not null default now(),\",\n \" unique (partner_dedupe_key)\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createEstablishmentSecondaryCnaesSql(): string {\n return [\n \"create table if not exists establishment_secondary_cnaes (\",\n \" cnpj_full text not null,\",\n \" cnae_code text not null,\",\n \" primary key (cnpj_full, cnae_code)\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createSimplesSql(): string {\n return [\n \"create table if not exists simples_options (\",\n simplesLayout.fields.map(createColumnSql).join(\",\\n\") + \",\",\n \" created_at timestamp without time zone not null default now(),\",\n \" updated_at timestamp without time zone not null default now(),\",\n \" primary key (cnpj_root),\",\n \" constraint chk_simples_flag check (simples_option_flag in ('S', 'N') or simples_option_flag is null or simples_option_flag = ''),\",\n \" constraint chk_mei_flag check (mei_option_flag in ('S', 'N') or mei_option_flag is null or mei_option_flag = '')\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createOperationalSchemaParts(): string[] {\n return [\n \"-- Final operational tables (simplified for fast first-load materialization)\",\n createCompaniesSql(),\n createEstablishmentsSql(),\n createEstablishmentSecondaryCnaesSql(),\n createPartnersSql(),\n createSimplesSql(),\n ];\n}\n","import {\n companiesLayout,\n establishmentsLayout,\n partnersLayout,\n simplesLayout,\n} from \"../../dictionary/layouts/index.js\";\nimport { createColumnSql } from \"./shared.js\";\n\nfunction createUnloggedStagingTableSql(\n tableName: string,\n columnsSql: string,\n): string {\n return [\n `create unlogged table if not exists ${tableName} (`,\n \" staging_id bigserial primary key,\",\n columnsSql,\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createStagingCompaniesSql(): string {\n return createUnloggedStagingTableSql(\n \"staging_companies\",\n companiesLayout.fields.map(createColumnSql).join(\",\\n\"),\n );\n}\n\nexport function createStagingEstablishmentsSql(): string {\n return createUnloggedStagingTableSql(\n \"staging_establishments\",\n establishmentsLayout.fields.map(createColumnSql).join(\",\\n\"),\n );\n}\n\nexport function createStagingPartnersSql(): string {\n return createUnloggedStagingTableSql(\n \"staging_partners\",\n partnersLayout.fields.map(createColumnSql).join(\",\\n\"),\n );\n}\n\nexport function createStagingSimplesSql(): string {\n return createUnloggedStagingTableSql(\n \"staging_simples_options\",\n simplesLayout.fields.map(createColumnSql).join(\",\\n\"),\n );\n}\n\nexport function createStagingSchemaParts(): string[] {\n return [\n \"-- Staging tables for bulk-oriented imports\",\n createStagingCompaniesSql(),\n createStagingEstablishmentsSql(),\n createStagingPartnersSql(),\n createStagingSimplesSql(),\n ];\n}\n","import { createControlSchemaParts } from \"./control.js\";\nimport { createDomainSchemaParts, createDomainSeedParts } from \"./domain.js\";\nimport { createIndexesSql } from \"./indexes.js\";\nimport { createOperationalSchemaParts } from \"./operational.js\";\nimport { createStagingSchemaParts } from \"./staging.js\";\nimport type { SchemaProfile } from \"./types.js\";\n\nfunction createSchemaBody(profile: SchemaProfile): string[] {\n switch (profile) {\n case \"staging\":\n return createStagingSchemaParts();\n case \"final\":\n return [\n ...createDomainSchemaParts(),\n ...createOperationalSchemaParts(),\n ...createControlSchemaParts(),\n ...createDomainSeedParts(),\n createIndexesSql(),\n ];\n case \"full\":\n default:\n return [\n ...createDomainSchemaParts(),\n ...createOperationalSchemaParts(),\n ...createControlSchemaParts(),\n ...createStagingSchemaParts(),\n ...createDomainSeedParts(),\n createIndexesSql(),\n ];\n }\n}\n\nfunction createSchemaHeader(profile: SchemaProfile): string[] {\n return [\n \"-- CNPJ DB Loader PostgreSQL schema\",\n `-- Profile: ${profile}`,\n \"-- Generated from the internal Receita Federal model.\",\n \"begin;\",\n ];\n}\n\nexport function generateSchemaParts(profile: SchemaProfile): string[] {\n return [\n ...createSchemaHeader(profile),\n ...createSchemaBody(profile),\n \"commit;\",\n ];\n}\n","import { ValidationError } from \"../../core/errors/index.js\";\n\nexport const SCHEMA_PROFILES = [\"full\", \"final\", \"staging\"] as const;\n\nexport type SchemaProfile = (typeof SCHEMA_PROFILES)[number];\n\nexport type SchemaGenerationOptions = {\n profile?: SchemaProfile;\n};\n\nconst SCHEMA_PROFILE_ALIASES: Record<string, SchemaProfile> = {\n all: \"full\",\n combined: \"full\",\n full: \"full\",\n final: \"final\",\n \"final-load\": \"final\",\n load: \"final\",\n minimal: \"final\",\n operational: \"final\",\n production: \"final\",\n stage: \"staging\",\n staging: \"staging\",\n};\n\nexport function normalizeSchemaProfile(input?: string): SchemaProfile {\n const normalized = input?.trim().toLowerCase();\n\n if (!normalized) {\n return \"full\";\n }\n\n const profile = SCHEMA_PROFILE_ALIASES[normalized];\n if (profile) {\n return profile;\n }\n\n throw new ValidationError(\n `Invalid schema profile \"${input}\". Expected one of: full, final, or staging. Aliases such as final-load, load, operational, and stage are also accepted.`,\n );\n}\n","import path from \"node:path\";\n\nimport type {\n DatasetType,\n FileInspection,\n InspectSummary,\n} from \"./inspect.service.js\";\nimport { inspectFiles } from \"./inspect.service.js\";\n\nconst EXPECTED_DATASETS: DatasetType[] = [\n \"companies\",\n \"establishments\",\n \"partners\",\n \"simples_options\",\n \"countries\",\n \"cities\",\n \"partner_qualifications\",\n \"legal_natures\",\n \"cnaes\",\n \"reasons\",\n];\n\nexport type ValidationSummary = {\n ok: boolean;\n errors: string[];\n warnings: string[];\n inspected: InspectSummary;\n validatedPath: string;\n presentDatasets: DatasetType[];\n missingDatasets: DatasetType[];\n nextStep?: string | undefined;\n};\n\nfunction isRecognizedDataset(\n entry: FileInspection,\n): entry is FileInspection & { inferredType: DatasetType } {\n return (\n entry.inferredType !== \"zip-archive\" && entry.inferredType !== \"unknown\"\n );\n}\n\nfunction uniqueDatasets(entries: FileInspection[]): DatasetType[] {\n return [\n ...new Set(\n entries.filter(isRecognizedDataset).map((entry) => entry.inferredType),\n ),\n ].sort();\n}\n\nfunction summarizeUnknownEntries(unknownEntries: FileInspection[]): string[] {\n if (unknownEntries.length === 0) {\n return [];\n }\n\n const preview = unknownEntries.slice(0, 5).map((entry) => entry.relativePath);\n const warnings = [\n `Found ${unknownEntries.length} unrecognized file(s) inside the validated tree.`,\n ];\n\n for (const item of preview) {\n warnings.push(`Unrecognized file: ${item}`);\n }\n\n if (unknownEntries.length > preview.length) {\n warnings.push(\n `Additional unrecognized files were omitted from the terminal output. Check the log file for the complete list.`,\n );\n }\n\n return warnings;\n}\n\nfunction selectEntriesForValidation(inspected: InspectSummary): {\n validatedPath: string;\n entries: FileInspection[];\n} {\n if (inspected.detectedInputMode !== \"mixed\") {\n return {\n validatedPath: inspected.inputPath,\n entries: inspected.entries,\n };\n }\n\n const extractedPrefix = `extracted${path.sep}`;\n const extractedEntries = inspected.entries.filter(\n (entry) =>\n entry.relativePath === \"extracted\" ||\n entry.relativePath.startsWith(extractedPrefix),\n );\n\n if (extractedEntries.length > 0) {\n return {\n validatedPath: path.join(inspected.inputPath, \"extracted\"),\n entries: extractedEntries.map((entry) => ({\n ...entry,\n relativePath:\n entry.relativePath === \"extracted\"\n ? \".\"\n : entry.relativePath.slice(extractedPrefix.length),\n })),\n };\n }\n\n return {\n validatedPath: inspected.inputPath,\n entries: inspected.entries.filter(\n (entry) => !entry.relativePath.toLowerCase().endsWith(\".zip\"),\n ),\n };\n}\n\nfunction inferNextStep(summary: {\n ok: boolean;\n detectedInputMode: InspectSummary[\"detectedInputMode\"];\n inputPath: string;\n validatedPath: string;\n missingDatasets: DatasetType[];\n zipArchivesFound: number;\n presentDatasets: DatasetType[];\n}): string | undefined {\n const normalizedInputPath = summary.inputPath.replace(/\\\\/g, \"/\");\n\n if (summary.detectedInputMode === \"zip-archives-only\") {\n return `cnpj-db-loader extract ${normalizedInputPath}`;\n }\n\n if (\n !summary.ok &&\n summary.zipArchivesFound > 0 &&\n summary.presentDatasets.length === 0\n ) {\n return `cnpj-db-loader extract ${normalizedInputPath}`;\n }\n\n if (!summary.ok && summary.missingDatasets.length > 0) {\n return `Review the extracted files and ensure all expected dataset blocks are present.`;\n }\n\n if (summary.ok) {\n const normalizedValidatedPath = summary.validatedPath.replace(/\\\\/g, \"/\");\n const validatedBaseName = path\n .basename(summary.validatedPath)\n .toLowerCase();\n if (\n validatedBaseName === \"sanitized\" ||\n validatedBaseName.endsWith(\"-sanitized\")\n ) {\n return `cnpj-db-loader database config show`;\n }\n\n return `cnpj-db-loader sanitize ${normalizedValidatedPath}`;\n }\n\n return undefined;\n}\n\nexport async function validateInputDirectory(\n inputPath: string,\n): Promise<ValidationSummary> {\n const inspected = await inspectFiles(inputPath);\n const errors: string[] = [];\n const warnings: string[] = [];\n\n if (inspected.totalEntries === 0) {\n errors.push(\n \"No files or directories were found in the provided input path.\",\n );\n }\n\n const selected = selectEntriesForValidation(inspected);\n const recognizedEntries = selected.entries.filter(isRecognizedDataset);\n const presentDatasets = uniqueDatasets(recognizedEntries);\n const missingDatasets = EXPECTED_DATASETS.filter(\n (dataset) => !presentDatasets.includes(dataset),\n );\n\n const unknownEntries = selected.entries.filter(\n (entry) => entry.entryKind === \"file\" && entry.inferredType === \"unknown\",\n );\n\n if (inspected.detectedInputMode === \"zip-archives-only\") {\n warnings.push(\n `No extracted dataset tree was found in ${inspected.inputPath}. Extraction is required before validation can check dataset completeness.`,\n );\n } else {\n if (presentDatasets.length === 0) {\n errors.push(\n `No recognized extracted dataset files were found in ${selected.validatedPath}.`,\n );\n }\n\n if (missingDatasets.length > 0) {\n errors.push(\n `The extracted dataset tree is incomplete. Missing dataset block(s): ${missingDatasets.join(\", \")}.`,\n );\n }\n\n if (\n inspected.detectedInputMode === \"mixed\" &&\n presentDatasets.length > 0 &&\n missingDatasets.length === 0\n ) {\n warnings.push(\n `A valid extracted dataset tree was found at ${selected.validatedPath}. ZIP archives are also present in the parent directory, but extraction does not need to be run again.`,\n );\n }\n }\n\n warnings.push(...summarizeUnknownEntries(unknownEntries));\n\n const nextStep = inferNextStep({\n ok: errors.length === 0,\n detectedInputMode: inspected.detectedInputMode,\n inputPath: inspected.inputPath,\n validatedPath: selected.validatedPath,\n missingDatasets,\n zipArchivesFound: inspected.zipArchivesFound,\n presentDatasets,\n });\n\n return {\n ok: errors.length === 0,\n errors,\n warnings,\n inspected,\n validatedPath: selected.validatedPath,\n presentDatasets,\n missingDatasets,\n nextStep,\n };\n}\n","import { mkdir, readdir, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport extract from \"extract-zip\";\n\nimport { detectOs, defaultExtractedOutputPath } from \"../core/utils/index.js\";\n\nexport type ExtractionEntry = {\n archivePath: string;\n archiveName: string;\n destinationPath: string;\n success: boolean;\n sizeInBytes: number;\n errorMessage?: string;\n};\n\nexport type ExtractionSummary = {\n inputPath: string;\n outputPath: string;\n operatingSystem: string;\n zipFilesFound: number;\n extractedArchives: string[];\n skippedEntries: string[];\n failedArchives: string[];\n totalArchiveBytes: number;\n extractedArchiveBytes: number;\n entries: ExtractionEntry[];\n};\n\nexport type ExtractionProgressEvent =\n | {\n kind: \"start\";\n totalArchives: number;\n totalBytes: number;\n inputPath: string;\n outputPath: string;\n }\n | {\n kind: \"archive-start\";\n currentArchiveName: string;\n currentArchivePath: string;\n archiveSizeInBytes: number;\n archiveIndex: number;\n totalArchives: number;\n completedArchives: number;\n extractedBytes: number;\n totalBytes: number;\n }\n | {\n kind: \"archive-complete\";\n currentArchiveName: string;\n currentArchivePath: string;\n archiveSizeInBytes: number;\n archiveIndex: number;\n totalArchives: number;\n completedArchives: number;\n extractedBytes: number;\n totalBytes: number;\n }\n | {\n kind: \"archive-failed\";\n currentArchiveName: string;\n currentArchivePath: string;\n archiveSizeInBytes: number;\n archiveIndex: number;\n totalArchives: number;\n completedArchives: number;\n extractedBytes: number;\n totalBytes: number;\n errorMessage: string;\n }\n | {\n kind: \"finish\";\n totalArchives: number;\n completedArchives: number;\n failedArchives: number;\n extractedBytes: number;\n totalBytes: number;\n outputPath: string;\n };\n\nexport type ExtractionProgressListener = (\n event: ExtractionProgressEvent,\n) => void;\n\nasync function findZipFiles(rootPath: string): Promise<string[]> {\n const entries = await readdir(rootPath, { withFileTypes: true });\n const found: string[] = [];\n\n for (const entry of entries) {\n const fullPath = path.join(rootPath, entry.name);\n\n if (entry.isDirectory()) {\n if (entry.name.toLowerCase() === \"extracted\") {\n continue;\n }\n\n found.push(...(await findZipFiles(fullPath)));\n continue;\n }\n\n if (entry.isFile() && entry.name.toLowerCase().endsWith(\".zip\")) {\n found.push(fullPath);\n }\n }\n\n return found.sort((left, right) => left.localeCompare(right));\n}\n\nasync function extractSingleArchive(\n zipPath: string,\n outputRootPath: string,\n archiveSizeInBytes: number,\n): Promise<ExtractionEntry> {\n const archiveName = path.basename(zipPath);\n const folderName = path.basename(zipPath, path.extname(zipPath));\n const destinationPath = path.join(outputRootPath, folderName);\n\n try {\n await mkdir(destinationPath, { recursive: true });\n await extract(zipPath, { dir: destinationPath });\n\n return {\n archivePath: zipPath,\n archiveName,\n destinationPath,\n success: true,\n sizeInBytes: archiveSizeInBytes,\n };\n } catch (error) {\n return {\n archivePath: zipPath,\n archiveName,\n destinationPath,\n success: false,\n sizeInBytes: archiveSizeInBytes,\n errorMessage: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nexport async function extractArchives(\n inputPath: string,\n outputPath?: string,\n onProgress?: ExtractionProgressListener,\n): Promise<ExtractionSummary> {\n const resolvedInputPath = path.resolve(inputPath);\n const resolvedOutputPath = path.resolve(\n outputPath ?? defaultExtractedOutputPath(resolvedInputPath),\n );\n await mkdir(resolvedOutputPath, { recursive: true });\n\n const zipFiles = await findZipFiles(resolvedInputPath);\n const zipFileStats = await Promise.all(\n zipFiles.map(async (zipFile) => ({ zipFile, stat: await stat(zipFile) })),\n );\n const totalArchiveBytes = zipFileStats.reduce(\n (sum, item) => sum + item.stat.size,\n 0,\n );\n\n onProgress?.({\n kind: \"start\",\n totalArchives: zipFiles.length,\n totalBytes: totalArchiveBytes,\n inputPath: resolvedInputPath,\n outputPath: resolvedOutputPath,\n });\n\n const extractedArchives: string[] = [];\n const failedArchives: string[] = [];\n const entries: ExtractionEntry[] = [];\n let extractedArchiveBytes = 0;\n let completedArchivesCount = 0;\n\n for (const [index, item] of zipFileStats.entries()) {\n const archiveName = path.basename(item.zipFile);\n\n onProgress?.({\n kind: \"archive-start\",\n currentArchiveName: archiveName,\n currentArchivePath: item.zipFile,\n archiveSizeInBytes: item.stat.size,\n archiveIndex: index + 1,\n totalArchives: zipFiles.length,\n completedArchives: completedArchivesCount,\n extractedBytes: extractedArchiveBytes,\n totalBytes: totalArchiveBytes,\n });\n\n const result = await extractSingleArchive(\n item.zipFile,\n resolvedOutputPath,\n item.stat.size,\n );\n entries.push(result);\n\n if (result.success) {\n extractedArchives.push(result.archiveName);\n extractedArchiveBytes += result.sizeInBytes;\n completedArchivesCount += 1;\n\n onProgress?.({\n kind: \"archive-complete\",\n currentArchiveName: result.archiveName,\n currentArchivePath: result.archivePath,\n archiveSizeInBytes: result.sizeInBytes,\n archiveIndex: index + 1,\n totalArchives: zipFiles.length,\n completedArchives: completedArchivesCount,\n extractedBytes: extractedArchiveBytes,\n totalBytes: totalArchiveBytes,\n });\n } else {\n failedArchives.push(result.archiveName);\n onProgress?.({\n kind: \"archive-failed\",\n currentArchiveName: result.archiveName,\n currentArchivePath: result.archivePath,\n archiveSizeInBytes: result.sizeInBytes,\n archiveIndex: index + 1,\n totalArchives: zipFiles.length,\n completedArchives: completedArchivesCount,\n extractedBytes: extractedArchiveBytes,\n totalBytes: totalArchiveBytes,\n errorMessage: result.errorMessage ?? \"Unknown extraction error\",\n });\n }\n }\n\n const skippedEntries: string[] = [];\n const outputEntries = await readdir(resolvedOutputPath);\n\n for (const entry of outputEntries) {\n const fullPath = path.join(resolvedOutputPath, entry);\n const entryStat = await stat(fullPath);\n if (!entryStat.isFile() && !entryStat.isDirectory()) {\n skippedEntries.push(entry);\n }\n }\n\n onProgress?.({\n kind: \"finish\",\n totalArchives: zipFiles.length,\n completedArchives: completedArchivesCount,\n failedArchives: failedArchives.length,\n extractedBytes: extractedArchiveBytes,\n totalBytes: totalArchiveBytes,\n outputPath: resolvedOutputPath,\n });\n\n return {\n inputPath: resolvedInputPath,\n outputPath: resolvedOutputPath,\n operatingSystem: detectOs(),\n zipFilesFound: zipFiles.length,\n extractedArchives,\n skippedEntries,\n failedArchives,\n totalArchiveBytes,\n extractedArchiveBytes,\n entries,\n };\n}\n","export type InputMode = \"unzip\" | \"already-extracted\";\n\nexport function resolveInputMode(options: {\n unzip?: boolean;\n alreadyExtracted?: boolean;\n}): InputMode {\n if (options.unzip && options.alreadyExtracted) {\n throw new Error(\n 'Choose only one input mode: use either \"--unzip\" or \"--already-extracted\".',\n );\n }\n\n if (options.unzip) {\n return \"unzip\";\n }\n\n return \"already-extracted\";\n}\n","import { appendFile, mkdir, writeFile } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nimport {\n buildStructuredLogEntry,\n serializeErrorDetails,\n} from \"./logging/entry.js\";\nimport type {\n LogLevel,\n LogStatus,\n StructuredLogEntry,\n} from \"./logging/types.js\";\n\nconst DEFAULT_APP_DIRECTORY_NAME = \".cnpjdbloader\";\nconst DEFAULT_LOGS_DIRECTORY_NAME = \"logs\";\n\ntype WriteLogOptions = {\n baseDirectory?: string;\n event?: string;\n level?: LogLevel;\n status?: LogStatus;\n message?: string;\n};\n\nfunction sanitizeSegment(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\nfunction createTimestamp(): string {\n const now = new Date();\n const parts = [\n now.getFullYear(),\n String(now.getMonth() + 1).padStart(2, \"0\"),\n String(now.getDate()).padStart(2, \"0\"),\n String(now.getHours()).padStart(2, \"0\"),\n String(now.getMinutes()).padStart(2, \"0\"),\n String(now.getSeconds()).padStart(2, \"0\"),\n ];\n\n return `${parts[0]}${parts[1]}${parts[2]}-${parts[3]}${parts[4]}${parts[5]}`;\n}\n\nexport function getUserAppDirectoryPath(): string {\n return path.join(os.homedir(), DEFAULT_APP_DIRECTORY_NAME);\n}\n\nexport function getLogsDirectoryPath(\n baseDirectory = getUserAppDirectoryPath(),\n): string {\n return path.join(baseDirectory, DEFAULT_LOGS_DIRECTORY_NAME);\n}\n\nasync function ensureLogsDirectory(baseDirectory?: string): Promise<string> {\n const logsDirectory = getLogsDirectoryPath(baseDirectory);\n await mkdir(logsDirectory, { recursive: true });\n return logsDirectory;\n}\n\nfunction buildCommandLogEntry(\n commandName: string,\n payload: unknown,\n options?: Omit<WriteLogOptions, \"baseDirectory\">,\n): StructuredLogEntry {\n return buildStructuredLogEntry({\n payload,\n defaultEvent: options?.event ?? \"command_completed\",\n defaultLevel: options?.level ?? \"info\",\n command: commandName,\n status: options?.status ?? \"success\",\n ...(options?.message ? { message: options.message } : {}),\n });\n}\n\nexport async function writeCommandLog(\n commandName: string,\n payload: unknown,\n baseDirectoryOrOptions?: string | WriteLogOptions,\n maybeOptions?: Omit<WriteLogOptions, \"baseDirectory\">,\n): Promise<string> {\n const options: WriteLogOptions =\n typeof baseDirectoryOrOptions === \"string\"\n ? { ...maybeOptions, baseDirectory: baseDirectoryOrOptions }\n : (baseDirectoryOrOptions ?? {});\n\n const logsDirectory = await ensureLogsDirectory(options.baseDirectory);\n const fileName = `${createTimestamp()}-${sanitizeSegment(commandName)}.json`;\n const filePath = path.join(logsDirectory, fileName);\n const entry = buildCommandLogEntry(commandName, payload, options);\n\n await writeFile(filePath, `${JSON.stringify(entry, null, 2)}\\n`, \"utf8\");\n return filePath;\n}\n\nexport async function writeCommandFailureLog(\n commandName: string,\n error: unknown,\n input?: {\n argv?: string[];\n context?: Record<string, unknown>;\n baseDirectory?: string;\n fatal?: boolean;\n },\n): Promise<string> {\n return writeCommandLog(\n commandName,\n {\n error: serializeErrorDetails(error),\n ...(input?.argv ? { argv: input.argv } : {}),\n ...(input?.context ? { context: input.context } : {}),\n },\n {\n ...(input?.baseDirectory ? { baseDirectory: input.baseDirectory } : {}),\n event: \"command_failed\",\n level: input?.fatal ? \"fatal\" : \"error\",\n status: \"failure\",\n message: \"Command execution failed.\",\n },\n );\n}\n\nexport async function createJsonLinesLog(\n commandName: string,\n baseDirectory?: string,\n): Promise<string> {\n const logsDirectory = await ensureLogsDirectory(baseDirectory);\n const fileName = `${createTimestamp()}-${sanitizeSegment(commandName)}.jsonl`;\n const filePath = path.join(logsDirectory, fileName);\n await writeFile(filePath, \"\", \"utf8\");\n return filePath;\n}\n\nexport async function appendJsonLinesLog(\n filePath: string,\n payload: unknown,\n options?: Omit<WriteLogOptions, \"baseDirectory\" | \"status\"> & {\n command?: string;\n status?: LogStatus;\n },\n): Promise<void> {\n const entry = buildStructuredLogEntry({\n payload,\n defaultEvent: options?.event ?? \"log_entry\",\n defaultLevel: options?.level ?? \"info\",\n ...(options?.command ? { command: options.command } : {}),\n ...(options?.status ? { status: options.status } : {}),\n ...(options?.message ? { message: options.message } : {}),\n });\n\n await appendFile(filePath, `${JSON.stringify(entry)}\\n`, \"utf8\");\n}\n\nexport type { LogLevel, LogStatus, StructuredLogEntry };\n","export const LOG_LEVELS = [\n \"trace\",\n \"debug\",\n \"info\",\n \"warning\",\n \"error\",\n \"critical\",\n \"fatal\",\n] as const;\n\nexport type LogLevel = (typeof LOG_LEVELS)[number];\n\nexport const LOG_STATUSES = [\"success\", \"failure\"] as const;\n\nexport type LogStatus = (typeof LOG_STATUSES)[number];\n\nexport type LogRecord = Record<string, unknown>;\n\nexport type StructuredLogEntry = LogRecord & {\n timestamp: string;\n level: LogLevel;\n severity: LogLevel;\n event: string;\n kind: string;\n command?: string;\n status?: LogStatus;\n message?: string;\n};\n","import {\n LOG_LEVELS,\n LOG_STATUSES,\n type LogLevel,\n type LogRecord,\n type LogStatus,\n type StructuredLogEntry,\n} from \"./types.js\";\n\ntype BuildStructuredLogEntryInput = {\n payload: unknown;\n defaultEvent: string;\n defaultLevel: LogLevel;\n command?: string;\n status?: LogStatus;\n message?: string;\n};\n\nconst EVENT_LEVEL_MAP: Record<string, LogLevel> = {\n archive_complete: \"info\",\n archive_failed: \"error\",\n archive_start: \"info\",\n batch_committed: \"debug\",\n batch_retry_fallback: \"warning\",\n command_completed: \"info\",\n command_failed: \"error\",\n dataset_completed: \"info\",\n dataset_started: \"info\",\n file_failed: \"error\",\n file_metrics: \"info\",\n import_failed: \"error\",\n import_finished: \"info\",\n import_plan_ready: \"info\",\n import_plan_reused: \"info\",\n import_started: \"info\",\n log_entry: \"info\",\n materialization_completed: \"info\",\n materialization_dataset_completed: \"info\",\n materialization_dataset_failed: \"error\",\n materialization_dataset_heartbeat: \"debug\",\n materialization_dataset_started: \"info\",\n materialization_finished: \"info\",\n materialization_started: \"info\",\n preparing_progress: \"debug\",\n preparing_start: \"info\",\n row_quarantined: \"warning\",\n};\n\nfunction isRecord(value: unknown): value is LogRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isLogLevel(value: unknown): value is LogLevel {\n return typeof value === \"string\" && LOG_LEVELS.includes(value as LogLevel);\n}\n\nfunction isLogStatus(value: unknown): value is LogStatus {\n return typeof value === \"string\" && LOG_STATUSES.includes(value as LogStatus);\n}\n\nfunction readOptionalString(\n record: LogRecord,\n key: string,\n): string | undefined {\n const value = record[key];\n return typeof value === \"string\" && value.trim() !== \"\" ? value : undefined;\n}\n\nfunction normalizeEventName(value: string): string {\n return value.trim().replace(/-/g, \"_\");\n}\n\nfunction resolveLogLevel(\n explicitLevel: LogLevel | undefined,\n event: string,\n fallbackLevel: LogLevel,\n): LogLevel {\n if (explicitLevel) {\n return explicitLevel;\n }\n\n return EVENT_LEVEL_MAP[event] ?? fallbackLevel;\n}\n\nfunction buildPrimitivePayloadEntry(\n input: BuildStructuredLogEntryInput,\n): StructuredLogEntry {\n const event = normalizeEventName(input.defaultEvent);\n const level = resolveLogLevel(undefined, event, input.defaultLevel);\n\n return {\n timestamp: new Date().toISOString(),\n level,\n severity: level,\n event,\n kind: event,\n ...(input.command ? { command: input.command } : {}),\n ...(input.status ? { status: input.status } : {}),\n ...(input.message ? { message: input.message } : {}),\n payload: input.payload,\n };\n}\n\nexport function buildStructuredLogEntry(\n input: BuildStructuredLogEntryInput,\n): StructuredLogEntry {\n if (!isRecord(input.payload)) {\n return buildPrimitivePayloadEntry(input);\n }\n\n const payload = { ...input.payload };\n const rawEvent =\n readOptionalString(payload, \"event\") ??\n readOptionalString(payload, \"kind\") ??\n input.defaultEvent;\n const event = normalizeEventName(rawEvent);\n const explicitLevel =\n (isLogLevel(payload.level) ? payload.level : undefined) ??\n (isLogLevel(payload.severity) ? payload.severity : undefined);\n const level = resolveLogLevel(explicitLevel, event, input.defaultLevel);\n const timestamp =\n readOptionalString(payload, \"timestamp\") ?? new Date().toISOString();\n const command = readOptionalString(payload, \"command\") ?? input.command;\n const status =\n (isLogStatus(payload.status) ? payload.status : undefined) ?? input.status;\n const message = readOptionalString(payload, \"message\") ?? input.message;\n const kind = normalizeEventName(readOptionalString(payload, \"kind\") ?? event);\n\n return {\n ...payload,\n timestamp,\n level,\n severity: level,\n event,\n kind,\n ...(command ? { command } : {}),\n ...(status ? { status } : {}),\n ...(message ? { message } : {}),\n };\n}\n\nexport function serializeErrorDetails(error: unknown): LogRecord {\n if (error instanceof Error) {\n const details: LogRecord = {\n name: error.name,\n message: error.message,\n };\n\n if (typeof error.stack === \"string\" && error.stack.trim() !== \"\") {\n details.stack = error.stack;\n }\n\n const errorWithCode = error as Error & { code?: unknown; cause?: unknown };\n\n if (typeof errorWithCode.code === \"string\") {\n details.code = errorWithCode.code;\n }\n\n if (errorWithCode.cause !== undefined) {\n details.cause =\n errorWithCode.cause instanceof Error\n ? serializeErrorDetails(errorWithCode.cause)\n : errorWithCode.cause;\n }\n\n return details;\n }\n\n return {\n message: String(error),\n };\n}\n","import path from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\n\nimport { Client } from \"pg\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport { appendJsonLinesLog, createJsonLinesLog } from \"../logging.service.js\";\nimport {\n buildImportPerformanceSummary,\n buildImportWarnings,\n createDatasetPerformanceTracker,\n finalizeDatasetPerformance,\n summarizeImportedDatasets,\n type MutableDatasetPerformance,\n} from \"./finalizer.js\";\nimport { importDatasetFile } from \"./file-import.js\";\nimport {\n ensureImportCheckpointSupport,\n hydrateImportPlanWithCheckpoints,\n} from \"./checkpoint-manager.js\";\nimport {\n ensureMaterializationCheckpointTable,\n resetMaterializationCheckpoints,\n} from \"./materialization-checkpoints.js\";\nimport { materializeStagedDatasets } from \"./materializer.js\";\nimport { isMaterializationDataset } from \"./materialization-sql.js\";\nimport {\n collectDatasetEntriesForImport,\n prepareImportPlan,\n resolveRequestedDatasets,\n type PreparedImportPlan,\n} from \"./planner.js\";\nimport {\n updateImportPlanPhaseState,\n updateImportPlanStatus,\n readLatestImportPlanForValidatedPath,\n} from \"./plan-store.js\";\nimport { ensureImportQuarantineSupport } from \"./quarantine-writer.js\";\nimport { detectImportSchemaCapabilities } from \"./schema-capabilities.js\";\nimport {\n ensureStagingSchemaSupport,\n resetStagingTablesForFreshPlan,\n} from \"./staging-schema.js\";\nimport type { InspectSummary } from \"../inspect.service.js\";\nimport type {\n ImportDatasetPlan,\n ImportDatasetType,\n ImportOptions,\n ImportPerformanceSummary,\n ImportSummary,\n} from \"./types.js\";\n\ntype DatasetTrackerMap = Map<ImportDatasetType, MutableDatasetPerformance>;\n\ntype SharedPipelineInput = {\n inputPath: string;\n validatedPath: string;\n inspection: InspectSummary;\n dbUrl: string;\n options?: ImportOptions;\n targetDatabase: string;\n};\n\ntype PipelineCounters = {\n committedRows: number;\n committedBatches: number;\n completedFiles: number;\n secondaryCnaesRows: number;\n quarantinedRows: number;\n resumedFiles: number;\n skippedCompletedFiles: number;\n};\n\ntype PreparedExecution = {\n client: Client;\n progressLogPath: string;\n planId: number | null;\n planReused: boolean;\n plan: PreparedImportPlan[\"plan\"];\n datasetPerformanceTrackers: DatasetTrackerMap;\n scanDurationMs: number;\n sourceFingerprint: string;\n loadBatchSize: number;\n materializeBatchSize: number;\n counters: PipelineCounters;\n checkpointBaselineRows: number;\n checkpointBaselineBatches: number;\n schemaCapabilities: Awaited<\n ReturnType<typeof detectImportSchemaCapabilities>\n >;\n};\n\nfunction createCounters(): PipelineCounters {\n return {\n committedRows: 0,\n committedBatches: 0,\n completedFiles: 0,\n secondaryCnaesRows: 0,\n quarantinedRows: 0,\n resumedFiles: 0,\n skippedCompletedFiles: 0,\n };\n}\n\nfunction createDatasetTrackers(\n datasets: readonly ImportDatasetPlan[],\n scanDurations: Partial<Record<ImportDatasetType, number>>,\n): DatasetTrackerMap {\n const trackers = new Map<ImportDatasetType, MutableDatasetPerformance>();\n\n for (const datasetPlan of datasets) {\n trackers.set(\n datasetPlan.dataset,\n createDatasetPerformanceTracker(\n datasetPlan,\n scanDurations[datasetPlan.dataset] ?? 0,\n ),\n );\n }\n\n return trackers;\n}\n\nfunction applyCheckpointMetricsToTrackers(\n datasets: readonly ImportDatasetPlan[],\n trackers: DatasetTrackerMap,\n): void {\n for (const datasetPlan of datasets) {\n const tracker = trackers.get(datasetPlan.dataset);\n if (!tracker) {\n continue;\n }\n\n for (const filePlan of datasetPlan.files) {\n if (\n filePlan.checkpoint?.status === \"completed\" &&\n filePlan.checkpoint.byteOffset >= filePlan.fileSize\n ) {\n tracker.skippedCompletedFiles += 1;\n continue;\n }\n\n if (\n filePlan.checkpoint &&\n (filePlan.checkpoint.byteOffset > 0 ||\n filePlan.checkpoint.rowsCommitted > 0)\n ) {\n tracker.resumedFiles += 1;\n }\n }\n }\n}\n\nfunction resolveLoadBatchSize(options: ImportOptions | undefined): number {\n return Math.max(1, options?.loadBatchSize ?? options?.batchSize ?? 500);\n}\n\nfunction resolveMaterializeBatchSize(\n options: ImportOptions | undefined,\n): number {\n return Math.max(1, options?.materializeBatchSize ?? 50_000);\n}\n\nfunction buildExpectedStagedRowsByDataset(\n datasets: readonly ImportDatasetPlan[],\n): ReadonlyMap<ImportDatasetType, number> {\n return new Map(\n datasets\n .filter((datasetPlan) => isMaterializationDataset(datasetPlan.dataset))\n .map((datasetPlan) => [\n datasetPlan.dataset,\n datasetPlan.files.reduce(\n (sum, filePlan) => sum + (filePlan.checkpoint?.rowsCommitted ?? 0),\n 0,\n ),\n ]),\n );\n}\n\nasync function prepareExecutionForLoad(\n input: SharedPipelineInput,\n): Promise<PreparedExecution> {\n const selectedDatasets = resolveRequestedDatasets(input.options?.dataset);\n const datasetEntries = collectDatasetEntriesForImport(\n input.inspection,\n selectedDatasets,\n );\n const loadBatchSize = resolveLoadBatchSize(input.options);\n const materializeBatchSize = resolveMaterializeBatchSize(input.options);\n const progressLogPath = await createJsonLinesLog(\"import-progress\");\n const client = new Client({ connectionString: input.dbUrl });\n\n await client.connect();\n await ensureImportCheckpointSupport(client);\n await ensureMaterializationCheckpointTable(client);\n await ensureImportQuarantineSupport(client);\n\n const preparedPlan = await prepareImportPlan({\n client,\n inputPath: input.inputPath,\n validatedPath: input.validatedPath,\n batchSize: loadBatchSize,\n datasetEntries,\n targetDatabase: input.targetDatabase,\n progressLogPath,\n ...(input.options?.onProgress\n ? { onProgress: input.options.onProgress }\n : {}),\n });\n\n const datasetPerformanceTrackers = createDatasetTrackers(\n preparedPlan.plan.datasets,\n preparedPlan.datasetScanDurationsMs,\n );\n\n const schemaCapabilities = await detectImportSchemaCapabilities(client);\n await ensureStagingSchemaSupport(\n client,\n preparedPlan.plan.datasets.map((datasetPlan) => datasetPlan.dataset),\n );\n\n const checkpointTotals = await hydrateImportPlanWithCheckpoints(\n client,\n preparedPlan.plan.datasets,\n loadBatchSize,\n );\n\n const counters = createCounters();\n counters.committedRows = checkpointTotals.committedRows;\n counters.committedBatches = checkpointTotals.committedBatches;\n counters.completedFiles = checkpointTotals.completedFiles;\n counters.resumedFiles = checkpointTotals.resumedFiles;\n counters.skippedCompletedFiles = checkpointTotals.skippedCompletedFiles;\n\n applyCheckpointMetricsToTrackers(\n preparedPlan.plan.datasets,\n datasetPerformanceTrackers,\n );\n\n if (preparedPlan.planId !== null && !preparedPlan.planReused) {\n await resetMaterializationCheckpoints(client, preparedPlan.planId);\n await updateImportPlanPhaseState(client, {\n planId: preparedPlan.planId,\n loadStatus: \"pending\",\n materializationStatus: \"pending\",\n lastPhase: \"planning\",\n lastError: null,\n });\n }\n\n return {\n client,\n progressLogPath,\n planId: preparedPlan.planId,\n planReused: preparedPlan.planReused,\n plan: preparedPlan.plan,\n datasetPerformanceTrackers,\n scanDurationMs: preparedPlan.scanDurationMs,\n sourceFingerprint: preparedPlan.sourceFingerprint,\n loadBatchSize,\n materializeBatchSize,\n counters,\n checkpointBaselineRows: checkpointTotals.committedRows,\n checkpointBaselineBatches: checkpointTotals.committedBatches,\n schemaCapabilities,\n };\n}\n\nasync function prepareExecutionForMaterialization(\n input: SharedPipelineInput,\n): Promise<PreparedExecution> {\n const progressLogPath = await createJsonLinesLog(\"import-progress\");\n const client = new Client({ connectionString: input.dbUrl });\n await client.connect();\n await ensureImportCheckpointSupport(client);\n await ensureMaterializationCheckpointTable(client);\n await ensureImportQuarantineSupport(client);\n\n const savedPlan = await readLatestImportPlanForValidatedPath(\n client,\n input.validatedPath,\n input.targetDatabase,\n );\n\n if (!savedPlan) {\n throw new ValidationError(\n 'No saved import plan was found for this validated input path. Run \"cnpj-db-loader import load\" or \"cnpj-db-loader import\" first.',\n );\n }\n\n const requestedDatasets = resolveRequestedDatasets(input.options?.dataset);\n const requestedSet = new Set(requestedDatasets);\n const filteredDatasets = savedPlan.datasets.filter((datasetPlan) =>\n requestedSet.has(datasetPlan.dataset),\n );\n\n if (filteredDatasets.length === 0) {\n throw new ValidationError(\n \"No datasets from the requested selection are available in the saved import plan.\",\n );\n }\n\n const plan = {\n datasets: filteredDatasets,\n totalFiles: filteredDatasets.reduce(\n (sum, datasetPlan) => sum + datasetPlan.files.length,\n 0,\n ),\n totalRows: filteredDatasets.reduce(\n (sum, datasetPlan) => sum + datasetPlan.totalRows,\n 0,\n ),\n totalBatches: filteredDatasets.reduce(\n (sum, datasetPlan) => sum + datasetPlan.totalBatches,\n 0,\n ),\n };\n\n const datasetPerformanceTrackers = createDatasetTrackers(plan.datasets, {});\n const schemaCapabilities = await detectImportSchemaCapabilities(client);\n await ensureStagingSchemaSupport(\n client,\n plan.datasets.map((datasetPlan) => datasetPlan.dataset),\n );\n\n const checkpointTotals = await hydrateImportPlanWithCheckpoints(\n client,\n plan.datasets,\n savedPlan.plan.batchSize,\n );\n\n const counters = createCounters();\n counters.committedRows = checkpointTotals.committedRows;\n counters.committedBatches = checkpointTotals.committedBatches;\n counters.completedFiles = checkpointTotals.completedFiles;\n counters.resumedFiles = checkpointTotals.resumedFiles;\n counters.skippedCompletedFiles = checkpointTotals.skippedCompletedFiles;\n applyCheckpointMetricsToTrackers(plan.datasets, datasetPerformanceTrackers);\n\n input.options?.onProgress?.({\n kind: \"plan_ready\",\n totalDatasets: plan.datasets.length,\n totalFiles: plan.totalFiles,\n batchSize: savedPlan.plan.batchSize,\n loadBatchSize: savedPlan.plan.batchSize,\n materializeBatchSize: resolveMaterializeBatchSize(input.options),\n totalRows: plan.totalRows,\n totalBatches: plan.totalBatches,\n targetDatabase: input.targetDatabase,\n executionOrder: plan.datasets.map((item) => item.dataset),\n reused: true,\n planId: savedPlan.plan.id,\n });\n\n await appendJsonLinesLog(progressLogPath, {\n kind: \"materialization_plan_reused\",\n planId: savedPlan.plan.id,\n sourceFingerprint: savedPlan.plan.sourceFingerprint,\n inputPath: path.resolve(input.inputPath),\n validatedPath: input.validatedPath,\n targetDatabase: input.targetDatabase,\n totalDatasets: plan.datasets.length,\n totalFiles: plan.totalFiles,\n totalRows: plan.totalRows,\n totalBatches: plan.totalBatches,\n materializeBatchSize: resolveMaterializeBatchSize(input.options),\n executionOrder: plan.datasets.map((item) => item.dataset),\n timestamp: new Date().toISOString(),\n });\n\n return {\n client,\n progressLogPath,\n planId: savedPlan.plan.id,\n planReused: true,\n plan,\n datasetPerformanceTrackers,\n scanDurationMs: 0,\n sourceFingerprint: savedPlan.plan.sourceFingerprint,\n loadBatchSize: savedPlan.plan.batchSize,\n materializeBatchSize: resolveMaterializeBatchSize(input.options),\n counters,\n checkpointBaselineRows: checkpointTotals.committedRows,\n checkpointBaselineBatches: checkpointTotals.committedBatches,\n schemaCapabilities,\n };\n}\n\nasync function runLoadStage(\n input: SharedPipelineInput,\n execution: PreparedExecution,\n stageLabel: \"import\" | \"load\",\n): Promise<void> {\n if (!execution.planReused) {\n const resetTables = await resetStagingTablesForFreshPlan(\n execution.client,\n execution.plan.datasets.map((datasetPlan) => datasetPlan.dataset),\n );\n\n if (resetTables.length > 0) {\n await appendJsonLinesLog(execution.progressLogPath, {\n kind: \"staging_reset\",\n tables: resetTables,\n timestamp: new Date().toISOString(),\n });\n }\n }\n\n if (execution.planId !== null) {\n await updateImportPlanStatus(\n execution.client,\n execution.planId,\n \"in_progress\",\n );\n await updateImportPlanPhaseState(execution.client, {\n planId: execution.planId,\n loadStatus: \"in_progress\",\n lastPhase: \"load\",\n lastError: null,\n });\n }\n\n input.options?.onProgress?.({\n kind: \"start\",\n inputPath: path.resolve(input.inputPath),\n validatedPath: input.validatedPath,\n totalDatasets: execution.plan.datasets.length,\n totalFiles: execution.plan.totalFiles,\n targetDatabase: input.targetDatabase,\n totalRows: execution.plan.totalRows,\n totalBatches: execution.plan.totalBatches,\n committedRows: execution.counters.committedRows,\n committedBatches: execution.counters.committedBatches,\n });\n\n await appendJsonLinesLog(execution.progressLogPath, {\n kind: `${stageLabel}_started`,\n planId: execution.planId,\n sourceFingerprint: execution.sourceFingerprint,\n inputPath: path.resolve(input.inputPath),\n validatedPath: input.validatedPath,\n targetDatabase: input.targetDatabase,\n totalDatasets: execution.plan.datasets.length,\n totalFiles: execution.plan.totalFiles,\n totalRows: execution.plan.totalRows,\n totalBatches: execution.plan.totalBatches,\n loadBatchSize: execution.loadBatchSize,\n materializeBatchSize: execution.materializeBatchSize,\n resumedFiles: execution.counters.resumedFiles,\n skippedCompletedFiles: execution.counters.skippedCompletedFiles,\n committedRows: execution.counters.committedRows,\n committedBatches: execution.counters.committedBatches,\n timestamp: new Date().toISOString(),\n });\n\n let globalFileIndex = 0;\n for (const [datasetIndex, datasetPlan] of execution.plan.datasets.entries()) {\n const datasetTracker = execution.datasetPerformanceTrackers.get(\n datasetPlan.dataset,\n );\n if (!datasetTracker) {\n continue;\n }\n\n await appendJsonLinesLog(execution.progressLogPath, {\n kind: \"dataset_started\",\n dataset: datasetPlan.dataset,\n datasetIndex: datasetIndex + 1,\n totalDatasets: execution.plan.datasets.length,\n plannedRows: datasetPlan.totalRows,\n plannedBatches: datasetPlan.totalBatches,\n resumedFiles: datasetTracker.resumedFiles,\n skippedCompletedFiles: datasetTracker.skippedCompletedFiles,\n timestamp: new Date().toISOString(),\n });\n\n for (const filePlan of datasetPlan.files) {\n globalFileIndex += 1;\n\n const rowsBefore = execution.counters.committedRows;\n const batchesBefore = execution.counters.committedBatches;\n const fileStartedAt = performance.now();\n const filePerformanceBefore = {\n insertDurationMs: datasetTracker.insertDurationMs,\n retryDurationMs: datasetTracker.retryDurationMs,\n quarantineDurationMs: datasetTracker.quarantineDurationMs,\n retriedRows: datasetTracker.retriedRows,\n retriedBatches: datasetTracker.retriedBatches,\n quarantinedRows: datasetTracker.quarantinedRows,\n };\n\n await importDatasetFile(\n execution.client,\n filePlan,\n execution.schemaCapabilities,\n execution.counters,\n {\n datasetIndex: datasetIndex + 1,\n totalDatasets: execution.plan.datasets.length,\n totalFiles: execution.plan.totalFiles,\n totalBatches: execution.plan.totalBatches,\n fileIndex: globalFileIndex,\n onProgress: input.options?.onProgress,\n progressLogPath: execution.progressLogPath,\n batchSize: execution.loadBatchSize,\n verboseProgress: input.options?.verboseProgress ?? false,\n performance: datasetTracker,\n },\n );\n\n datasetTracker.importDurationMs += performance.now() - fileStartedAt;\n datasetTracker.importedRows +=\n execution.counters.committedRows - rowsBefore;\n datasetTracker.committedBatches +=\n execution.counters.committedBatches - batchesBefore;\n\n await appendJsonLinesLog(execution.progressLogPath, {\n kind: \"file_metrics\",\n dataset: datasetPlan.dataset,\n datasetIndex: datasetIndex + 1,\n filePath: filePlan.absolutePath,\n fileDisplayPath: filePlan.displayPath,\n fileIndex: globalFileIndex,\n importedRows: execution.counters.committedRows - rowsBefore,\n committedBatches: execution.counters.committedBatches - batchesBefore,\n insertDurationMs:\n datasetTracker.insertDurationMs -\n filePerformanceBefore.insertDurationMs,\n retryDurationMs:\n datasetTracker.retryDurationMs -\n filePerformanceBefore.retryDurationMs,\n quarantineDurationMs:\n datasetTracker.quarantineDurationMs -\n filePerformanceBefore.quarantineDurationMs,\n retriedRows:\n datasetTracker.retriedRows - filePerformanceBefore.retriedRows,\n retriedBatches:\n datasetTracker.retriedBatches - filePerformanceBefore.retriedBatches,\n quarantinedRows:\n datasetTracker.quarantinedRows -\n filePerformanceBefore.quarantinedRows,\n durationMs: performance.now() - fileStartedAt,\n timestamp: new Date().toISOString(),\n });\n }\n\n await appendJsonLinesLog(execution.progressLogPath, {\n kind: \"dataset_completed\",\n dataset: datasetPlan.dataset,\n datasetIndex: datasetIndex + 1,\n totalDatasets: execution.plan.datasets.length,\n metrics: finalizeDatasetPerformance(datasetTracker),\n timestamp: new Date().toISOString(),\n });\n }\n\n if (execution.planId !== null) {\n await updateImportPlanPhaseState(execution.client, {\n planId: execution.planId,\n loadStatus: \"completed\",\n lastPhase: \"load_completed\",\n lastError: null,\n });\n }\n}\n\nasync function runMaterializationStage(\n execution: PreparedExecution,\n onProgress: ImportOptions[\"onProgress\"],\n): Promise<void> {\n if (execution.planId === null) {\n throw new ValidationError(\n \"The materialization stage requires a persisted import plan.\",\n );\n }\n\n await updateImportPlanStatus(\n execution.client,\n execution.planId,\n \"in_progress\",\n );\n await updateImportPlanPhaseState(execution.client, {\n planId: execution.planId,\n materializationStatus: \"in_progress\",\n lastPhase: \"materialization\",\n lastError: null,\n });\n\n await hydrateImportPlanWithCheckpoints(\n execution.client,\n execution.plan.datasets,\n execution.loadBatchSize,\n );\n\n const materializationSummary = await materializeStagedDatasets({\n client: execution.client,\n planId: execution.planId,\n datasets: execution.plan.datasets.map((datasetPlan) => datasetPlan.dataset),\n schemaCapabilities: execution.schemaCapabilities,\n progressLogPath: execution.progressLogPath,\n datasetPerformanceTrackers: execution.datasetPerformanceTrackers,\n expectedRowsByDataset: new Map(\n execution.plan.datasets.map((datasetPlan) => [\n datasetPlan.dataset,\n datasetPlan.totalRows,\n ]),\n ),\n expectedStagedRowsByDataset: buildExpectedStagedRowsByDataset(\n execution.plan.datasets,\n ),\n onProgress,\n completedFiles: execution.counters.completedFiles,\n totalFiles: execution.plan.totalFiles,\n processedRows: execution.counters.committedRows,\n totalRows: execution.plan.totalRows,\n committedBatches: execution.counters.committedBatches,\n totalBatches: execution.plan.totalBatches,\n chunkSize: execution.materializeBatchSize,\n });\n\n void materializationSummary;\n\n await updateImportPlanPhaseState(execution.client, {\n planId: execution.planId,\n materializationStatus: \"completed\",\n lastPhase: \"materialization_completed\",\n lastError: null,\n });\n}\n\nasync function buildSummary(\n input: SharedPipelineInput,\n execution: PreparedExecution,\n overallStartedAt: number,\n executionMode: \"full\" | \"load\" | \"materialize\",\n): Promise<ImportSummary> {\n const executionDurationMs =\n performance.now() - overallStartedAt - execution.scanDurationMs;\n const datasetPerformance = execution.plan.datasets\n .map((datasetPlan) =>\n execution.datasetPerformanceTrackers.get(datasetPlan.dataset),\n )\n .filter((item): item is MutableDatasetPerformance => item !== undefined);\n const executionRowsCommitted = Math.max(\n 0,\n execution.counters.committedRows - execution.checkpointBaselineRows,\n );\n const executionBatchesCommitted = Math.max(\n 0,\n execution.counters.committedBatches - execution.checkpointBaselineBatches,\n );\n\n const performanceSummary: ImportPerformanceSummary =\n buildImportPerformanceSummary({\n planReused: execution.planReused,\n totalDurationMs: performance.now() - overallStartedAt,\n scanDurationMs: execution.scanDurationMs,\n executionDurationMs,\n lookupLoadDurationMs: 0,\n executionRowsCommitted,\n executionBatchesCommitted,\n datasets: datasetPerformance,\n });\n\n input.options?.onProgress?.({\n kind: \"finish\",\n totalDatasets: execution.plan.datasets.length,\n totalFiles: execution.plan.totalFiles,\n completedFiles: execution.counters.completedFiles,\n processedRows: execution.counters.committedRows,\n totalRows: execution.plan.totalRows,\n committedBatches: execution.counters.committedBatches,\n totalBatches: execution.plan.totalBatches,\n quarantinedRows: execution.counters.quarantinedRows,\n });\n\n await appendJsonLinesLog(execution.progressLogPath, {\n kind: \"import_finished\",\n totalDatasets: execution.plan.datasets.length,\n totalFiles: execution.plan.totalFiles,\n completedFiles: execution.counters.completedFiles,\n processedRows: execution.counters.committedRows,\n totalRows: execution.plan.totalRows,\n committedBatches: execution.counters.committedBatches,\n totalBatches: execution.plan.totalBatches,\n quarantinedRows: execution.counters.quarantinedRows,\n resumedFiles: execution.counters.resumedFiles,\n skippedCompletedFiles: execution.counters.skippedCompletedFiles,\n performance: performanceSummary,\n timestamp: new Date().toISOString(),\n });\n\n const datasetSummaries = summarizeImportedDatasets(execution.plan.datasets);\n\n return {\n executionMode,\n inputPath: path.resolve(input.inputPath),\n validatedPath: input.validatedPath,\n targetDatabase: input.targetDatabase,\n importPlanId: execution.planId,\n reusedImportPlan: execution.planReused,\n importedDatasets: datasetSummaries.map((item) => item.dataset),\n importedFiles: execution.counters.completedFiles,\n processedRows: execution.counters.committedRows,\n plannedRows: execution.plan.totalRows,\n committedBatches: execution.counters.committedBatches,\n plannedBatches: execution.plan.totalBatches,\n quarantinedRows: execution.counters.quarantinedRows,\n resumedFiles: execution.counters.resumedFiles,\n skippedCompletedFiles: execution.counters.skippedCompletedFiles,\n datasetSummaries,\n performance: performanceSummary,\n warnings: buildImportWarnings(),\n progressLogPath: execution.progressLogPath,\n };\n}\n\nasync function finalizePlanCompletion(\n execution: PreparedExecution,\n): Promise<void> {\n if (execution.planId === null) {\n return;\n }\n\n await updateImportPlanStatus(execution.client, execution.planId, \"completed\");\n await updateImportPlanPhaseState(execution.client, {\n planId: execution.planId,\n loadStatus: \"completed\",\n materializationStatus: \"completed\",\n lastPhase: \"completed\",\n lastError: null,\n });\n}\n\nasync function closeClient(client: Client): Promise<void> {\n await client.end().catch(() => undefined);\n}\n\nexport async function runImportPipeline(\n input: SharedPipelineInput,\n): Promise<ImportSummary> {\n const overallStartedAt = performance.now();\n let execution: PreparedExecution | null = null;\n\n try {\n execution = await prepareExecutionForLoad(input);\n await runLoadStage(input, execution, \"import\");\n await runMaterializationStage(execution, input.options?.onProgress);\n await finalizePlanCompletion(execution);\n return await buildSummary(input, execution, overallStartedAt, \"full\");\n } catch (error) {\n if (execution && execution.planId !== null) {\n await updateImportPlanStatus(\n execution.client,\n execution.planId,\n \"failed\",\n ).catch(() => undefined);\n await updateImportPlanPhaseState(execution.client, {\n planId: execution.planId,\n lastError: error instanceof Error ? error.message : String(error),\n }).catch(() => undefined);\n }\n\n if (execution) {\n await appendJsonLinesLog(execution.progressLogPath, {\n kind: \"import_failed\",\n planId: execution.planId,\n sourceFingerprint: execution.sourceFingerprint,\n inputPath: path.resolve(input.inputPath),\n validatedPath: input.validatedPath,\n targetDatabase: input.targetDatabase,\n error: error instanceof Error ? error.message : String(error),\n timestamp: new Date().toISOString(),\n }).catch(() => undefined);\n }\n throw error;\n } finally {\n if (execution) {\n await closeClient(execution.client);\n }\n }\n}\n\nexport async function runImportLoadPipeline(\n input: SharedPipelineInput,\n): Promise<ImportSummary> {\n const overallStartedAt = performance.now();\n let execution: PreparedExecution | null = null;\n\n try {\n execution = await prepareExecutionForLoad(input);\n await runLoadStage(input, execution, \"load\");\n if (execution.planId !== null) {\n await updateImportPlanStatus(\n execution.client,\n execution.planId,\n \"in_progress\",\n );\n }\n return await buildSummary(input, execution, overallStartedAt, \"load\");\n } catch (error) {\n if (execution && execution.planId !== null) {\n await updateImportPlanStatus(\n execution.client,\n execution.planId,\n \"failed\",\n ).catch(() => undefined);\n await updateImportPlanPhaseState(execution.client, {\n planId: execution.planId,\n loadStatus: \"failed\",\n lastPhase: \"load_failed\",\n lastError: error instanceof Error ? error.message : String(error),\n }).catch(() => undefined);\n }\n throw error;\n } finally {\n if (execution) {\n await closeClient(execution.client);\n }\n }\n}\n\nexport async function runImportMaterializationPipeline(\n input: SharedPipelineInput,\n): Promise<ImportSummary> {\n const overallStartedAt = performance.now();\n let execution: PreparedExecution | null = null;\n\n try {\n execution = await prepareExecutionForMaterialization(input);\n await runMaterializationStage(execution, input.options?.onProgress);\n await finalizePlanCompletion(execution);\n return await buildSummary(\n input,\n execution,\n overallStartedAt,\n \"materialize\",\n );\n } catch (error) {\n if (execution && execution.planId !== null) {\n await updateImportPlanStatus(\n execution.client,\n execution.planId,\n \"failed\",\n ).catch(() => undefined);\n await updateImportPlanPhaseState(execution.client, {\n planId: execution.planId,\n materializationStatus: \"failed\",\n lastPhase: \"materialization_failed\",\n lastError: error instanceof Error ? error.message : String(error),\n }).catch(() => undefined);\n }\n throw error;\n } finally {\n if (execution) {\n await closeClient(execution.client);\n }\n }\n}\n","import type {\n ImportDatasetPerformanceSummary,\n ImportDatasetPlan,\n ImportDatasetType,\n ImportPerformanceSummary,\n} from \"./types.js\";\n\nexport type MutableDatasetPerformance = Omit<\n ImportDatasetPerformanceSummary,\n \"rowsPerSecond\" | \"batchesPerMinute\"\n>;\n\nexport function calculateRowsPerSecond(\n rows: number,\n durationMs: number,\n): number {\n if (rows <= 0 || durationMs <= 0) {\n return 0;\n }\n\n return rows / (durationMs / 1000);\n}\n\nexport function calculateBatchesPerMinute(\n batches: number,\n durationMs: number,\n): number {\n if (batches <= 0 || durationMs <= 0) {\n return 0;\n }\n\n return batches / (durationMs / 60000);\n}\n\nexport function createDatasetPerformanceTracker(\n datasetPlan: ImportDatasetPlan,\n scanDurationMs: number,\n): MutableDatasetPerformance {\n return {\n dataset: datasetPlan.dataset,\n files: datasetPlan.files.length,\n plannedRows: datasetPlan.totalRows,\n importedRows: 0,\n plannedBatches: datasetPlan.totalBatches,\n committedBatches: 0,\n resumedFiles: 0,\n skippedCompletedFiles: 0,\n retriedRows: 0,\n retriedBatches: 0,\n quarantinedRows: 0,\n scanDurationMs,\n importDurationMs: 0,\n insertDurationMs: 0,\n retryDurationMs: 0,\n quarantineDurationMs: 0,\n materializationDurationMs: 0,\n };\n}\n\nexport function finalizeDatasetPerformance(\n tracker: MutableDatasetPerformance,\n): ImportDatasetPerformanceSummary {\n return {\n ...tracker,\n rowsPerSecond: calculateRowsPerSecond(\n tracker.importedRows,\n tracker.importDurationMs,\n ),\n batchesPerMinute: calculateBatchesPerMinute(\n tracker.committedBatches,\n tracker.importDurationMs,\n ),\n };\n}\n\nexport function buildImportPerformanceSummary(input: {\n planReused: boolean;\n totalDurationMs: number;\n scanDurationMs: number;\n executionDurationMs: number;\n lookupLoadDurationMs: number;\n executionRowsCommitted: number;\n executionBatchesCommitted: number;\n datasets: MutableDatasetPerformance[];\n}): ImportPerformanceSummary {\n const finalizedDatasets = input.datasets.map(finalizeDatasetPerformance);\n\n return {\n planReused: input.planReused,\n totalDurationMs: input.totalDurationMs,\n scanDurationMs: input.scanDurationMs,\n executionDurationMs: input.executionDurationMs,\n lookupLoadDurationMs: input.lookupLoadDurationMs,\n insertDurationMs: finalizedDatasets.reduce(\n (sum, item) => sum + item.insertDurationMs,\n 0,\n ),\n retryDurationMs: finalizedDatasets.reduce(\n (sum, item) => sum + item.retryDurationMs,\n 0,\n ),\n quarantineDurationMs: finalizedDatasets.reduce(\n (sum, item) => sum + item.quarantineDurationMs,\n 0,\n ),\n materializationDurationMs: finalizedDatasets.reduce(\n (sum, item) => sum + item.materializationDurationMs,\n 0,\n ),\n rowsPerSecond: calculateRowsPerSecond(\n input.executionRowsCommitted,\n input.executionDurationMs,\n ),\n batchesPerMinute: calculateBatchesPerMinute(\n input.executionBatchesCommitted,\n input.executionDurationMs,\n ),\n datasets: finalizedDatasets,\n };\n}\n\nexport function buildImportWarnings(): string[] {\n return [\n \"The importer uses exact file planning, checkpointed batch commits, and byte-offset resume. If a load unit fails, rerunning the same command resumes from the last committed checkpoint instead of restarting the full load.\",\n \"Import plans are persisted in the database and reused for the same validated input, source files, and load batch size so resumed imports do not recount rows unnecessarily.\",\n \"Large datasets now land in lightweight staging tables through PostgreSQL COPY with only light normalization on the write hot path. Materialization into the simplified final schema keeps the first load focused on fast persistence instead of eager relational enrichment.\",\n \"When a new import plan starts, the selected staging tables are truncated before loading so staged bulk loads stay clean and predictable. Resumed plans keep the staged rows that already match the saved checkpoints.\",\n \"Rows that fail parsing, normalization, COPY fallback, or row-level inserts are moved to import_quarantine and the import continues from the next row.\",\n \"The import summary includes baseline timing and throughput metrics for scan, execution, staging writes, materialization, retry, and quarantine paths so future performance changes can be measured against a stable reference.\",\n \"The load batch size defines the staging load unit size, while the materialization batch size defines how many staged rows each consolidation chunk processes before saving a materialization checkpoint.\",\n ];\n}\n\nexport function summarizeImportedDatasets(\n datasets: ImportDatasetPlan[],\n): Array<{\n dataset: ImportDatasetType;\n files: number;\n rows: number;\n}> {\n return datasets.map((datasetPlan) => ({\n dataset: datasetPlan.dataset,\n files: datasetPlan.files.length,\n rows: datasetPlan.totalRows,\n }));\n}\n","import { performance } from \"node:perf_hooks\";\n\nimport { Client } from \"pg\";\n\nimport { appendJsonLinesLog } from \"../logging.service.js\";\nimport {\n DATASET_LAYOUTS,\n type ImportCheckpointStatus,\n type ImportFilePlan,\n type ImportProgressListener,\n type ImportSchemaCapabilities,\n} from \"./types.js\";\nimport {\n markImportCheckpointFailed,\n readImportCheckpoint,\n writeImportCheckpoint,\n} from \"./checkpoint-manager.js\";\nimport { parseImportSourceLine } from \"./parser.js\";\nimport { createImportRowNormalizer } from \"./normalizer.js\";\nimport { readImportSourceLines } from \"./source-reader.js\";\nimport {\n writeImportBatchToTarget,\n writeImportRowToTarget,\n} from \"./staging-writer.js\";\nimport { resolveImportWriteTarget } from \"./targets.js\";\nimport { writeImportQuarantineRow } from \"./quarantine-writer.js\";\nimport { buildParsedPayload } from \"./transform.js\";\n\nexport async function importDatasetFile(\n client: Client,\n filePlan: ImportFilePlan,\n schemaCapabilities: ImportSchemaCapabilities,\n counters: {\n committedRows: number;\n committedBatches: number;\n completedFiles: number;\n secondaryCnaesRows: number;\n quarantinedRows: number;\n },\n progress: {\n datasetIndex: number;\n totalDatasets: number;\n totalFiles: number;\n totalBatches: number;\n fileIndex: number;\n onProgress: ImportProgressListener | undefined;\n progressLogPath: string;\n batchSize: number;\n verboseProgress: boolean;\n performance: {\n insertDurationMs: number;\n retryDurationMs: number;\n quarantineDurationMs: number;\n retriedRows: number;\n retriedBatches: number;\n quarantinedRows: number;\n };\n },\n): Promise<number> {\n const dataset = filePlan.dataset;\n const filePath = filePlan.absolutePath;\n const layout = DATASET_LAYOUTS[dataset];\n const writeTarget = resolveImportWriteTarget(dataset);\n let checkpoint =\n filePlan.checkpoint ??\n (await readImportCheckpoint(\n client,\n dataset,\n filePath,\n filePlan.fileSize,\n filePlan.fileMtime,\n ));\n\n const emitProgress = (): void => {\n progress.onProgress?.({\n kind: \"progress\",\n dataset,\n datasetIndex: progress.datasetIndex,\n totalDatasets: progress.totalDatasets,\n currentFilePath: filePath,\n currentFileDisplayPath: filePlan.displayPath,\n fileIndex: progress.fileIndex,\n completedFiles: counters.completedFiles,\n totalFiles: progress.totalFiles,\n currentFileRowsCommitted: checkpoint.rowsCommitted,\n currentFileRowsTotal: filePlan.totalRows,\n committedRows: counters.committedRows,\n committedBatches: counters.committedBatches,\n totalBatches: progress.totalBatches,\n currentBatch:\n filePlan.totalBatches === 0\n ? 0\n : Math.min(\n filePlan.totalBatches,\n Math.max(\n 1,\n Math.ceil(\n Math.max(checkpoint.rowsCommitted, 1) / progress.batchSize,\n ),\n ),\n ),\n batchSize: progress.batchSize,\n checkpointOffset: checkpoint.byteOffset,\n currentFileSize: filePlan.fileSize,\n verboseProgress: progress.verboseProgress,\n });\n };\n\n if (\n checkpoint.status === \"completed\" &&\n checkpoint.byteOffset >= filePlan.fileSize\n ) {\n emitProgress();\n return checkpoint.rowsCommitted;\n }\n\n const rowNormalizer = createImportRowNormalizer({\n dataset,\n filePath,\n layout,\n schemaCapabilities,\n });\n const columns = rowNormalizer.columns;\n\n let fileRowsCommitted = checkpoint.rowsCommitted;\n let batchRows: ReturnType<typeof rowNormalizer.normalize>[] = [];\n let batchLastOffset = checkpoint.byteOffset;\n\n const persistCheckpoint = async (\n status: ImportCheckpointStatus,\n byteOffset: number,\n rowsCommitted: number,\n ): Promise<void> => {\n checkpoint = {\n ...checkpoint,\n byteOffset,\n rowsCommitted,\n status,\n lastError: null,\n };\n await writeImportCheckpoint(client, checkpoint);\n };\n\n const runInTransaction = async (\n callback: () => Promise<void>,\n ): Promise<void> => {\n await client.query(\"begin\");\n try {\n await callback();\n await client.query(\"commit\");\n } catch (error) {\n await client.query(\"rollback\");\n throw error;\n }\n };\n\n const quarantineRow = async (input: {\n rowNumber: number;\n checkpointOffset: number;\n rawLine: string;\n error: unknown;\n parsedPayload: Record<string, unknown> | null;\n }): Promise<void> => {\n const quarantineStartedAt = performance.now();\n\n await runInTransaction(async () => {\n await writeImportQuarantineRow(client, {\n dataset,\n filePath,\n rowNumber: input.rowNumber,\n checkpointOffset: input.checkpointOffset,\n rawLine: input.rawLine,\n error: input.error,\n parsedPayload: input.parsedPayload,\n });\n await persistCheckpoint(\n \"in_progress\",\n input.checkpointOffset,\n input.rowNumber,\n );\n });\n\n progress.performance.quarantineDurationMs +=\n performance.now() - quarantineStartedAt;\n progress.performance.quarantinedRows += 1;\n counters.quarantinedRows += 1;\n\n await appendJsonLinesLog(progress.progressLogPath, {\n kind: \"row_quarantined\",\n dataset,\n datasetIndex: progress.datasetIndex,\n filePath,\n fileDisplayPath: filePlan.displayPath,\n fileIndex: progress.fileIndex,\n rowNumber: input.rowNumber,\n checkpointOffset: input.checkpointOffset,\n error:\n input.error instanceof Error\n ? input.error.message\n : String(input.error),\n durationMs: performance.now() - quarantineStartedAt,\n timestamp: new Date().toISOString(),\n });\n };\n\n const commitBatch = async (markCompleted: boolean): Promise<void> => {\n if (batchRows.length === 0) {\n if (markCompleted) {\n await runInTransaction(async () => {\n await persistCheckpoint(\n \"completed\",\n filePlan.fileSize,\n fileRowsCommitted,\n );\n });\n emitProgress();\n }\n return;\n }\n\n const batchStartedAt = performance.now();\n\n try {\n const batchResult = await (async () => {\n let result:\n | Awaited<ReturnType<typeof writeImportBatchToTarget>>\n | undefined;\n\n await runInTransaction(async () => {\n result = await writeImportBatchToTarget({\n client,\n dataset,\n rows: batchRows,\n schemaCapabilities,\n });\n await persistCheckpoint(\n markCompleted ? \"completed\" : \"in_progress\",\n markCompleted ? filePlan.fileSize : batchLastOffset,\n fileRowsCommitted,\n );\n });\n\n return result;\n })();\n\n progress.performance.insertDurationMs +=\n performance.now() - batchStartedAt;\n counters.committedRows += batchRows.length;\n counters.committedBatches += 1;\n counters.secondaryCnaesRows += batchResult?.writtenSecondaryRows ?? 0;\n\n await appendJsonLinesLog(progress.progressLogPath, {\n kind: \"batch_committed\",\n dataset,\n datasetIndex: progress.datasetIndex,\n filePath,\n fileDisplayPath: filePlan.displayPath,\n fileIndex: progress.fileIndex,\n batchNumber: counters.committedBatches,\n batchSize: progress.batchSize,\n batchRows: batchRows.length,\n fileRowsCommitted,\n fileRowsTotal: filePlan.totalRows,\n totalRowsCommitted: counters.committedRows,\n totalBatchesCommitted: counters.committedBatches,\n totalBatchesPlanned: progress.totalBatches,\n checkpointOffset: checkpoint.byteOffset,\n fileSize: filePlan.fileSize,\n secondaryCnaesRows: batchResult?.writtenSecondaryRows ?? 0,\n writeTarget: batchResult?.writeTarget ?? writeTarget,\n writeMode: batchResult?.writeMode ?? \"insert\",\n targetTable: batchResult?.targetTable ?? null,\n durationMs: performance.now() - batchStartedAt,\n timestamp: new Date().toISOString(),\n });\n } catch (batchError) {\n progress.performance.insertDurationMs +=\n performance.now() - batchStartedAt;\n progress.performance.retriedBatches += 1;\n\n await appendJsonLinesLog(progress.progressLogPath, {\n kind: \"batch_retry_fallback\",\n dataset,\n datasetIndex: progress.datasetIndex,\n filePath,\n fileDisplayPath: filePlan.displayPath,\n fileIndex: progress.fileIndex,\n batchRows: batchRows.length,\n checkpointOffset: checkpoint.byteOffset,\n writeTarget,\n error:\n batchError instanceof Error ? batchError.message : String(batchError),\n timestamp: new Date().toISOString(),\n });\n\n for (const row of batchRows) {\n const retryStartedAt = performance.now();\n\n try {\n const rowResult = await (async () => {\n let result:\n | Awaited<ReturnType<typeof writeImportRowToTarget>>\n | undefined;\n\n await runInTransaction(async () => {\n result = await writeImportRowToTarget({\n client,\n dataset,\n row,\n schemaCapabilities,\n });\n await persistCheckpoint(\n \"in_progress\",\n row.nextOffset,\n row.sourceRowNumber,\n );\n });\n\n return result;\n })();\n\n progress.performance.retryDurationMs +=\n performance.now() - retryStartedAt;\n progress.performance.retriedRows += 1;\n counters.committedRows += 1;\n counters.secondaryCnaesRows += rowResult?.writtenSecondaryRows ?? 0;\n } catch (rowError) {\n progress.performance.retryDurationMs +=\n performance.now() - retryStartedAt;\n progress.performance.retriedRows += 1;\n await quarantineRow({\n rowNumber: row.sourceRowNumber,\n checkpointOffset: row.nextOffset,\n rawLine: row.rawLine,\n error: rowError,\n parsedPayload: buildParsedPayload(columns, row.values),\n });\n }\n }\n\n counters.committedBatches += 1;\n if (markCompleted) {\n await runInTransaction(async () => {\n await persistCheckpoint(\n \"completed\",\n filePlan.fileSize,\n fileRowsCommitted,\n );\n });\n }\n }\n\n batchRows = [];\n emitProgress();\n };\n\n emitProgress();\n\n try {\n for await (const sourceLine of readImportSourceLines(\n filePath,\n checkpoint.byteOffset,\n )) {\n if (sourceLine.rawLine.trim() === \"\") {\n checkpoint.byteOffset = sourceLine.nextOffset;\n continue;\n }\n\n try {\n const nextSourceRowNumber = fileRowsCommitted + 1;\n const parsedLine = parseImportSourceLine(sourceLine);\n const normalizedRow = rowNormalizer.normalize(\n parsedLine,\n nextSourceRowNumber,\n );\n\n batchRows.push(normalizedRow);\n fileRowsCommitted = nextSourceRowNumber;\n batchLastOffset = sourceLine.nextOffset;\n\n if (batchRows.length >= progress.batchSize) {\n await commitBatch(false);\n }\n } catch (rowError) {\n fileRowsCommitted += 1;\n batchLastOffset = sourceLine.nextOffset;\n await quarantineRow({\n rowNumber: fileRowsCommitted,\n checkpointOffset: sourceLine.nextOffset,\n rawLine: sourceLine.rawLine,\n error: rowError,\n parsedPayload: null,\n });\n emitProgress();\n }\n }\n\n if (batchRows.length > 0 || checkpoint.byteOffset < filePlan.fileSize) {\n await commitBatch(true);\n }\n\n counters.completedFiles += 1;\n emitProgress();\n\n return fileRowsCommitted;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n await markImportCheckpointFailed(client, checkpoint, message);\n await appendJsonLinesLog(progress.progressLogPath, {\n kind: \"file_failed\",\n dataset,\n datasetIndex: progress.datasetIndex,\n filePath,\n fileDisplayPath: filePlan.displayPath,\n fileIndex: progress.fileIndex,\n fileRowsCommitted: checkpoint.rowsCommitted,\n fileRowsTotal: filePlan.totalRows,\n checkpointOffset: checkpoint.byteOffset,\n fileSize: filePlan.fileSize,\n error: message,\n timestamp: new Date().toISOString(),\n });\n throw error;\n }\n}\n","import type { Client } from \"pg\";\n\nimport {\n ensureCheckpointTable,\n hydratePlanWithCheckpoints,\n markCheckpointFailed,\n readCheckpoint,\n writeCheckpoint,\n} from \"./checkpoints.js\";\n\nexport {\n ensureCheckpointTable as ensureImportCheckpointTable,\n hydratePlanWithCheckpoints as hydrateImportPlanWithCheckpoints,\n markCheckpointFailed as markImportCheckpointFailed,\n readCheckpoint as readImportCheckpoint,\n writeCheckpoint as writeImportCheckpoint,\n};\n\nexport async function ensureImportCheckpointSupport(\n client: Client,\n): Promise<void> {\n await ensureCheckpointTable(client);\n}\n","import { ValidationError } from \"../../core/errors/index.js\";\nimport type { TableLayout } from \"../../dictionary/layouts/index.js\";\nimport type {\n ImportDatasetType,\n ImportSchemaCapabilities,\n ImportWriteTarget,\n} from \"./types.js\";\n\nexport type FieldValueParser = (rawValue: string) => unknown;\n\nexport type PartnerDedupeKeyIndices = {\n cnpjRoot: number;\n partnerTypeCode: number;\n partnerName: number;\n partnerDocument: number;\n partnerQualificationCode: number;\n entryDate: number;\n countryCode: number;\n legalRepresentativeDocument: number;\n legalRepresentativeName: number;\n legalRepresentativeQualificationCode: number;\n ageGroupCode: number;\n};\n\nexport type EstablishmentCnpjFullIndices = {\n cnpjRoot: number;\n cnpjOrder: number;\n cnpjCheckDigits: number;\n};\n\nexport function parseDelimitedLine(line: string): string[] {\n const fields: string[] = [];\n let current = \"\";\n let inQuotes = false;\n\n for (let index = 0; index < line.length; index += 1) {\n const char = line[index];\n const next = line[index + 1];\n\n if (char === '\"') {\n if (inQuotes && next === '\"') {\n current += '\"';\n index += 1;\n continue;\n }\n\n inQuotes = !inQuotes;\n continue;\n }\n\n if (char === \";\" && !inQuotes) {\n fields.push(current);\n current = \"\";\n continue;\n }\n\n current += char;\n }\n\n fields.push(current);\n return fields;\n}\n\nexport function normalizeFieldCount(\n fields: string[],\n expectedLength: number,\n filePath: string,\n lineNumber: number,\n): string[] {\n const normalized = [...fields];\n\n while (\n normalized.length > expectedLength &&\n normalized[normalized.length - 1]?.trim() === \"\"\n ) {\n normalized.pop();\n }\n\n if (normalized.length < expectedLength) {\n while (normalized.length < expectedLength) {\n normalized.push(\"\");\n }\n }\n\n if (normalized.length !== expectedLength) {\n throw new ValidationError(\n `Unexpected field count in ${filePath} at line ${lineNumber}. Expected ${expectedLength}, received ${normalized.length}.`,\n );\n }\n\n return normalized;\n}\n\nexport function createFieldValueParser(\n dataType: TableLayout[\"fields\"][number][\"dataType\"],\n): FieldValueParser {\n switch (dataType) {\n case \"integer\":\n return (rawValue) => {\n const trimmed = rawValue.trim();\n if (trimmed === \"\") {\n return null;\n }\n\n return /^-?\\d+$/.test(trimmed) ? Number.parseInt(trimmed, 10) : null;\n };\n case \"numeric\":\n return (rawValue) => {\n const trimmed = rawValue.trim();\n if (trimmed === \"\") {\n return null;\n }\n\n if (trimmed.includes(\",\") && trimmed.includes(\".\")) {\n return trimmed.replace(/\\./g, \"\").replace(/,/g, \".\");\n }\n\n if (trimmed.includes(\",\")) {\n return trimmed.replace(/,/g, \".\");\n }\n\n return trimmed;\n };\n case \"date\":\n return (rawValue) => {\n const trimmed = rawValue.trim();\n if (trimmed === \"\" || trimmed === \"00000000\") {\n return null;\n }\n\n if (!/^\\d{8}$/.test(trimmed)) {\n return null;\n }\n\n return `${trimmed.slice(0, 4)}-${trimmed.slice(4, 6)}-${trimmed.slice(6, 8)}`;\n };\n case \"boolean\":\n return (rawValue) => {\n const trimmed = rawValue.trim();\n if (trimmed === \"\") {\n return null;\n }\n\n const normalized = trimmed.toLowerCase();\n if ([\"1\", \"true\", \"t\", \"y\", \"yes\", \"s\"].includes(normalized)) {\n return true;\n }\n if ([\"0\", \"false\", \"f\", \"n\", \"no\"].includes(normalized)) {\n return false;\n }\n return null;\n };\n default:\n return (rawValue) => {\n const trimmed = rawValue.trim();\n return trimmed === \"\" ? null : trimmed;\n };\n }\n}\n\nexport function toDatabaseValue(\n dataType: TableLayout[\"fields\"][number][\"dataType\"],\n rawValue: string,\n): unknown {\n return createFieldValueParser(dataType)(rawValue);\n}\n\nfunction normalizeCode(value: unknown, fallback: string): string {\n if (typeof value === \"string\" && value.trim() !== \"\") {\n return value.trim();\n }\n\n return fallback;\n}\n\nexport function createPartnerDedupeKeyBuilder(\n indices: PartnerDedupeKeyIndices,\n): (record: readonly unknown[]) => string {\n const orderedIndices = [\n indices.cnpjRoot,\n indices.partnerTypeCode,\n indices.partnerName,\n indices.partnerDocument,\n indices.partnerQualificationCode,\n indices.entryDate,\n indices.countryCode,\n indices.legalRepresentativeDocument,\n indices.legalRepresentativeName,\n indices.legalRepresentativeQualificationCode,\n indices.ageGroupCode,\n ];\n\n return (record) =>\n orderedIndices\n .map((index) => {\n const value = record[index];\n return value == null ? \"\" : String(value).trim();\n })\n .join(\"|\");\n}\n\nexport function createEstablishmentCnpjFullBuilder(\n indices: EstablishmentCnpjFullIndices,\n): (record: readonly unknown[]) => string {\n return (record) => {\n const root = String(record[indices.cnpjRoot] ?? \"\").trim();\n const order = String(record[indices.cnpjOrder] ?? \"\").trim();\n const digits = String(record[indices.cnpjCheckDigits] ?? \"\").trim();\n return `${root}${order}${digits}`;\n };\n}\n\nfunction buildPartnerDedupeKey(\n recordByColumn: Record<string, unknown>,\n): string {\n return [\n recordByColumn.cnpj_root,\n recordByColumn.partner_type_code,\n recordByColumn.partner_name,\n recordByColumn.partner_document,\n recordByColumn.partner_qualification_code,\n recordByColumn.entry_date,\n recordByColumn.country_code,\n recordByColumn.legal_representative_document,\n recordByColumn.legal_representative_name,\n recordByColumn.legal_representative_qualification_code,\n recordByColumn.age_group_code,\n ]\n .map((value) => (value == null ? \"\" : String(value).trim()))\n .join(\"|\");\n}\n\nexport function transformRecord(\n dataset: ImportDatasetType,\n layout: TableLayout,\n rawFields: string[],\n schemaCapabilities: ImportSchemaCapabilities,\n writeTarget: ImportWriteTarget,\n): unknown[] {\n const values = layout.fields.map((field, index) =>\n toDatabaseValue(field.dataType, rawFields[index] ?? \"\"),\n );\n\n const recordByColumn = Object.fromEntries(\n layout.fields.map((field, index) => [field.columnName, values[index]]),\n ) as Record<string, unknown>;\n\n if (dataset === \"companies\") {\n recordByColumn.company_size_code = normalizeCode(\n recordByColumn.company_size_code,\n \"00\",\n );\n }\n\n if (dataset === \"establishments\") {\n recordByColumn.branch_type_code = normalizeCode(\n recordByColumn.branch_type_code,\n \"1\",\n );\n recordByColumn.registration_status_code = normalizeCode(\n recordByColumn.registration_status_code,\n \"01\",\n );\n }\n\n const normalizedValues = layout.fields.map(\n (field) => recordByColumn[field.columnName],\n );\n\n if (writeTarget === \"final\") {\n if (\n dataset === \"establishments\" &&\n schemaCapabilities.includeEstablishmentCnpjFullInInsert\n ) {\n return [\n ...normalizedValues,\n `${recordByColumn.cnpj_root ?? \"\"}${recordByColumn.cnpj_order ?? \"\"}${recordByColumn.cnpj_check_digits ?? \"\"}`,\n ];\n }\n\n if (\n dataset === \"partners\" &&\n schemaCapabilities.includePartnerDedupeKeyInInsert\n ) {\n return [...normalizedValues, buildPartnerDedupeKey(recordByColumn)];\n }\n }\n\n return normalizedValues;\n}\n\nexport function buildParsedPayload(\n columns: string[],\n values: unknown[],\n): Record<string, unknown> {\n return Object.fromEntries(\n columns.map((column, index) => [column, values[index] ?? null]),\n );\n}\n\nexport function extractSecondaryCnaes(\n record: unknown[],\n columns: string[],\n): Array<[string, string, number]> {\n void record;\n void columns;\n return [];\n}\n","import { parseDelimitedLine } from \"./transform.js\";\nimport type { ImportSourceLine } from \"./source-reader.js\";\n\nexport type ParsedImportSourceLine = ImportSourceLine & {\n fields: string[];\n};\n\nexport function parseImportSourceLine(\n sourceLine: ImportSourceLine,\n): ParsedImportSourceLine {\n return {\n ...sourceLine,\n fields: parseDelimitedLine(sourceLine.rawLine),\n };\n}\n","import { Client } from \"pg\";\n\nimport { DATASET_LAYOUTS } from \"./types.js\";\nimport type {\n ImportDatasetType,\n ImportSchemaCapabilities,\n ImportWriteTarget,\n} from \"./types.js\";\n\nexport function getInsertColumns(\n dataset: ImportDatasetType,\n schemaCapabilities: ImportSchemaCapabilities,\n writeTarget: ImportWriteTarget = \"final\",\n): string[] {\n const columns = DATASET_LAYOUTS[dataset].fields.map(\n (field) => field.columnName,\n );\n\n if (writeTarget === \"final\") {\n if (\n dataset === \"establishments\" &&\n schemaCapabilities.includeEstablishmentCnpjFullInInsert\n ) {\n return [...columns, \"cnpj_full\"];\n }\n\n if (\n dataset === \"partners\" &&\n schemaCapabilities.includePartnerDedupeKeyInInsert\n ) {\n return [...columns, \"partner_dedupe_key\"];\n }\n }\n\n return columns;\n}\n\nexport function getConflictClause(\n dataset: ImportDatasetType,\n columns: string[],\n schemaCapabilities?: ImportSchemaCapabilities,\n): string {\n switch (dataset) {\n case \"countries\":\n case \"cities\":\n case \"partner_qualifications\":\n case \"legal_natures\":\n case \"cnaes\":\n case \"reasons\":\n return \"on conflict (code) do update set description = excluded.description\";\n case \"companies\": {\n const updateColumns = columns\n .filter((column) => column !== \"cnpj_root\")\n .map((column) => `${column} = excluded.${column}`)\n .concat([\"updated_at = now()\"])\n .join(\", \");\n return `on conflict (cnpj_root) do update set ${updateColumns}`;\n }\n case \"establishments\": {\n const updateColumns = columns\n .filter(\n (column) =>\n ![\n \"cnpj_root\",\n \"cnpj_order\",\n \"cnpj_check_digits\",\n \"cnpj_full\",\n ].includes(column),\n )\n .map((column) => `${column} = excluded.${column}`)\n .concat([\"updated_at = now()\"])\n .join(\", \");\n const conflictTarget =\n schemaCapabilities?.includeEstablishmentCnpjFullInInsert\n ? \"cnpj_full\"\n : \"cnpj_root, cnpj_order, cnpj_check_digits\";\n return `on conflict (${conflictTarget}) do update set ${updateColumns}`;\n }\n case \"simples_options\": {\n const updateColumns = columns\n .filter((column) => column !== \"cnpj_root\")\n .map((column) => `${column} = excluded.${column}`)\n .concat([\"updated_at = now()\"])\n .join(\", \");\n return `on conflict (cnpj_root) do update set ${updateColumns}`;\n }\n case \"partners\": {\n const updateColumns = columns\n .filter((column) => column !== \"partner_dedupe_key\")\n .map((column) => `${column} = excluded.${column}`)\n .concat([\"updated_at = now()\"])\n .join(\", \");\n return `on conflict (partner_dedupe_key) do update set ${updateColumns}`;\n }\n default:\n return \"\";\n }\n}\n\nexport function buildInsertQuery(\n tableName: string,\n columns: string[],\n rows: readonly unknown[][],\n conflictClause = \"\",\n): { text: string; values: unknown[] } {\n const values: unknown[] = [];\n\n const valueGroups = rows.map((row, rowIndex) => {\n const placeholders = row.map((_, columnIndex) => {\n const placeholderIndex = rowIndex * columns.length + columnIndex + 1;\n values.push(row[columnIndex]);\n return `$${placeholderIndex}`;\n });\n\n return `(${placeholders.join(\", \")})`;\n });\n\n const parts = [\n `insert into ${tableName} (${columns.join(\", \")})`,\n `values ${valueGroups.join(\", \")}`,\n ];\n\n if (conflictClause) {\n parts.push(conflictClause);\n }\n\n return {\n text: parts.join(\" \"),\n values,\n };\n}\n\nexport function buildSecondaryInsertQuery(\n tableName: string,\n rows: ReadonlyArray<[string, string, number]>,\n conflictClause = \"\",\n): {\n text: string;\n values: unknown[];\n} {\n return buildInsertQuery(\n tableName,\n [\"establishment_cnpj_full\", \"cnae_code\", \"source_order\"],\n rows,\n conflictClause,\n );\n}\n\nexport async function flushInsertQuery(\n client: Client,\n query: { text: string; values: unknown[] },\n): Promise<void> {\n await client.query(query);\n}\n","import { ValidationError } from \"../../core/errors/index.js\";\nimport type { TableLayout } from \"../../dictionary/layouts/index.js\";\nimport { getInsertColumns } from \"./sql.js\";\nimport { resolveImportWriteTarget } from \"./targets.js\";\nimport {\n createEstablishmentCnpjFullBuilder,\n createFieldValueParser,\n createPartnerDedupeKeyBuilder,\n normalizeFieldCount,\n} from \"./transform.js\";\nimport type { ParsedImportSourceLine } from \"./parser.js\";\nimport type {\n BatchRow,\n ImportDatasetType,\n ImportSchemaCapabilities,\n} from \"./types.js\";\n\nexport type NormalizeImportRowInput = {\n dataset: ImportDatasetType;\n filePath: string;\n layout: TableLayout;\n parsedLine: ParsedImportSourceLine;\n schemaCapabilities: ImportSchemaCapabilities;\n sourceRowNumber: number;\n};\n\nexport type ImportRowNormalizer = {\n columns: string[];\n normalize: (\n parsedLine: ParsedImportSourceLine,\n sourceRowNumber: number,\n ) => BatchRow;\n};\n\nfunction validateRequiredColumns(\n requiredIndexes: readonly number[],\n values: readonly unknown[],\n layout: TableLayout,\n): void {\n for (const index of requiredIndexes) {\n if (values[index] !== null) {\n continue;\n }\n\n throw new ValidationError(\n `Missing required value for ${layout.fields[index]?.columnName ?? \"unknown column\"}.`,\n );\n }\n}\n\nfunction resolveLayoutColumnIndex(\n layout: TableLayout,\n columnName: string,\n): number {\n return layout.fields.findIndex((field) => field.columnName === columnName);\n}\n\nexport function createImportRowNormalizer(input: {\n dataset: ImportDatasetType;\n filePath: string;\n layout: TableLayout;\n schemaCapabilities: ImportSchemaCapabilities;\n}): ImportRowNormalizer {\n const writeTarget = resolveImportWriteTarget(input.dataset);\n const columns = getInsertColumns(\n input.dataset,\n input.schemaCapabilities,\n writeTarget,\n );\n const expectedLength = input.layout.fields.length;\n const requiredIndexes = input.layout.fields\n .map((field, index) => (field.nullable ? -1 : index))\n .filter((index) => index >= 0);\n const fieldParsers = input.layout.fields.map((field) =>\n createFieldValueParser(field.dataType),\n );\n const companySizeIndex =\n input.dataset === \"companies\"\n ? resolveLayoutColumnIndex(input.layout, \"company_size_code\")\n : -1;\n const branchTypeIndex =\n input.dataset === \"establishments\"\n ? resolveLayoutColumnIndex(input.layout, \"branch_type_code\")\n : -1;\n const registrationStatusIndex =\n input.dataset === \"establishments\"\n ? resolveLayoutColumnIndex(input.layout, \"registration_status_code\")\n : -1;\n const appendEstablishmentCnpjFull =\n input.dataset === \"establishments\" &&\n writeTarget === \"final\" &&\n input.schemaCapabilities.includeEstablishmentCnpjFullInInsert;\n const appendPartnerDedupeKey =\n input.dataset === \"partners\" &&\n writeTarget === \"final\" &&\n input.schemaCapabilities.includePartnerDedupeKeyInInsert;\n const buildEstablishmentCnpjFull = appendEstablishmentCnpjFull\n ? createEstablishmentCnpjFullBuilder({\n cnpjRoot: resolveLayoutColumnIndex(input.layout, \"cnpj_root\"),\n cnpjOrder: resolveLayoutColumnIndex(input.layout, \"cnpj_order\"),\n cnpjCheckDigits: resolveLayoutColumnIndex(\n input.layout,\n \"cnpj_check_digits\",\n ),\n })\n : null;\n const buildPartnerDedupeKey = appendPartnerDedupeKey\n ? createPartnerDedupeKeyBuilder({\n cnpjRoot: resolveLayoutColumnIndex(input.layout, \"cnpj_root\"),\n partnerTypeCode: resolveLayoutColumnIndex(\n input.layout,\n \"partner_type_code\",\n ),\n partnerName: resolveLayoutColumnIndex(input.layout, \"partner_name\"),\n partnerDocument: resolveLayoutColumnIndex(\n input.layout,\n \"partner_document\",\n ),\n partnerQualificationCode: resolveLayoutColumnIndex(\n input.layout,\n \"partner_qualification_code\",\n ),\n entryDate: resolveLayoutColumnIndex(input.layout, \"entry_date\"),\n countryCode: resolveLayoutColumnIndex(input.layout, \"country_code\"),\n legalRepresentativeDocument: resolveLayoutColumnIndex(\n input.layout,\n \"legal_representative_document\",\n ),\n legalRepresentativeName: resolveLayoutColumnIndex(\n input.layout,\n \"legal_representative_name\",\n ),\n legalRepresentativeQualificationCode: resolveLayoutColumnIndex(\n input.layout,\n \"legal_representative_qualification_code\",\n ),\n ageGroupCode: resolveLayoutColumnIndex(input.layout, \"age_group_code\"),\n })\n : null;\n\n return {\n columns,\n normalize(parsedLine, sourceRowNumber) {\n const normalizedFields = normalizeFieldCount(\n parsedLine.fields,\n expectedLength,\n input.filePath,\n parsedLine.lineNumber,\n );\n const values = new Array<unknown>(expectedLength);\n\n for (let index = 0; index < expectedLength; index += 1) {\n values[index] =\n fieldParsers[index]?.(normalizedFields[index] ?? \"\") ?? null;\n }\n\n if (companySizeIndex >= 0) {\n const currentValue = values[companySizeIndex];\n values[companySizeIndex] =\n typeof currentValue === \"string\" && currentValue.trim() !== \"\"\n ? currentValue.trim()\n : \"00\";\n }\n\n if (branchTypeIndex >= 0) {\n const currentValue = values[branchTypeIndex];\n values[branchTypeIndex] =\n typeof currentValue === \"string\" && currentValue.trim() !== \"\"\n ? currentValue.trim()\n : \"1\";\n }\n\n if (registrationStatusIndex >= 0) {\n const currentValue = values[registrationStatusIndex];\n values[registrationStatusIndex] =\n typeof currentValue === \"string\" && currentValue.trim() !== \"\"\n ? currentValue.trim()\n : \"01\";\n }\n\n validateRequiredColumns(requiredIndexes, values, input.layout);\n\n if (buildEstablishmentCnpjFull) {\n values.push(buildEstablishmentCnpjFull(values));\n }\n\n if (buildPartnerDedupeKey) {\n values.push(buildPartnerDedupeKey(values));\n }\n\n return {\n values,\n rawLine: parsedLine.rawLine,\n nextOffset: parsedLine.nextOffset,\n sourceRowNumber,\n secondaryRows: [],\n };\n },\n };\n}\n\nexport function normalizeImportRow({\n dataset,\n filePath,\n layout,\n parsedLine,\n schemaCapabilities,\n sourceRowNumber,\n}: NormalizeImportRowInput): BatchRow {\n return createImportRowNormalizer({\n dataset,\n filePath,\n layout,\n schemaCapabilities,\n }).normalize(parsedLine, sourceRowNumber);\n}\n","import { createHash } from \"node:crypto\";\nimport { createReadStream } from \"node:fs\";\nimport { stat } from \"node:fs/promises\";\nimport { performance } from \"node:perf_hooks\";\nimport path from \"node:path\";\n\nimport type { FileInspection } from \"../inspect.service.js\";\nimport type {\n ImportDatasetPlan,\n ImportProgressListener,\n ImportSourceFile,\n} from \"./types.js\";\nimport type { ImportDatasetType } from \"./types.js\";\n\nexport type IteratedLine = {\n line: string;\n nextOffset: number;\n};\n\nexport type ImportPlanBuildResult = {\n datasets: ImportDatasetPlan[];\n totalFiles: number;\n totalRows: number;\n totalBatches: number;\n scanDurationMs: number;\n datasetScanDurationsMs: Partial<Record<ImportDatasetType, number>>;\n};\n\nexport function resolveAbsolutePath(\n validatedPath: string,\n entry: FileInspection,\n): string {\n return path.join(validatedPath, entry.relativePath);\n}\n\nexport function buildDisplayPath(filePath: string): string {\n return `${path.basename(path.dirname(filePath))} > ${path.basename(filePath)}`;\n}\n\nexport async function* iterateFileLines(\n filePath: string,\n startOffset = 0,\n): AsyncGenerator<IteratedLine> {\n const stream = createReadStream(filePath, { start: startOffset });\n let buffered = Buffer.alloc(0);\n let offset = startOffset;\n\n try {\n for await (const chunk of stream) {\n const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n buffered = buffered.length\n ? Buffer.concat([buffered, chunkBuffer])\n : chunkBuffer;\n\n while (true) {\n const newlineIndex = buffered.indexOf(0x0a);\n if (newlineIndex === -1) {\n break;\n }\n\n let lineBuffer = buffered.subarray(0, newlineIndex);\n const consumed = newlineIndex + 1;\n\n if (\n lineBuffer.length > 0 &&\n lineBuffer[lineBuffer.length - 1] === 0x0d\n ) {\n lineBuffer = lineBuffer.subarray(0, lineBuffer.length - 1);\n }\n\n offset += consumed;\n yield {\n line: lineBuffer.toString(\"utf8\"),\n nextOffset: offset,\n };\n\n buffered = buffered.subarray(consumed);\n }\n }\n\n if (buffered.length > 0) {\n offset += buffered.length;\n yield {\n line: buffered.toString(\"utf8\"),\n nextOffset: offset,\n };\n }\n } finally {\n stream.close();\n }\n}\n\nexport async function countFileRowsExact(filePath: string): Promise<number> {\n let count = 0;\n\n for await (const item of iterateFileLines(filePath, 0)) {\n if (item.line.trim() !== \"\") {\n count += 1;\n }\n }\n\n return count;\n}\n\nexport function sortEntries(\n left: FileInspection,\n right: FileInspection,\n): number {\n return left.relativePath.localeCompare(right.relativePath, undefined, {\n numeric: true,\n sensitivity: \"base\",\n });\n}\n\nexport async function collectImportSourceFiles(\n validatedPath: string,\n datasetEntries: Array<{\n dataset: ImportDatasetType;\n files: FileInspection[];\n }>,\n): Promise<\n Array<{\n dataset: ImportDatasetType;\n files: ImportSourceFile[];\n }>\n> {\n const collected: Array<{\n dataset: ImportDatasetType;\n files: ImportSourceFile[];\n }> = [];\n\n for (const item of datasetEntries) {\n const files: ImportSourceFile[] = [];\n\n for (const entry of item.files.sort(sortEntries)) {\n const absolutePath = resolveAbsolutePath(validatedPath, entry);\n const fileStats = await stat(absolutePath);\n files.push({\n dataset: item.dataset,\n absolutePath,\n relativePath: entry.relativePath,\n displayPath: buildDisplayPath(absolutePath),\n fileSize: fileStats.size,\n fileMtime: fileStats.mtime,\n });\n }\n\n collected.push({\n dataset: item.dataset,\n files,\n });\n }\n\n return collected;\n}\n\nexport function buildImportPlanFingerprint(\n validatedPath: string,\n batchSize: number,\n datasetEntries: Array<{\n dataset: ImportDatasetType;\n files: ImportSourceFile[];\n }>,\n): string {\n const hash = createHash(\"sha256\");\n hash.update(\n JSON.stringify({\n validatedPath: path.resolve(validatedPath),\n batchSize,\n datasets: datasetEntries.map((item) => ({\n dataset: item.dataset,\n files: item.files.map((file) => ({\n relativePath: file.relativePath,\n fileSize: file.fileSize,\n fileMtime: file.fileMtime.toISOString(),\n })),\n })),\n }),\n );\n return hash.digest(\"hex\");\n}\n\nexport async function buildImportPlan(\n inputPath: string,\n validatedPath: string,\n datasetEntries: Array<{\n dataset: ImportDatasetType;\n files: ImportSourceFile[];\n }>,\n batchSize: number,\n onProgress: ImportProgressListener | undefined,\n targetDatabase: string,\n): Promise<ImportPlanBuildResult> {\n const totalFiles = datasetEntries.reduce(\n (sum, item) => sum + item.files.length,\n 0,\n );\n let scannedFiles = 0;\n let countedRows = 0;\n const planBuildStartedAt = performance.now();\n\n onProgress?.({\n kind: \"preparing_start\",\n inputPath: path.resolve(inputPath),\n validatedPath,\n totalDatasets: datasetEntries.length,\n totalFiles,\n batchSize,\n loadBatchSize: batchSize,\n targetDatabase,\n });\n\n const datasets: ImportDatasetPlan[] = [];\n const datasetScanDurationsMs: Partial<Record<ImportDatasetType, number>> = {};\n\n for (const item of datasetEntries) {\n const files = [];\n let datasetRows = 0;\n let datasetBatches = 0;\n const datasetScanStartedAt = performance.now();\n\n for (const sourceFile of item.files) {\n const totalRows = await countFileRowsExact(sourceFile.absolutePath);\n const totalBatches =\n totalRows === 0 ? 0 : Math.ceil(totalRows / batchSize);\n\n files.push({\n dataset: item.dataset,\n absolutePath: sourceFile.absolutePath,\n displayPath: sourceFile.displayPath,\n fileSize: sourceFile.fileSize,\n fileMtime: sourceFile.fileMtime,\n totalRows,\n totalBatches,\n });\n\n scannedFiles += 1;\n countedRows += totalRows;\n datasetRows += totalRows;\n datasetBatches += totalBatches;\n\n onProgress?.({\n kind: \"preparing_progress\",\n scannedFiles,\n totalFiles,\n countedRows,\n currentFileDisplayPath: sourceFile.displayPath,\n });\n }\n\n datasetScanDurationsMs[item.dataset] =\n performance.now() - datasetScanStartedAt;\n\n datasets.push({\n dataset: item.dataset,\n files,\n totalRows: datasetRows,\n totalBatches: datasetBatches,\n });\n }\n\n const totalRows = datasets.reduce((sum, item) => sum + item.totalRows, 0);\n const totalBatches = datasets.reduce(\n (sum, item) => sum + item.totalBatches,\n 0,\n );\n\n return {\n datasets,\n totalFiles,\n totalRows,\n totalBatches,\n scanDurationMs: performance.now() - planBuildStartedAt,\n datasetScanDurationsMs,\n };\n}\n","import { iterateFileLines } from \"./planning.js\";\n\nexport type ImportSourceLine = {\n rawLine: string;\n nextOffset: number;\n lineNumber: number;\n};\n\nexport async function* readImportSourceLines(\n filePath: string,\n startOffset = 0,\n startLineNumber = 0,\n): AsyncGenerator<ImportSourceLine> {\n let lineNumber = startLineNumber;\n\n for await (const item of iterateFileLines(filePath, startOffset)) {\n lineNumber += 1;\n yield {\n rawLine: item.line,\n nextOffset: item.nextOffset,\n lineNumber,\n };\n }\n}\n","import { Query, escapeIdentifier, type Client } from \"pg\";\n\nfunction escapeCopyTextValue(value: unknown): string {\n if (value == null) {\n return \"\\\\N\";\n }\n\n const text =\n typeof value === \"boolean\"\n ? value\n ? \"t\"\n : \"f\"\n : value instanceof Date\n ? value.toISOString()\n : String(value);\n\n return text\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\t/g, \"\\\\t\")\n .replace(/\\n/g, \"\\\\n\")\n .replace(/\\r/g, \"\\\\r\")\n .replace(/\\f/g, \"\\\\f\")\n .split(String.fromCharCode(8))\n .join(\"\\\\b\")\n .replace(/\\v/g, \"\\\\v\");\n}\n\nfunction serializeCopyRows(rows: readonly unknown[][]): Buffer {\n const body = rows\n .map((row) => row.map((value) => escapeCopyTextValue(value)).join(\"\\t\"))\n .join(\"\\n\");\n\n return Buffer.from(`${body}\\n`, \"utf8\");\n}\n\nfunction buildCopyStatement(\n tableName: string,\n columns: readonly string[],\n): string {\n const escapedColumns = columns.map((column) => escapeIdentifier(column));\n return `copy ${escapeIdentifier(tableName)} (${escapedColumns.join(\", \")}) from stdin with (format text, null '\\\\N')`;\n}\n\nclass CopyFromTextQuery extends Query {\n private readonly payload: Buffer;\n\n constructor(\n text: string,\n payload: Buffer,\n callback: (error?: Error) => void,\n ) {\n super(text, undefined, callback);\n this.payload = payload;\n }\n\n handleCopyInResponse(connection: {\n sendCopyFromChunk: (chunk: Buffer) => void;\n endCopyFrom: () => void;\n sendCopyFail: (message: string) => void;\n }): void {\n try {\n if (this.payload.length > 0) {\n connection.sendCopyFromChunk(this.payload);\n }\n connection.endCopyFrom();\n } catch (error) {\n connection.sendCopyFail(\n error instanceof Error ? error.message : String(error),\n );\n }\n }\n}\n\nexport async function copyRowsToTable(\n client: Client,\n tableName: string,\n columns: readonly string[],\n rows: readonly unknown[][],\n): Promise<void> {\n if (rows.length === 0) {\n return;\n }\n\n const statement = buildCopyStatement(tableName, columns);\n const payload = serializeCopyRows(rows);\n\n await new Promise<void>((resolve, reject) => {\n const query = new CopyFromTextQuery(statement, payload, (error) => {\n if (error) {\n reject(error);\n return;\n }\n\n resolve();\n });\n\n client.query(query);\n });\n}\n","import type { Client } from \"pg\";\n\nimport { copyRowsToTable } from \"./copy-from.js\";\nimport {\n buildInsertQuery,\n buildSecondaryInsertQuery,\n flushInsertQuery,\n getConflictClause,\n getInsertColumns,\n} from \"./sql.js\";\nimport {\n getSecondaryTargetTableName,\n getTargetTableName,\n resolveImportWriteTarget,\n usesStagingWriteTarget,\n} from \"./targets.js\";\nimport type {\n BatchRow,\n ImportDatasetType,\n ImportSchemaCapabilities,\n} from \"./types.js\";\n\nexport type ImportBatchWriteInput = {\n client: Client;\n dataset: ImportDatasetType;\n rows: BatchRow[];\n schemaCapabilities: ImportSchemaCapabilities;\n};\n\nexport type ImportBatchWriteResult = {\n writtenRows: number;\n writtenSecondaryRows: number;\n writeTarget: \"final\" | \"staging\";\n writeMode: \"copy\" | \"insert\";\n targetTable: string;\n};\n\nasync function writeBatchToFinalTarget(\n client: Client,\n dataset: ImportDatasetType,\n rows: BatchRow[],\n schemaCapabilities: ImportSchemaCapabilities,\n): Promise<ImportBatchWriteResult> {\n const targetTable = getTargetTableName(dataset);\n const columns = getInsertColumns(dataset, schemaCapabilities, \"final\");\n const batchValues = rows.map((row) => row.values);\n const secondaryRows = rows.flatMap((row) => row.secondaryRows);\n\n await flushInsertQuery(\n client,\n buildInsertQuery(\n targetTable,\n columns,\n batchValues,\n getConflictClause(dataset, columns),\n ),\n );\n\n const secondaryTargetTable = getSecondaryTargetTableName(dataset);\n if (secondaryTargetTable && secondaryRows.length > 0) {\n await flushInsertQuery(\n client,\n buildSecondaryInsertQuery(\n secondaryTargetTable,\n secondaryRows,\n \"on conflict (establishment_cnpj_full, cnae_code) do update set source_order = excluded.source_order\",\n ),\n );\n }\n\n return {\n writtenRows: rows.length,\n writtenSecondaryRows: secondaryRows.length,\n writeTarget: \"final\",\n writeMode: \"insert\",\n targetTable,\n };\n}\n\nasync function writeBatchToStagingTarget(\n client: Client,\n dataset: ImportDatasetType,\n rows: BatchRow[],\n schemaCapabilities: ImportSchemaCapabilities,\n): Promise<ImportBatchWriteResult> {\n const targetTable = getTargetTableName(dataset);\n const columns = getInsertColumns(dataset, schemaCapabilities, \"staging\");\n const batchValues = rows.map((row) => row.values);\n const secondaryRows = rows.flatMap((row) => row.secondaryRows);\n\n await copyRowsToTable(client, targetTable, columns, batchValues);\n\n const secondaryTargetTable = getSecondaryTargetTableName(dataset);\n if (secondaryTargetTable && secondaryRows.length > 0) {\n await copyRowsToTable(\n client,\n secondaryTargetTable,\n [\"establishment_cnpj_full\", \"cnae_code\", \"source_order\"],\n secondaryRows,\n );\n }\n\n return {\n writtenRows: rows.length,\n writtenSecondaryRows: secondaryRows.length,\n writeTarget: \"staging\",\n writeMode: \"copy\",\n targetTable,\n };\n}\n\nasync function writeRowInsertFallback(\n client: Client,\n dataset: ImportDatasetType,\n row: BatchRow,\n schemaCapabilities: ImportSchemaCapabilities,\n): Promise<ImportBatchWriteResult> {\n const writeTarget = resolveImportWriteTarget(dataset);\n const targetTable = getTargetTableName(dataset);\n const columns = getInsertColumns(dataset, schemaCapabilities, writeTarget);\n const conflictClause =\n writeTarget === \"final\" ? getConflictClause(dataset, columns) : \"\";\n\n await flushInsertQuery(\n client,\n buildInsertQuery(targetTable, columns, [row.values], conflictClause),\n );\n\n const secondaryTargetTable = getSecondaryTargetTableName(dataset);\n if (secondaryTargetTable && row.secondaryRows.length > 0) {\n await flushInsertQuery(\n client,\n buildSecondaryInsertQuery(\n secondaryTargetTable,\n row.secondaryRows,\n writeTarget === \"final\"\n ? \"on conflict (establishment_cnpj_full, cnae_code) do update set source_order = excluded.source_order\"\n : \"\",\n ),\n );\n }\n\n return {\n writtenRows: 1,\n writtenSecondaryRows: row.secondaryRows.length,\n writeTarget,\n writeMode: \"insert\",\n targetTable,\n };\n}\n\nexport async function writeImportBatchToTarget({\n client,\n dataset,\n rows,\n schemaCapabilities,\n}: ImportBatchWriteInput): Promise<ImportBatchWriteResult> {\n if (rows.length === 0) {\n return {\n writtenRows: 0,\n writtenSecondaryRows: 0,\n writeTarget: resolveImportWriteTarget(dataset),\n writeMode: usesStagingWriteTarget(dataset) ? \"copy\" : \"insert\",\n targetTable: getTargetTableName(dataset),\n };\n }\n\n if (usesStagingWriteTarget(dataset)) {\n return writeBatchToStagingTarget(client, dataset, rows, schemaCapabilities);\n }\n\n return writeBatchToFinalTarget(client, dataset, rows, schemaCapabilities);\n}\n\nexport async function writeImportRowToTarget(\n input: Omit<ImportBatchWriteInput, \"rows\"> & { row: BatchRow },\n): Promise<ImportBatchWriteResult> {\n return writeRowInsertFallback(\n input.client,\n input.dataset,\n input.row,\n input.schemaCapabilities,\n );\n}\n","import { Client } from \"pg\";\n\nimport { ensureTableShape } from \"./schema-validation.js\";\nimport type { ImportDatasetType } from \"./types.js\";\n\nfunction classifyQuarantineError(error: unknown): {\n code: string;\n category: string;\n canRetryLater: boolean;\n} {\n const errorCode =\n typeof error === \"object\" && error && \"code\" in error\n ? String((error as { code?: string }).code ?? \"QUARANTINED_ROW\")\n : \"QUARANTINED_ROW\";\n const errorMessage =\n error instanceof Error ? error.message : String(error ?? \"Unknown error\");\n const normalizedMessage = errorMessage.toLowerCase();\n\n if (normalizedMessage.includes(\"invalid byte sequence for encoding\")) {\n return {\n code: errorCode,\n category: \"invalid_utf8_sequence\",\n canRetryLater: true,\n };\n }\n\n if (normalizedMessage.includes(\"violates not-null constraint\")) {\n return {\n code: errorCode,\n category: \"not_null_violation\",\n canRetryLater: false,\n };\n }\n\n if (normalizedMessage.includes(\"violates foreign key constraint\")) {\n return {\n code: errorCode,\n category: \"foreign_key_violation\",\n canRetryLater: false,\n };\n }\n\n if (normalizedMessage.includes(\"field count\")) {\n return {\n code: errorCode,\n category: \"invalid_field_count\",\n canRetryLater: true,\n };\n }\n\n if (normalizedMessage.includes(\"transform\")) {\n return {\n code: errorCode,\n category: \"transform_error\",\n canRetryLater: true,\n };\n }\n\n return {\n code: errorCode,\n category: \"unknown\",\n canRetryLater: false,\n };\n}\n\nexport async function ensureQuarantineTable(client: Client): Promise<void> {\n await ensureTableShape(client, {\n tableName: \"import_quarantine\",\n requiredColumns: [\n \"dataset\",\n \"file_path\",\n \"row_number\",\n \"checkpoint_offset\",\n \"error_code\",\n \"error_category\",\n \"error_stage\",\n \"error_message\",\n \"raw_line\",\n \"parsed_payload\",\n \"sanitizations_applied\",\n \"retry_count\",\n \"can_retry_later\",\n \"created_at\",\n ],\n helpMessage:\n 'The import quarantine schema is required. Run \"cnpj-db-loader schema generate --profile full\" and apply the SQL before importing.',\n });\n}\n\nexport type QuarantineInput = {\n dataset: ImportDatasetType;\n filePath: string;\n rowNumber: number;\n checkpointOffset: number;\n rawLine: string;\n error: unknown;\n parsedPayload?: Record<string, unknown> | null;\n errorStage?: string | null;\n sanitizationsApplied?: unknown[] | null;\n retryCount?: number;\n canRetryLater?: boolean;\n errorCategory?: string | null;\n};\n\nexport async function writeQuarantineRow(\n client: Client,\n input: QuarantineInput,\n): Promise<void> {\n const classified = classifyQuarantineError(input.error);\n const errorMessage =\n input.error instanceof Error ? input.error.message : String(input.error);\n\n await client.query(\n `insert into import_quarantine (\n dataset,\n file_path,\n row_number,\n checkpoint_offset,\n error_code,\n error_category,\n error_stage,\n error_message,\n raw_line,\n parsed_payload,\n sanitizations_applied,\n retry_count,\n can_retry_later,\n created_at\n ) values (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10::jsonb, $11::jsonb, $12, $13, now()\n )`,\n [\n input.dataset,\n input.filePath,\n input.rowNumber,\n input.checkpointOffset,\n classified.code,\n input.errorCategory ?? classified.category,\n input.errorStage ?? null,\n errorMessage,\n input.rawLine,\n input.parsedPayload ? JSON.stringify(input.parsedPayload) : null,\n input.sanitizationsApplied\n ? JSON.stringify(input.sanitizationsApplied)\n : null,\n input.retryCount ?? 0,\n input.canRetryLater ?? classified.canRetryLater,\n ],\n );\n}\n","import type { Client } from \"pg\";\n\nimport { ensureQuarantineTable, writeQuarantineRow } from \"./quarantine.js\";\n\nexport {\n ensureQuarantineTable as ensureImportQuarantineTable,\n writeQuarantineRow as writeImportQuarantineRow,\n};\n\nexport async function ensureImportQuarantineSupport(\n client: Client,\n): Promise<void> {\n await ensureQuarantineTable(client);\n}\n","import { performance } from \"node:perf_hooks\";\n\nimport type { Client } from \"pg\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport { appendJsonLinesLog } from \"../logging.service.js\";\nimport {\n readMaterializationCheckpoint,\n writeMaterializationCheckpoint,\n writeMaterializationCheckpointProgress,\n type MaterializationCheckpointRecord,\n} from \"./materialization-checkpoints.js\";\nimport {\n buildMaterializationChunkQuery,\n isMaterializationDataset,\n type MaterializationDataset,\n} from \"./materialization-sql.js\";\nimport {\n getLookupReconciliationSources,\n reconcileMaterializationLookups,\n} from \"./materialization-lookups.js\";\nimport { type MutableDatasetPerformance } from \"./finalizer.js\";\nimport { getFinalTargetTableName } from \"./targets.js\";\nimport type {\n ImportDatasetType,\n ImportProgressListener,\n ImportSchemaCapabilities,\n} from \"./types.js\";\n\nconst MATERIALIZATION_ORDER: readonly MaterializationDataset[] = [\n \"companies\",\n \"establishments\",\n \"simples_options\",\n \"partners\",\n];\n\nconst DEFAULT_MATERIALIZATION_CHUNK_SIZE = 50_000;\nconst MATERIALIZATION_HEARTBEAT_INTERVAL_MS = 15_000;\nconst MATERIALIZATION_CHECKPOINT_INTERVAL_CHUNKS = 25;\nconst MATERIALIZATION_CHUNK_LOG_INTERVAL = 50;\nconst EXACT_TARGET_COUNT_DATASETS: ReadonlySet<MaterializationDataset> =\n new Set([\"companies\", \"establishments\", \"simples_options\"]);\n\nconst STAGING_TABLE_BY_DATASET: Record<MaterializationDataset, string> = {\n companies: \"staging_companies\",\n establishments: \"staging_establishments\",\n simples_options: \"staging_simples_options\",\n partners: \"staging_partners\",\n};\n\ntype ChunkRow = {\n max_staging_id: string;\n source_rows: string;\n affected_rows: string;\n};\n\ntype CountRow = {\n total_count: string;\n};\n\ntype StagingStateRow = {\n total_count: string;\n max_staging_id: string;\n};\n\ntype StagingMaxRow = {\n max_staging_id: string;\n};\n\ntype QuarantineCountRow = {\n quarantined_rows: string;\n};\n\ntype ValidatedCheckpoint = {\n checkpoint: MaterializationCheckpointRecord;\n adjusted: boolean;\n reason: string | null;\n stagingMaxId: number;\n targetRows: number | null;\n};\n\nexport type MaterializationSummary = {\n datasets: Array<{\n dataset: MaterializationDataset;\n targetTable: string;\n affectedRows: number;\n sourceRows: number;\n chunksCompleted: number;\n durationMs: number;\n }>;\n};\n\nfunction resolveMaterializationDatasets(\n datasets: readonly ImportDatasetType[],\n): MaterializationDataset[] {\n const requested = new Set(\n datasets.filter((dataset): dataset is MaterializationDataset =>\n isMaterializationDataset(dataset),\n ),\n );\n\n return MATERIALIZATION_ORDER.filter((dataset) => requested.has(dataset));\n}\n\nfunction emitMaterializationProgress(\n listener: ImportProgressListener | undefined,\n input: {\n datasets: readonly MaterializationDataset[];\n dataset: MaterializationDataset;\n datasetIndex: number;\n targetTable: string;\n stepLabel: string;\n completedDatasets: number;\n completedFiles: number;\n totalFiles: number;\n processedRows: number;\n totalRows: number;\n committedBatches: number;\n totalBatches: number;\n elapsedMs?: number;\n reason?: string;\n chunkSize?: number;\n rowsMaterialized?: number;\n datasetRowCount?: number;\n chunksCompleted?: number;\n estimatedChunks?: number;\n lastStagingId?: number;\n },\n): void {\n listener?.({\n kind: \"materialization_progress\",\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.datasets.length,\n completedDatasets: input.completedDatasets,\n targetTable: input.targetTable,\n stepLabel: input.stepLabel,\n completedFiles: input.completedFiles,\n totalFiles: input.totalFiles,\n processedRows: input.processedRows,\n totalRows: input.totalRows,\n committedBatches: input.committedBatches,\n totalBatches: input.totalBatches,\n ...(input.elapsedMs === undefined ? {} : { elapsedMs: input.elapsedMs }),\n ...(input.reason === undefined ? {} : { reason: input.reason }),\n ...(input.chunkSize === undefined ? {} : { chunkSize: input.chunkSize }),\n ...(input.rowsMaterialized === undefined\n ? {}\n : { rowsMaterialized: input.rowsMaterialized }),\n ...(input.datasetRowCount === undefined\n ? {}\n : { datasetRowCount: input.datasetRowCount }),\n ...(input.chunksCompleted === undefined\n ? {}\n : { chunksCompleted: input.chunksCompleted }),\n ...(input.estimatedChunks === undefined\n ? {}\n : { estimatedChunks: input.estimatedChunks }),\n ...(input.lastStagingId === undefined\n ? {}\n : { lastStagingId: input.lastStagingId }),\n });\n}\n\nasync function executeChunkQuery(\n client: Client,\n text: string,\n values: readonly unknown[],\n): Promise<{ maxStagingId: number; sourceRows: number; affectedRows: number }> {\n const result = await client.query<ChunkRow>(text, [...values]);\n const row = result.rows[0];\n return {\n maxStagingId: row ? Number.parseInt(row.max_staging_id, 10) : 0,\n sourceRows: row ? Number.parseInt(row.source_rows, 10) : 0,\n affectedRows: row ? Number.parseInt(row.affected_rows, 10) : 0,\n };\n}\n\nasync function readStagingState(\n client: Client,\n stagingTable: string,\n): Promise<{ rowCount: number; maxStagingId: number }> {\n const result = await client.query<StagingStateRow>(\n `select count(*)::bigint as total_count, coalesce(max(staging_id), 0)::bigint as max_staging_id from ${stagingTable}`,\n );\n\n return {\n rowCount: Number.parseInt(result.rows[0]?.total_count ?? \"0\", 10),\n maxStagingId: Number.parseInt(result.rows[0]?.max_staging_id ?? \"0\", 10),\n };\n}\n\nasync function readStagingMaxId(\n client: Client,\n stagingTable: string,\n): Promise<number> {\n const result = await client.query<StagingMaxRow>(\n `select coalesce(max(staging_id), 0)::bigint as max_staging_id from ${stagingTable}`,\n );\n\n return Number.parseInt(result.rows[0]?.max_staging_id ?? \"0\", 10);\n}\n\nasync function readQuarantinedRowCountForPlan(input: {\n client: Client;\n planId: number;\n dataset: MaterializationDataset;\n}): Promise<number> {\n const result = await input.client.query<QuarantineCountRow>(\n `select count(*)::bigint as quarantined_rows\n from (\n select distinct q.file_path, q.row_number\n from import_quarantine q\n inner join import_plan_files pf\n on pf.plan_id = $1\n and pf.dataset = q.dataset\n and pf.file_path = q.file_path\n where q.dataset = $2\n and q.row_number is not null\n ) quarantined`,\n [input.planId, input.dataset],\n );\n\n return Number.parseInt(result.rows[0]?.quarantined_rows ?? \"0\", 10);\n}\n\nfunction buildEmptyStagingMessage(\n stagingTable: string,\n dataset: MaterializationDataset,\n expectedRows: number | undefined,\n): string {\n if (typeof expectedRows === \"number\" && expectedRows > 0) {\n return `The staging table ${stagingTable} is empty, but ${expectedRows} row(s) are expected for ${dataset} based on the saved load checkpoints. Run \"cnpj-db-loader import load\" again or clear stale checkpoint data before materializing.`;\n }\n\n return `The staging table ${stagingTable} is empty for ${dataset}. Load the dataset into staging before running materialization.`;\n}\n\nfunction buildStagingMismatchMessage(\n stagingTable: string,\n dataset: MaterializationDataset,\n expectedRows: number,\n actualRows: number,\n): string {\n return `The staging table ${stagingTable} currently contains ${actualRows} row(s), but ${expectedRows} row(s) are expected for ${dataset} based on the saved load checkpoints. The saved staging state no longer matches the persisted load progress. Reload staging or clear the stale checkpoint data before retrying materialization.`;\n}\n\nasync function validateStagingDatasetState(input: {\n client: Client;\n planId: number;\n dataset: MaterializationDataset;\n datasetIndex: number;\n totalDatasets: number;\n expectedRows: number | undefined;\n progressLogPath: string;\n}): Promise<{\n rowCount: number;\n maxStagingId: number;\n effectiveExpectedRows: number | undefined;\n quarantinedRows: number;\n reusedValidation: boolean;\n}> {\n const stagingTable = STAGING_TABLE_BY_DATASET[input.dataset];\n const checkpoint = await readMaterializationCheckpoint(\n input.client,\n input.planId,\n input.dataset,\n getFinalTargetTableName(input.dataset),\n );\n\n const canReuseValidatedStagingState =\n checkpoint.status === \"completed\" &&\n checkpoint.stagingRowCountVerified !== null &&\n checkpoint.stagingMaxStagingIdVerified !== null;\n\n if (canReuseValidatedStagingState) {\n const verifiedRowCount = checkpoint.stagingRowCountVerified;\n const verifiedMaxStagingId = checkpoint.stagingMaxStagingIdVerified;\n const liveMaxStagingId = await readStagingMaxId(input.client, stagingTable);\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_staging_validation_checked\",\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.totalDatasets,\n stagingTable,\n expectedRows: input.expectedRows ?? null,\n actualRows: verifiedRowCount,\n maxStagingId: liveMaxStagingId,\n reusedValidation:\n liveMaxStagingId === verifiedMaxStagingId && liveMaxStagingId > 0,\n timestamp: new Date().toISOString(),\n });\n\n if (liveMaxStagingId === 0) {\n throw new ValidationError(\n buildEmptyStagingMessage(\n stagingTable,\n input.dataset,\n verifiedRowCount ?? undefined,\n ),\n );\n }\n\n if (\n verifiedRowCount !== null &&\n liveMaxStagingId === verifiedMaxStagingId\n ) {\n return {\n rowCount: verifiedRowCount,\n maxStagingId: liveMaxStagingId,\n effectiveExpectedRows: verifiedRowCount,\n quarantinedRows: 0,\n reusedValidation: true,\n };\n }\n }\n\n const state = await readStagingState(input.client, stagingTable);\n const quarantinedRows = await readQuarantinedRowCountForPlan({\n client: input.client,\n planId: input.planId,\n dataset: input.dataset,\n });\n const effectiveExpectedRows =\n typeof input.expectedRows === \"number\"\n ? Math.max(0, input.expectedRows - quarantinedRows)\n : undefined;\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_staging_validation_completed\",\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.totalDatasets,\n stagingTable,\n expectedRows: input.expectedRows ?? null,\n quarantinedRows,\n effectiveExpectedRows: effectiveExpectedRows ?? null,\n actualRows: state.rowCount,\n maxStagingId: state.maxStagingId,\n timestamp: new Date().toISOString(),\n });\n\n if (state.rowCount === 0) {\n throw new ValidationError(\n buildEmptyStagingMessage(\n stagingTable,\n input.dataset,\n effectiveExpectedRows ?? input.expectedRows,\n ),\n );\n }\n\n if (\n typeof effectiveExpectedRows === \"number\" &&\n effectiveExpectedRows > 0 &&\n state.rowCount !== effectiveExpectedRows\n ) {\n throw new ValidationError(\n buildStagingMismatchMessage(\n stagingTable,\n input.dataset,\n effectiveExpectedRows,\n state.rowCount,\n ),\n );\n }\n\n return {\n ...state,\n effectiveExpectedRows,\n quarantinedRows,\n reusedValidation: false,\n };\n}\n\nasync function readRowCount(\n client: Client,\n tableName: string,\n): Promise<number> {\n const result = await client.query<CountRow>(\n `select count(*)::bigint as total_count from ${tableName}`,\n );\n\n return Number.parseInt(result.rows[0]?.total_count ?? \"0\", 10);\n}\n\nasync function persistCheckpoint(\n client: Client,\n checkpoint: MaterializationCheckpointRecord,\n): Promise<void> {\n await writeMaterializationCheckpoint(client, checkpoint);\n}\n\nasync function persistCheckpointProgress(\n client: Client,\n checkpoint: MaterializationCheckpointRecord,\n): Promise<void> {\n await writeMaterializationCheckpointProgress(client, checkpoint);\n}\n\nfunction shouldFlushChunkCheckpoint(chunksCompleted: number): boolean {\n return (\n chunksCompleted === 1 ||\n chunksCompleted % MATERIALIZATION_CHECKPOINT_INTERVAL_CHUNKS === 0\n );\n}\n\nfunction shouldLogChunkCompletion(chunksCompleted: number): boolean {\n return (\n chunksCompleted === 1 ||\n chunksCompleted % MATERIALIZATION_CHUNK_LOG_INTERVAL === 0\n );\n}\n\nfunction withValidatedStagingState(\n checkpoint: MaterializationCheckpointRecord,\n stagingState: { rowCount: number; maxStagingId: number },\n): MaterializationCheckpointRecord {\n return {\n ...checkpoint,\n stagingRowCountVerified: stagingState.rowCount,\n stagingMaxStagingIdVerified: stagingState.maxStagingId,\n stagingValidatedAt: new Date(),\n };\n}\n\nfunction clearLookupReconciliationState(\n checkpoint: MaterializationCheckpointRecord,\n): MaterializationCheckpointRecord {\n return {\n ...checkpoint,\n lookupReconciliationStatus: \"pending\",\n lookupReconciliationRowCountVerified: null,\n lookupReconciliationMaxStagingIdVerified: null,\n lookupReconciliationCompletedAt: null,\n };\n}\n\nfunction shouldReuseLookupReconciliation(input: {\n checkpoint: MaterializationCheckpointRecord;\n stagingState: { rowCount: number; maxStagingId: number };\n}): boolean {\n return (\n input.checkpoint.lookupReconciliationStatus === \"completed\" &&\n input.checkpoint.lookupReconciliationRowCountVerified ===\n input.stagingState.rowCount &&\n input.checkpoint.lookupReconciliationMaxStagingIdVerified ===\n input.stagingState.maxStagingId\n );\n}\n\nfunction resetCheckpointForReplay(\n checkpoint: MaterializationCheckpointRecord,\n): MaterializationCheckpointRecord {\n return clearLookupReconciliationState({\n ...checkpoint,\n status: \"pending\",\n rowsMaterialized: 0,\n lastStagingId: 0,\n chunksCompleted: 0,\n lastError: null,\n startedAt: null,\n completedAt: null,\n lastChunkFirstStagingId: 0,\n lastChunkLastStagingId: 0,\n lastChunkRows: 0,\n });\n}\n\nasync function validateDatasetCheckpoint(input: {\n client: Client;\n planId: number;\n dataset: MaterializationDataset;\n targetTable: string;\n expectedRows?: number;\n stagingMaxId: number;\n skipCompletedTargetValidation?: boolean;\n}): Promise<ValidatedCheckpoint> {\n let checkpoint = await readMaterializationCheckpoint(\n input.client,\n input.planId,\n input.dataset,\n input.targetTable,\n );\n const stagingMaxId = input.stagingMaxId;\n\n let adjusted = false;\n let reason: string | null = null;\n let targetRows: number | null = null;\n\n if (checkpoint.lastStagingId > stagingMaxId && stagingMaxId > 0) {\n checkpoint = resetCheckpointForReplay(checkpoint);\n adjusted = true;\n reason =\n \"Checkpoint references a staging range beyond the current staging table. The dataset will be rematerialized from the beginning.\";\n } else if (\n checkpoint.status === \"completed\" &&\n checkpoint.lastStagingId < stagingMaxId\n ) {\n checkpoint = {\n ...checkpoint,\n status: \"in_progress\",\n completedAt: null,\n lastError: null,\n };\n adjusted = true;\n reason =\n \"Checkpoint was marked as completed before the current staging tail. The dataset will resume materialization from the saved staging cursor.\";\n }\n\n if (\n EXACT_TARGET_COUNT_DATASETS.has(input.dataset) &&\n input.expectedRows !== undefined &&\n !input.skipCompletedTargetValidation &&\n (checkpoint.status === \"completed\" ||\n checkpoint.lastStagingId >= stagingMaxId)\n ) {\n targetRows = await readRowCount(input.client, input.targetTable);\n\n if (targetRows < input.expectedRows) {\n checkpoint = resetCheckpointForReplay(checkpoint);\n adjusted = true;\n reason = `The target table currently has ${targetRows} row(s), but ${input.expectedRows} row(s) are expected for ${input.dataset}. The dataset will be rematerialized from the beginning.`;\n }\n }\n\n if (adjusted) {\n await persistCheckpoint(input.client, checkpoint);\n }\n\n return {\n checkpoint,\n adjusted,\n reason,\n stagingMaxId,\n targetRows,\n };\n}\n\ntype EstablishmentSecondaryCnaesCountRow = {\n total_count: string;\n};\n\ntype EstablishmentSecondaryCnaesExistsRow = {\n exists: boolean;\n};\n\nasync function readEstablishmentSecondaryCnaesCount(\n client: Client,\n): Promise<number> {\n const result = await client.query<EstablishmentSecondaryCnaesCountRow>(\n `select count(*)::bigint as total_count from establishment_secondary_cnaes`,\n );\n\n return Number.parseInt(result.rows[0]?.total_count ?? \"0\", 10);\n}\n\nasync function hasEstablishmentsWithSecondaryCnaes(\n client: Client,\n): Promise<boolean> {\n const result = await client.query<EstablishmentSecondaryCnaesExistsRow>(\n `select exists (\n select 1\n from establishments\n where secondary_cnaes_raw is not null\n and secondary_cnaes_raw <> ''\n limit 1\n ) as exists`,\n );\n\n return result.rows[0]?.exists ?? false;\n}\n\nasync function backfillEstablishmentSecondaryCnaesFromFinal(input: {\n client: Client;\n progressLogPath: string;\n}): Promise<number> {\n const existingRows = await readEstablishmentSecondaryCnaesCount(input.client);\n\n if (existingRows > 0) {\n return 0;\n }\n\n if (!(await hasEstablishmentsWithSecondaryCnaes(input.client))) {\n return 0;\n }\n\n const startedAt = performance.now();\n const result = await input.client.query(\n `insert into establishment_secondary_cnaes (cnpj_full, cnae_code)\n select distinct\n e.cnpj_full,\n btrim(cnae_code) as cnae_code\n from establishments e\n cross join lateral unnest(\n string_to_array(e.secondary_cnaes_raw, ',')\n ) as cnae_code\n where e.secondary_cnaes_raw is not null\n and e.secondary_cnaes_raw <> ''\n and btrim(cnae_code) <> ''\n on conflict (cnpj_full, cnae_code) do nothing`,\n );\n\n const insertedRows = result.rowCount ?? 0;\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"establishment_secondary_cnaes_backfilled\",\n targetTable: \"establishment_secondary_cnaes\",\n insertedRows,\n durationMs: performance.now() - startedAt,\n timestamp: new Date().toISOString(),\n });\n\n return insertedRows;\n}\n\nasync function materializeDatasetByChunks(input: {\n client: Client;\n planId: number;\n dataset: MaterializationDataset;\n datasetIndex: number;\n datasets: readonly MaterializationDataset[];\n targetTable: string;\n chunkSize: number;\n expectedRows?: number;\n expectedStagedRows?: number;\n schemaCapabilities: ImportSchemaCapabilities;\n progressLogPath: string;\n onProgress?: ImportProgressListener | undefined;\n completedFiles: number;\n totalFiles: number;\n processedRows: number;\n totalRows: number;\n committedBatches: number;\n totalBatches: number;\n completedDatasets: number;\n}): Promise<{\n affectedRows: number;\n sourceRows: number;\n chunksCompleted: number;\n durationMs: number;\n}> {\n const startedAt = performance.now();\n const validationReason =\n \"Validating the live staging row count and staging cursor before resuming materialization.\";\n\n emitMaterializationProgress(input.onProgress, {\n datasets: input.datasets,\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n targetTable: input.targetTable,\n stepLabel: \"Validating staging state\",\n reason: validationReason,\n chunkSize: input.chunkSize,\n completedDatasets: input.completedDatasets,\n completedFiles: input.completedFiles,\n totalFiles: input.totalFiles,\n processedRows: input.processedRows,\n totalRows: input.totalRows,\n committedBatches: input.committedBatches,\n totalBatches: input.totalBatches,\n });\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_staging_validation_started\",\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.datasets.length,\n targetTable: input.targetTable,\n expectedRows: input.expectedStagedRows ?? null,\n timestamp: new Date().toISOString(),\n });\n\n const stagingState = await validateStagingDatasetState({\n client: input.client,\n planId: input.planId,\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.datasets.length,\n expectedRows: input.expectedStagedRows,\n progressLogPath: input.progressLogPath,\n });\n const estimatedChunks = Math.max(\n 1,\n Math.ceil(stagingState.rowCount / input.chunkSize),\n );\n\n const validated = await validateDatasetCheckpoint({\n client: input.client,\n planId: input.planId,\n dataset: input.dataset,\n targetTable: input.targetTable,\n stagingMaxId: stagingState.maxStagingId,\n skipCompletedTargetValidation: stagingState.reusedValidation,\n ...(input.expectedRows === undefined\n ? {}\n : { expectedRows: input.expectedRows }),\n });\n let checkpoint = withValidatedStagingState(\n validated.checkpoint,\n stagingState,\n );\n await persistCheckpoint(input.client, checkpoint);\n\n if (validated.adjusted && validated.reason) {\n emitMaterializationProgress(input.onProgress, {\n datasets: input.datasets,\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n targetTable: input.targetTable,\n stepLabel: \"Checkpoint reconciled — resuming safely\",\n reason: validated.reason,\n chunkSize: input.chunkSize,\n rowsMaterialized: checkpoint.rowsMaterialized,\n datasetRowCount: stagingState.rowCount,\n chunksCompleted: checkpoint.chunksCompleted,\n estimatedChunks,\n lastStagingId: checkpoint.lastStagingId,\n completedDatasets: input.completedDatasets,\n completedFiles: input.completedFiles,\n totalFiles: input.totalFiles,\n processedRows: input.processedRows,\n totalRows: input.totalRows,\n committedBatches: input.committedBatches,\n totalBatches: input.totalBatches,\n });\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_checkpoint_reconciled\",\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.datasets.length,\n targetTable: input.targetTable,\n reason: validated.reason,\n stagingMaxId: validated.stagingMaxId,\n targetRows: validated.targetRows,\n expectedRows: input.expectedRows ?? null,\n timestamp: new Date().toISOString(),\n });\n }\n\n if (checkpoint.status === \"completed\") {\n emitMaterializationProgress(input.onProgress, {\n datasets: input.datasets,\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n targetTable: input.targetTable,\n stepLabel: `Checkpoint complete — verified ${checkpoint.chunksCompleted} chunk(s)`,\n reason:\n \"The live staging state matches the last verified materialization checkpoint.\",\n chunkSize: input.chunkSize,\n rowsMaterialized: checkpoint.rowsMaterialized,\n datasetRowCount: stagingState.rowCount,\n chunksCompleted: checkpoint.chunksCompleted,\n estimatedChunks,\n lastStagingId: checkpoint.lastStagingId,\n completedDatasets: input.completedDatasets,\n completedFiles: input.completedFiles,\n totalFiles: input.totalFiles,\n processedRows: input.processedRows,\n totalRows: input.totalRows,\n committedBatches: input.committedBatches,\n totalBatches: input.totalBatches,\n });\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_dataset_skipped\",\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.datasets.length,\n targetTable: input.targetTable,\n rowsMaterialized: checkpoint.rowsMaterialized,\n chunksCompleted: checkpoint.chunksCompleted,\n verified: true,\n timestamp: new Date().toISOString(),\n });\n\n return {\n affectedRows: checkpoint.rowsMaterialized,\n sourceRows: checkpoint.rowsMaterialized,\n chunksCompleted: checkpoint.chunksCompleted,\n durationMs: performance.now() - startedAt,\n };\n }\n\n const lookupSources = input.schemaCapabilities.requiresLookupReconciliation\n ? getLookupReconciliationSources(input.dataset)\n : [];\n if (lookupSources.length === 0) {\n checkpoint = {\n ...checkpoint,\n lookupReconciliationStatus: \"completed\",\n lookupReconciliationRowCountVerified: stagingState.rowCount,\n lookupReconciliationMaxStagingIdVerified: stagingState.maxStagingId,\n lookupReconciliationCompletedAt:\n checkpoint.lookupReconciliationCompletedAt ?? new Date(),\n };\n await persistCheckpoint(input.client, checkpoint);\n } else if (shouldReuseLookupReconciliation({ checkpoint, stagingState })) {\n emitMaterializationProgress(input.onProgress, {\n datasets: input.datasets,\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n targetTable: input.targetTable,\n stepLabel: \"Reusing lookup reconciliation\",\n reason:\n \"Staging row count and staging cursor are unchanged since the last completed lookup reconciliation.\",\n chunkSize: input.chunkSize,\n rowsMaterialized: checkpoint.rowsMaterialized,\n datasetRowCount: stagingState.rowCount,\n chunksCompleted: checkpoint.chunksCompleted,\n estimatedChunks,\n lastStagingId: checkpoint.lastStagingId,\n completedDatasets: input.completedDatasets,\n completedFiles: input.completedFiles,\n totalFiles: input.totalFiles,\n processedRows: input.processedRows,\n totalRows: input.totalRows,\n committedBatches: input.committedBatches,\n totalBatches: input.totalBatches,\n });\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_lookup_reconciliation_reused\",\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.datasets.length,\n targetTable: input.targetTable,\n stagingRowCount: stagingState.rowCount,\n stagingMaxId: stagingState.maxStagingId,\n timestamp: new Date().toISOString(),\n });\n } else {\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_lookup_reconciliation_started\",\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.datasets.length,\n targetTable: input.targetTable,\n lookupTables: lookupSources,\n timestamp: new Date().toISOString(),\n });\n\n const reconciliation = await reconcileMaterializationLookups({\n client: input.client,\n dataset: input.dataset,\n onLookupStart: (lookupTable, lookupIndex, lookupTotal) => {\n emitMaterializationProgress(input.onProgress, {\n datasets: input.datasets,\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n targetTable: input.targetTable,\n stepLabel: `Reconciling lookup dependencies (${lookupIndex}/${lookupTotal})`,\n reason: `Checking ${lookupTable} for missing lookup codes and placeholder rows.`,\n chunkSize: input.chunkSize,\n rowsMaterialized: checkpoint.rowsMaterialized,\n datasetRowCount: stagingState.rowCount,\n chunksCompleted: checkpoint.chunksCompleted,\n estimatedChunks,\n lastStagingId: checkpoint.lastStagingId,\n completedDatasets: input.completedDatasets,\n completedFiles: input.completedFiles,\n totalFiles: input.totalFiles,\n processedRows: input.processedRows,\n totalRows: input.totalRows,\n committedBatches: input.committedBatches,\n totalBatches: input.totalBatches,\n });\n },\n });\n\n checkpoint = {\n ...checkpoint,\n lookupReconciliationStatus: \"completed\",\n lookupReconciliationRowCountVerified: stagingState.rowCount,\n lookupReconciliationMaxStagingIdVerified: stagingState.maxStagingId,\n lookupReconciliationCompletedAt: new Date(),\n };\n await persistCheckpoint(input.client, checkpoint);\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_lookup_reconciliation_completed\",\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.datasets.length,\n targetTable: input.targetTable,\n totalInsertedCodes: reconciliation.totalInsertedCodes,\n results: reconciliation.results.map((item) => ({\n lookupTable: item.lookupTable,\n insertedCodes: item.insertedCodes,\n })),\n durationMs: reconciliation.durationMs,\n timestamp: new Date().toISOString(),\n });\n }\n\n checkpoint = {\n ...checkpoint,\n status: \"in_progress\",\n targetTable: input.targetTable,\n startedAt: checkpoint.startedAt ?? new Date(),\n completedAt: null,\n lastError: null,\n };\n await persistCheckpoint(input.client, checkpoint);\n\n let affectedRows = checkpoint.rowsMaterialized;\n let sourceRows = checkpoint.rowsMaterialized;\n let chunksCompleted = checkpoint.chunksCompleted;\n const targetHasRows =\n checkpoint.rowsMaterialized > 0 ||\n (await readRowCount(input.client, input.targetTable)) > 0;\n const useConflictClause = targetHasRows || input.dataset === \"partners\";\n\n const heartbeatTimer = setInterval(() => {\n const elapsedMs = performance.now() - startedAt;\n emitMaterializationProgress(input.onProgress, {\n datasets: input.datasets,\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n targetTable: input.targetTable,\n stepLabel: `Materializing chunk ${chunksCompleted + 1}`,\n reason: `Writing rows into ${input.targetTable} from the current staging range.`,\n completedDatasets: input.completedDatasets,\n completedFiles: input.completedFiles,\n totalFiles: input.totalFiles,\n processedRows: input.processedRows,\n totalRows: input.totalRows,\n committedBatches: input.committedBatches,\n totalBatches: input.totalBatches,\n elapsedMs,\n chunkSize: input.chunkSize,\n rowsMaterialized: affectedRows,\n datasetRowCount: stagingState.rowCount,\n chunksCompleted,\n estimatedChunks,\n lastStagingId: checkpoint.lastStagingId,\n });\n }, MATERIALIZATION_HEARTBEAT_INTERVAL_MS);\n\n try {\n while (true) {\n emitMaterializationProgress(input.onProgress, {\n datasets: input.datasets,\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n targetTable: input.targetTable,\n stepLabel: `Materializing chunk ${chunksCompleted + 1}`,\n reason: `Writing rows into ${input.targetTable} from the current staging range.`,\n completedDatasets: input.completedDatasets,\n completedFiles: input.completedFiles,\n totalFiles: input.totalFiles,\n processedRows: input.processedRows,\n totalRows: input.totalRows,\n committedBatches: input.committedBatches,\n totalBatches: input.totalBatches,\n chunkSize: input.chunkSize,\n rowsMaterialized: affectedRows,\n datasetRowCount: stagingState.rowCount,\n chunksCompleted,\n estimatedChunks,\n lastStagingId: checkpoint.lastStagingId,\n });\n\n const query = buildMaterializationChunkQuery({\n dataset: input.dataset,\n schemaCapabilities: input.schemaCapabilities,\n lastStagingId: checkpoint.lastStagingId,\n chunkSize: input.chunkSize,\n useConflictClause,\n });\n const chunkStartedAt = performance.now();\n const chunkFirstStagingId = checkpoint.lastStagingId + 1;\n\n let chunkResult: {\n maxStagingId: number;\n sourceRows: number;\n affectedRows: number;\n };\n\n await input.client.query(\"begin\");\n try {\n chunkResult = await executeChunkQuery(\n input.client,\n query.text,\n query.values,\n );\n\n if (chunkResult.sourceRows === 0) {\n checkpoint = {\n ...checkpoint,\n status: \"completed\",\n completedAt: new Date(),\n lastError: null,\n };\n await persistCheckpoint(input.client, checkpoint);\n await input.client.query(\"commit\");\n break;\n }\n\n checkpoint = {\n ...checkpoint,\n lastStagingId: chunkResult.maxStagingId,\n rowsMaterialized:\n checkpoint.rowsMaterialized + chunkResult.affectedRows,\n chunksCompleted: checkpoint.chunksCompleted + 1,\n lastError: null,\n lastChunkFirstStagingId: chunkFirstStagingId,\n lastChunkLastStagingId: chunkResult.maxStagingId,\n lastChunkRows: chunkResult.sourceRows,\n };\n if (shouldFlushChunkCheckpoint(checkpoint.chunksCompleted)) {\n await persistCheckpointProgress(input.client, checkpoint);\n }\n await input.client.query(\"commit\");\n } catch (error) {\n await input.client.query(\"rollback\");\n const message = error instanceof Error ? error.message : String(error);\n checkpoint = {\n ...checkpoint,\n status: \"failed\",\n lastError: message,\n };\n await persistCheckpoint(input.client, checkpoint);\n throw error;\n }\n\n affectedRows = checkpoint.rowsMaterialized;\n sourceRows += chunkResult.sourceRows;\n chunksCompleted = checkpoint.chunksCompleted;\n\n if (shouldLogChunkCompletion(chunksCompleted)) {\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_chunk_completed\",\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.datasets.length,\n targetTable: input.targetTable,\n chunkNumber: chunksCompleted,\n chunkSize: input.chunkSize,\n chunkFirstStagingId,\n sourceRows: chunkResult.sourceRows,\n affectedRows: chunkResult.affectedRows,\n lastStagingId: checkpoint.lastStagingId,\n totalRowsMaterialized: affectedRows,\n durationMs: performance.now() - chunkStartedAt,\n timestamp: new Date().toISOString(),\n });\n }\n }\n } finally {\n clearInterval(heartbeatTimer);\n }\n\n return {\n affectedRows,\n sourceRows,\n chunksCompleted,\n durationMs: performance.now() - startedAt,\n };\n}\n\nexport async function materializeStagedDatasets(input: {\n client: Client;\n planId: number;\n datasets: readonly ImportDatasetType[];\n schemaCapabilities: ImportSchemaCapabilities;\n progressLogPath: string;\n datasetPerformanceTrackers: Map<ImportDatasetType, MutableDatasetPerformance>;\n expectedRowsByDataset: ReadonlyMap<ImportDatasetType, number>;\n expectedStagedRowsByDataset: ReadonlyMap<ImportDatasetType, number>;\n onProgress?: ImportProgressListener | undefined;\n completedFiles: number;\n totalFiles: number;\n processedRows: number;\n totalRows: number;\n committedBatches: number;\n totalBatches: number;\n chunkSize?: number;\n}): Promise<MaterializationSummary> {\n const materializationDatasets = resolveMaterializationDatasets(\n input.datasets,\n );\n const chunkSize = Math.max(\n 1,\n input.chunkSize ?? DEFAULT_MATERIALIZATION_CHUNK_SIZE,\n );\n\n const summary: MaterializationSummary = {\n datasets: [],\n };\n\n if (materializationDatasets.length === 0) {\n return summary;\n }\n\n input.onProgress?.({\n kind: \"materialization_start\",\n totalDatasets: materializationDatasets.length,\n datasets: [...materializationDatasets],\n completedFiles: input.completedFiles,\n totalFiles: input.totalFiles,\n processedRows: input.processedRows,\n totalRows: input.totalRows,\n committedBatches: input.committedBatches,\n totalBatches: input.totalBatches,\n });\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_started\",\n datasets: materializationDatasets,\n chunkSize,\n timestamp: new Date().toISOString(),\n });\n\n for (const [datasetIndex, dataset] of materializationDatasets.entries()) {\n const targetTable = getFinalTargetTableName(dataset);\n const datasetPosition = datasetIndex + 1;\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_dataset_started\",\n dataset,\n datasetIndex: datasetPosition,\n totalDatasets: materializationDatasets.length,\n targetTable,\n chunkSize,\n timestamp: new Date().toISOString(),\n });\n\n try {\n const expectedRows = input.expectedRowsByDataset.get(dataset);\n const expectedStagedRows = input.expectedStagedRowsByDataset.get(dataset);\n const result = await materializeDatasetByChunks({\n client: input.client,\n planId: input.planId,\n dataset,\n datasetIndex: datasetPosition,\n datasets: materializationDatasets,\n targetTable,\n chunkSize,\n ...(expectedRows === undefined ? {} : { expectedRows }),\n ...(expectedStagedRows === undefined ? {} : { expectedStagedRows }),\n schemaCapabilities: input.schemaCapabilities,\n progressLogPath: input.progressLogPath,\n onProgress: input.onProgress,\n completedFiles: input.completedFiles,\n totalFiles: input.totalFiles,\n processedRows: input.processedRows,\n totalRows: input.totalRows,\n committedBatches: input.committedBatches,\n totalBatches: input.totalBatches,\n completedDatasets: summary.datasets.length,\n });\n\n if (\n dataset === \"establishments\" &&\n input.schemaCapabilities.includeEstablishmentSecondaryCnaesTable\n ) {\n await backfillEstablishmentSecondaryCnaesFromFinal({\n client: input.client,\n progressLogPath: input.progressLogPath,\n });\n }\n\n const tracker = input.datasetPerformanceTrackers.get(dataset);\n if (tracker) {\n tracker.materializationDurationMs += result.durationMs;\n }\n\n summary.datasets.push({\n dataset,\n targetTable,\n affectedRows: result.affectedRows,\n sourceRows: result.sourceRows,\n chunksCompleted: result.chunksCompleted,\n durationMs: result.durationMs,\n });\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_dataset_completed\",\n dataset,\n datasetIndex: datasetPosition,\n totalDatasets: materializationDatasets.length,\n targetTable,\n affectedRows: result.affectedRows,\n sourceRows: result.sourceRows,\n chunksCompleted: result.chunksCompleted,\n durationMs: result.durationMs,\n timestamp: new Date().toISOString(),\n });\n } catch (error) {\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_dataset_failed\",\n dataset,\n datasetIndex: datasetPosition,\n totalDatasets: materializationDatasets.length,\n targetTable,\n error: error instanceof Error ? error.message : String(error),\n timestamp: new Date().toISOString(),\n });\n throw error;\n }\n }\n\n input.onProgress?.({\n kind: \"materialization_finish\",\n totalDatasets: materializationDatasets.length,\n completedDatasets: summary.datasets.length,\n });\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_completed\",\n datasets: summary.datasets.map((item) => ({\n dataset: item.dataset,\n targetTable: item.targetTable,\n affectedRows: item.affectedRows,\n sourceRows: item.sourceRows,\n chunksCompleted: item.chunksCompleted,\n durationMs: item.durationMs,\n })),\n timestamp: new Date().toISOString(),\n });\n\n return summary;\n}\n","import {\n companiesLayout,\n establishmentsLayout,\n partnersLayout,\n simplesLayout,\n} from \"../../dictionary/layouts/index.js\";\nimport { getConflictClause } from \"./sql.js\";\nimport type { ImportDatasetType, ImportSchemaCapabilities } from \"./types.js\";\n\nexport type MaterializationDataset =\n | \"companies\"\n | \"establishments\"\n | \"partners\"\n | \"simples_options\";\n\ntype MaterializationChunkQuery = {\n text: string;\n values: readonly unknown[];\n};\n\nconst MATERIALIZATION_COLUMNS: Record<\n MaterializationDataset,\n readonly string[]\n> = {\n companies: companiesLayout.fields.map((field) => field.columnName),\n establishments: establishmentsLayout.fields.map((field) => field.columnName),\n partners: partnersLayout.fields.map((field) => field.columnName),\n simples_options: simplesLayout.fields.map((field) => field.columnName),\n};\n\nfunction buildPartnerDedupeExpression(alias: string): string {\n return [\n `md5(`,\n ` coalesce(${alias}.cnpj_root, '') || '|' ||`,\n ` coalesce(${alias}.partner_type_code, '') || '|' ||`,\n ` coalesce(${alias}.partner_name, '') || '|' ||`,\n ` coalesce(${alias}.partner_document, '') || '|' ||`,\n ` coalesce(${alias}.partner_qualification_code, '') || '|' ||`,\n ` coalesce((${alias}.entry_date - date '2000-01-01')::text, '') || '|' ||`,\n ` coalesce(${alias}.country_code, '') || '|' ||`,\n ` coalesce(${alias}.legal_representative_document, '') || '|' ||`,\n ` coalesce(${alias}.legal_representative_name, '') || '|' ||`,\n ` coalesce(${alias}.legal_representative_qualification_code, '') || '|' ||`,\n ` coalesce(${alias}.age_group_code, '')`,\n ` )`,\n ].join(\"\\n\");\n}\n\nfunction buildEstablishmentCnpjFullExpression(alias: string): string {\n return `${alias}.cnpj_root || ${alias}.cnpj_order || ${alias}.cnpj_check_digits`;\n}\n\nfunction buildChunkInsertSql(input: {\n stagingTable: string;\n targetTable: string;\n insertColumns: readonly string[];\n selectColumns: readonly string[];\n conflictClause: string;\n lastStagingId: number;\n chunkSize: number;\n extraSelects?: readonly string[];\n}): MaterializationChunkQuery {\n const extraSelects = input.extraSelects ?? [];\n const chunkSelectList = [\n \"source.staging_id\",\n ...input.selectColumns.map((column) => `source.${column}`),\n ...extraSelects,\n ].join(\",\\n \");\n const insertSelectList = input.insertColumns.join(\", \");\n\n return {\n text: [\n \"with chunked as (\",\n ` select\\n ${chunkSelectList}`,\n ` from ${input.stagingTable} source`,\n \" where source.staging_id > $1\",\n \" order by source.staging_id asc\",\n \" limit $2\",\n \"),\",\n \"inserted as (\",\n ` insert into ${input.targetTable} (${input.insertColumns.join(\", \")})`,\n ` select ${insertSelectList}`,\n \" from chunked\",\n ...(input.conflictClause ? [input.conflictClause] : []),\n \")\",\n \"select\",\n \" coalesce(max(staging_id), $1::bigint)::bigint as max_staging_id,\",\n \" count(*)::bigint as source_rows,\",\n \" count(*)::bigint as affected_rows\",\n \"from chunked;\",\n ].join(\"\\n\"),\n values: [input.lastStagingId, input.chunkSize],\n };\n}\n\nfunction buildEstablishmentsChunkInsertSql(input: {\n insertColumns: readonly string[];\n selectColumns: readonly string[];\n conflictClause: string;\n lastStagingId: number;\n chunkSize: number;\n includeSecondaryCnaesTable: boolean;\n}): MaterializationChunkQuery {\n const chunkSelectList = [\n \"source.staging_id\",\n ...input.selectColumns.map((column) => `source.${column}`),\n `${buildEstablishmentCnpjFullExpression(\"source\")} as cnpj_full`,\n ].join(\",\\n \");\n const insertSelectList = input.insertColumns.join(\", \");\n const secondaryCnaesCtes = input.includeSecondaryCnaesTable\n ? [\n \",\",\n \"deleted_secondary_cnaes as (\",\n \" delete from establishment_secondary_cnaes target\",\n \" using (select distinct cnpj_full from inserted_establishments) source_keys\",\n \" where target.cnpj_full = source_keys.cnpj_full\",\n \" returning 1\",\n \"),\",\n \"secondary_cnaes_source as (\",\n \" select distinct\",\n \" chunked.cnpj_full,\",\n \" btrim(cnae_code) as cnae_code\",\n \" from chunked\",\n \" inner join inserted_establishments inserted\",\n \" on inserted.cnpj_full = chunked.cnpj_full\",\n \" cross join lateral unnest(string_to_array(chunked.secondary_cnaes_raw, ',')) as cnae_code\",\n \" where chunked.secondary_cnaes_raw is not null\",\n \" and chunked.secondary_cnaes_raw <> ''\",\n \" and btrim(cnae_code) <> ''\",\n \"),\",\n \"inserted_secondary_cnaes as (\",\n \" insert into establishment_secondary_cnaes (cnpj_full, cnae_code)\",\n \" select cnpj_full, cnae_code\",\n \" from secondary_cnaes_source\",\n \" on conflict (cnpj_full, cnae_code) do nothing\",\n \" returning 1\",\n \")\",\n ]\n : [];\n\n return {\n text: [\n \"with chunked as (\",\n ` select\\n ${chunkSelectList}`,\n \" from staging_establishments source\",\n \" where source.staging_id > $1\",\n \" order by source.staging_id asc\",\n \" limit $2\",\n \"),\",\n \"inserted_establishments as (\",\n ` insert into establishments (${input.insertColumns.join(\", \")})`,\n ` select ${insertSelectList}`,\n \" from chunked\",\n ...(input.conflictClause ? [input.conflictClause] : []),\n \" returning cnpj_full\",\n \")\",\n ...secondaryCnaesCtes,\n \"select\",\n \" coalesce(max(staging_id), $1::bigint)::bigint as max_staging_id,\",\n \" count(*)::bigint as source_rows,\",\n \" count(*)::bigint as affected_rows\",\n \"from chunked;\",\n ].join(\"\\n\"),\n values: [input.lastStagingId, input.chunkSize],\n };\n}\n\nfunction buildPartnersChunkInsertSql(input: {\n insertColumns: readonly string[];\n lastStagingId: number;\n chunkSize: number;\n includePartnerDedupeKeyInInsert: boolean;\n schemaCapabilities: ImportSchemaCapabilities;\n}): MaterializationChunkQuery {\n const baseColumns = MATERIALIZATION_COLUMNS.partners;\n const chunkSelectList = [\n \"source.staging_id\",\n ...baseColumns.map((column) => `source.${column}`),\n ...(input.includePartnerDedupeKeyInInsert\n ? [`${buildPartnerDedupeExpression(\"source\")} as partner_dedupe_key`]\n : []),\n ].join(\",\\n \");\n const insertSelectList = input.insertColumns.join(\", \");\n const conflictClause = getConflictClause(\n \"partners\",\n [...input.insertColumns],\n input.schemaCapabilities,\n );\n\n return {\n text: [\n \"with chunked as (\",\n ` select\\n ${chunkSelectList}`,\n \" from staging_partners source\",\n \" where source.staging_id > $1\",\n \" order by source.staging_id asc\",\n \" limit $2\",\n \"),\",\n \"deduped as (\",\n \" select *\",\n \" from (\",\n \" select\",\n \" chunked.*,\",\n \" row_number() over (partition by partner_dedupe_key order by staging_id asc) as dedupe_rank\",\n \" from chunked\",\n \" ) ranked\",\n \" where dedupe_rank = 1\",\n \"),\",\n \"inserted as (\",\n ` insert into partners (${input.insertColumns.join(\", \")})`,\n ` select ${insertSelectList}`,\n \" from deduped\",\n conflictClause,\n \")\",\n \"select\",\n \" coalesce((select max(staging_id) from chunked), $1::bigint)::bigint as max_staging_id,\",\n \" coalesce((select count(*) from chunked), 0)::bigint as source_rows,\",\n \" coalesce((select count(*) from deduped), 0)::bigint as affected_rows;\",\n ].join(\"\\n\"),\n values: [input.lastStagingId, input.chunkSize],\n };\n}\n\nexport function buildMaterializationChunkQuery(input: {\n dataset: MaterializationDataset;\n schemaCapabilities: ImportSchemaCapabilities;\n lastStagingId: number;\n chunkSize: number;\n useConflictClause?: boolean;\n}): MaterializationChunkQuery {\n const baseColumns = MATERIALIZATION_COLUMNS[input.dataset];\n const useConflictClause = input.useConflictClause ?? true;\n\n switch (input.dataset) {\n case \"partners\": {\n const insertColumns = input.schemaCapabilities\n .includePartnerDedupeKeyInInsert\n ? [...baseColumns, \"partner_dedupe_key\"]\n : [...baseColumns];\n return buildPartnersChunkInsertSql({\n insertColumns,\n lastStagingId: input.lastStagingId,\n chunkSize: input.chunkSize,\n includePartnerDedupeKeyInInsert:\n input.schemaCapabilities.includePartnerDedupeKeyInInsert,\n schemaCapabilities: input.schemaCapabilities,\n });\n }\n case \"companies\":\n return buildChunkInsertSql({\n stagingTable: \"staging_companies\",\n targetTable: \"companies\",\n insertColumns: baseColumns,\n selectColumns: baseColumns,\n conflictClause: useConflictClause\n ? getConflictClause(\n \"companies\",\n [...baseColumns],\n input.schemaCapabilities,\n )\n : \"\",\n lastStagingId: input.lastStagingId,\n chunkSize: input.chunkSize,\n });\n case \"establishments\": {\n const insertColumns = input.schemaCapabilities\n .includeEstablishmentCnpjFullInInsert\n ? [...baseColumns, \"cnpj_full\"]\n : [...baseColumns];\n return buildEstablishmentsChunkInsertSql({\n insertColumns,\n selectColumns: baseColumns,\n conflictClause: useConflictClause\n ? getConflictClause(\n \"establishments\",\n [...insertColumns],\n input.schemaCapabilities,\n )\n : \"\",\n lastStagingId: input.lastStagingId,\n chunkSize: input.chunkSize,\n includeSecondaryCnaesTable:\n input.schemaCapabilities.includeEstablishmentSecondaryCnaesTable,\n });\n }\n case \"simples_options\":\n return buildChunkInsertSql({\n stagingTable: \"staging_simples_options\",\n targetTable: \"simples_options\",\n insertColumns: baseColumns,\n selectColumns: baseColumns,\n conflictClause: useConflictClause\n ? getConflictClause(\n \"simples_options\",\n [...baseColumns],\n input.schemaCapabilities,\n )\n : \"\",\n lastStagingId: input.lastStagingId,\n chunkSize: input.chunkSize,\n });\n }\n}\n\nexport function isMaterializationDataset(\n dataset: ImportDatasetType,\n): dataset is MaterializationDataset {\n return [\n \"companies\",\n \"establishments\",\n \"partners\",\n \"simples_options\",\n ].includes(dataset);\n}\n","import { performance } from \"node:perf_hooks\";\n\nimport type { Client } from \"pg\";\n\nimport { LOOKUP_PLACEHOLDER_LABEL, type LookupTableName } from \"./types.js\";\nimport type { MaterializationDataset } from \"./materialization-sql.js\";\n\ntype LookupReconciliationSource = {\n lookupTable: LookupTableName;\n sourceSql: string;\n};\n\ntype LookupReconciliationResult = {\n lookupTable: LookupTableName;\n insertedCodes: number;\n};\n\nexport type MaterializationLookupReconciliationSummary = {\n dataset: MaterializationDataset;\n results: LookupReconciliationResult[];\n totalInsertedCodes: number;\n durationMs: number;\n};\n\ntype CountRow = {\n inserted_count: string;\n};\n\nconst COMPANIES_LOOKUP_SOURCES: readonly LookupReconciliationSource[] = [\n {\n lookupTable: \"legal_natures\",\n sourceSql:\n \"select source.legal_nature_code as code from staging_companies source\",\n },\n {\n lookupTable: \"partner_qualifications\",\n sourceSql:\n \"select source.responsible_qualification_code as code from staging_companies source\",\n },\n {\n lookupTable: \"company_sizes\",\n sourceSql:\n \"select source.company_size_code as code from staging_companies source\",\n },\n];\n\nconst ESTABLISHMENTS_LOOKUP_SOURCES: readonly LookupReconciliationSource[] = [\n {\n lookupTable: \"branch_types\",\n sourceSql:\n \"select source.branch_type_code as code from staging_establishments source\",\n },\n {\n lookupTable: \"registration_statuses\",\n sourceSql:\n \"select source.registration_status_code as code from staging_establishments source\",\n },\n {\n lookupTable: \"reasons\",\n sourceSql:\n \"select source.registration_status_reason_code as code from staging_establishments source\",\n },\n {\n lookupTable: \"countries\",\n sourceSql:\n \"select source.country_code as code from staging_establishments source\",\n },\n {\n lookupTable: \"cnaes\",\n sourceSql:\n \"select source.main_cnae_code as code from staging_establishments source\",\n },\n {\n lookupTable: \"cities\",\n sourceSql:\n \"select source.city_code as code from staging_establishments source\",\n },\n];\n\nconst PARTNERS_LOOKUP_SOURCES: readonly LookupReconciliationSource[] = [\n {\n lookupTable: \"partner_types\",\n sourceSql:\n \"select source.partner_type_code as code from staging_partners source\",\n },\n {\n lookupTable: \"partner_qualifications\",\n sourceSql:\n \"select source.partner_qualification_code as code from staging_partners source\",\n },\n {\n lookupTable: \"countries\",\n sourceSql:\n \"select source.country_code as code from staging_partners source\",\n },\n {\n lookupTable: \"partner_qualifications\",\n sourceSql:\n \"select source.legal_representative_qualification_code as code from staging_partners source\",\n },\n {\n lookupTable: \"age_groups\",\n sourceSql:\n \"select source.age_group_code as code from staging_partners source\",\n },\n];\n\nconst LOOKUP_SOURCES_BY_DATASET: Readonly<\n Record<MaterializationDataset, readonly LookupReconciliationSource[]>\n> = {\n companies: COMPANIES_LOOKUP_SOURCES,\n establishments: ESTABLISHMENTS_LOOKUP_SOURCES,\n partners: PARTNERS_LOOKUP_SOURCES,\n simples_options: [],\n};\n\nexport function getLookupReconciliationSources(\n dataset: MaterializationDataset,\n): readonly LookupTableName[] {\n return LOOKUP_SOURCES_BY_DATASET[dataset].map((source) => source.lookupTable);\n}\n\nasync function ensureLookupCodesFromSource(input: {\n client: Client;\n lookupTable: LookupTableName;\n sourceSql: string;\n}): Promise<number> {\n const result = await input.client.query<CountRow>(\n [\n \"with distinct_codes as (\",\n \" select distinct trim(source_codes.code) as code\",\n ` from (${input.sourceSql}) source_codes`,\n \" where trim(source_codes.code) <> ''\",\n \"),\",\n \"missing_codes as (\",\n \" select distinct distinct_codes.code\",\n \" from distinct_codes\",\n ` left join ${input.lookupTable} lookup_table on lookup_table.code = distinct_codes.code`,\n \" where lookup_table.code is null\",\n \"),\",\n \"inserted as (\",\n ` insert into ${input.lookupTable} (code, description)`,\n \" select\",\n \" missing_codes.code,\",\n \" $1 || ' (' || missing_codes.code || ')'\",\n \" from missing_codes\",\n \" on conflict (code) do nothing\",\n \" returning code\",\n \")\",\n \"select count(*)::bigint as inserted_count from inserted;\",\n ].join(\"\\n\"),\n [LOOKUP_PLACEHOLDER_LABEL[input.lookupTable]],\n );\n\n return Number.parseInt(result.rows[0]?.inserted_count ?? \"0\", 10);\n}\n\nexport async function reconcileMaterializationLookups(input: {\n client: Client;\n dataset: MaterializationDataset;\n onLookupStart?:\n | ((lookupTable: LookupTableName, index: number, total: number) => void)\n | undefined;\n}): Promise<MaterializationLookupReconciliationSummary> {\n const startedAt = performance.now();\n const sources = LOOKUP_SOURCES_BY_DATASET[input.dataset];\n const aggregate = new Map<LookupTableName, number>();\n\n for (const [index, source] of sources.entries()) {\n input.onLookupStart?.(source.lookupTable, index + 1, sources.length);\n\n const insertedCodes = await ensureLookupCodesFromSource({\n client: input.client,\n lookupTable: source.lookupTable,\n sourceSql: source.sourceSql,\n });\n\n aggregate.set(\n source.lookupTable,\n (aggregate.get(source.lookupTable) ?? 0) + insertedCodes,\n );\n }\n\n const results = [...aggregate.entries()].map(\n ([lookupTable, insertedCodes]) => ({\n lookupTable,\n insertedCodes,\n }),\n );\n\n return {\n dataset: input.dataset,\n results,\n totalInsertedCodes: results.reduce(\n (sum, item) => sum + item.insertedCodes,\n 0,\n ),\n durationMs: performance.now() - startedAt,\n };\n}\n","import path from \"node:path\";\n\nimport type { Client } from \"pg\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport type { FileInspection, InspectSummary } from \"../inspect.service.js\";\nimport { appendJsonLinesLog } from \"../logging.service.js\";\nimport {\n ensureImportPlanTables,\n readSavedImportPlan,\n saveImportPlan,\n} from \"./plan-store.js\";\nimport {\n buildImportPlan,\n buildImportPlanFingerprint,\n collectImportSourceFiles,\n} from \"./planning.js\";\nimport {\n IMPORT_ORDER,\n isImportDatasetType,\n type ImportDatasetPlan,\n type ImportDatasetType,\n type ImportProgressListener,\n} from \"./types.js\";\n\nexport type ImportDatasetEntry = {\n dataset: ImportDatasetType;\n files: FileInspection[];\n};\n\nexport type PreparedImportPlan = {\n planId: number | null;\n planReused: boolean;\n plan: {\n datasets: ImportDatasetPlan[];\n totalFiles: number;\n totalRows: number;\n totalBatches: number;\n };\n scanDurationMs: number;\n datasetScanDurationsMs: Partial<Record<ImportDatasetType, number>>;\n sourceFingerprint: string;\n};\n\nexport function resolveRequestedDatasets(\n requestedDataset: string | undefined,\n): ImportDatasetType[] {\n if (!requestedDataset) {\n return IMPORT_ORDER;\n }\n\n if (!isImportDatasetType(requestedDataset)) {\n throw new ValidationError(`Unsupported dataset type: ${requestedDataset}.`);\n }\n\n return IMPORT_ORDER.filter((dataset) => dataset === requestedDataset);\n}\n\nexport function collectDatasetEntriesForImport(\n inspection: InspectSummary,\n selectedDatasets: ImportDatasetType[],\n): ImportDatasetEntry[] {\n return selectedDatasets\n .map((dataset) => ({\n dataset,\n files: inspection.entries.filter(\n (entry) => entry.entryKind === \"file\" && entry.inferredType === dataset,\n ),\n }))\n .filter((entry) => entry.files.length > 0);\n}\n\nexport async function prepareImportPlan(input: {\n client: Client;\n inputPath: string;\n validatedPath: string;\n batchSize: number;\n datasetEntries: ImportDatasetEntry[];\n targetDatabase: string;\n progressLogPath: string;\n onProgress?: ImportProgressListener;\n}): Promise<PreparedImportPlan> {\n const {\n client,\n inputPath,\n validatedPath,\n batchSize,\n datasetEntries,\n targetDatabase,\n progressLogPath,\n onProgress,\n } = input;\n\n if (datasetEntries.length === 0) {\n throw new ValidationError(\n \"No validated dataset files were found for the requested import.\",\n );\n }\n\n await ensureImportPlanTables(client);\n\n const sourceFiles = await collectImportSourceFiles(\n validatedPath,\n datasetEntries,\n );\n const sourceFingerprint = buildImportPlanFingerprint(\n validatedPath,\n batchSize,\n sourceFiles,\n );\n const savedPlan = await readSavedImportPlan(client, sourceFingerprint);\n\n if (savedPlan) {\n const plan = {\n datasets: savedPlan.datasets,\n totalFiles: savedPlan.plan.totalFiles,\n totalRows: savedPlan.plan.totalRows,\n totalBatches: savedPlan.plan.totalBatches,\n };\n\n onProgress?.({\n kind: \"plan_ready\",\n totalDatasets: plan.datasets.length,\n totalFiles: plan.totalFiles,\n batchSize,\n loadBatchSize: batchSize,\n totalRows: plan.totalRows,\n totalBatches: plan.totalBatches,\n targetDatabase,\n executionOrder: plan.datasets.map((item) => item.dataset),\n reused: true,\n planId: savedPlan.plan.id,\n });\n\n await appendJsonLinesLog(progressLogPath, {\n kind: \"import_plan_reused\",\n planId: savedPlan.plan.id,\n sourceFingerprint,\n inputPath: path.resolve(inputPath),\n validatedPath,\n targetDatabase,\n totalDatasets: plan.datasets.length,\n totalFiles: plan.totalFiles,\n totalRows: plan.totalRows,\n totalBatches: plan.totalBatches,\n batchSize,\n executionOrder: plan.datasets.map((item) => item.dataset),\n scanDurationMs: 0,\n timestamp: new Date().toISOString(),\n });\n\n return {\n planId: savedPlan.plan.id,\n planReused: true,\n plan,\n scanDurationMs: 0,\n datasetScanDurationsMs: {},\n sourceFingerprint,\n };\n }\n\n const builtPlan = await buildImportPlan(\n inputPath,\n validatedPath,\n sourceFiles,\n batchSize,\n onProgress,\n targetDatabase,\n );\n const plan = {\n datasets: builtPlan.datasets,\n totalFiles: builtPlan.totalFiles,\n totalRows: builtPlan.totalRows,\n totalBatches: builtPlan.totalBatches,\n };\n const persistedPlan = await saveImportPlan(client, {\n sourceFingerprint,\n inputPath: path.resolve(inputPath),\n validatedPath,\n batchSize,\n targetDatabase,\n datasets: plan.datasets,\n totalFiles: plan.totalFiles,\n totalRows: plan.totalRows,\n totalBatches: plan.totalBatches,\n });\n\n onProgress?.({\n kind: \"plan_ready\",\n totalDatasets: plan.datasets.length,\n totalFiles: plan.totalFiles,\n batchSize,\n loadBatchSize: batchSize,\n totalRows: plan.totalRows,\n totalBatches: plan.totalBatches,\n targetDatabase,\n executionOrder: plan.datasets.map((item) => item.dataset),\n reused: false,\n planId: persistedPlan.id,\n });\n\n await appendJsonLinesLog(progressLogPath, {\n kind: \"import_plan_ready\",\n planId: persistedPlan.id,\n sourceFingerprint,\n inputPath: path.resolve(inputPath),\n validatedPath,\n targetDatabase,\n totalDatasets: plan.datasets.length,\n totalFiles: plan.totalFiles,\n totalRows: plan.totalRows,\n totalBatches: plan.totalBatches,\n batchSize,\n executionOrder: plan.datasets.map((item) => item.dataset),\n scanDurationMs: builtPlan.scanDurationMs,\n datasetScanDurationsMs: builtPlan.datasetScanDurationsMs,\n timestamp: new Date().toISOString(),\n });\n\n return {\n planId: persistedPlan.id,\n planReused: false,\n plan,\n scanDurationMs: builtPlan.scanDurationMs,\n datasetScanDurationsMs: builtPlan.datasetScanDurationsMs,\n sourceFingerprint,\n };\n}\n","import { Client } from \"pg\";\n\nimport type { ImportSchemaCapabilities } from \"./types.js\";\n\ntype ColumnCapabilityRow = {\n table_name: string;\n column_name: string;\n is_generated: string;\n};\n\ntype LookupConstraintRow = {\n requires_lookup_reconciliation: boolean;\n};\n\nfunction canInsertIntoColumn(\n rows: readonly ColumnCapabilityRow[],\n tableName: string,\n columnName: string,\n): boolean {\n const row = rows.find(\n (item) => item.table_name === tableName && item.column_name === columnName,\n );\n\n if (!row) {\n return false;\n }\n\n return row.is_generated.toUpperCase() !== \"ALWAYS\";\n}\n\nfunction hasRequiredColumns(\n rows: readonly ColumnCapabilityRow[],\n tableName: string,\n columnNames: readonly string[],\n): boolean {\n const availableColumns = new Set(\n rows\n .filter((item) => item.table_name === tableName)\n .map((item) => item.column_name),\n );\n\n return columnNames.every((columnName) => availableColumns.has(columnName));\n}\n\nexport async function detectImportSchemaCapabilities(\n client: Client,\n): Promise<ImportSchemaCapabilities> {\n const [columnResult, lookupConstraintResult] = await Promise.all([\n client.query<ColumnCapabilityRow>(\n `select table_name, column_name, is_generated\n from information_schema.columns\n where table_schema = current_schema()\n and (\n (table_name = 'establishments' and column_name = 'cnpj_full') or\n (table_name = 'establishment_secondary_cnaes' and column_name in ('cnpj_full', 'cnae_code')) or\n (table_name = 'partners' and column_name = 'partner_dedupe_key')\n )`,\n ),\n client.query<LookupConstraintRow>(\n `select exists (\n select 1\n from pg_constraint constraint_item\n inner join pg_class source_table on source_table.oid = constraint_item.conrelid\n inner join pg_namespace source_namespace on source_namespace.oid = source_table.relnamespace\n inner join pg_class target_table on target_table.oid = constraint_item.confrelid\n where constraint_item.contype = 'f'\n and source_namespace.nspname = current_schema()\n and source_table.relname in ('companies', 'establishments', 'partners', 'establishment_secondary_cnaes')\n and target_table.relname in (\n 'countries',\n 'cities',\n 'partner_qualifications',\n 'legal_natures',\n 'cnaes',\n 'reasons',\n 'company_sizes',\n 'branch_types',\n 'registration_statuses',\n 'partner_types',\n 'age_groups'\n )\n ) as requires_lookup_reconciliation`,\n ),\n ]);\n\n return {\n includeEstablishmentCnpjFullInInsert: canInsertIntoColumn(\n columnResult.rows,\n \"establishments\",\n \"cnpj_full\",\n ),\n includeEstablishmentSecondaryCnaesTable: hasRequiredColumns(\n columnResult.rows,\n \"establishment_secondary_cnaes\",\n [\"cnpj_full\", \"cnae_code\"],\n ),\n includePartnerDedupeKeyInInsert: canInsertIntoColumn(\n columnResult.rows,\n \"partners\",\n \"partner_dedupe_key\",\n ),\n requiresLookupReconciliation:\n lookupConstraintResult.rows[0]?.requires_lookup_reconciliation ?? false,\n };\n}\n","import { ValidationError } from \"../core/errors/index.js\";\nimport { resolveDatabaseUrl } from \"./database.service.js\";\nimport { inspectFiles } from \"./inspect.service.js\";\nimport { validateInputDirectory } from \"./validate.service.js\";\nimport {\n runImportLoadPipeline,\n runImportMaterializationPipeline,\n runImportPipeline,\n} from \"./import/runner.js\";\nimport {\n maskDatabaseLabel,\n isImportDatasetType,\n type ImportOptions,\n type ImportSummary,\n} from \"./import/types.js\";\n\nexport type {\n ImportCheckpointRecord,\n ImportCheckpointStatus,\n ImportDatasetPlan,\n ImportDatasetType,\n ImportFilePlan,\n ImportOptions,\n ImportPerformanceSummary,\n ImportPlanRecord,\n ImportPhaseStatus,\n ImportProgressEvent,\n ImportProgressListener,\n ImportSchemaCapabilities,\n ImportSummary,\n} from \"./import/types.js\";\n\nfunction validateRequestedDataset(dataset: string | undefined): void {\n if (dataset && !isImportDatasetType(dataset)) {\n throw new ValidationError(`Unsupported dataset type: ${dataset}.`);\n }\n}\n\nasync function prepareImportInput(\n inputPath: string,\n options: ImportOptions,\n): Promise<{\n inputPath: string;\n validatedPath: string;\n inspection: Awaited<ReturnType<typeof inspectFiles>>;\n dbUrl: string;\n targetDatabase: string;\n options: ImportOptions;\n}> {\n validateRequestedDataset(options.dataset);\n\n const validation = await validateInputDirectory(inputPath);\n if (!validation.ok) {\n throw new ValidationError(\n `The input directory is not ready for import. ${validation.errors.join(\" \")}`,\n );\n }\n\n const inspection = await inspectFiles(validation.validatedPath);\n const dbUrl = await resolveDatabaseUrl(options.dbUrl);\n\n return {\n inputPath,\n validatedPath: validation.validatedPath,\n inspection,\n dbUrl,\n options,\n targetDatabase: maskDatabaseLabel(dbUrl),\n };\n}\n\nexport async function importDataToDatabase(\n inputPath: string,\n options: ImportOptions = {},\n): Promise<ImportSummary> {\n const prepared = await prepareImportInput(inputPath, options);\n return runImportPipeline(prepared);\n}\n\nexport async function loadImportDataToStaging(\n inputPath: string,\n options: ImportOptions = {},\n): Promise<ImportSummary> {\n const prepared = await prepareImportInput(inputPath, options);\n return runImportLoadPipeline(prepared);\n}\n\nexport async function materializeImportedData(\n inputPath: string,\n options: ImportOptions = {},\n): Promise<ImportSummary> {\n const prepared = await prepareImportInput(inputPath, options);\n return runImportMaterializationPipeline(prepared);\n}\n","import { Client } from \"pg\";\n\nimport { ServiceError, ValidationError } from \"../core/errors/index.js\";\nimport { resolveDatabaseUrl } from \"./database.service.js\";\nimport { ensureQuarantineTable } from \"./import/quarantine.js\";\nimport {\n readQuarantineList,\n readQuarantineRecordById,\n readQuarantineStats,\n} from \"./quarantine/queries.js\";\nimport type {\n QuarantineListFilters,\n QuarantineListSummary,\n QuarantineRecord,\n QuarantineStatsFilters,\n QuarantineStatsSummary,\n} from \"./quarantine/types.js\";\n\nasync function withQuarantineClient<T>(\n dbUrl: string | undefined,\n action: (client: Client) => Promise<T>,\n): Promise<T> {\n const url = await resolveDatabaseUrl(dbUrl);\n const client = new Client({ connectionString: url });\n\n try {\n await client.connect();\n await ensureQuarantineTable(client);\n return await action(client);\n } catch (error) {\n if (error instanceof ValidationError) {\n throw error;\n }\n\n throw new ServiceError(\n \"The quarantine command failed while querying PostgreSQL.\",\n error,\n );\n } finally {\n await client.end().catch(() => undefined);\n }\n}\n\nexport async function getQuarantineStats(\n filters: QuarantineStatsFilters & { dbUrl?: string },\n): Promise<QuarantineStatsSummary> {\n return withQuarantineClient(filters.dbUrl, async (client) =>\n readQuarantineStats(client, filters),\n );\n}\n\nexport async function listQuarantineRows(\n filters: QuarantineListFilters & { dbUrl?: string },\n): Promise<QuarantineListSummary> {\n if (!Number.isInteger(filters.limit) || filters.limit <= 0) {\n throw new ValidationError(\n 'The \"--limit\" option must be a positive integer.',\n );\n }\n\n if (\n typeof filters.afterId === \"number\" &&\n (!Number.isInteger(filters.afterId) || filters.afterId < 0)\n ) {\n throw new ValidationError(\n 'The \"--after-id\" option must be a non-negative integer.',\n );\n }\n\n return withQuarantineClient(filters.dbUrl, async (client) =>\n readQuarantineList(client, filters),\n );\n}\n\nexport async function showQuarantineRow(\n id: number,\n options?: { dbUrl?: string },\n): Promise<QuarantineRecord> {\n if (!Number.isInteger(id) || id <= 0) {\n throw new ValidationError(\n \"The quarantine row id must be a positive integer.\",\n );\n }\n\n const record = await withQuarantineClient(options?.dbUrl, async (client) =>\n readQuarantineRecordById(client, id),\n );\n\n if (!record) {\n throw new ValidationError(`No quarantine row was found with id ${id}.`);\n }\n\n return record;\n}\n\nexport type {\n QuarantineListFilters,\n QuarantineListSummary,\n QuarantineRecord,\n QuarantineStatsFilters,\n QuarantineStatsSummary,\n} from \"./quarantine/types.js\";\n","import type { Client } from \"pg\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport type {\n QuarantineListFilters,\n QuarantineListRow,\n QuarantineListSummary,\n QuarantineRecord,\n QuarantineStatsCount,\n QuarantineStatsFilters,\n QuarantineStatsSummary,\n} from \"./types.js\";\n\ntype WhereClause = {\n sql: string;\n values: unknown[];\n};\n\nfunction buildWhereClause(filters: QuarantineStatsFilters): WhereClause {\n const conditions: string[] = [];\n const values: unknown[] = [];\n\n const pushCondition = (condition: string, value: unknown): void => {\n values.push(value);\n conditions.push(condition.replace(\"$VALUE$\", `$${values.length}`));\n };\n\n if (filters.dataset) {\n pushCondition(\"dataset = $VALUE$\", filters.dataset);\n }\n\n if (filters.category) {\n pushCondition(\"coalesce(error_category, '') = $VALUE$\", filters.category);\n }\n\n if (filters.stage) {\n pushCondition(\"coalesce(error_stage, '') = $VALUE$\", filters.stage);\n }\n\n if (filters.retryable && filters.terminal) {\n throw new ValidationError(\n 'Use either \"--retryable\" or \"--terminal\", but not both together.',\n );\n }\n\n if (filters.retryable) {\n conditions.push(\"can_retry_later = true\");\n }\n\n if (filters.terminal) {\n conditions.push(\"can_retry_later = false\");\n }\n\n return {\n sql: conditions.length > 0 ? `where ${conditions.join(\" and \")}` : \"\",\n values,\n };\n}\n\nfunction mapCountRows(\n rows: Array<Record<string, unknown>>,\n keyName: string,\n): QuarantineStatsCount[] {\n return rows.map((row) => ({\n key: String(row[keyName] ?? \"unknown\"),\n count: Number(row.count ?? 0),\n }));\n}\n\nexport async function readQuarantineStats(\n client: Client,\n filters: QuarantineStatsFilters,\n): Promise<QuarantineStatsSummary> {\n const where = buildWhereClause(filters);\n\n const totalRowsResult = await client.query(\n `select\n count(*)::bigint as total_rows,\n count(*) filter (where can_retry_later = true)::bigint as retryable_rows,\n count(*) filter (where can_retry_later = false)::bigint as terminal_rows\n from import_quarantine\n ${where.sql}`,\n where.values,\n );\n\n const rowsByDatasetResult = await client.query(\n `select dataset, count(*)::bigint as count\n from import_quarantine\n ${where.sql}\n group by dataset\n order by count desc, dataset asc`,\n where.values,\n );\n\n const rowsByCategoryResult = await client.query(\n `select coalesce(error_category, 'unknown') as error_category, count(*)::bigint as count\n from import_quarantine\n ${where.sql}\n group by coalesce(error_category, 'unknown')\n order by count desc, error_category asc`,\n where.values,\n );\n\n const rowsByStageResult = await client.query(\n `select coalesce(error_stage, 'unknown') as error_stage, count(*)::bigint as count\n from import_quarantine\n ${where.sql}\n group by coalesce(error_stage, 'unknown')\n order by count desc, error_stage asc`,\n where.values,\n );\n\n const totals = totalRowsResult.rows[0] ?? {};\n\n return {\n totalRows: Number(totals.total_rows ?? 0),\n retryableRows: Number(totals.retryable_rows ?? 0),\n terminalRows: Number(totals.terminal_rows ?? 0),\n rowsByDataset: mapCountRows(rowsByDatasetResult.rows, \"dataset\"),\n rowsByCategory: mapCountRows(rowsByCategoryResult.rows, \"error_category\"),\n rowsByStage: mapCountRows(rowsByStageResult.rows, \"error_stage\"),\n appliedFilters: filters,\n };\n}\n\nexport async function readQuarantineList(\n client: Client,\n filters: QuarantineListFilters,\n): Promise<QuarantineListSummary> {\n const where = buildWhereClause(filters);\n const conditions = where.sql ? [where.sql.replace(/^where\\s+/i, \"\")] : [];\n const values = [...where.values];\n\n if (typeof filters.afterId === \"number\") {\n values.push(filters.afterId);\n conditions.push(`id > $${values.length}`);\n }\n\n values.push(filters.limit);\n\n const query = `select\n id,\n dataset,\n file_path,\n row_number,\n checkpoint_offset,\n error_code,\n error_category,\n error_stage,\n error_message,\n retry_count,\n can_retry_later,\n created_at\n from import_quarantine\n ${conditions.length > 0 ? `where ${conditions.join(\" and \")}` : \"\"}\n order by id asc\n limit $${values.length}`;\n\n const result = await client.query(query, values);\n\n return {\n rows: result.rows.map(\n (row) =>\n ({\n id: Number(row.id),\n dataset: String(row.dataset),\n filePath: String(row.file_path),\n rowNumber: row.row_number === null ? null : Number(row.row_number),\n checkpointOffset:\n row.checkpoint_offset === null\n ? null\n : Number(row.checkpoint_offset),\n errorCode: row.error_code === null ? null : String(row.error_code),\n errorCategory:\n row.error_category === null ? null : String(row.error_category),\n errorStage: row.error_stage === null ? null : String(row.error_stage),\n errorMessage: String(row.error_message),\n retryCount: Number(row.retry_count ?? 0),\n canRetryLater: Boolean(row.can_retry_later),\n createdAt: new Date(row.created_at).toISOString(),\n }) satisfies QuarantineListRow,\n ),\n appliedFilters: filters,\n };\n}\n\nexport async function readQuarantineRecordById(\n client: Client,\n id: number,\n): Promise<QuarantineRecord | null> {\n const result = await client.query(\n `select\n id,\n dataset,\n file_path,\n row_number,\n checkpoint_offset,\n error_code,\n error_category,\n error_stage,\n error_message,\n raw_line,\n parsed_payload,\n sanitizations_applied,\n retry_count,\n can_retry_later,\n created_at\n from import_quarantine\n where id = $1`,\n [id],\n );\n\n const row = result.rows[0];\n if (!row) {\n return null;\n }\n\n return {\n id: Number(row.id),\n dataset: String(row.dataset),\n filePath: String(row.file_path),\n rowNumber: row.row_number === null ? null : Number(row.row_number),\n checkpointOffset:\n row.checkpoint_offset === null ? null : Number(row.checkpoint_offset),\n errorCode: row.error_code === null ? null : String(row.error_code),\n errorCategory:\n row.error_category === null ? null : String(row.error_category),\n errorStage: row.error_stage === null ? null : String(row.error_stage),\n errorMessage: String(row.error_message),\n rawLine: String(row.raw_line),\n parsedPayload:\n row.parsed_payload && typeof row.parsed_payload === \"object\"\n ? (row.parsed_payload as Record<string, unknown>)\n : null,\n sanitizationsApplied: Array.isArray(row.sanitizations_applied)\n ? (row.sanitizations_applied as unknown[])\n : [],\n retryCount: Number(row.retry_count ?? 0),\n canRetryLater: Boolean(row.can_retry_later),\n createdAt: new Date(row.created_at).toISOString(),\n };\n}\n","import { ValidationError } from \"../../core/errors/index.js\";\nimport type {\n FederalRevenueClientOptions,\n FederalRevenueFile,\n FederalRevenueReference,\n FederalRevenueReferenceSelection,\n} from \"./types.js\";\n\nexport const DEFAULT_FEDERAL_REVENUE_SHARE_TOKEN = \"YggdBLfdninEJX9\";\nexport const DEFAULT_FEDERAL_REVENUE_WEBDAV_URL =\n \"https://arquivos.receitafederal.gov.br/public.php/webdav\";\nexport const DEFAULT_FEDERAL_REVENUE_USER_AGENT =\n \"cnpj-db-loader federal-revenue-client\";\n\nconst REFERENCE_PATTERN = /^\\d{4}-\\d{2}$/;\n\nfunction trimTrailingSlash(value: string): string {\n return value.replace(/\\/+$/g, \"\");\n}\n\nfunction normalizeBaseUrl(value?: string): string {\n return trimTrailingSlash(value ?? DEFAULT_FEDERAL_REVENUE_WEBDAV_URL);\n}\n\nfunction getShareToken(value?: string): string {\n return value ?? DEFAULT_FEDERAL_REVENUE_SHARE_TOKEN;\n}\n\nfunction encodePathSegment(value: string): string {\n return encodeURIComponent(value).replace(/%2F/gi, \"/\");\n}\n\nfunction decodeXml(value: string): string {\n return value\n .replace(/&amp;/g, \"&\")\n .replace(/&lt;/g, \"<\")\n .replace(/&gt;/g, \">\")\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\");\n}\n\nfunction decodeHrefSegment(value: string): string {\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n}\n\nfunction getAuthHeader(shareToken: string): string {\n return `Basic ${Buffer.from(`${shareToken}:`).toString(\"base64\")}`;\n}\n\nfunction buildUrl(baseUrl: string, segments: string[] = []): string {\n if (segments.length === 0) {\n return `${baseUrl}/`;\n }\n\n return `${baseUrl}/${segments.map(encodePathSegment).join(\"/\")}`;\n}\n\nfunction extractFirst(block: string, tagName: string): string | undefined {\n const pattern = new RegExp(\n `<(?:[a-zA-Z0-9_-]+:)?${tagName}\\\\b[^>]*>([\\\\s\\\\S]*?)<\\\\/(?:[a-zA-Z0-9_-]+:)?${tagName}>`,\n \"i\",\n );\n const match = block.match(pattern);\n return match?.[1] ? decodeXml(match[1].trim()) : undefined;\n}\n\nfunction isCollectionResponse(block: string): boolean {\n return /<(?:[a-zA-Z0-9_-]+:)?collection\\b/i.test(block);\n}\n\nfunction getNameFromHref(href: string): string {\n const cleanHref = href.split(\"?\")[0] ?? href;\n const withoutTrailingSlash = cleanHref.replace(/\\/+$/g, \"\");\n const rawName = withoutTrailingSlash.split(\"/\").pop() ?? withoutTrailingSlash;\n return decodeHrefSegment(rawName);\n}\n\ntype PropfindEntry = {\n href: string;\n name: string;\n isCollection: boolean;\n sizeInBytes?: number | undefined;\n lastModified?: string | undefined;\n etag?: string | undefined;\n};\n\nfunction parsePropfindXml(xml: string): PropfindEntry[] {\n const responseBlocks = xml.match(\n /<(?:[a-zA-Z0-9_-]+:)?response\\b[\\s\\S]*?<\\/(?:[a-zA-Z0-9_-]+:)?response>/gi,\n );\n\n if (!responseBlocks) {\n return [];\n }\n\n return responseBlocks\n .map<PropfindEntry | undefined>((block) => {\n const href = extractFirst(block, \"href\");\n if (!href) {\n return undefined;\n }\n\n const size = extractFirst(block, \"getcontentlength\");\n const parsedSize = size ? Number.parseInt(size, 10) : undefined;\n const lastModified = extractFirst(block, \"getlastmodified\");\n const etag = extractFirst(block, \"getetag\");\n\n return {\n href,\n name: getNameFromHref(href),\n isCollection: isCollectionResponse(block),\n ...(Number.isFinite(parsedSize) ? { sizeInBytes: parsedSize } : {}),\n ...(lastModified ? { lastModified } : {}),\n ...(etag ? { etag } : {}),\n };\n })\n .filter((entry): entry is PropfindEntry => entry !== undefined);\n}\n\nasync function propfind(\n pathSegments: string[],\n options: FederalRevenueClientOptions = {},\n): Promise<{ entries: PropfindEntry[]; baseUrl: string; shareToken: string }> {\n const baseUrl = normalizeBaseUrl(options.baseUrl);\n const shareToken = getShareToken(options.shareToken);\n let response: Response;\n\n try {\n response = await fetch(buildUrl(baseUrl, pathSegments), {\n method: \"PROPFIND\",\n headers: {\n Accept: \"application/xml,text/xml,*/*\",\n Authorization: getAuthHeader(shareToken),\n Depth: \"1\",\n \"User-Agent\": options.userAgent ?? DEFAULT_FEDERAL_REVENUE_USER_AGENT,\n },\n });\n } catch (error) {\n throw new ValidationError(\n `Federal Revenue WebDAV request failed before receiving a response: ${error instanceof Error ? error.message : String(error)}.`,\n { baseUrl, pathSegments },\n );\n }\n\n if (!response.ok) {\n throw new ValidationError(\n `Federal Revenue WebDAV request failed with status ${response.status} ${response.statusText}.`,\n { status: response.status, statusText: response.statusText },\n );\n }\n\n const xml = await response.text();\n return {\n entries: parsePropfindXml(xml),\n baseUrl,\n shareToken,\n };\n}\n\nexport function validateFederalRevenueReference(reference: string): void {\n if (!REFERENCE_PATTERN.test(reference)) {\n throw new ValidationError(\n `Federal Revenue reference is invalid: ${reference}. Expected YYYY-MM.`,\n );\n }\n}\n\nexport function getCurrentFederalRevenueReference(date = new Date()): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n return `${year}-${month}`;\n}\n\nexport async function listFederalRevenueReferences(\n options: FederalRevenueClientOptions = {},\n): Promise<{ references: FederalRevenueReference[]; remoteBaseUrl: string }> {\n const result = await propfind([], options);\n const references = result.entries\n .filter((entry) => entry.isCollection && REFERENCE_PATTERN.test(entry.name))\n .map<FederalRevenueReference>((entry) => ({\n reference: entry.name,\n href: entry.href,\n }))\n .sort((left, right) => left.reference.localeCompare(right.reference));\n\n return {\n references,\n remoteBaseUrl: result.baseUrl,\n };\n}\n\nexport async function resolveFederalRevenueReference(\n input: {\n reference?: string | undefined;\n current?: boolean | undefined;\n } & FederalRevenueClientOptions = {},\n): Promise<FederalRevenueReferenceSelection> {\n const { references } = await listFederalRevenueReferences(input);\n const availableReferences = references.map((item) => item.reference);\n const latest = availableReferences.at(-1);\n\n if (!latest) {\n throw new ValidationError(\n \"Federal Revenue reference discovery failed: no monthly references were found in the public share.\",\n );\n }\n\n if (input.reference) {\n validateFederalRevenueReference(input.reference);\n\n if (!availableReferences.includes(input.reference)) {\n throw new ValidationError(\n `Federal Revenue reference not found: ${input.reference}. Latest available reference is ${latest}.`,\n {\n requestedReference: input.reference,\n latestAvailableReference: latest,\n availableReferences,\n },\n );\n }\n\n return {\n mode: \"explicit\",\n selectedReference: input.reference,\n availableReferences,\n };\n }\n\n if (input.current) {\n const currentReference = getCurrentFederalRevenueReference();\n\n if (!availableReferences.includes(currentReference)) {\n throw new ValidationError(\n `Federal Revenue current reference is not available yet: ${currentReference}. Latest available reference is ${latest}.`,\n {\n requestedReference: currentReference,\n latestAvailableReference: latest,\n availableReferences,\n },\n );\n }\n\n return {\n mode: \"current\",\n selectedReference: currentReference,\n availableReferences,\n };\n }\n\n return {\n mode: \"latest\",\n selectedReference: latest,\n availableReferences,\n };\n}\n\nexport async function listFederalRevenueFiles(\n reference: string,\n options: FederalRevenueClientOptions = {},\n): Promise<{ files: FederalRevenueFile[]; remoteBaseUrl: string }> {\n validateFederalRevenueReference(reference);\n const result = await propfind([reference], options);\n const files = result.entries\n .filter(\n (entry) =>\n !entry.isCollection && entry.name.toLowerCase().endsWith(\".zip\"),\n )\n .map<FederalRevenueFile>((entry) => ({\n name: entry.name,\n href: entry.href,\n downloadUrl: buildUrl(result.baseUrl, [reference, entry.name]),\n ...(entry.sizeInBytes !== undefined\n ? { sizeInBytes: entry.sizeInBytes }\n : {}),\n ...(entry.lastModified ? { lastModified: entry.lastModified } : {}),\n ...(entry.etag ? { etag: entry.etag } : {}),\n }))\n .sort((left, right) => left.name.localeCompare(right.name));\n\n return {\n files,\n remoteBaseUrl: result.baseUrl,\n };\n}\n\nexport function buildFederalRevenueDownloadHeaders(\n options: FederalRevenueClientOptions = {},\n): Record<string, string> {\n return {\n Authorization: getAuthHeader(getShareToken(options.shareToken)),\n \"User-Agent\": options.userAgent ?? DEFAULT_FEDERAL_REVENUE_USER_AGENT,\n };\n}\n","import { createWriteStream } from \"node:fs\";\nimport { mkdir, rename, stat, unlink } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { Readable } from \"node:stream\";\nimport type { ReadableStream as NodeReadableStream } from \"node:stream/web\";\nimport { pipeline } from \"node:stream/promises\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport {\n buildFederalRevenueDownloadHeaders,\n listFederalRevenueFiles,\n resolveFederalRevenueReference,\n} from \"./client.js\";\nimport {\n buildFederalRevenueReferenceOutputPath,\n createFederalRevenueManifest,\n evaluateFederalRevenueManifestFiles,\n finalizeFederalRevenueManifest,\n getFederalRevenueManifestPath,\n readFederalRevenueManifest,\n updateFederalRevenueManifestFile,\n} from \"./manifest.js\";\nimport type {\n FederalRevenueCheckOptions,\n FederalRevenueCheckSummary,\n FederalRevenueDownloadEntry,\n FederalRevenueDownloadOptions,\n FederalRevenueDownloadSummary,\n FederalRevenueFile,\n FederalRevenueLocalFileStatus,\n} from \"./types.js\";\n\nconst DEFAULT_DOWNLOAD_RETRIES = 3;\n\nfunction resolveRetryCount(value: number | undefined): number {\n if (value === undefined || Number.isNaN(value)) {\n return DEFAULT_DOWNLOAD_RETRIES;\n }\n\n return Math.max(1, Math.floor(value));\n}\n\nasync function safeStat(filePath: string): Promise<{\n exists: boolean;\n size: number;\n}> {\n try {\n const fileStat = await stat(filePath);\n return {\n exists: fileStat.isFile(),\n size: fileStat.size,\n };\n } catch {\n return {\n exists: false,\n size: 0,\n };\n }\n}\n\nasync function safeUnlink(filePath: string): Promise<void> {\n try {\n await unlink(filePath);\n } catch {\n // Ignore cleanup errors. A later write attempt will surface any real issue.\n }\n}\n\nfunction isCompletedLocalFile(localSize: number, remoteSize?: number): boolean {\n if (remoteSize === undefined) {\n return localSize > 0;\n }\n\n return localSize === remoteSize;\n}\n\nfunction toLocalStatus(\n entry: FederalRevenueDownloadEntry,\n): FederalRevenueLocalFileStatus {\n if (entry.status === \"failed\") {\n return \"failed\";\n }\n\n return \"downloaded\";\n}\n\nasync function downloadSingleFile(\n file: FederalRevenueFile,\n outputPath: string,\n options: FederalRevenueDownloadOptions,\n): Promise<FederalRevenueDownloadEntry> {\n const filePath = path.join(outputPath, file.name);\n const partialFilePath = `${filePath}.part`;\n const localFile = await safeStat(filePath);\n\n if (\n !options.overwrite &&\n localFile.exists &&\n isCompletedLocalFile(localFile.size, file.sizeInBytes)\n ) {\n return {\n fileName: file.name,\n filePath,\n status: \"skipped\",\n sizeInBytes: localFile.size,\n remoteSizeInBytes: file.sizeInBytes,\n };\n }\n\n const retries = resolveRetryCount(options.retries);\n let lastError: unknown;\n\n for (let attempt = 1; attempt <= retries; attempt += 1) {\n await safeUnlink(partialFilePath);\n\n try {\n const response = await fetch(file.downloadUrl, {\n method: \"GET\",\n headers: buildFederalRevenueDownloadHeaders(options),\n });\n\n if (!response.ok) {\n throw new ValidationError(\n `Federal Revenue download failed for ${file.name}: HTTP ${response.status} ${response.statusText}.`,\n {\n fileName: file.name,\n status: response.status,\n statusText: response.statusText,\n attempt,\n },\n );\n }\n\n if (!response.body) {\n throw new ValidationError(\n `Federal Revenue download failed for ${file.name}: response body is empty.`,\n {\n fileName: file.name,\n attempt,\n },\n );\n }\n\n await pipeline(\n Readable.fromWeb(response.body as NodeReadableStream<Uint8Array>),\n createWriteStream(partialFilePath),\n );\n\n const downloadedFile = await safeStat(partialFilePath);\n if (\n file.sizeInBytes !== undefined &&\n downloadedFile.size !== file.sizeInBytes\n ) {\n throw new ValidationError(\n `Federal Revenue download failed for ${file.name}: local size does not match the remote size.`,\n {\n fileName: file.name,\n expectedSize: file.sizeInBytes,\n actualSize: downloadedFile.size,\n attempt,\n },\n );\n }\n\n await safeUnlink(filePath);\n await rename(partialFilePath, filePath);\n\n return {\n fileName: file.name,\n filePath,\n status: \"downloaded\",\n sizeInBytes: downloadedFile.size,\n remoteSizeInBytes: file.sizeInBytes,\n };\n } catch (error) {\n lastError = error;\n }\n }\n\n return {\n fileName: file.name,\n filePath,\n status: \"failed\",\n remoteSizeInBytes: file.sizeInBytes,\n errorMessage:\n lastError instanceof Error ? lastError.message : String(lastError),\n };\n}\n\nfunction shouldDownloadFile(\n file: FederalRevenueFile,\n incompleteFileNames: Set<string> | undefined,\n): boolean {\n if (!incompleteFileNames) {\n return true;\n }\n\n return incompleteFileNames.has(file.name);\n}\n\nexport async function checkFederalRevenueDataset(\n options: FederalRevenueCheckOptions = {},\n): Promise<FederalRevenueCheckSummary> {\n const selection = await resolveFederalRevenueReference(options);\n const { files, remoteBaseUrl } = await listFederalRevenueFiles(\n selection.selectedReference,\n options,\n );\n const totalBytes = files.reduce(\n (sum, file) => sum + (file.sizeInBytes ?? 0),\n 0,\n );\n\n return {\n selectedReference: selection.selectedReference,\n selectionMode: selection.mode,\n availableReferences: selection.availableReferences,\n files,\n totalFiles: files.length,\n totalBytes,\n remoteBaseUrl,\n };\n}\n\nexport async function downloadFederalRevenueDataset(\n options: FederalRevenueDownloadOptions = {},\n): Promise<FederalRevenueDownloadSummary> {\n const startedAt = new Date().toISOString();\n const check = await checkFederalRevenueDataset(options);\n const outputPath = buildFederalRevenueReferenceOutputPath(\n check.selectedReference,\n options.outputPath,\n );\n const manifestPath = getFederalRevenueManifestPath(outputPath);\n\n await mkdir(outputPath, { recursive: true });\n await createFederalRevenueManifest({\n reference: check.selectedReference,\n outputPath,\n remoteBaseUrl: check.remoteBaseUrl,\n files: check.files,\n lastCommand: options.manifestCommand ?? \"download\",\n });\n\n const manifest = await readFederalRevenueManifest(outputPath);\n const evaluatedFiles = manifest\n ? await evaluateFederalRevenueManifestFiles(manifest.files)\n : [];\n const incompleteFileNames = options.incompleteOnly\n ? new Set(\n evaluatedFiles\n .filter((entry) => entry.status !== \"downloaded\")\n .map((entry) => entry.fileName),\n )\n : undefined;\n const filesToProcess = check.files.filter((file) =>\n shouldDownloadFile(file, incompleteFileNames),\n );\n\n options.onProgress?.({\n kind: \"start\",\n reference: check.selectedReference,\n outputPath,\n totalFiles: filesToProcess.length,\n totalBytes: check.totalBytes,\n });\n\n const entries: FederalRevenueDownloadEntry[] = [];\n let downloadedBytes = 0;\n let downloadedFiles = 0;\n let skippedFiles = 0;\n let failedFiles = 0;\n\n for (const [index, file] of filesToProcess.entries()) {\n options.onProgress?.({\n kind: \"file-start\",\n reference: check.selectedReference,\n fileName: file.name,\n fileIndex: index + 1,\n totalFiles: filesToProcess.length,\n completedFiles: entries.length,\n downloadedBytes,\n totalBytes: check.totalBytes,\n fileSizeInBytes: file.sizeInBytes,\n });\n\n const entry = await downloadSingleFile(file, outputPath, options);\n entries.push(entry);\n\n await updateFederalRevenueManifestFile(outputPath, {\n fileName: entry.fileName,\n status: toLocalStatus(entry),\n localSizeInBytes: entry.sizeInBytes,\n errorMessage: entry.errorMessage,\n downloadedAt:\n entry.status === \"downloaded\" || entry.status === \"skipped\"\n ? new Date().toISOString()\n : undefined,\n });\n\n if (entry.status === \"downloaded\") {\n downloadedFiles += 1;\n downloadedBytes += entry.sizeInBytes ?? file.sizeInBytes ?? 0;\n options.onProgress?.({\n kind: \"file-complete\",\n reference: check.selectedReference,\n fileName: file.name,\n fileIndex: index + 1,\n totalFiles: filesToProcess.length,\n completedFiles: entries.length,\n downloadedBytes,\n totalBytes: check.totalBytes,\n fileSizeInBytes: file.sizeInBytes,\n });\n continue;\n }\n\n if (entry.status === \"skipped\") {\n skippedFiles += 1;\n downloadedBytes += entry.sizeInBytes ?? file.sizeInBytes ?? 0;\n options.onProgress?.({\n kind: \"file-skipped\",\n reference: check.selectedReference,\n fileName: file.name,\n fileIndex: index + 1,\n totalFiles: filesToProcess.length,\n completedFiles: entries.length,\n downloadedBytes,\n totalBytes: check.totalBytes,\n fileSizeInBytes: file.sizeInBytes,\n });\n continue;\n }\n\n failedFiles += 1;\n options.onProgress?.({\n kind: \"file-failed\",\n reference: check.selectedReference,\n fileName: file.name,\n fileIndex: index + 1,\n totalFiles: filesToProcess.length,\n completedFiles: entries.length,\n downloadedBytes,\n totalBytes: check.totalBytes,\n errorMessage: entry.errorMessage ?? \"Unknown download error\",\n fileSizeInBytes: file.sizeInBytes,\n });\n }\n\n await finalizeFederalRevenueManifest(\n outputPath,\n failedFiles > 0 ? \"failed\" : \"completed\",\n );\n\n const finalManifest = await readFederalRevenueManifest(outputPath);\n const finalFiles = finalManifest\n ? await evaluateFederalRevenueManifestFiles(finalManifest.files)\n : [];\n const partialFiles = finalFiles.filter(\n (entry) => entry.status === \"partial\",\n ).length;\n const missingFiles = finalFiles.filter(\n (entry) => entry.status === \"missing\",\n ).length;\n\n options.onProgress?.({\n kind: \"finish\",\n reference: check.selectedReference,\n outputPath,\n totalFiles: filesToProcess.length,\n downloadedFiles,\n skippedFiles,\n failedFiles,\n downloadedBytes,\n totalBytes: check.totalBytes,\n });\n\n const warnings: string[] = [];\n\n if (options.incompleteOnly && filesToProcess.length === 0) {\n warnings.push(\"No incomplete Federal Revenue files were found for retry.\");\n }\n\n if (failedFiles > 0) {\n warnings.push(\n \"Some Federal Revenue files could not be downloaded. Check the log file and use retry after fixing the cause.\",\n );\n }\n\n return {\n reference: check.selectedReference,\n selectionMode: check.selectionMode,\n outputPath,\n manifestPath,\n remoteBaseUrl: check.remoteBaseUrl,\n filesFound: check.totalFiles,\n downloadedFiles,\n skippedFiles,\n failedFiles,\n partialFiles,\n missingFiles,\n totalBytes: check.totalBytes,\n downloadedBytes,\n entries,\n startedAt,\n finishedAt: new Date().toISOString(),\n warnings,\n nextStep: `cnpj-db-loader extract ${outputPath.replace(/\\\\/g, \"/\")}`,\n };\n}\n\nexport async function retryFederalRevenueDataset(\n options: FederalRevenueDownloadOptions = {},\n): Promise<FederalRevenueDownloadSummary> {\n return downloadFederalRevenueDataset({\n ...options,\n incompleteOnly: true,\n manifestCommand: \"retry\",\n });\n}\n","import { mkdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { validateFederalRevenueReference } from \"./client.js\";\nimport type {\n FederalRevenueFile,\n FederalRevenueLocalFileStatus,\n FederalRevenueManifest,\n FederalRevenueManifestFile,\n FederalRevenueManifestLastCommand,\n} from \"./types.js\";\n\nexport const FEDERAL_REVENUE_MANIFEST_VERSION = 1;\nexport const FEDERAL_REVENUE_CONTROL_DIR = \".cnpj-db-loader\";\nexport const FEDERAL_REVENUE_CONTROL_SCOPE = \"federal-revenue\";\nexport const DEFAULT_FEDERAL_REVENUE_DOWNLOAD_ROOT = path.join(\n process.cwd(),\n \"downloads\",\n \"federal-revenue\",\n);\n\nexport function buildFederalRevenueReferenceOutputPath(\n reference: string,\n outputPath?: string,\n): string {\n validateFederalRevenueReference(reference);\n return path.resolve(\n outputPath ?? DEFAULT_FEDERAL_REVENUE_DOWNLOAD_ROOT,\n reference,\n );\n}\n\nexport function getFederalRevenueControlDirectory(outputPath: string): string {\n return path.join(\n outputPath,\n FEDERAL_REVENUE_CONTROL_DIR,\n FEDERAL_REVENUE_CONTROL_SCOPE,\n );\n}\n\nexport function getFederalRevenueManifestPath(outputPath: string): string {\n return path.join(\n getFederalRevenueControlDirectory(outputPath),\n \"manifest.json\",\n );\n}\n\nexport function getFederalRevenueSyncLockPath(outputPath: string): string {\n return path.join(getFederalRevenueControlDirectory(outputPath), \"sync.lock\");\n}\n\nasync function safeFileStat(filePath: string): Promise<{\n exists: boolean;\n size: number;\n}> {\n try {\n const fileStat = await stat(filePath);\n return {\n exists: fileStat.isFile(),\n size: fileStat.size,\n };\n } catch {\n return {\n exists: false,\n size: 0,\n };\n }\n}\n\nfunction isCompleteSize(localSize: number, remoteSize?: number): boolean {\n if (remoteSize === undefined) {\n return localSize > 0;\n }\n\n return localSize === remoteSize;\n}\n\nfunction buildManifestFile(\n file: FederalRevenueFile,\n outputPath: string,\n previous?: FederalRevenueManifestFile,\n): FederalRevenueManifestFile {\n const filePath = path.join(outputPath, file.name);\n const partialFilePath = `${filePath}.part`;\n const entry: FederalRevenueManifestFile = {\n fileName: file.name,\n filePath,\n partialFilePath,\n href: file.href,\n downloadUrl: file.downloadUrl,\n status: previous?.status ?? \"missing\",\n updatedAt: previous?.updatedAt ?? new Date().toISOString(),\n };\n\n if (file.sizeInBytes !== undefined) {\n entry.remoteSizeInBytes = file.sizeInBytes;\n }\n\n if (file.lastModified !== undefined) {\n entry.lastModified = file.lastModified;\n }\n\n if (file.etag !== undefined) {\n entry.etag = file.etag;\n }\n\n if (previous?.localSizeInBytes !== undefined) {\n entry.localSizeInBytes = previous.localSizeInBytes;\n }\n\n if (previous?.downloadedAt !== undefined) {\n entry.downloadedAt = previous.downloadedAt;\n }\n\n if (previous?.errorMessage !== undefined) {\n entry.errorMessage = previous.errorMessage;\n }\n\n return entry;\n}\n\nexport async function readFederalRevenueManifest(\n outputPath: string,\n): Promise<FederalRevenueManifest | undefined> {\n try {\n const manifestContent = await readFile(\n getFederalRevenueManifestPath(outputPath),\n \"utf8\",\n );\n return JSON.parse(manifestContent) as FederalRevenueManifest;\n } catch {\n return undefined;\n }\n}\n\nexport async function writeFederalRevenueManifest(\n manifest: FederalRevenueManifest,\n): Promise<void> {\n await mkdir(getFederalRevenueControlDirectory(manifest.outputPath), {\n recursive: true,\n });\n await writeFile(\n getFederalRevenueManifestPath(manifest.outputPath),\n `${JSON.stringify(manifest, null, 2)}\\n`,\n \"utf8\",\n );\n}\n\nexport async function createFederalRevenueManifest(input: {\n reference: string;\n outputPath: string;\n remoteBaseUrl: string;\n files: FederalRevenueFile[];\n lastCommand: FederalRevenueManifestLastCommand;\n}): Promise<FederalRevenueManifest> {\n const existingManifest = await readFederalRevenueManifest(input.outputPath);\n const previousByName = new Map(\n existingManifest?.files.map((file) => [file.fileName, file]) ?? [],\n );\n const now = new Date().toISOString();\n\n const manifest: FederalRevenueManifest = {\n version: FEDERAL_REVENUE_MANIFEST_VERSION,\n reference: input.reference,\n remoteBaseUrl: input.remoteBaseUrl,\n outputPath: input.outputPath,\n createdAt: existingManifest?.createdAt ?? now,\n updatedAt: now,\n lastCommand: input.lastCommand,\n lastStatus: \"running\",\n files: input.files.map((file) =>\n buildManifestFile(file, input.outputPath, previousByName.get(file.name)),\n ),\n };\n\n await writeFederalRevenueManifest(manifest);\n return manifest;\n}\n\nexport async function evaluateFederalRevenueManifestFile(\n entry: FederalRevenueManifestFile,\n): Promise<FederalRevenueManifestFile> {\n const localFile = await safeFileStat(entry.filePath);\n const partialFile = await safeFileStat(entry.partialFilePath);\n const nextEntry: FederalRevenueManifestFile = {\n ...entry,\n updatedAt: new Date().toISOString(),\n };\n\n delete nextEntry.localSizeInBytes;\n\n if (\n localFile.exists &&\n isCompleteSize(localFile.size, entry.remoteSizeInBytes)\n ) {\n nextEntry.status = \"downloaded\";\n nextEntry.localSizeInBytes = localFile.size;\n delete nextEntry.errorMessage;\n return nextEntry;\n }\n\n if (partialFile.exists) {\n nextEntry.status = \"partial\";\n nextEntry.localSizeInBytes = partialFile.size;\n return nextEntry;\n }\n\n if (localFile.exists) {\n nextEntry.status = \"partial\";\n nextEntry.localSizeInBytes = localFile.size;\n nextEntry.errorMessage = `Local file size does not match the remote size. Expected ${entry.remoteSizeInBytes ?? \"unknown\"} byte(s), found ${localFile.size} byte(s).`;\n return nextEntry;\n }\n\n if (entry.status === \"failed\") {\n return nextEntry;\n }\n\n nextEntry.status = \"missing\";\n return nextEntry;\n}\n\nexport async function evaluateFederalRevenueManifestFiles(\n entries: FederalRevenueManifestFile[],\n): Promise<FederalRevenueManifestFile[]> {\n const evaluated: FederalRevenueManifestFile[] = [];\n\n for (const entry of entries) {\n evaluated.push(await evaluateFederalRevenueManifestFile(entry));\n }\n\n return evaluated;\n}\n\nexport async function updateFederalRevenueManifestFile(\n outputPath: string,\n input: {\n fileName: string;\n status: FederalRevenueLocalFileStatus;\n localSizeInBytes?: number | undefined;\n errorMessage?: string | undefined;\n downloadedAt?: string | undefined;\n },\n): Promise<void> {\n const manifest = await readFederalRevenueManifest(outputPath);\n if (!manifest) {\n return;\n }\n\n const updatedAt = new Date().toISOString();\n manifest.updatedAt = updatedAt;\n manifest.files = manifest.files.map((file) => {\n if (file.fileName !== input.fileName) {\n return file;\n }\n\n const updatedFile: FederalRevenueManifestFile = {\n ...file,\n status: input.status,\n updatedAt,\n };\n\n delete updatedFile.errorMessage;\n delete updatedFile.localSizeInBytes;\n delete updatedFile.downloadedAt;\n\n if (input.localSizeInBytes !== undefined) {\n updatedFile.localSizeInBytes = input.localSizeInBytes;\n }\n\n if (input.errorMessage !== undefined) {\n updatedFile.errorMessage = input.errorMessage;\n }\n\n if (input.downloadedAt !== undefined) {\n updatedFile.downloadedAt = input.downloadedAt;\n }\n\n return updatedFile;\n });\n\n await writeFederalRevenueManifest(manifest);\n}\n\nexport async function finalizeFederalRevenueManifest(\n outputPath: string,\n lastStatus: FederalRevenueManifest[\"lastStatus\"],\n): Promise<void> {\n const manifest = await readFederalRevenueManifest(outputPath);\n if (!manifest) {\n return;\n }\n\n manifest.updatedAt = new Date().toISOString();\n manifest.lastStatus = lastStatus;\n manifest.files = await evaluateFederalRevenueManifestFiles(manifest.files);\n await writeFederalRevenueManifest(manifest);\n}\n","import { ValidationError } from \"../../core/errors/index.js\";\nimport {\n getCurrentFederalRevenueReference,\n resolveFederalRevenueReference,\n validateFederalRevenueReference,\n} from \"./client.js\";\nimport {\n buildFederalRevenueReferenceOutputPath,\n evaluateFederalRevenueManifestFiles,\n getFederalRevenueManifestPath,\n readFederalRevenueManifest,\n} from \"./manifest.js\";\nimport type {\n FederalRevenueClientOptions,\n FederalRevenueLocalStatusEntry,\n FederalRevenueReferenceMode,\n FederalRevenueStatusOptions,\n FederalRevenueStatusSummary,\n} from \"./types.js\";\n\nfunction toStatusEntry(\n file: Awaited<ReturnType<typeof evaluateFederalRevenueManifestFiles>>[number],\n): FederalRevenueLocalStatusEntry {\n const entry: FederalRevenueLocalStatusEntry = {\n fileName: file.fileName,\n filePath: file.filePath,\n partialFilePath: file.partialFilePath,\n status: file.status,\n };\n\n if (file.remoteSizeInBytes !== undefined) {\n entry.remoteSizeInBytes = file.remoteSizeInBytes;\n }\n\n if (file.localSizeInBytes !== undefined) {\n entry.localSizeInBytes = file.localSizeInBytes;\n }\n\n if (file.errorMessage !== undefined) {\n entry.errorMessage = file.errorMessage;\n }\n\n return entry;\n}\n\nasync function resolveLocalReference(\n options: FederalRevenueStatusOptions,\n): Promise<{\n reference: string;\n mode: FederalRevenueReferenceMode;\n availableReferences: string[];\n}> {\n if (options.reference) {\n validateFederalRevenueReference(options.reference);\n return {\n reference: options.reference,\n mode: \"explicit\",\n availableReferences: [],\n };\n }\n\n if (options.current) {\n return {\n reference: getCurrentFederalRevenueReference(),\n mode: \"current\",\n availableReferences: [],\n };\n }\n\n const selection = await resolveFederalRevenueReference(\n options as FederalRevenueClientOptions,\n );\n\n return {\n reference: selection.selectedReference,\n mode: selection.mode,\n availableReferences: selection.availableReferences,\n };\n}\n\nexport async function getFederalRevenueStatus(\n options: FederalRevenueStatusOptions = {},\n): Promise<FederalRevenueStatusSummary> {\n const selection = await resolveLocalReference(options);\n const outputPath = buildFederalRevenueReferenceOutputPath(\n selection.reference,\n options.outputPath,\n );\n const manifestPath = getFederalRevenueManifestPath(outputPath);\n const manifest = await readFederalRevenueManifest(outputPath);\n\n if (!manifest) {\n return {\n reference: selection.reference,\n selectionMode: selection.mode,\n outputPath,\n manifestPath,\n manifestFound: false,\n filesFound: 0,\n downloadedFiles: 0,\n failedFiles: 0,\n partialFiles: 0,\n missingFiles: 0,\n totalBytes: 0,\n localBytes: 0,\n isComplete: false,\n entries: [],\n warnings: [\n \"No local Federal Revenue manifest was found for this reference. Run download or sync first.\",\n ],\n };\n }\n\n if (manifest.reference !== selection.reference) {\n throw new ValidationError(\n `Federal Revenue manifest mismatch: expected ${selection.reference}, found ${manifest.reference}.`,\n { outputPath, manifestPath },\n );\n }\n\n const evaluatedFiles = await evaluateFederalRevenueManifestFiles(\n manifest.files,\n );\n const entries = evaluatedFiles.map(toStatusEntry);\n const downloadedFiles = entries.filter(\n (entry) => entry.status === \"downloaded\",\n ).length;\n const failedFiles = entries.filter(\n (entry) => entry.status === \"failed\",\n ).length;\n const partialFiles = entries.filter(\n (entry) => entry.status === \"partial\",\n ).length;\n const missingFiles = entries.filter(\n (entry) => entry.status === \"missing\",\n ).length;\n const totalBytes = entries.reduce(\n (sum, entry) => sum + (entry.remoteSizeInBytes ?? 0),\n 0,\n );\n const localBytes = entries.reduce(\n (sum, entry) => sum + (entry.localSizeInBytes ?? 0),\n 0,\n );\n const warnings: string[] = [];\n\n if (failedFiles > 0 || partialFiles > 0 || missingFiles > 0) {\n warnings.push(\n \"The local Federal Revenue reference is not complete. Use retry to resume incomplete or failed files.\",\n );\n }\n\n return {\n reference: selection.reference,\n selectionMode: selection.mode,\n outputPath,\n manifestPath,\n manifestFound: true,\n filesFound: entries.length,\n downloadedFiles,\n failedFiles,\n partialFiles,\n missingFiles,\n totalBytes,\n localBytes,\n isComplete:\n entries.length > 0 &&\n failedFiles === 0 &&\n partialFiles === 0 &&\n missingFiles === 0,\n entries,\n warnings,\n updatedAt: manifest.updatedAt,\n lastCommand: manifest.lastCommand,\n lastStatus: manifest.lastStatus,\n };\n}\n","import { readdir, rm, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport {\n getCurrentFederalRevenueReference,\n resolveFederalRevenueReference,\n validateFederalRevenueReference,\n} from \"./client.js\";\nimport {\n buildFederalRevenueReferenceOutputPath,\n getFederalRevenueManifestPath,\n readFederalRevenueManifest,\n writeFederalRevenueManifest,\n} from \"./manifest.js\";\nimport type {\n FederalRevenueCleanMode,\n FederalRevenueCleanOptions,\n FederalRevenueCleanSummary,\n FederalRevenueClientOptions,\n FederalRevenueManifestFile,\n FederalRevenueReferenceMode,\n} from \"./types.js\";\n\nasync function safeStat(filePath: string): Promise<{\n exists: boolean;\n size: number;\n isDirectory: boolean;\n}> {\n try {\n const fileStat = await stat(filePath);\n return {\n exists: true,\n size: fileStat.size,\n isDirectory: fileStat.isDirectory(),\n };\n } catch {\n return {\n exists: false,\n size: 0,\n isDirectory: false,\n };\n }\n}\n\nasync function listPartialFiles(rootPath: string): Promise<string[]> {\n const rootStat = await safeStat(rootPath);\n if (!rootStat.exists || !rootStat.isDirectory) {\n return [];\n }\n\n const result: string[] = [];\n const entries = await readdir(rootPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const entryPath = path.join(rootPath, entry.name);\n\n if (entry.isDirectory()) {\n result.push(...(await listPartialFiles(entryPath)));\n continue;\n }\n\n if (entry.isFile() && entry.name.endsWith(\".part\")) {\n result.push(entryPath);\n }\n }\n\n return result;\n}\n\nasync function removeFileIfExists(filePath: string): Promise<{\n removed: boolean;\n size: number;\n}> {\n const fileStat = await safeStat(filePath);\n if (!fileStat.exists || fileStat.isDirectory) {\n return { removed: false, size: 0 };\n }\n\n await rm(filePath, { force: true });\n return { removed: true, size: fileStat.size };\n}\n\nasync function resolveCleanReference(\n options: FederalRevenueCleanOptions,\n): Promise<{ reference: string; mode: FederalRevenueReferenceMode }> {\n if (options.reference) {\n validateFederalRevenueReference(options.reference);\n return { reference: options.reference, mode: \"explicit\" };\n }\n\n if (options.current) {\n return { reference: getCurrentFederalRevenueReference(), mode: \"current\" };\n }\n\n const selection = await resolveFederalRevenueReference(\n options as FederalRevenueClientOptions,\n );\n\n return { reference: selection.selectedReference, mode: selection.mode };\n}\n\nfunction resolveCleanMode(\n options: FederalRevenueCleanOptions,\n): FederalRevenueCleanMode {\n const modes: FederalRevenueCleanMode[] = [];\n\n if (options.partials) {\n modes.push(\"partials\");\n }\n\n if (options.failed) {\n modes.push(\"failed\");\n }\n\n if (options.all) {\n modes.push(\"all\");\n }\n\n if (modes.length !== 1) {\n throw new ValidationError(\n \"Federal Revenue cleanup requires exactly one cleanup mode: --partials, --failed, or --all.\",\n );\n }\n\n return modes[0]!;\n}\n\nfunction shouldCleanFailedEntry(file: FederalRevenueManifestFile): boolean {\n return file.status === \"failed\" || file.status === \"partial\";\n}\n\nexport async function cleanFederalRevenueDataset(\n options: FederalRevenueCleanOptions = {},\n): Promise<FederalRevenueCleanSummary> {\n const startedAt = new Date().toISOString();\n const cleanMode = resolveCleanMode(options);\n const selection = await resolveCleanReference(options);\n const outputPath = buildFederalRevenueReferenceOutputPath(\n selection.reference,\n options.outputPath,\n );\n const manifestPath = getFederalRevenueManifestPath(outputPath);\n const removedPaths: string[] = [];\n let removedBytes = 0;\n const warnings: string[] = [];\n\n if (cleanMode === \"all\") {\n const outputStat = await safeStat(outputPath);\n if (outputStat.exists) {\n await rm(outputPath, { recursive: true, force: true });\n removedPaths.push(outputPath);\n removedBytes += outputStat.size;\n } else {\n warnings.push(\n \"The selected Federal Revenue reference folder does not exist locally.\",\n );\n }\n\n return {\n reference: selection.reference,\n selectionMode: selection.mode,\n outputPath,\n manifestPath,\n mode: cleanMode,\n removedFiles: removedPaths.length,\n removedBytes,\n removedPaths,\n warnings,\n startedAt,\n finishedAt: new Date().toISOString(),\n };\n }\n\n if (cleanMode === \"partials\") {\n const partialFiles = await listPartialFiles(outputPath);\n\n for (const partialFile of partialFiles) {\n const result = await removeFileIfExists(partialFile);\n if (result.removed) {\n removedPaths.push(partialFile);\n removedBytes += result.size;\n }\n }\n\n if (partialFiles.length === 0) {\n warnings.push(\"No partial Federal Revenue download files were found.\");\n }\n }\n\n if (cleanMode === \"failed\") {\n const manifest = await readFederalRevenueManifest(outputPath);\n\n if (!manifest) {\n warnings.push(\n \"No local Federal Revenue manifest was found for this reference.\",\n );\n } else {\n for (const file of manifest.files.filter(shouldCleanFailedEntry)) {\n for (const candidate of [file.filePath, file.partialFilePath]) {\n const result = await removeFileIfExists(candidate);\n if (result.removed) {\n removedPaths.push(candidate);\n removedBytes += result.size;\n }\n }\n }\n\n manifest.updatedAt = new Date().toISOString();\n manifest.files = manifest.files.map((file) => {\n if (!shouldCleanFailedEntry(file)) {\n return file;\n }\n\n const updatedFile: FederalRevenueManifestFile = {\n ...file,\n status: \"missing\",\n updatedAt: manifest.updatedAt,\n };\n delete updatedFile.localSizeInBytes;\n delete updatedFile.errorMessage;\n delete updatedFile.downloadedAt;\n return updatedFile;\n });\n await writeFederalRevenueManifest(manifest);\n }\n\n if (removedPaths.length === 0 && warnings.length === 0) {\n warnings.push(\"No failed or partial Federal Revenue files were found.\");\n }\n }\n\n return {\n reference: selection.reference,\n selectionMode: selection.mode,\n outputPath,\n manifestPath,\n mode: cleanMode,\n removedFiles: removedPaths.length,\n removedBytes,\n removedPaths,\n warnings,\n startedAt,\n finishedAt: new Date().toISOString(),\n };\n}\n","import { mkdir, open, readFile, unlink } from \"node:fs/promises\";\nimport { randomUUID } from \"node:crypto\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport {\n getFederalRevenueControlDirectory,\n getFederalRevenueSyncLockPath,\n} from \"./manifest.js\";\nimport type {\n FederalRevenueLockFile,\n FederalRevenueSyncLockOptions,\n} from \"./types.js\";\n\nasync function readLock(\n lockPath: string,\n): Promise<FederalRevenueLockFile | undefined> {\n try {\n return JSON.parse(\n await readFile(lockPath, \"utf8\"),\n ) as FederalRevenueLockFile;\n } catch {\n return undefined;\n }\n}\n\nasync function removeLock(lockPath: string): Promise<void> {\n try {\n await unlink(lockPath);\n } catch {\n // Ignore missing lock files. The next exclusive write still validates the lock state.\n }\n}\n\nexport async function withFederalRevenueSyncLock<T>(\n input: {\n reference: string;\n outputPath: string;\n options?: FederalRevenueSyncLockOptions | undefined;\n },\n callback: () => Promise<T>,\n): Promise<T> {\n const lockPath = getFederalRevenueSyncLockPath(input.outputPath);\n const token = randomUUID();\n const lockFile: FederalRevenueLockFile = {\n reference: input.reference,\n outputPath: input.outputPath,\n lockPath,\n pid: process.pid,\n token,\n startedAt: new Date().toISOString(),\n };\n\n await mkdir(getFederalRevenueControlDirectory(input.outputPath), {\n recursive: true,\n });\n\n if (input.options?.forceLock) {\n await removeLock(lockPath);\n }\n\n let handle: Awaited<ReturnType<typeof open>> | undefined;\n\n try {\n handle = await open(lockPath, \"wx\");\n await handle.writeFile(`${JSON.stringify(lockFile, null, 2)}\\n`, \"utf8\");\n } catch {\n const existingLock = await readLock(lockPath);\n throw new ValidationError(\n `Federal Revenue sync is already running for ${existingLock?.reference ?? input.reference}. Use --force-lock only if the previous process is no longer active.`,\n {\n lockPath,\n pid: existingLock?.pid,\n startedAt: existingLock?.startedAt,\n },\n );\n } finally {\n await handle?.close();\n }\n\n try {\n return await callback();\n } finally {\n const currentLock = await readLock(lockPath);\n if (currentLock?.token === token) {\n await removeLock(lockPath);\n }\n }\n}\n","export type {\n SanitizeDatasetType,\n SanitizeOptions,\n SanitizePlan,\n SanitizeProgressEvent,\n SanitizeProgressListener,\n SanitizeSummary,\n} from \"./sanitize/types.js\";\n\nimport path from \"node:path\";\n\nimport { ValidationError } from \"../core/errors/index.js\";\nimport { inspectFiles } from \"./inspect.service.js\";\nimport { validateInputDirectory } from \"./validate.service.js\";\nimport { buildDisplayPath } from \"./import/planning.js\";\nimport type {\n SanitizeDatasetType,\n SanitizeFilePlan,\n SanitizeOptions,\n SanitizePlan,\n SanitizeSummary,\n} from \"./sanitize/types.js\";\nimport {\n isRecognizedSanitizeEntry,\n isSanitizeDatasetType,\n} from \"./sanitize/types.js\";\nimport { sanitizeDatasetFile } from \"./sanitize/runner.js\";\n\nfunction defaultSanitizedOutputPath(validatedPath: string): string {\n const baseName = path.basename(validatedPath);\n if (baseName.toLowerCase() === \"extracted\") {\n return path.join(path.dirname(validatedPath), \"sanitized\");\n }\n\n return path.join(path.dirname(validatedPath), `${baseName}-sanitized`);\n}\n\nfunction inferNextStep(outputPath: string): string {\n return `cnpj-db-loader import ${outputPath.replace(/\\\\/g, \"/\")}`;\n}\n\nfunction buildSanitizePlan(\n validatedPath: string,\n outputPath: string,\n inspectedPath: Awaited<ReturnType<typeof inspectFiles>>,\n selectedDataset?: SanitizeDatasetType,\n): SanitizePlan {\n const files = inspectedPath.entries\n .filter(isRecognizedSanitizeEntry)\n .filter(\n (entry) => !selectedDataset || entry.inferredType === selectedDataset,\n )\n .map<SanitizeFilePlan>((entry) => ({\n dataset: entry.inferredType,\n relativePath: entry.relativePath,\n absolutePath: path.join(validatedPath, entry.relativePath),\n outputPath: path.join(outputPath, entry.relativePath),\n displayPath: buildDisplayPath(\n path.join(validatedPath, entry.relativePath),\n ),\n fileSize: entry.size,\n }));\n\n return {\n validatedPath,\n outputPath,\n totalFiles: files.length,\n totalBytes: files.reduce((sum, item) => sum + item.fileSize, 0),\n datasets: [...new Set(files.map((item) => item.dataset))],\n files,\n };\n}\n\nexport async function sanitizeInputDirectory(\n inputPath: string,\n options: SanitizeOptions = {},\n): Promise<SanitizeSummary> {\n if (options.dataset && !isSanitizeDatasetType(options.dataset)) {\n throw new ValidationError(`Unsupported dataset type: ${options.dataset}.`);\n }\n\n const validation = await validateInputDirectory(inputPath);\n if (!validation.ok) {\n throw new ValidationError(\n `The input directory is not ready for sanitization. ${validation.errors.join(\" \")}`,\n );\n }\n\n const validatedPath = validation.validatedPath;\n const outputPath = path.resolve(\n options.outputPath ?? defaultSanitizedOutputPath(validatedPath),\n );\n const inspectedValidatedPath = await inspectFiles(validatedPath);\n const plan = buildSanitizePlan(\n validatedPath,\n outputPath,\n inspectedValidatedPath,\n options.dataset,\n );\n\n if (plan.totalFiles === 0) {\n throw new ValidationError(\n \"No recognized validated dataset files were found for sanitization.\",\n );\n }\n\n options.onProgress?.({\n kind: \"start\",\n validatedPath,\n outputPath,\n totalFiles: plan.totalFiles,\n totalBytes: plan.totalBytes,\n datasets: plan.datasets,\n });\n\n let processedFiles = 0;\n let processedRows = 0;\n let processedBytes = 0;\n let nulBytesRemoved = 0;\n let changedFiles = 0;\n const fileSummaries: SanitizeSummary[\"files\"] = [];\n\n for (const [index, filePlan] of plan.files.entries()) {\n const fileResult = await sanitizeDatasetFile(filePlan, (chunk) => {\n options.onProgress?.({\n kind: \"progress\",\n currentFileDisplayPath: filePlan.displayPath,\n fileIndex: index + 1,\n totalFiles: plan.totalFiles,\n bytesProcessed: processedBytes + chunk.fileBytesProcessed,\n totalBytes: plan.totalBytes,\n fileBytesProcessed: chunk.fileBytesProcessed,\n currentFileSize: chunk.currentFileSize,\n processedRows: processedRows + chunk.processedRows,\n nulBytesRemoved: nulBytesRemoved + chunk.nulBytesRemoved,\n changedFiles,\n });\n });\n\n processedFiles += 1;\n processedRows += fileResult.lineCount;\n processedBytes += fileResult.totalBytesRead;\n nulBytesRemoved += fileResult.nulBytesRemoved;\n changedFiles += fileResult.changed ? 1 : 0;\n\n fileSummaries.push({\n dataset: filePlan.dataset,\n relativePath: filePlan.relativePath,\n outputPath: filePlan.outputPath,\n lineCount: fileResult.lineCount,\n changed: fileResult.changed,\n nulBytesRemoved: fileResult.nulBytesRemoved,\n });\n }\n\n options.onProgress?.({\n kind: \"finish\",\n totalFiles: plan.totalFiles,\n processedRows,\n nulBytesRemoved,\n changedFiles,\n totalBytes: plan.totalBytes,\n });\n\n return {\n inputPath: path.resolve(inputPath),\n validatedPath,\n outputPath,\n totalFiles: plan.totalFiles,\n totalBytes: plan.totalBytes,\n processedFiles,\n processedRows,\n nulBytesRemoved,\n changedFiles,\n unchangedFiles: plan.totalFiles - changedFiles,\n datasets: plan.datasets,\n files: fileSummaries,\n warnings: [\n \"Sanitization prepares a clean dataset tree for import by removing known low-level byte issues such as NUL bytes before PostgreSQL loading begins.\",\n \"The import command still keeps quarantine and row-level recovery for unexpected issues, but sanitizing first reduces the amount of slow fallback work during import.\",\n ],\n nextStep: inferNextStep(outputPath),\n };\n}\n","import type { DatasetType, FileInspection } from \"../inspect.service.js\";\n\nexport type SanitizeDatasetType = Exclude<\n DatasetType,\n \"zip-archive\" | \"unknown\"\n>;\n\nexport type SanitizeFilePlan = {\n dataset: SanitizeDatasetType;\n relativePath: string;\n absolutePath: string;\n outputPath: string;\n displayPath: string;\n fileSize: number;\n};\n\nexport type SanitizePlan = {\n validatedPath: string;\n outputPath: string;\n totalFiles: number;\n totalBytes: number;\n datasets: SanitizeDatasetType[];\n files: SanitizeFilePlan[];\n};\n\nexport type SanitizedFileResult = {\n plan: SanitizeFilePlan;\n totalBytesRead: number;\n totalBytesWritten: number;\n nulBytesRemoved: number;\n lineCount: number;\n changed: boolean;\n};\n\nexport type SanitizeSummary = {\n inputPath: string;\n validatedPath: string;\n outputPath: string;\n totalFiles: number;\n totalBytes: number;\n processedFiles: number;\n processedRows: number;\n nulBytesRemoved: number;\n changedFiles: number;\n unchangedFiles: number;\n datasets: SanitizeDatasetType[];\n files: Array<{\n dataset: SanitizeDatasetType;\n relativePath: string;\n outputPath: string;\n lineCount: number;\n changed: boolean;\n nulBytesRemoved: number;\n }>;\n warnings: string[];\n nextStep?: string | undefined;\n};\n\nexport type SanitizeProgressEvent =\n | {\n kind: \"start\";\n validatedPath: string;\n outputPath: string;\n totalFiles: number;\n totalBytes: number;\n datasets: SanitizeDatasetType[];\n }\n | {\n kind: \"progress\";\n currentFileDisplayPath: string;\n fileIndex: number;\n totalFiles: number;\n bytesProcessed: number;\n totalBytes: number;\n fileBytesProcessed: number;\n currentFileSize: number;\n processedRows: number;\n nulBytesRemoved: number;\n changedFiles: number;\n }\n | {\n kind: \"finish\";\n totalFiles: number;\n processedRows: number;\n nulBytesRemoved: number;\n changedFiles: number;\n totalBytes: number;\n };\n\nexport type SanitizeProgressListener = (event: SanitizeProgressEvent) => void;\n\nexport type SanitizeOptions = {\n outputPath?: string | undefined;\n dataset?: SanitizeDatasetType | undefined;\n onProgress?: SanitizeProgressListener | undefined;\n};\n\nexport function isSanitizeDatasetType(\n value: string,\n): value is SanitizeDatasetType {\n return [\n \"companies\",\n \"establishments\",\n \"partners\",\n \"simples_options\",\n \"countries\",\n \"cities\",\n \"partner_qualifications\",\n \"legal_natures\",\n \"cnaes\",\n \"reasons\",\n ].includes(value);\n}\n\nexport function isRecognizedSanitizeEntry(\n entry: FileInspection,\n): entry is FileInspection & { inferredType: SanitizeDatasetType } {\n return (\n entry.entryKind === \"file\" &&\n entry.inferredType !== \"zip-archive\" &&\n entry.inferredType !== \"unknown\"\n );\n}\n","import { createReadStream, createWriteStream } from \"node:fs\";\nimport { mkdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { SanitizeFilePlan, SanitizedFileResult } from \"./types.js\";\n\nfunction stripNulBytes(chunk: Buffer): { buffer: Buffer; removed: number } {\n let removed = 0;\n\n for (let index = 0; index < chunk.length; index += 1) {\n if (chunk[index] === 0x00) {\n removed += 1;\n }\n }\n\n if (removed === 0) {\n return { buffer: chunk, removed: 0 };\n }\n\n const sanitized = Buffer.allocUnsafe(chunk.length - removed);\n let outputIndex = 0;\n\n for (let index = 0; index < chunk.length; index += 1) {\n const value = chunk[index]!;\n if (value !== 0x00) {\n sanitized[outputIndex] = value;\n outputIndex += 1;\n }\n }\n\n return { buffer: sanitized, removed };\n}\n\nexport async function sanitizeDatasetFile(\n plan: SanitizeFilePlan,\n onChunk?: (update: {\n bytesProcessed: number;\n fileBytesProcessed: number;\n currentFileSize: number;\n processedRows: number;\n nulBytesRemoved: number;\n }) => void,\n): Promise<SanitizedFileResult> {\n await mkdir(path.dirname(plan.outputPath), { recursive: true });\n\n const input = createReadStream(plan.absolutePath);\n const output = createWriteStream(plan.outputPath);\n\n let totalBytesRead = 0;\n let totalBytesWritten = 0;\n let nulBytesRemoved = 0;\n let lineCount = 0;\n let sawAnyByte = false;\n let lastByteWasNewline = false;\n\n try {\n for await (const chunk of input) {\n const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n totalBytesRead += chunkBuffer.length;\n\n const { buffer, removed } = stripNulBytes(chunkBuffer);\n nulBytesRemoved += removed;\n sawAnyByte = sawAnyByte || buffer.length > 0;\n\n for (let index = 0; index < buffer.length; index += 1) {\n if (buffer[index] === 0x0a) {\n lineCount += 1;\n }\n }\n\n if (buffer.length > 0) {\n lastByteWasNewline = buffer[buffer.length - 1] === 0x0a;\n }\n\n totalBytesWritten += buffer.length;\n output.write(buffer);\n\n onChunk?.({\n bytesProcessed: chunkBuffer.length,\n fileBytesProcessed: totalBytesRead,\n currentFileSize: plan.fileSize,\n processedRows: lineCount,\n nulBytesRemoved,\n });\n }\n\n if (sawAnyByte && !lastByteWasNewline) {\n lineCount += 1;\n }\n } finally {\n input.close();\n output.end();\n await new Promise<void>((resolve) => output.on(\"finish\", () => resolve()));\n }\n\n return {\n plan,\n totalBytesRead,\n totalBytesWritten,\n nulBytesRemoved,\n lineCount,\n changed: nulBytesRemoved > 0 || totalBytesRead !== totalBytesWritten,\n };\n}\n","import { ValidationError } from \"../../core/errors/index.js\";\nimport { extractArchives } from \"../extract.service.js\";\nimport { importDataToDatabase } from \"../import.service.js\";\nimport { sanitizeInputDirectory } from \"../sanitize.service.js\";\nimport { validateInputDirectory } from \"../validate.service.js\";\nimport {\n checkFederalRevenueDataset,\n downloadFederalRevenueDataset,\n} from \"./download.js\";\nimport { withFederalRevenueSyncLock } from \"./lock.js\";\nimport { buildFederalRevenueReferenceOutputPath } from \"./manifest.js\";\nimport type {\n FederalRevenueDownloadOptions,\n FederalRevenueSyncOptions,\n FederalRevenueSyncSummary,\n} from \"./types.js\";\n\nfunction buildLockedDownloadOptions(\n options: FederalRevenueSyncOptions,\n reference: string,\n): FederalRevenueDownloadOptions {\n const { current, forceLock, ...downloadOptions } = options;\n void current;\n void forceLock;\n\n return {\n ...downloadOptions,\n reference,\n manifestCommand: \"sync\",\n };\n}\n\nasync function runFederalRevenueSyncPipeline(\n options: FederalRevenueSyncOptions,\n reference: string,\n): Promise<FederalRevenueSyncSummary> {\n const startedAt = new Date().toISOString();\n const download = await downloadFederalRevenueDataset(\n buildLockedDownloadOptions(options, reference),\n );\n\n if (download.failedFiles > 0) {\n throw new ValidationError(\n `Federal Revenue sync cannot continue because ${download.failedFiles} file(s) failed to download. Run federal-revenue retry ${download.reference} after fixing the cause.`,\n { reference: download.reference, outputPath: download.outputPath },\n );\n }\n\n if (download.partialFiles > 0 || download.missingFiles > 0) {\n throw new ValidationError(\n `Federal Revenue sync cannot continue because the local reference is incomplete. Partial files: ${download.partialFiles}. Missing files: ${download.missingFiles}.`,\n {\n reference: download.reference,\n outputPath: download.outputPath,\n partialFiles: download.partialFiles,\n missingFiles: download.missingFiles,\n },\n );\n }\n\n const extraction = await extractArchives(\n download.outputPath,\n options.extractOutputPath,\n options.onExtractProgress,\n );\n\n if (extraction.failedArchives.length > 0) {\n throw new ValidationError(\n `Federal Revenue sync cannot continue because ${extraction.failedArchives.length} archive(s) failed to extract.`,\n {\n reference: download.reference,\n failedArchives: extraction.failedArchives,\n outputPath: extraction.outputPath,\n },\n );\n }\n\n const validation = await validateInputDirectory(extraction.outputPath);\n if (!validation.ok) {\n throw new ValidationError(\n `Federal Revenue sync cannot continue because the extracted dataset is not valid. ${validation.errors.join(\" \")}`,\n { reference: download.reference, errors: validation.errors },\n );\n }\n\n const sanitization = await sanitizeInputDirectory(extraction.outputPath, {\n ...options.sanitizeOptions,\n outputPath: options.sanitizeOutputPath,\n onProgress: options.onSanitizeProgress,\n });\n\n const importSummary = await importDataToDatabase(sanitization.outputPath, {\n ...options.importOptions,\n onProgress: options.onImportProgress,\n });\n\n return {\n reference: download.reference,\n download,\n extraction,\n validation,\n sanitization,\n import: importSummary,\n startedAt,\n finishedAt: new Date().toISOString(),\n warnings: [\n ...download.warnings,\n ...validation.warnings,\n ...sanitization.warnings,\n ...importSummary.warnings,\n ],\n };\n}\n\nexport async function syncFederalRevenueDataset(\n options: FederalRevenueSyncOptions = {},\n): Promise<FederalRevenueSyncSummary> {\n const check = await checkFederalRevenueDataset(options);\n const outputPath = buildFederalRevenueReferenceOutputPath(\n check.selectedReference,\n options.outputPath,\n );\n\n return withFederalRevenueSyncLock(\n {\n reference: check.selectedReference,\n outputPath,\n options: { forceLock: options.forceLock },\n },\n () => runFederalRevenueSyncPipeline(options, check.selectedReference),\n );\n}\n","import { createWriteStream } from \"node:fs\";\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport { inspectFiles } from \"../inspect.service.js\";\nimport { validateInputDirectory } from \"../validate.service.js\";\nimport { buildDisplayPath, sortEntries } from \"../import/planning.js\";\nimport { readImportSourceLines } from \"../import/source-reader.js\";\nimport { parseImportSourceLine } from \"../import/parser.js\";\nimport {\n DATASET_LAYOUTS,\n IMPORT_ORDER,\n isImportDatasetType,\n type ImportDatasetType,\n type ImportSchemaCapabilities,\n} from \"../import/types.js\";\nimport { normalizeFieldCount, transformRecord } from \"../import/transform.js\";\nimport { formatCsvRow } from \"./csv.js\";\nimport { generatePostgresDirectImportScript } from \"./script.js\";\nimport type {\n PostgresCsvDatasetSummary,\n PostgresCsvExportOptions,\n PostgresCsvExportSummary,\n PostgresCsvFile,\n} from \"./types.js\";\n\nconst POSTGRES_DIRECT_SCHEMA_CAPABILITIES: ImportSchemaCapabilities = {\n includeEstablishmentCnpjFullInInsert: true,\n includeEstablishmentSecondaryCnaesTable: true,\n includePartnerDedupeKeyInInsert: true,\n requiresLookupReconciliation: false,\n};\n\nfunction defaultPostgresCsvOutputPath(inputPath: string): string {\n const baseName = path.basename(inputPath);\n return path.join(path.dirname(inputPath), `${baseName}-postgres-csv`);\n}\n\nfunction normalizeOutputFileName(relativePath: string): string {\n const parsed = path.parse(relativePath);\n const baseName = parsed.name || parsed.base || \"dataset\";\n return path.join(parsed.dir, `${baseName}.csv`);\n}\n\nfunction resolveDatasetOutputPath(\n outputPath: string,\n dataset: ImportDatasetType,\n relativePath: string,\n): string {\n return path.join(outputPath, dataset, normalizeOutputFileName(relativePath));\n}\n\nfunction inferNextStep(scriptPath: string): string {\n return `psql \"postgres://postgres:postgres@localhost:5432/cnpj\" -f ${scriptPath.replace(/\\\\/g, \"/\")}`;\n}\n\nasync function writeCsvFile(input: {\n dataset: ImportDatasetType;\n inputFile: string;\n outputFile: string;\n}): Promise<number> {\n const layout = DATASET_LAYOUTS[input.dataset];\n const columns = layout.fields.map((field) => field.columnName);\n\n await mkdir(path.dirname(input.outputFile), { recursive: true });\n\n const output = createWriteStream(input.outputFile, { encoding: \"utf8\" });\n let rows = 0;\n\n try {\n output.write(`${formatCsvRow(columns)}\\n`);\n\n for await (const sourceLine of readImportSourceLines(input.inputFile)) {\n if (sourceLine.rawLine.trim() === \"\") {\n continue;\n }\n\n const parsed = parseImportSourceLine(sourceLine);\n const normalizedFields = normalizeFieldCount(\n parsed.fields,\n layout.fields.length,\n input.inputFile,\n parsed.lineNumber,\n );\n const values = transformRecord(\n input.dataset,\n layout,\n normalizedFields,\n POSTGRES_DIRECT_SCHEMA_CAPABILITIES,\n \"staging\",\n );\n\n output.write(`${formatCsvRow(values)}\\n`);\n rows += 1;\n }\n } finally {\n output.end();\n await new Promise<void>((resolve, reject) => {\n output.on(\"finish\", () => resolve());\n output.on(\"error\", (error) => reject(error));\n });\n }\n\n return rows;\n}\n\nexport async function exportPostgresCsvDataset(\n inputPath: string,\n options: PostgresCsvExportOptions = {},\n): Promise<PostgresCsvExportSummary> {\n if (options.dataset && !isImportDatasetType(options.dataset)) {\n throw new ValidationError(`Unsupported dataset type: ${options.dataset}.`);\n }\n\n const validation = await validateInputDirectory(inputPath);\n if (!validation.ok) {\n throw new ValidationError(\n `The input directory is not ready for PostgreSQL CSV export. ${validation.errors.join(\" \")}`,\n );\n }\n\n const validatedPath = validation.validatedPath;\n const outputPath = path.resolve(\n options.outputPath ?? defaultPostgresCsvOutputPath(validatedPath),\n );\n const inspected = await inspectFiles(validatedPath);\n const recognizedFiles = inspected.entries\n .filter((entry) => entry.entryKind === \"file\")\n .flatMap((entry) => {\n if (!isImportDatasetType(entry.inferredType)) {\n return [];\n }\n\n if (options.dataset && entry.inferredType !== options.dataset) {\n return [];\n }\n\n return [{ ...entry, inferredType: entry.inferredType }];\n })\n .sort(sortEntries);\n\n if (recognizedFiles.length === 0) {\n throw new ValidationError(\n \"No recognized dataset files were found for PostgreSQL CSV export.\",\n );\n }\n\n const datasets = [\n ...new Set(recognizedFiles.map((entry) => entry.inferredType)),\n ].sort(\n (left, right) => IMPORT_ORDER.indexOf(left) - IMPORT_ORDER.indexOf(right),\n );\n\n options.onProgress?.({\n kind: \"start\",\n inputPath: path.resolve(inputPath),\n validatedPath,\n outputPath,\n totalFiles: recognizedFiles.length,\n datasets,\n });\n\n const exportedFiles: PostgresCsvFile[] = [];\n const summariesByDataset = new Map<\n ImportDatasetType,\n PostgresCsvDatasetSummary\n >();\n\n for (const [index, entry] of recognizedFiles.entries()) {\n const dataset = entry.inferredType;\n const inputFile = path.join(validatedPath, entry.relativePath);\n const outputFile = resolveDatasetOutputPath(\n outputPath,\n dataset,\n entry.relativePath,\n );\n\n options.onProgress?.({\n kind: \"file_start\",\n dataset,\n fileIndex: index + 1,\n totalFiles: recognizedFiles.length,\n inputFile: buildDisplayPath(inputFile),\n outputFile,\n });\n\n const rowCount = await writeCsvFile({ dataset, inputFile, outputFile });\n\n exportedFiles.push({\n dataset,\n absolutePath: outputFile,\n relativePath: path.relative(outputPath, outputFile),\n rowCount,\n });\n\n const currentSummary = summariesByDataset.get(dataset) ?? {\n dataset,\n files: 0,\n rows: 0,\n outputFiles: [],\n };\n currentSummary.files += 1;\n currentSummary.rows += rowCount;\n currentSummary.outputFiles.push(outputFile);\n summariesByDataset.set(dataset, currentSummary);\n\n options.onProgress?.({\n kind: \"file_finish\",\n dataset,\n fileIndex: index + 1,\n totalFiles: recognizedFiles.length,\n inputFile: buildDisplayPath(inputFile),\n outputFile,\n rows: rowCount,\n });\n }\n\n const scriptName = options.scriptName ?? \"import-postgres-direct.sql\";\n const scriptPath = path.join(outputPath, scriptName);\n const script = generatePostgresDirectImportScript({ files: exportedFiles });\n await writeFile(scriptPath, script, \"utf8\");\n\n const manifestPath = path.join(outputPath, \"manifest.json\");\n const summaryDatasets = [...summariesByDataset.values()].sort(\n (left, right) =>\n IMPORT_ORDER.indexOf(left.dataset) - IMPORT_ORDER.indexOf(right.dataset),\n );\n const totalRows = summaryDatasets.reduce((sum, item) => sum + item.rows, 0);\n\n const manifest = {\n generatedAt: new Date().toISOString(),\n inputPath: path.resolve(inputPath),\n validatedPath,\n outputPath,\n scriptPath,\n totalFiles: exportedFiles.length,\n totalRows,\n datasets: summaryDatasets,\n };\n await writeFile(\n manifestPath,\n `${JSON.stringify(manifest, null, 2)}\\n`,\n \"utf8\",\n );\n\n options.onProgress?.({\n kind: \"finish\",\n outputPath,\n scriptPath,\n totalFiles: exportedFiles.length,\n totalRows,\n });\n\n return {\n inputPath: path.resolve(inputPath),\n validatedPath,\n outputPath,\n scriptPath,\n manifestPath,\n totalFiles: exportedFiles.length,\n totalRows,\n datasets: summaryDatasets,\n warnings: [\n \"PostgreSQL-ready CSV export is intended for hybrid bulk imports after extraction, validation and sanitization.\",\n \"The generated SQL script resets staging tables and then upserts final tables. Review it before running against production databases.\",\n ],\n nextStep: inferNextStep(scriptPath),\n };\n}\n","export function formatCsvValue(value: unknown): string {\n if (value === null || value === undefined) {\n return \"\";\n }\n\n if (value instanceof Date) {\n return formatCsvValue(value.toISOString());\n }\n\n const text = String(value);\n const shouldQuote = /[\",\\r\\n]/.test(text);\n\n if (!shouldQuote) {\n return text;\n }\n\n return `\"${text.replace(/\"/g, '\"\"')}\"`;\n}\n\nexport function formatCsvRow(values: readonly unknown[]): string {\n return values.map(formatCsvValue).join(\",\");\n}\n","import path from \"node:path\";\n\nimport {\n companiesLayout,\n establishmentsLayout,\n partnersLayout,\n simplesLayout,\n} from \"../../dictionary/layouts/index.js\";\nimport type { FieldDefinition } from \"../../dictionary/layouts/index.js\";\nimport type { ImportDatasetType } from \"../import/types.js\";\nimport { DATASET_LAYOUTS } from \"../import/types.js\";\nimport type { PostgresCsvFile, PostgresDirectSourceFile } from \"./types.js\";\n\ntype CsvScriptGenerationInput = {\n files: PostgresCsvFile[];\n};\n\ntype SanitizedScriptGenerationInput = {\n files: PostgresDirectSourceFile[];\n sourceEncoding: string;\n};\n\nconst STAGING_DATASETS: readonly ImportDatasetType[] = [\n \"companies\",\n \"establishments\",\n \"partners\",\n \"simples_options\",\n];\n\nconst DOMAIN_DATASETS: readonly ImportDatasetType[] = [\n \"partner_qualifications\",\n \"legal_natures\",\n \"countries\",\n \"cities\",\n \"reasons\",\n \"cnaes\",\n];\n\nconst STAGING_TABLE_BY_DATASET: Partial<Record<ImportDatasetType, string>> = {\n companies: \"staging_companies\",\n establishments: \"staging_establishments\",\n partners: \"staging_partners\",\n simples_options: \"staging_simples_options\",\n};\n\nfunction quoteSqlLiteral(value: string): string {\n return `'${value.replace(/'/g, \"''\")}'`;\n}\n\nfunction quoteIdentifier(value: string): string {\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n}\n\nfunction normalizePathForPsql(filePath: string): string {\n return path.resolve(filePath).replace(/\\\\/g, \"/\");\n}\n\nfunction csvCopyCommand(\n tableName: string,\n columns: readonly string[],\n filePath: string,\n): string {\n const normalizedFilePath = normalizePathForPsql(filePath);\n return `\\\\copy ${tableName} (${columns.join(\", \")}) from ${quoteSqlLiteral(normalizedFilePath)} with (format csv, header true, delimiter ',', quote '\"', escape '\"', null '')`;\n}\n\nfunction receitaCopyCommand(\n tableName: string,\n columns: readonly string[],\n filePath: string,\n): string {\n const normalizedFilePath = normalizePathForPsql(filePath);\n return `\\\\copy ${tableName} (${columns.join(\", \")}) from ${quoteSqlLiteral(normalizedFilePath)} with (format csv, header false, delimiter ';', quote '\"', escape '\"')`;\n}\n\nfunction datasetColumns(dataset: ImportDatasetType): string[] {\n return DATASET_LAYOUTS[dataset].fields.map((field) => field.columnName);\n}\n\nfunction updateAssignments(\n columns: readonly string[],\n excludedColumns: readonly string[],\n): string {\n return columns\n .filter((column) => !excludedColumns.includes(column))\n .map((column) => `${column} = excluded.${column}`)\n .concat([\"updated_at = now()\"])\n .join(\",\\n \");\n}\n\nfunction partnerDedupeExpression(alias: string): string {\n return [\n \"md5(\",\n ` coalesce(${alias}.cnpj_root, '') || '|' ||`,\n ` coalesce(${alias}.partner_type_code, '') || '|' ||`,\n ` coalesce(${alias}.partner_name, '') || '|' ||`,\n ` coalesce(${alias}.partner_document, '') || '|' ||`,\n ` coalesce(${alias}.partner_qualification_code, '') || '|' ||`,\n ` coalesce((${alias}.entry_date - date '2000-01-01')::text, '') || '|' ||`,\n ` coalesce(${alias}.country_code, '') || '|' ||`,\n ` coalesce(${alias}.legal_representative_document, '') || '|' ||`,\n ` coalesce(${alias}.legal_representative_name, '') || '|' ||`,\n ` coalesce(${alias}.legal_representative_qualification_code, '') || '|' ||`,\n ` coalesce(${alias}.age_group_code, '')`,\n \")\",\n ].join(\"\\n\");\n}\n\nfunction materializeCompaniesSql(): string {\n const columns = companiesLayout.fields.map((field) => field.columnName);\n\n return [\n \"\\\\echo 'Materializing companies...'\",\n \"with source as (\",\n \" select\",\n ` ${columns.map((column) => `source.${column}`).join(\",\\n \")},`,\n \" row_number() over (partition by source.cnpj_root order by source.staging_id desc) as dedupe_rank\",\n \" from staging_companies source\",\n \"),\",\n \"deduped as (\",\n \" select * from source where dedupe_rank = 1\",\n \")\",\n `insert into companies (${columns.join(\", \")})`,\n `select ${columns.join(\", \")}`,\n \"from deduped\",\n \"on conflict (cnpj_root) do update set\",\n ` ${updateAssignments(columns, [\"cnpj_root\"])};`,\n ].join(\"\\n\");\n}\n\nfunction materializeEstablishmentsSql(): string {\n const baseColumns = establishmentsLayout.fields.map(\n (field) => field.columnName,\n );\n const insertColumns = [...baseColumns, \"cnpj_full\"];\n\n return [\n \"\\\\echo 'Materializing establishments and secondary CNAEs...'\",\n \"with source as (\",\n \" select\",\n ` ${baseColumns.map((column) => `source.${column}`).join(\",\\n \")},`,\n \" source.cnpj_root || source.cnpj_order || source.cnpj_check_digits as cnpj_full,\",\n \" row_number() over (partition by source.cnpj_root || source.cnpj_order || source.cnpj_check_digits order by source.staging_id desc) as dedupe_rank\",\n \" from staging_establishments source\",\n \"),\",\n \"deduped as (\",\n \" select * from source where dedupe_rank = 1\",\n \"),\",\n \"upserted as (\",\n ` insert into establishments (${insertColumns.join(\", \")})`,\n ` select ${insertColumns.join(\", \")}`,\n \" from deduped\",\n \" on conflict (cnpj_full) do update set\",\n ` ${updateAssignments(insertColumns, [\"cnpj_root\", \"cnpj_order\", \"cnpj_check_digits\", \"cnpj_full\"])}`,\n \" returning cnpj_full\",\n \"),\",\n \"deleted_secondary_cnaes as (\",\n \" delete from establishment_secondary_cnaes target\",\n \" using (select cnpj_full from deduped) source_keys\",\n \" where target.cnpj_full = source_keys.cnpj_full\",\n \" returning 1\",\n \"),\",\n \"secondary_cnaes_source as (\",\n \" select distinct\",\n \" deduped.cnpj_full,\",\n \" btrim(cnae_code) as cnae_code\",\n \" from deduped\",\n \" cross join lateral unnest(string_to_array(deduped.secondary_cnaes_raw, ',')) as cnae_code\",\n \" where deduped.secondary_cnaes_raw is not null\",\n \" and deduped.secondary_cnaes_raw <> ''\",\n \" and btrim(cnae_code) <> ''\",\n \")\",\n \"insert into establishment_secondary_cnaes (cnpj_full, cnae_code)\",\n \"select cnpj_full, cnae_code\",\n \"from secondary_cnaes_source\",\n \"on conflict (cnpj_full, cnae_code) do nothing;\",\n ].join(\"\\n\");\n}\n\nfunction materializePartnersSql(): string {\n const baseColumns = partnersLayout.fields.map((field) => field.columnName);\n const insertColumns = [...baseColumns, \"partner_dedupe_key\"];\n\n return [\n \"\\\\echo 'Materializing partners...'\",\n \"with source as (\",\n \" select\",\n ` ${baseColumns.map((column) => `source.${column}`).join(\",\\n \")},`,\n ` ${partnerDedupeExpression(\"source\")} as partner_dedupe_key`,\n \" from staging_partners source\",\n \"),\",\n \"ranked as (\",\n \" select\",\n \" source.*,\",\n \" row_number() over (partition by source.partner_dedupe_key order by source.cnpj_root asc) as dedupe_rank\",\n \" from source\",\n \"),\",\n \"deduped as (\",\n \" select * from ranked where dedupe_rank = 1\",\n \")\",\n `insert into partners (${insertColumns.join(\", \")})`,\n `select ${insertColumns.join(\", \")}`,\n \"from deduped\",\n \"on conflict (partner_dedupe_key) do update set\",\n ` ${updateAssignments(insertColumns, [\"partner_dedupe_key\"])};`,\n ].join(\"\\n\");\n}\n\nfunction materializeSimplesSql(): string {\n const columns = simplesLayout.fields.map((field) => field.columnName);\n\n return [\n \"\\\\echo 'Materializing simples options...'\",\n \"with source as (\",\n \" select\",\n ` ${columns.map((column) => `source.${column}`).join(\",\\n \")},`,\n \" row_number() over (partition by source.cnpj_root order by source.staging_id desc) as dedupe_rank\",\n \" from staging_simples_options source\",\n \"),\",\n \"deduped as (\",\n \" select * from source where dedupe_rank = 1\",\n \")\",\n `insert into simples_options (${columns.join(\", \")})`,\n `select ${columns.join(\", \")}`,\n \"from deduped\",\n \"on conflict (cnpj_root) do update set\",\n ` ${updateAssignments(columns, [\"cnpj_root\"])};`,\n ].join(\"\\n\");\n}\n\nfunction copyDomainSql(\n dataset: ImportDatasetType,\n files: readonly PostgresCsvFile[],\n): string[] {\n if (files.length === 0) {\n return [];\n }\n\n const columns = datasetColumns(dataset);\n const tempTable = `tmp_hybrid_${dataset}`;\n const lines = [\n `\\\\echo 'Loading ${dataset} lookup data...'`,\n `drop table if exists ${tempTable};`,\n `create temporary table ${tempTable} (code text, description text);`,\n ];\n\n for (const file of files) {\n lines.push(csvCopyCommand(tempTable, columns, file.absolutePath));\n }\n\n lines.push(\n `insert into ${dataset} (${columns.join(\", \")})`,\n `select distinct on (code) ${columns.join(\", \")}`,\n `from ${tempTable}`,\n \"where code is not null and code <> ''\",\n \"order by code\",\n \"on conflict (code) do update set description = excluded.description;\",\n );\n\n return lines;\n}\n\nfunction copyStagingSql(\n dataset: ImportDatasetType,\n files: readonly PostgresCsvFile[],\n): string[] {\n if (files.length === 0) {\n return [];\n }\n\n const tableName = STAGING_TABLE_BY_DATASET[dataset];\n if (!tableName) {\n return [];\n }\n\n const columns = datasetColumns(dataset);\n return [\n `\\\\echo 'Loading ${dataset} staging data...'`,\n ...files.map((file) =>\n csvCopyCommand(tableName, columns, file.absolutePath),\n ),\n ];\n}\n\nfunction csvFilesByDataset(\n files: readonly PostgresCsvFile[],\n): Partial<Record<ImportDatasetType, PostgresCsvFile[]>> {\n const grouped: Partial<Record<ImportDatasetType, PostgresCsvFile[]>> = {};\n\n for (const file of files) {\n const items = grouped[file.dataset] ?? [];\n items.push(file);\n grouped[file.dataset] = items;\n }\n\n return grouped;\n}\n\nfunction directFilesByDataset(\n files: readonly PostgresDirectSourceFile[],\n): Partial<Record<ImportDatasetType, PostgresDirectSourceFile[]>> {\n const grouped: Partial<\n Record<ImportDatasetType, PostgresDirectSourceFile[]>\n > = {};\n\n for (const file of files) {\n const items = grouped[file.dataset] ?? [];\n items.push(file);\n grouped[file.dataset] = items;\n }\n\n return grouped;\n}\n\nfunction rawTableName(dataset: ImportDatasetType): string {\n return `tmp_hybrid_raw_${dataset}`;\n}\n\nfunction createRawTempTableSql(dataset: ImportDatasetType): string {\n const columns = DATASET_LAYOUTS[dataset].fields\n .map((field) => ` ${quoteIdentifier(field.columnName)} text`)\n .join(\",\\n\");\n\n return [\n `drop table if exists ${rawTableName(dataset)};`,\n `create temporary table ${rawTableName(dataset)} (`,\n columns,\n \");\",\n ].join(\"\\n\");\n}\n\nfunction textExpression(alias: string, column: string): string {\n return `nullif(btrim(${alias}.${quoteIdentifier(column)}), '')`;\n}\n\nfunction dateExpression(alias: string, column: string): string {\n const value = `btrim(${alias}.${quoteIdentifier(column)})`;\n return [\n \"case\",\n ` when ${value} = '' or ${value} = '00000000' then null`,\n ` when ${value} ~ '^\\\\d{8}$' then to_date(${value}, 'YYYYMMDD')`,\n \" else null\",\n \"end\",\n ].join(\" \");\n}\n\nfunction numericExpression(alias: string, column: string): string {\n const value = `btrim(${alias}.${quoteIdentifier(column)})`;\n return [\n \"case\",\n ` when ${value} = '' then null`,\n ` when ${value} like '%,%' and ${value} like '%.%' then replace(replace(${value}, '.', ''), ',', '.')::numeric`,\n ` when ${value} like '%,%' then replace(${value}, ',', '.')::numeric`,\n ` else ${value}::numeric`,\n \"end\",\n ].join(\" \");\n}\n\nfunction integerExpression(alias: string, column: string): string {\n const value = `btrim(${alias}.${quoteIdentifier(column)})`;\n return [\n \"case\",\n ` when ${value} = '' then null`,\n ` when ${value} ~ '^-?\\\\d+$' then ${value}::integer`,\n \" else null\",\n \"end\",\n ].join(\" \");\n}\n\nfunction booleanExpression(alias: string, column: string): string {\n const value = `lower(btrim(${alias}.${quoteIdentifier(column)}))`;\n return [\n \"case\",\n ` when ${value} in ('1', 'true', 't', 'y', 'yes', 's') then true`,\n ` when ${value} in ('0', 'false', 'f', 'n', 'no') then false`,\n \" else null\",\n \"end\",\n ].join(\" \");\n}\n\nfunction fieldExpression(\n dataset: ImportDatasetType,\n field: FieldDefinition,\n alias: string,\n): string {\n const column = field.columnName;\n\n if (dataset === \"companies\" && column === \"company_size_code\") {\n return `coalesce(${textExpression(alias, column)}, '00')`;\n }\n\n if (dataset === \"establishments\" && column === \"branch_type_code\") {\n return `coalesce(${textExpression(alias, column)}, '1')`;\n }\n\n if (dataset === \"establishments\" && column === \"registration_status_code\") {\n return `coalesce(${textExpression(alias, column)}, '01')`;\n }\n\n switch (field.dataType) {\n case \"date\":\n return dateExpression(alias, column);\n case \"numeric\":\n return numericExpression(alias, column);\n case \"integer\":\n return integerExpression(alias, column);\n case \"boolean\":\n return booleanExpression(alias, column);\n default:\n return textExpression(alias, column);\n }\n}\n\nfunction rawDomainSql(\n dataset: ImportDatasetType,\n files: readonly PostgresDirectSourceFile[],\n): string[] {\n if (files.length === 0) {\n return [];\n }\n\n const layout = DATASET_LAYOUTS[dataset];\n const columns = layout.fields.map((field) => field.columnName);\n const tableName = rawTableName(dataset);\n\n const lines = [\n `\\\\echo 'Loading ${dataset} lookup data directly from sanitized Receita files...'`,\n createRawTempTableSql(dataset),\n ];\n\n for (const file of files) {\n lines.push(receitaCopyCommand(tableName, columns, file.absolutePath));\n }\n\n lines.push(\n `insert into ${dataset} (${columns.join(\", \")})`,\n \"select distinct on (code)\",\n \" nullif(btrim(code), '') as code,\",\n \" nullif(btrim(description), '') as description\",\n `from ${tableName}`,\n \"where nullif(btrim(code), '') is not null\",\n \"order by code\",\n \"on conflict (code) do update set description = excluded.description;\",\n );\n\n return lines;\n}\n\nfunction rawStagingSql(\n dataset: ImportDatasetType,\n files: readonly PostgresDirectSourceFile[],\n): string[] {\n if (files.length === 0) {\n return [];\n }\n\n const targetTable = STAGING_TABLE_BY_DATASET[dataset];\n if (!targetTable) {\n return [];\n }\n\n const layout = DATASET_LAYOUTS[dataset];\n const columns = layout.fields.map((field) => field.columnName);\n const tableName = rawTableName(dataset);\n const alias = \"source\";\n const expressions = layout.fields.map(\n (field) =>\n ` ${fieldExpression(dataset, field, alias)} as ${field.columnName}`,\n );\n\n const lines = [\n `\\\\echo 'Loading ${dataset} staging data directly from sanitized Receita files...'`,\n createRawTempTableSql(dataset),\n ];\n\n for (const file of files) {\n lines.push(receitaCopyCommand(tableName, columns, file.absolutePath));\n }\n\n lines.push(\n `insert into ${targetTable} (${columns.join(\", \")})`,\n \"select\",\n expressions.join(\",\\n\"),\n `from ${tableName} ${alias};`,\n );\n\n return lines;\n}\n\nexport function generatePostgresDirectImportScript(\n input: CsvScriptGenerationInput,\n): string {\n const grouped = csvFilesByDataset(input.files);\n\n const lines = [\n \"-- CNPJ DB Loader hybrid PostgreSQL import script\",\n \"-- Generated from PostgreSQL-ready CSV files exported by cnpj-db-loader postgres export-csv.\",\n \"-- Execute with psql, for example:\",\n '-- psql \"postgres://postgres:postgres@localhost:5432/cnpj\" -f import-postgres-direct.sql',\n \"\",\n \"\\\\set ON_ERROR_STOP on\",\n \"\\\\echo 'Starting CNPJ DB Loader hybrid PostgreSQL import...'\",\n \"\",\n \"begin;\",\n \"\",\n \"-- Keep the final schema and seed data managed by sql/schema.sql.\",\n \"-- This script only resets staging tables and then upserts final data.\",\n \"truncate table staging_companies restart identity;\",\n \"truncate table staging_establishments restart identity;\",\n \"truncate table staging_partners restart identity;\",\n \"truncate table staging_simples_options restart identity;\",\n \"\",\n ];\n\n for (const dataset of DOMAIN_DATASETS) {\n lines.push(...copyDomainSql(dataset, grouped[dataset] ?? []), \"\");\n }\n\n for (const dataset of STAGING_DATASETS) {\n lines.push(...copyStagingSql(dataset, grouped[dataset] ?? []), \"\");\n }\n\n lines.push(...materializationAndAnalyzeSql());\n\n return lines.join(\"\\n\");\n}\n\nexport function generatePostgresSanitizedDirectImportScript(\n input: SanitizedScriptGenerationInput,\n): string {\n const grouped = directFilesByDataset(input.files);\n\n const lines = [\n \"-- CNPJ DB Loader direct PostgreSQL import script\",\n \"-- Generated from sanitized Receita files by cnpj-db-loader postgres generate-script.\",\n \"-- This path avoids rewriting the dataset into a second CSV tree.\",\n \"-- Execute with psql, for example:\",\n '-- psql \"postgres://postgres:postgres@localhost:5432/cnpj\" -f import-postgres-direct.sql',\n \"\",\n \"\\\\set ON_ERROR_STOP on\",\n `\\\\echo 'Using source file encoding ${input.sourceEncoding} for psql copy operations...'`,\n `set client_encoding to ${quoteSqlLiteral(input.sourceEncoding)};`,\n \"\\\\echo 'Starting CNPJ DB Loader direct PostgreSQL import from sanitized files...'\",\n \"\",\n \"begin;\",\n \"\",\n \"-- Keep the final schema and seed data managed by sql/schema.sql.\",\n \"-- This script copies sanitized Receita files into temporary raw tables,\",\n \"-- transforms values inside PostgreSQL, resets staging tables and upserts final data.\",\n \"truncate table staging_companies restart identity;\",\n \"truncate table staging_establishments restart identity;\",\n \"truncate table staging_partners restart identity;\",\n \"truncate table staging_simples_options restart identity;\",\n \"\",\n ];\n\n for (const dataset of DOMAIN_DATASETS) {\n lines.push(...rawDomainSql(dataset, grouped[dataset] ?? []), \"\");\n }\n\n for (const dataset of STAGING_DATASETS) {\n lines.push(...rawStagingSql(dataset, grouped[dataset] ?? []), \"\");\n }\n\n lines.push(...materializationAndAnalyzeSql());\n\n return lines.join(\"\\n\");\n}\n\nfunction materializationAndAnalyzeSql(): string[] {\n return [\n materializeCompaniesSql(),\n \"\",\n materializeEstablishmentsSql(),\n \"\",\n materializePartnersSql(),\n \"\",\n materializeSimplesSql(),\n \"\",\n \"\\\\echo 'Refreshing planner statistics...'\",\n \"analyze companies;\",\n \"analyze establishments;\",\n \"analyze establishment_secondary_cnaes;\",\n \"analyze partners;\",\n \"analyze simples_options;\",\n \"analyze cnaes;\",\n \"analyze cities;\",\n \"analyze countries;\",\n \"analyze legal_natures;\",\n \"analyze partner_qualifications;\",\n \"analyze reasons;\",\n \"\",\n \"commit;\",\n \"\",\n \"\\\\echo 'CNPJ DB Loader hybrid PostgreSQL import completed.'\",\n \"\",\n ];\n}\n","import { mkdir, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport { inspectFiles } from \"../inspect.service.js\";\nimport { validateInputDirectory } from \"../validate.service.js\";\nimport { buildDisplayPath, sortEntries } from \"../import/planning.js\";\nimport {\n IMPORT_ORDER,\n isImportDatasetType,\n type ImportDatasetType,\n} from \"../import/types.js\";\nimport { generatePostgresSanitizedDirectImportScript } from \"./script.js\";\nimport type {\n PostgresDirectScriptDatasetSummary,\n PostgresDirectScriptOptions,\n PostgresDirectScriptSummary,\n PostgresDirectSourceFile,\n} from \"./types.js\";\n\nconst DEFAULT_SOURCE_ENCODING = \"WIN1252\";\n\nfunction defaultPostgresDirectOutputPath(inputPath: string): string {\n const baseName = path.basename(inputPath);\n if (baseName.toLowerCase() === \"sanitized\") {\n return path.join(path.dirname(inputPath), \"postgres-direct\");\n }\n\n return path.join(path.dirname(inputPath), `${baseName}-postgres-direct`);\n}\n\nfunction inferNextStep(scriptPath: string): string {\n return `psql \"postgres://postgres:postgres@localhost:5432/cnpj\" -f ${scriptPath.replace(/\\\\/g, \"/\")}`;\n}\n\nfunction normalizeSourceEncoding(value: string | undefined): string {\n const encoding = (value ?? DEFAULT_SOURCE_ENCODING).trim();\n\n if (!/^[A-Za-z0-9_-]+$/.test(encoding)) {\n throw new ValidationError(\n `Invalid source encoding: ${value}. Use a PostgreSQL client encoding name such as WIN1252 or UTF8.`,\n );\n }\n\n return encoding.toUpperCase();\n}\n\nexport async function generatePostgresDirectScript(\n inputPath: string,\n options: PostgresDirectScriptOptions = {},\n): Promise<PostgresDirectScriptSummary> {\n if (options.dataset && !isImportDatasetType(options.dataset)) {\n throw new ValidationError(`Unsupported dataset type: ${options.dataset}.`);\n }\n\n const validation = await validateInputDirectory(inputPath);\n if (!validation.ok && !options.dataset) {\n throw new ValidationError(\n `The input directory is not ready for PostgreSQL direct script generation. ${validation.errors.join(\" \")}`,\n );\n }\n\n const validatedPath = validation.ok\n ? validation.validatedPath\n : path.resolve(inputPath);\n const outputPath = path.resolve(\n options.outputPath ?? defaultPostgresDirectOutputPath(validatedPath),\n );\n const sourceEncoding = normalizeSourceEncoding(options.sourceEncoding);\n const inspected = await inspectFiles(validatedPath);\n const recognizedFiles = inspected.entries\n .filter((entry) => entry.entryKind === \"file\")\n .flatMap((entry) => {\n if (!isImportDatasetType(entry.inferredType)) {\n return [];\n }\n\n if (options.dataset && entry.inferredType !== options.dataset) {\n return [];\n }\n\n return [{ ...entry, inferredType: entry.inferredType }];\n })\n .sort(sortEntries);\n\n if (recognizedFiles.length === 0) {\n throw new ValidationError(\n \"No recognized dataset files were found for PostgreSQL direct script generation.\",\n );\n }\n\n const datasets = [\n ...new Set(recognizedFiles.map((entry) => entry.inferredType)),\n ].sort(\n (left, right) => IMPORT_ORDER.indexOf(left) - IMPORT_ORDER.indexOf(right),\n );\n\n options.onProgress?.({\n kind: \"start\",\n inputPath: path.resolve(inputPath),\n validatedPath,\n outputPath,\n totalFiles: recognizedFiles.length,\n datasets,\n sourceEncoding,\n });\n\n await mkdir(outputPath, { recursive: true });\n\n const sourceFiles: PostgresDirectSourceFile[] = [];\n const summariesByDataset = new Map<\n ImportDatasetType,\n PostgresDirectScriptDatasetSummary\n >();\n\n for (const [index, entry] of recognizedFiles.entries()) {\n const dataset = entry.inferredType;\n const absolutePath = path.join(validatedPath, entry.relativePath);\n const fileStats = await stat(absolutePath);\n\n sourceFiles.push({\n dataset,\n absolutePath,\n relativePath: entry.relativePath,\n fileSize: fileStats.size,\n });\n\n const currentSummary = summariesByDataset.get(dataset) ?? {\n dataset,\n files: 0,\n totalBytes: 0,\n sourceFiles: [],\n };\n currentSummary.files += 1;\n currentSummary.totalBytes += fileStats.size;\n currentSummary.sourceFiles.push(absolutePath);\n summariesByDataset.set(dataset, currentSummary);\n\n options.onProgress?.({\n kind: \"file_registered\",\n dataset,\n fileIndex: index + 1,\n totalFiles: recognizedFiles.length,\n inputFile: buildDisplayPath(absolutePath),\n fileSize: fileStats.size,\n });\n }\n\n const scriptName = options.scriptName ?? \"import-postgres-direct.sql\";\n const scriptPath = path.join(outputPath, scriptName);\n const script = generatePostgresSanitizedDirectImportScript({\n files: sourceFiles,\n sourceEncoding,\n });\n await writeFile(scriptPath, script, \"utf8\");\n\n const manifestPath = path.join(outputPath, \"manifest.json\");\n const summaryDatasets = [...summariesByDataset.values()].sort(\n (left, right) =>\n IMPORT_ORDER.indexOf(left.dataset) - IMPORT_ORDER.indexOf(right.dataset),\n );\n const totalBytes = summaryDatasets.reduce(\n (sum, item) => sum + item.totalBytes,\n 0,\n );\n\n const manifest = {\n generatedAt: new Date().toISOString(),\n mode: \"direct-sanitized-script\",\n inputPath: path.resolve(inputPath),\n validatedPath,\n outputPath,\n scriptPath,\n sourceEncoding,\n totalFiles: sourceFiles.length,\n totalBytes,\n datasets: summaryDatasets,\n };\n await writeFile(\n manifestPath,\n `${JSON.stringify(manifest, null, 2)}\\n`,\n \"utf8\",\n );\n\n options.onProgress?.({\n kind: \"finish\",\n outputPath,\n scriptPath,\n totalFiles: sourceFiles.length,\n totalBytes,\n });\n\n return {\n inputPath: path.resolve(inputPath),\n validatedPath,\n outputPath,\n scriptPath,\n manifestPath,\n sourceEncoding,\n totalFiles: sourceFiles.length,\n totalBytes,\n datasets: summaryDatasets,\n warnings: [\n ...(validation.ok ? [] : validation.errors),\n \"This script imports sanitized Receita files directly with psql \\\\copy. It avoids rewriting the full dataset into a second CSV tree.\",\n \"The generated script expects the database schema generated by cnpj-db-loader to be applied before execution.\",\n \"Use --source-encoding UTF8 only if your sanitized files are already UTF-8. The default WIN1252 matches the usual Receita file encoding.\",\n ],\n nextStep: inferNextStep(scriptPath),\n };\n}\n"],"mappings":"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","names":["os","path","tableExists","tableExists","result","path","writeFile","writeFile","path","path","inferNextStep","mkdir","readdir","stat","path","readdir","path","mkdir","stat","mkdir","writeFile","os","path","path","os","mkdir","writeFile","path","performance","Client","performance","buildPartnerDedupeKey","stat","path","totalRows","totalBatches","persistCheckpoint","performance","performance","performance","performance","STAGING_TABLE_BY_DATASET","performance","path","plan","path","Client","path","performance","Client","Client","mkdir","stat","path","mkdir","readFile","stat","writeFile","path","path","stat","readFile","mkdir","writeFile","stat","path","mkdir","readdir","stat","path","safeStat","stat","readdir","path","mkdir","readFile","unlink","readFile","unlink","mkdir","path","createReadStream","createWriteStream","mkdir","path","path","inferNextStep","createWriteStream","mkdir","writeFile","path","path","STAGING_TABLE_BY_DATASET","path","path","inferNextStep","mkdir","createWriteStream","writeFile","mkdir","stat","writeFile","path","path","inferNextStep","mkdir","stat","writeFile"]}
1
+ {"version":3,"sources":["../src/core/errors/app-error.ts","../src/core/errors/service-error.ts","../src/core/errors/validation-error.ts","../src/core/utils/filesystem.ts","../src/core/utils/format.ts","../src/core/utils/string.ts","../src/core/utils/path.ts","../src/core/utils/os.ts","../src/config/config-path.ts","../src/services/config.service.ts","../src/services/database.service.ts","../src/services/import/schema-validation.ts","../src/services/import/checkpoints.ts","../src/services/import/materialization-checkpoints.ts","../src/services/import/plan-store.ts","../src/services/import/targets.ts","../src/services/import/staging-schema.ts","../src/dictionary/layouts/companies.layout.ts","../src/dictionary/layouts/domain.layout.ts","../src/dictionary/layouts/establishments.layout.ts","../src/dictionary/layouts/partners.layout.ts","../src/dictionary/layouts/simples.layout.ts","../src/services/import/types.ts","../src/services/database/cleanup.ts","../src/services/dictionary.service.ts","../src/services/doctor.service.ts","../src/services/inspect.service.ts","../src/services/schema.service.ts","../src/services/schema/control.ts","../src/services/schema/shared.ts","../src/services/schema/domain.ts","../src/services/schema/indexes.ts","../src/services/schema/operational.ts","../src/services/schema/staging.ts","../src/services/schema/builders.ts","../src/services/schema/types.ts","../src/services/validate.service.ts","../src/services/extract.service.ts","../src/services/input-mode.service.ts","../src/services/logging.service.ts","../src/services/logging/types.ts","../src/services/logging/entry.ts","../src/services/import/runner.ts","../src/services/import/finalizer.ts","../src/services/import/file-import.ts","../src/services/import/checkpoint-manager.ts","../src/services/import/transform.ts","../src/services/import/parser.ts","../src/services/import/sql.ts","../src/services/import/normalizer.ts","../src/services/import/planning.ts","../src/services/import/source-reader.ts","../src/services/import/copy-from.ts","../src/services/import/staging-writer.ts","../src/services/import/quarantine.ts","../src/services/import/quarantine-writer.ts","../src/services/import/materializer.ts","../src/services/import/materialization-sql.ts","../src/services/import/materialization-lookups.ts","../src/services/import/planner.ts","../src/services/import/schema-capabilities.ts","../src/services/import.service.ts","../src/services/quarantine.service.ts","../src/services/quarantine/queries.ts","../src/services/federal-revenue/client.ts","../src/services/federal-revenue/download.ts","../src/services/federal-revenue/manifest.ts","../src/services/federal-revenue/status.ts","../src/services/federal-revenue/clean.ts","../src/services/federal-revenue/lock.ts","../src/services/sanitize.service.ts","../src/services/sanitize/types.ts","../src/services/sanitize/encoding.ts","../src/services/sanitize/runner.ts","../src/services/federal-revenue/sync.ts","../src/services/postgres-direct/exporter.ts","../src/services/postgres-direct/csv.ts","../src/services/postgres-direct/script.ts","../src/services/postgres-direct/generator.ts"],"sourcesContent":["export class AppError extends Error {\n public readonly code: string;\n public readonly details?: unknown;\n\n constructor(message: string, code = \"APP_ERROR\", details?: unknown) {\n super(message);\n this.name = \"AppError\";\n this.code = code;\n this.details = details;\n }\n}\n","import { AppError } from \"./app-error.js\";\n\nexport class ServiceError extends AppError {\n constructor(message: string, details?: unknown) {\n super(message, \"SERVICE_ERROR\", details);\n this.name = \"ServiceError\";\n }\n}\n","import { AppError } from \"./app-error.js\";\n\nexport class ValidationError extends AppError {\n constructor(message: string, details?: unknown) {\n super(message, \"VALIDATION_ERROR\", details);\n this.name = \"ValidationError\";\n }\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nexport async function ensureDirectory(filePath: string): Promise<void> {\n await mkdir(dirname(filePath), { recursive: true });\n}\n\nexport async function safeReadText(\n filePath: string,\n): Promise<string | undefined> {\n try {\n return await readFile(filePath, \"utf8\");\n } catch {\n return undefined;\n }\n}\n\nexport async function safeWriteText(\n filePath: string,\n content: string,\n): Promise<void> {\n await ensureDirectory(filePath);\n await writeFile(filePath, content, \"utf8\");\n}\n","export function prettyJson(value: unknown): string {\n return JSON.stringify(value, null, 2);\n}\n","export function toTitleCase(value: string): string {\n return value\n .trim()\n .split(/\\s+/)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())\n .join(\" \");\n}\n","import path from \"node:path\";\n\nexport function defaultExtractedOutputPath(inputPath: string): string {\n return path.join(inputPath, \"extracted\");\n}\n","import os from \"node:os\";\n\nexport type SupportedOs = \"windows\" | \"macos\" | \"linux\" | \"unknown\";\n\nexport function detectOs(): SupportedOs {\n const platform = os.platform();\n\n if (platform === \"win32\") {\n return \"windows\";\n }\n\n if (platform === \"darwin\") {\n return \"macos\";\n }\n\n if (platform === \"linux\") {\n return \"linux\";\n }\n\n return \"unknown\";\n}\n","import os from \"node:os\";\nimport path from \"node:path\";\n\nexport function getConfigFilePath(): string {\n if (process.platform === \"win32\") {\n const appData =\n process.env.APPDATA ?? path.join(os.homedir(), \"AppData\", \"Roaming\");\n return path.join(appData, \"cnpj-db-loader\", \"config.json\");\n }\n\n return path.join(os.homedir(), \".config\", \"cnpj-db-loader\", \"config.json\");\n}\n","import { ValidationError } from \"../core/errors/index.js\";\nimport type { DatabaseConfig } from \"../core/types/index.js\";\nimport { safeReadText, safeWriteText } from \"../core/utils/index.js\";\nimport { getConfigFilePath } from \"../config/config-path.js\";\n\nexport async function readDatabaseConfig(): Promise<DatabaseConfig> {\n const raw = await safeReadText(getConfigFilePath());\n if (!raw) {\n return {};\n }\n\n return JSON.parse(raw) as DatabaseConfig;\n}\n\nexport async function writeDatabaseConfig(\n config: DatabaseConfig,\n): Promise<void> {\n await safeWriteText(getConfigFilePath(), JSON.stringify(config, null, 2));\n}\n\nexport function assertPostgresUrl(url: string): void {\n let parsed: URL;\n\n try {\n parsed = new URL(url);\n } catch {\n throw new ValidationError(\"The provided database URL is not a valid URL.\", {\n url,\n });\n }\n\n if (![\"postgres:\", \"postgresql:\"].includes(parsed.protocol)) {\n throw new ValidationError(\n \"The database URL must use the postgres or postgresql protocol.\",\n { url },\n );\n }\n}\n\nexport async function setDefaultDbUrl(url: string): Promise<void> {\n assertPostgresUrl(url);\n await writeDatabaseConfig({ defaultDbUrl: url });\n}\n\nexport async function resetDefaultDbUrl(): Promise<void> {\n await writeDatabaseConfig({});\n}\n","import { Client } from \"pg\";\n\nimport { ServiceError, ValidationError } from \"../core/errors/index.js\";\nimport { readDatabaseConfig } from \"./config.service.js\";\nimport {\n cleanupDatabaseCheckpoints,\n cleanupDatabaseMaterializedTables,\n cleanupDatabasePlans,\n cleanupDatabaseStaging,\n type CheckpointCleanupPhase,\n type DatabaseCleanupSummary,\n} from \"./database/cleanup.js\";\nimport type { ImportDatasetType } from \"./import/types.js\";\n\nexport type { CheckpointCleanupPhase, DatabaseCleanupSummary };\n\nexport async function resolveDatabaseUrl(override?: string): Promise<string> {\n if (override) {\n return override;\n }\n\n const config = await readDatabaseConfig();\n\n if (!config.defaultDbUrl) {\n throw new ValidationError(\n 'No database connection is configured. Use \"cnpj-db-loader database config set <postgres-url>\" or pass \"--db-url\".',\n );\n }\n\n return config.defaultDbUrl;\n}\n\nexport async function testDatabaseConnection(url: string): Promise<void> {\n const client = new Client({ connectionString: url });\n\n try {\n await client.connect();\n await client.query(\"select 1\");\n } catch (error) {\n throw new ServiceError(\"The PostgreSQL connection test failed.\", error);\n } finally {\n await client.end().catch(() => undefined);\n }\n}\n\nasync function withDatabaseClient<T>(\n dbUrl: string,\n operation: (client: Client) => Promise<T>,\n): Promise<T> {\n const client = new Client({ connectionString: dbUrl });\n await client.connect();\n\n try {\n return await operation(client);\n } catch (error) {\n throw new ServiceError(\"The database maintenance operation failed.\", error);\n } finally {\n await client.end().catch(() => undefined);\n }\n}\n\nexport async function cleanupDatabaseStagingData(\n options: {\n dbUrl?: string;\n dataset?: ImportDatasetType | undefined;\n validatedPath?: string | undefined;\n } = {},\n): Promise<DatabaseCleanupSummary> {\n const dbUrl = await resolveDatabaseUrl(options.dbUrl);\n return withDatabaseClient(dbUrl, async (client) =>\n cleanupDatabaseStaging(client, {\n dbUrl,\n dataset: options.dataset,\n validatedPath: options.validatedPath,\n }),\n );\n}\n\nexport async function cleanupDatabaseMaterializedData(\n options: {\n dbUrl?: string;\n dataset?: ImportDatasetType | undefined;\n } = {},\n): Promise<DatabaseCleanupSummary> {\n const dbUrl = await resolveDatabaseUrl(options.dbUrl);\n return withDatabaseClient(dbUrl, async (client) =>\n cleanupDatabaseMaterializedTables(client, {\n dbUrl,\n dataset: options.dataset,\n }),\n );\n}\n\nexport async function cleanupDatabaseCheckpointsData(\n options: {\n dbUrl?: string;\n phase?: CheckpointCleanupPhase | undefined;\n dataset?: ImportDatasetType | undefined;\n validatedPath?: string | undefined;\n planId?: number | undefined;\n } = {},\n): Promise<DatabaseCleanupSummary> {\n const phase = options.phase ?? \"all\";\n if (![\"load\", \"materialization\", \"all\"].includes(phase)) {\n throw new ValidationError(\n `Unsupported checkpoint cleanup phase: ${phase}. Use load, materialization, or all.`,\n );\n }\n\n const dbUrl = await resolveDatabaseUrl(options.dbUrl);\n return withDatabaseClient(dbUrl, async (client) =>\n cleanupDatabaseCheckpoints(client, {\n dbUrl,\n phase,\n dataset: options.dataset,\n validatedPath: options.validatedPath,\n planId: options.planId,\n }),\n );\n}\n\nexport async function cleanupDatabasePlansData(\n options: {\n dbUrl?: string;\n validatedPath?: string | undefined;\n planId?: number | undefined;\n } = {},\n): Promise<DatabaseCleanupSummary> {\n const dbUrl = await resolveDatabaseUrl(options.dbUrl);\n return withDatabaseClient(dbUrl, async (client) =>\n cleanupDatabasePlans(client, {\n dbUrl,\n validatedPath: options.validatedPath,\n planId: options.planId,\n }),\n );\n}\n\nexport async function resolveDbUrl(override?: string): Promise<string> {\n return resolveDatabaseUrl(override);\n}\n","import type { Client } from \"pg\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\n\nasync function tableExists(\n client: Client,\n tableName: string,\n): Promise<boolean> {\n const result = await client.query<{ exists: string | null }>(\n \"select to_regclass(current_schema() || '.' || $1) as exists\",\n [tableName],\n );\n\n return Boolean(result.rows[0]?.exists);\n}\n\nasync function readColumnNames(\n client: Client,\n tableName: string,\n): Promise<Set<string>> {\n const result = await client.query<{ column_name: string }>(\n `select column_name\n from information_schema.columns\n where table_schema = current_schema()\n and table_name = $1`,\n [tableName],\n );\n\n return new Set(result.rows.map((row) => row.column_name));\n}\n\nexport async function ensureTableShape(\n client: Client,\n input: {\n tableName: string;\n requiredColumns: readonly string[];\n helpMessage: string;\n },\n): Promise<void> {\n const exists = await tableExists(client, input.tableName);\n\n if (!exists) {\n throw new ValidationError(\n `${input.helpMessage} Missing table: ${input.tableName}.`,\n );\n }\n\n const availableColumns = await readColumnNames(client, input.tableName);\n const missingColumns = input.requiredColumns.filter(\n (columnName) => !availableColumns.has(columnName),\n );\n\n if (missingColumns.length > 0) {\n throw new ValidationError(\n `${input.helpMessage} Table ${input.tableName} is missing required columns: ${missingColumns.join(\", \")}.`,\n );\n }\n}\n","import { Client } from \"pg\";\n\nimport { ensureTableShape } from \"./schema-validation.js\";\nimport type {\n ImportCheckpointRecord,\n ImportCheckpointStatus,\n ImportDatasetPlan,\n} from \"./types.js\";\n\nexport async function ensureCheckpointTable(client: Client): Promise<void> {\n await ensureTableShape(client, {\n tableName: \"import_checkpoints\",\n requiredColumns: [\n \"dataset\",\n \"file_path\",\n \"file_size\",\n \"file_mtime\",\n \"byte_offset\",\n \"rows_committed\",\n \"status\",\n \"last_error\",\n \"updated_at\",\n ],\n helpMessage:\n 'The import checkpoint schema is required. Run \"cnpj-db-loader schema generate --profile full\" and apply the SQL before importing.',\n });\n}\n\nexport async function readCheckpoint(\n client: Client,\n dataset: ImportCheckpointRecord[\"dataset\"],\n filePath: string,\n fileSize: number,\n fileMtime: Date,\n): Promise<ImportCheckpointRecord> {\n const existing = await client.query<{\n file_size: string;\n file_mtime: Date;\n byte_offset: string;\n rows_committed: string;\n status: ImportCheckpointStatus;\n last_error: string | null;\n }>(\n `select file_size, file_mtime, byte_offset, rows_committed, status, last_error\n from import_checkpoints\n where dataset = $1 and file_path = $2`,\n [dataset, filePath],\n );\n\n const baseRecord: ImportCheckpointRecord = {\n dataset,\n filePath,\n fileSize,\n fileMtime,\n byteOffset: 0,\n rowsCommitted: 0,\n status: \"pending\",\n lastError: null,\n };\n\n if (existing.rowCount === 0) {\n return baseRecord;\n }\n\n const row = existing.rows[0]!;\n const checkpoint: ImportCheckpointRecord = {\n dataset,\n filePath,\n fileSize: Number.parseInt(row.file_size, 10),\n fileMtime: new Date(row.file_mtime),\n byteOffset: Number.parseInt(row.byte_offset, 10),\n rowsCommitted: Number.parseInt(row.rows_committed, 10),\n status: row.status,\n lastError: row.last_error,\n };\n\n const sameMetadata =\n checkpoint.fileSize === fileSize &&\n checkpoint.fileMtime.getTime() === fileMtime.getTime();\n\n if (!sameMetadata) {\n return baseRecord;\n }\n\n return checkpoint;\n}\n\nexport async function writeCheckpoint(\n client: Client,\n checkpoint: ImportCheckpointRecord,\n): Promise<void> {\n await client.query(\n `insert into import_checkpoints (\n dataset,\n file_path,\n file_size,\n file_mtime,\n byte_offset,\n rows_committed,\n status,\n last_error,\n updated_at\n ) values ($1, $2, $3, $4, $5, $6, $7, $8, now())\n on conflict (dataset, file_path)\n do update set\n file_size = excluded.file_size,\n file_mtime = excluded.file_mtime,\n byte_offset = excluded.byte_offset,\n rows_committed = excluded.rows_committed,\n status = excluded.status,\n last_error = excluded.last_error,\n updated_at = now()`,\n [\n checkpoint.dataset,\n checkpoint.filePath,\n checkpoint.fileSize,\n checkpoint.fileMtime,\n checkpoint.byteOffset,\n checkpoint.rowsCommitted,\n checkpoint.status,\n checkpoint.lastError ?? null,\n ],\n );\n}\n\nexport async function markCheckpointFailed(\n client: Client,\n checkpoint: ImportCheckpointRecord,\n errorMessage: string,\n): Promise<void> {\n await writeCheckpoint(client, {\n ...checkpoint,\n status: \"failed\",\n lastError: errorMessage,\n });\n}\n\nexport async function hydratePlanWithCheckpoints(\n client: Client,\n datasets: ImportDatasetPlan[],\n batchSize: number,\n): Promise<{\n committedRows: number;\n committedBatches: number;\n completedFiles: number;\n resumedFiles: number;\n skippedCompletedFiles: number;\n}> {\n let committedRows = 0;\n let committedBatches = 0;\n let completedFiles = 0;\n let resumedFiles = 0;\n let skippedCompletedFiles = 0;\n\n for (const datasetPlan of datasets) {\n for (const filePlan of datasetPlan.files) {\n const checkpoint = await readCheckpoint(\n client,\n datasetPlan.dataset,\n filePlan.absolutePath,\n filePlan.fileSize,\n filePlan.fileMtime,\n );\n filePlan.checkpoint = checkpoint;\n\n if (checkpoint.rowsCommitted > 0) {\n committedRows += checkpoint.rowsCommitted;\n committedBatches += Math.min(\n filePlan.totalBatches,\n Math.ceil(checkpoint.rowsCommitted / batchSize),\n );\n }\n\n if (\n checkpoint.status === \"completed\" &&\n checkpoint.byteOffset >= filePlan.fileSize\n ) {\n completedFiles += 1;\n skippedCompletedFiles += 1;\n } else if (checkpoint.byteOffset > 0 || checkpoint.rowsCommitted > 0) {\n resumedFiles += 1;\n }\n }\n }\n\n return {\n committedRows,\n committedBatches,\n completedFiles,\n resumedFiles,\n skippedCompletedFiles,\n };\n}\n","import type { Client } from \"pg\";\n\nimport { ensureTableShape } from \"./schema-validation.js\";\nimport type { ImportPhaseStatus } from \"./types.js\";\n\nexport type MaterializationCheckpointRecord = {\n planId: number;\n dataset: string;\n targetTable: string;\n status: ImportPhaseStatus;\n rowsMaterialized: number;\n lastStagingId: number;\n chunksCompleted: number;\n lastError: string | null;\n startedAt: Date | null;\n completedAt: Date | null;\n updatedAt: Date;\n stagingRowCountVerified: number | null;\n stagingMaxStagingIdVerified: number | null;\n stagingValidatedAt: Date | null;\n lookupReconciliationStatus: ImportPhaseStatus;\n lookupReconciliationRowCountVerified: number | null;\n lookupReconciliationMaxStagingIdVerified: number | null;\n lookupReconciliationCompletedAt: Date | null;\n lastChunkFirstStagingId: number;\n lastChunkLastStagingId: number;\n lastChunkRows: number;\n};\n\ntype MaterializationCheckpointRow = {\n plan_id: string;\n dataset: string;\n target_table: string;\n status: ImportPhaseStatus;\n rows_materialized: string;\n last_staging_id: string;\n chunks_completed: string;\n last_error: string | null;\n started_at: Date | null;\n completed_at: Date | null;\n updated_at: Date;\n staging_row_count_verified: string | null;\n staging_max_staging_id_verified: string | null;\n staging_validated_at: Date | null;\n lookup_reconciliation_status: ImportPhaseStatus | null;\n lookup_reconciliation_row_count_verified: string | null;\n lookup_reconciliation_max_staging_id_verified: string | null;\n lookup_reconciliation_completed_at: Date | null;\n last_chunk_first_staging_id: string | null;\n last_chunk_last_staging_id: string | null;\n last_chunk_rows: string | null;\n};\n\nfunction parseNullableInt(value: string | null): number | null {\n return value === null ? null : Number.parseInt(value, 10);\n}\n\nfunction mapCheckpointRow(\n row: MaterializationCheckpointRow,\n): MaterializationCheckpointRecord {\n return {\n planId: Number.parseInt(row.plan_id, 10),\n dataset: row.dataset,\n targetTable: row.target_table,\n status: row.status,\n rowsMaterialized: Number.parseInt(row.rows_materialized, 10),\n lastStagingId: Number.parseInt(row.last_staging_id, 10),\n chunksCompleted: Number.parseInt(row.chunks_completed, 10),\n lastError: row.last_error,\n startedAt: row.started_at ? new Date(row.started_at) : null,\n completedAt: row.completed_at ? new Date(row.completed_at) : null,\n updatedAt: new Date(row.updated_at),\n stagingRowCountVerified: parseNullableInt(row.staging_row_count_verified),\n stagingMaxStagingIdVerified: parseNullableInt(\n row.staging_max_staging_id_verified,\n ),\n stagingValidatedAt: row.staging_validated_at\n ? new Date(row.staging_validated_at)\n : null,\n lookupReconciliationStatus: row.lookup_reconciliation_status ?? \"pending\",\n lookupReconciliationRowCountVerified: parseNullableInt(\n row.lookup_reconciliation_row_count_verified,\n ),\n lookupReconciliationMaxStagingIdVerified: parseNullableInt(\n row.lookup_reconciliation_max_staging_id_verified,\n ),\n lookupReconciliationCompletedAt: row.lookup_reconciliation_completed_at\n ? new Date(row.lookup_reconciliation_completed_at)\n : null,\n lastChunkFirstStagingId: Number.parseInt(\n row.last_chunk_first_staging_id ?? \"0\",\n 10,\n ),\n lastChunkLastStagingId: Number.parseInt(\n row.last_chunk_last_staging_id ?? \"0\",\n 10,\n ),\n lastChunkRows: Number.parseInt(row.last_chunk_rows ?? \"0\", 10),\n };\n}\n\nexport async function ensureMaterializationCheckpointTable(\n client: Client,\n): Promise<void> {\n await ensureTableShape(client, {\n tableName: \"import_materialization_checkpoints\",\n requiredColumns: [\n \"plan_id\",\n \"dataset\",\n \"target_table\",\n \"status\",\n \"rows_materialized\",\n \"last_staging_id\",\n \"chunks_completed\",\n \"last_error\",\n \"started_at\",\n \"completed_at\",\n \"updated_at\",\n \"staging_row_count_verified\",\n \"staging_max_staging_id_verified\",\n \"staging_validated_at\",\n \"lookup_reconciliation_status\",\n \"lookup_reconciliation_row_count_verified\",\n \"lookup_reconciliation_max_staging_id_verified\",\n \"lookup_reconciliation_completed_at\",\n \"last_chunk_first_staging_id\",\n \"last_chunk_last_staging_id\",\n \"last_chunk_rows\",\n ],\n helpMessage:\n 'The materialization checkpoint schema is required. Run \"cnpj-db-loader schema generate --profile full\" and apply the SQL before importing.',\n });\n}\n\nexport async function readMaterializationCheckpoint(\n client: Client,\n planId: number,\n dataset: string,\n targetTable: string,\n): Promise<MaterializationCheckpointRecord> {\n const result = await client.query<MaterializationCheckpointRow>(\n `select\n plan_id,\n dataset,\n target_table,\n status,\n rows_materialized,\n last_staging_id,\n chunks_completed,\n last_error,\n started_at,\n completed_at,\n updated_at,\n staging_row_count_verified,\n staging_max_staging_id_verified,\n staging_validated_at,\n lookup_reconciliation_status,\n lookup_reconciliation_row_count_verified,\n lookup_reconciliation_max_staging_id_verified,\n lookup_reconciliation_completed_at,\n last_chunk_first_staging_id,\n last_chunk_last_staging_id,\n last_chunk_rows\n from import_materialization_checkpoints\n where plan_id = $1 and dataset = $2`,\n [planId, dataset],\n );\n\n if (result.rowCount === 0) {\n return {\n planId,\n dataset,\n targetTable,\n status: \"pending\",\n rowsMaterialized: 0,\n lastStagingId: 0,\n chunksCompleted: 0,\n lastError: null,\n startedAt: null,\n completedAt: null,\n updatedAt: new Date(),\n stagingRowCountVerified: null,\n stagingMaxStagingIdVerified: null,\n stagingValidatedAt: null,\n lookupReconciliationStatus: \"pending\",\n lookupReconciliationRowCountVerified: null,\n lookupReconciliationMaxStagingIdVerified: null,\n lookupReconciliationCompletedAt: null,\n lastChunkFirstStagingId: 0,\n lastChunkLastStagingId: 0,\n lastChunkRows: 0,\n };\n }\n\n return mapCheckpointRow(result.rows[0]!);\n}\n\nexport async function writeMaterializationCheckpoint(\n client: Client,\n checkpoint: MaterializationCheckpointRecord,\n): Promise<void> {\n await client.query(\n `insert into import_materialization_checkpoints (\n plan_id,\n dataset,\n target_table,\n status,\n rows_materialized,\n last_staging_id,\n chunks_completed,\n last_error,\n started_at,\n completed_at,\n updated_at,\n staging_row_count_verified,\n staging_max_staging_id_verified,\n staging_validated_at,\n lookup_reconciliation_status,\n lookup_reconciliation_row_count_verified,\n lookup_reconciliation_max_staging_id_verified,\n lookup_reconciliation_completed_at,\n last_chunk_first_staging_id,\n last_chunk_last_staging_id,\n last_chunk_rows\n ) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, now(), $11, $12, $13, $14, $15, $16, $17, $18, $19, $20)\n on conflict (plan_id, dataset)\n do update set\n target_table = excluded.target_table,\n status = excluded.status,\n rows_materialized = excluded.rows_materialized,\n last_staging_id = excluded.last_staging_id,\n chunks_completed = excluded.chunks_completed,\n last_error = excluded.last_error,\n started_at = excluded.started_at,\n completed_at = excluded.completed_at,\n updated_at = now(),\n staging_row_count_verified = excluded.staging_row_count_verified,\n staging_max_staging_id_verified = excluded.staging_max_staging_id_verified,\n staging_validated_at = excluded.staging_validated_at,\n lookup_reconciliation_status = excluded.lookup_reconciliation_status,\n lookup_reconciliation_row_count_verified = excluded.lookup_reconciliation_row_count_verified,\n lookup_reconciliation_max_staging_id_verified = excluded.lookup_reconciliation_max_staging_id_verified,\n lookup_reconciliation_completed_at = excluded.lookup_reconciliation_completed_at,\n last_chunk_first_staging_id = excluded.last_chunk_first_staging_id,\n last_chunk_last_staging_id = excluded.last_chunk_last_staging_id,\n last_chunk_rows = excluded.last_chunk_rows`,\n [\n checkpoint.planId,\n checkpoint.dataset,\n checkpoint.targetTable,\n checkpoint.status,\n checkpoint.rowsMaterialized,\n checkpoint.lastStagingId,\n checkpoint.chunksCompleted,\n checkpoint.lastError,\n checkpoint.startedAt,\n checkpoint.completedAt,\n checkpoint.stagingRowCountVerified,\n checkpoint.stagingMaxStagingIdVerified,\n checkpoint.stagingValidatedAt,\n checkpoint.lookupReconciliationStatus,\n checkpoint.lookupReconciliationRowCountVerified,\n checkpoint.lookupReconciliationMaxStagingIdVerified,\n checkpoint.lookupReconciliationCompletedAt,\n checkpoint.lastChunkFirstStagingId,\n checkpoint.lastChunkLastStagingId,\n checkpoint.lastChunkRows,\n ],\n );\n}\n\nexport async function writeMaterializationCheckpointProgress(\n client: Client,\n checkpoint: MaterializationCheckpointRecord,\n): Promise<void> {\n await client.query(\n `update import_materialization_checkpoints\n set status = $3,\n rows_materialized = $4,\n last_staging_id = $5,\n chunks_completed = $6,\n last_error = $7,\n started_at = $8,\n completed_at = $9,\n updated_at = now(),\n last_chunk_first_staging_id = $10,\n last_chunk_last_staging_id = $11,\n last_chunk_rows = $12\n where plan_id = $1 and dataset = $2`,\n [\n checkpoint.planId,\n checkpoint.dataset,\n checkpoint.status,\n checkpoint.rowsMaterialized,\n checkpoint.lastStagingId,\n checkpoint.chunksCompleted,\n checkpoint.lastError,\n checkpoint.startedAt,\n checkpoint.completedAt,\n checkpoint.lastChunkFirstStagingId,\n checkpoint.lastChunkLastStagingId,\n checkpoint.lastChunkRows,\n ],\n );\n}\n\nexport async function resetMaterializationCheckpoints(\n client: Client,\n planId: number,\n): Promise<void> {\n await client.query(\n `delete from import_materialization_checkpoints where plan_id = $1`,\n [planId],\n );\n}\n","import { Client } from \"pg\";\n\nimport { ensureTableShape } from \"./schema-validation.js\";\nimport type {\n ImportDatasetPlan,\n ImportDatasetType,\n ImportPhaseStatus,\n ImportPlanRecord,\n ImportPlanStatus,\n} from \"./types.js\";\n\nexport async function ensureImportPlanTables(client: Client): Promise<void> {\n await ensureTableShape(client, {\n tableName: \"import_plans\",\n requiredColumns: [\n \"source_fingerprint\",\n \"input_path\",\n \"validated_path\",\n \"batch_size\",\n \"target_database\",\n \"total_datasets\",\n \"total_files\",\n \"total_rows\",\n \"total_batches\",\n \"execution_order\",\n \"status\",\n \"load_status\",\n \"materialization_status\",\n \"last_phase\",\n \"last_error\",\n \"created_at\",\n \"updated_at\",\n \"last_used_at\",\n ],\n helpMessage:\n 'The import plan schema is required. Run \"cnpj-db-loader schema generate --profile full\" and apply the SQL before importing.',\n });\n\n await ensureTableShape(client, {\n tableName: \"import_plan_files\",\n requiredColumns: [\n \"plan_id\",\n \"dataset\",\n \"dataset_index\",\n \"file_index\",\n \"file_path\",\n \"file_display_path\",\n \"file_size\",\n \"file_mtime\",\n \"total_rows\",\n \"total_batches\",\n ],\n helpMessage:\n 'The import plan schema is required. Run \"cnpj-db-loader schema generate --profile full\" and apply the SQL before importing.',\n });\n}\n\ntype ImportPlanRow = {\n id: string;\n source_fingerprint: string;\n input_path: string;\n validated_path: string;\n batch_size: string;\n target_database: string;\n total_datasets: string;\n total_files: string;\n total_rows: string;\n total_batches: string;\n execution_order: ImportDatasetType[];\n status: ImportPlanStatus;\n load_status: ImportPhaseStatus;\n materialization_status: ImportPhaseStatus;\n last_phase: string | null;\n last_error: string | null;\n created_at: Date;\n updated_at: Date;\n last_used_at: Date;\n};\n\ntype ImportPlanFileRow = {\n dataset: ImportDatasetType;\n file_path: string;\n file_display_path: string;\n file_size: string;\n file_mtime: Date;\n total_rows: string;\n total_batches: string;\n dataset_index: string;\n file_index: string;\n};\n\nfunction mapImportPlanRow(row: ImportPlanRow): ImportPlanRecord {\n return {\n id: Number.parseInt(row.id, 10),\n sourceFingerprint: row.source_fingerprint,\n inputPath: row.input_path,\n validatedPath: row.validated_path,\n batchSize: Number.parseInt(row.batch_size, 10),\n targetDatabase: row.target_database,\n totalDatasets: Number.parseInt(row.total_datasets, 10),\n totalFiles: Number.parseInt(row.total_files, 10),\n totalRows: Number.parseInt(row.total_rows, 10),\n totalBatches: Number.parseInt(row.total_batches, 10),\n executionOrder: row.execution_order,\n status: row.status,\n loadStatus: row.load_status,\n materializationStatus: row.materialization_status,\n lastPhase: row.last_phase,\n lastError: row.last_error,\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n lastUsedAt: new Date(row.last_used_at),\n };\n}\n\nasync function readPlanDatasets(\n client: Client,\n plan: ImportPlanRecord,\n): Promise<ImportDatasetPlan[]> {\n const filesResult = await client.query<ImportPlanFileRow>(\n `select\n dataset,\n file_path,\n file_display_path,\n file_size,\n file_mtime,\n total_rows,\n total_batches,\n dataset_index,\n file_index\n from import_plan_files\n where plan_id = $1\n order by dataset_index asc, file_index asc`,\n [plan.id],\n );\n\n const grouped = new Map<ImportDatasetType, ImportDatasetPlan>();\n\n for (const row of filesResult.rows) {\n const current = grouped.get(row.dataset) ?? {\n dataset: row.dataset,\n files: [],\n totalRows: 0,\n totalBatches: 0,\n };\n\n const fileTotalRows = Number.parseInt(row.total_rows, 10);\n const fileTotalBatches = Number.parseInt(row.total_batches, 10);\n\n current.files.push({\n dataset: row.dataset,\n absolutePath: row.file_path,\n displayPath: row.file_display_path,\n fileSize: Number.parseInt(row.file_size, 10),\n fileMtime: new Date(row.file_mtime),\n totalRows: fileTotalRows,\n totalBatches: fileTotalBatches,\n });\n current.totalRows += fileTotalRows;\n current.totalBatches += fileTotalBatches;\n grouped.set(row.dataset, current);\n }\n\n return plan.executionOrder\n .map((dataset) => grouped.get(dataset))\n .filter((item): item is ImportDatasetPlan => item !== undefined);\n}\n\nasync function readPlanRecordByQuery(\n client: Client,\n query: string,\n values: readonly unknown[],\n): Promise<{\n plan: ImportPlanRecord;\n datasets: ImportDatasetPlan[];\n} | null> {\n const planResult = await client.query<ImportPlanRow>(query, [...values]);\n\n if (planResult.rowCount === 0) {\n return null;\n }\n\n const plan = mapImportPlanRow(planResult.rows[0]!);\n const datasets = await readPlanDatasets(client, plan);\n\n await client.query(\n `update import_plans set last_used_at = now(), updated_at = now() where id = $1`,\n [plan.id],\n );\n\n return { plan, datasets };\n}\n\nexport async function readSavedImportPlan(\n client: Client,\n sourceFingerprint: string,\n): Promise<{\n plan: ImportPlanRecord;\n datasets: ImportDatasetPlan[];\n} | null> {\n return readPlanRecordByQuery(\n client,\n `select\n id,\n source_fingerprint,\n input_path,\n validated_path,\n batch_size,\n target_database,\n total_datasets,\n total_files,\n total_rows,\n total_batches,\n execution_order,\n status,\n load_status,\n materialization_status,\n last_phase,\n last_error,\n created_at,\n updated_at,\n last_used_at\n from import_plans\n where source_fingerprint = $1`,\n [sourceFingerprint],\n );\n}\n\nexport async function readLatestImportPlanForValidatedPath(\n client: Client,\n validatedPath: string,\n targetDatabase: string,\n): Promise<{\n plan: ImportPlanRecord;\n datasets: ImportDatasetPlan[];\n} | null> {\n return readPlanRecordByQuery(\n client,\n `select\n id,\n source_fingerprint,\n input_path,\n validated_path,\n batch_size,\n target_database,\n total_datasets,\n total_files,\n total_rows,\n total_batches,\n execution_order,\n status,\n load_status,\n materialization_status,\n last_phase,\n last_error,\n created_at,\n updated_at,\n last_used_at\n from import_plans\n where validated_path = $1\n and target_database = $2\n order by last_used_at desc, updated_at desc, id desc\n limit 1`,\n [validatedPath, targetDatabase],\n );\n}\n\nexport async function saveImportPlan(\n client: Client,\n input: {\n sourceFingerprint: string;\n inputPath: string;\n validatedPath: string;\n batchSize: number;\n targetDatabase: string;\n datasets: ImportDatasetPlan[];\n totalFiles: number;\n totalRows: number;\n totalBatches: number;\n },\n): Promise<ImportPlanRecord> {\n await client.query(\"begin\");\n try {\n const existing = await client.query<{ id: string }>(\n `select id from import_plans where source_fingerprint = $1`,\n [input.sourceFingerprint],\n );\n\n if ((existing.rowCount ?? 0) > 0) {\n await client.query(`delete from import_plan_files where plan_id = $1`, [\n existing.rows[0]!.id,\n ]);\n }\n\n const planResult = await client.query<ImportPlanRow>(\n `insert into import_plans (\n source_fingerprint,\n input_path,\n validated_path,\n batch_size,\n target_database,\n total_datasets,\n total_files,\n total_rows,\n total_batches,\n execution_order,\n status,\n load_status,\n materialization_status,\n last_phase,\n last_error,\n created_at,\n updated_at,\n last_used_at\n ) values (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10::jsonb, 'planned', 'pending', 'pending', 'planning', null, now(), now(), now()\n )\n on conflict (source_fingerprint)\n do update set\n input_path = excluded.input_path,\n validated_path = excluded.validated_path,\n batch_size = excluded.batch_size,\n target_database = excluded.target_database,\n total_datasets = excluded.total_datasets,\n total_files = excluded.total_files,\n total_rows = excluded.total_rows,\n total_batches = excluded.total_batches,\n execution_order = excluded.execution_order,\n status = 'planned',\n load_status = 'pending',\n materialization_status = 'pending',\n last_phase = 'planning',\n last_error = null,\n updated_at = now(),\n last_used_at = now()\n returning\n id,\n source_fingerprint,\n input_path,\n validated_path,\n batch_size,\n target_database,\n total_datasets,\n total_files,\n total_rows,\n total_batches,\n execution_order,\n status,\n load_status,\n materialization_status,\n last_phase,\n last_error,\n created_at,\n updated_at,\n last_used_at`,\n [\n input.sourceFingerprint,\n input.inputPath,\n input.validatedPath,\n input.batchSize,\n input.targetDatabase,\n input.datasets.length,\n input.totalFiles,\n input.totalRows,\n input.totalBatches,\n JSON.stringify(input.datasets.map((item) => item.dataset)),\n ],\n );\n\n const plan = mapImportPlanRow(planResult.rows[0]!);\n\n let fileIndex = 0;\n for (const [datasetIndex, datasetPlan] of input.datasets.entries()) {\n for (const filePlan of datasetPlan.files) {\n fileIndex += 1;\n await client.query(\n `insert into import_plan_files (\n plan_id,\n dataset,\n dataset_index,\n file_index,\n file_path,\n file_display_path,\n file_size,\n file_mtime,\n total_rows,\n total_batches\n ) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)\n on conflict (plan_id, file_path)\n do update set\n dataset = excluded.dataset,\n dataset_index = excluded.dataset_index,\n file_index = excluded.file_index,\n file_display_path = excluded.file_display_path,\n file_size = excluded.file_size,\n file_mtime = excluded.file_mtime,\n total_rows = excluded.total_rows,\n total_batches = excluded.total_batches`,\n [\n plan.id,\n datasetPlan.dataset,\n datasetIndex + 1,\n fileIndex,\n filePlan.absolutePath,\n filePlan.displayPath,\n filePlan.fileSize,\n filePlan.fileMtime,\n filePlan.totalRows,\n filePlan.totalBatches,\n ],\n );\n }\n }\n\n await client.query(\"commit\");\n return plan;\n } catch (error) {\n await client.query(\"rollback\");\n throw error;\n }\n}\n\nexport async function updateImportPlanStatus(\n client: Client,\n planId: number,\n status: ImportPlanStatus,\n): Promise<void> {\n await client.query(\n `update import_plans\n set status = $2,\n updated_at = now(),\n last_used_at = now()\n where id = $1`,\n [planId, status],\n );\n}\n\nexport async function updateImportPlanPhaseState(\n client: Client,\n input: {\n planId: number;\n loadStatus?: ImportPhaseStatus;\n materializationStatus?: ImportPhaseStatus;\n lastPhase?: string | null;\n lastError?: string | null;\n },\n): Promise<void> {\n const assignments: string[] = [\"updated_at = now()\", \"last_used_at = now()\"];\n const values: unknown[] = [input.planId];\n let nextIndex = 2;\n\n if (input.loadStatus !== undefined) {\n assignments.push(`load_status = $${nextIndex}`);\n values.push(input.loadStatus);\n nextIndex += 1;\n }\n\n if (input.materializationStatus !== undefined) {\n assignments.push(`materialization_status = $${nextIndex}`);\n values.push(input.materializationStatus);\n nextIndex += 1;\n }\n\n if (input.lastPhase !== undefined) {\n assignments.push(`last_phase = $${nextIndex}`);\n values.push(input.lastPhase);\n nextIndex += 1;\n }\n\n if (input.lastError !== undefined) {\n assignments.push(`last_error = $${nextIndex}`);\n values.push(input.lastError);\n nextIndex += 1;\n }\n\n await client.query(\n `update import_plans set ${assignments.join(\", \")} where id = $1`,\n values,\n );\n}\n","import type { ImportDatasetType, ImportWriteTarget } from \"./types.js\";\n\nexport const STAGED_IMPORT_DATASETS: ReadonlySet<ImportDatasetType> = new Set([\n \"companies\",\n \"establishments\",\n \"partners\",\n \"simples_options\",\n]);\n\nconst STAGING_TABLE_BY_DATASET: Partial<Record<ImportDatasetType, string>> = {\n companies: \"staging_companies\",\n establishments: \"staging_establishments\",\n partners: \"staging_partners\",\n simples_options: \"staging_simples_options\",\n};\n\nexport function usesStagingWriteTarget(dataset: ImportDatasetType): boolean {\n return STAGED_IMPORT_DATASETS.has(dataset);\n}\n\nexport function resolveImportWriteTarget(\n dataset: ImportDatasetType,\n): ImportWriteTarget {\n return usesStagingWriteTarget(dataset) ? \"staging\" : \"final\";\n}\n\nexport function getTargetTableName(dataset: ImportDatasetType): string {\n return STAGING_TABLE_BY_DATASET[dataset] ?? dataset;\n}\n\nexport function getSecondaryTargetTableName(\n dataset: ImportDatasetType,\n): string | null {\n void dataset;\n return null;\n}\n\nexport function collectRequiredStagingTables(\n datasets: readonly ImportDatasetType[],\n): string[] {\n const tableNames = new Set<string>();\n\n for (const dataset of datasets) {\n if (!usesStagingWriteTarget(dataset)) {\n continue;\n }\n\n tableNames.add(getTargetTableName(dataset));\n }\n\n return [...tableNames];\n}\n\nconst FINAL_TABLE_BY_DATASET: Partial<Record<ImportDatasetType, string>> = {\n companies: \"companies\",\n establishments: \"establishments\",\n partners: \"partners\",\n simples_options: \"simples_options\",\n};\n\nexport function getFinalTargetTableName(dataset: ImportDatasetType): string {\n return FINAL_TABLE_BY_DATASET[dataset] ?? dataset;\n}\n","import type { Client } from \"pg\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport type { ImportDatasetType } from \"./types.js\";\nimport { collectRequiredStagingTables } from \"./targets.js\";\n\nconst LEGACY_STAGING_TABLES = [\n \"staging_establishment_secondary_cnaes\",\n] as const;\n\nasync function tableExists(\n client: Client,\n tableName: string,\n): Promise<boolean> {\n const result = await client.query<{ exists: string | null }>(\n \"select to_regclass(current_schema() || '.' || $1) as exists\",\n [tableName],\n );\n\n return Boolean(result.rows[0]?.exists);\n}\n\nasync function collectResettableStagingTables(\n client: Client,\n datasets: readonly ImportDatasetType[],\n): Promise<string[]> {\n const tableNames = new Set(collectRequiredStagingTables(datasets));\n\n if (datasets.includes(\"establishments\")) {\n for (const tableName of LEGACY_STAGING_TABLES) {\n if (await tableExists(client, tableName)) {\n tableNames.add(tableName);\n }\n }\n }\n\n return [...tableNames];\n}\n\nexport async function ensureStagingSchemaSupport(\n client: Client,\n datasets: readonly ImportDatasetType[],\n): Promise<void> {\n const requiredTables = collectRequiredStagingTables(datasets);\n\n if (requiredTables.length === 0) {\n return;\n }\n\n const missingTables: string[] = [];\n const invalidTables: string[] = [];\n\n for (const tableName of requiredTables) {\n if (!(await tableExists(client, tableName))) {\n missingTables.push(tableName);\n continue;\n }\n\n const stagingIdResult = await client.query<{ exists: boolean }>(\n `select exists (\n select 1\n from information_schema.columns\n where table_schema = current_schema()\n and table_name = $1\n and column_name = 'staging_id'\n ) as exists`,\n [tableName],\n );\n\n if (!stagingIdResult.rows[0]?.exists) {\n invalidTables.push(tableName);\n }\n }\n\n if (missingTables.length > 0) {\n throw new ValidationError(\n `The staging schema is required for the selected bulk-load datasets. Missing tables: ${missingTables.join(\", \")}. Run \"cnpj-db-loader schema generate --profile full\" or \"cnpj-db-loader schema generate --profile staging\" and apply the SQL before importing.`,\n );\n }\n\n if (invalidTables.length > 0) {\n throw new ValidationError(\n `The staging schema is outdated for chunked materialization. Recreate or migrate these tables so they include the staging_id column: ${invalidTables.join(\", \")}.`,\n );\n }\n}\n\nexport async function resetStagingTablesForFreshPlan(\n client: Client,\n datasets: readonly ImportDatasetType[],\n): Promise<string[]> {\n const tableNames = await collectResettableStagingTables(client, datasets);\n\n if (tableNames.length === 0) {\n return [];\n }\n\n await client.query(`truncate ${tableNames.join(\", \")}`);\n return tableNames;\n}\n","import type { TableLayout } from \"./types.js\";\n\nexport const companiesLayout: TableLayout = {\n key: \"companies\",\n tableName: \"companies\",\n sourceName: \"EMPRESAS\",\n description: \"Main company registration block.\",\n fields: [\n { sourceLabel: \"CNPJ BÁSICO\", columnName: \"cnpj_root\", dataType: \"text\" },\n {\n sourceLabel: \"RAZÃO SOCIAL / NOME EMPRESARIAL\",\n columnName: \"company_name\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"NATUREZA JURÍDICA\",\n columnName: \"legal_nature_code\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"QUALIFICAÇÃO DO RESPONSÁVEL\",\n columnName: \"responsible_qualification_code\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"CAPITAL SOCIAL DA EMPRESA\",\n columnName: \"share_capital\",\n dataType: \"numeric\",\n },\n {\n sourceLabel: \"PORTE DA EMPRESA\",\n columnName: \"company_size_code\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"ENTE FEDERATIVO RESPONSÁVEL\",\n columnName: \"responsible_federative_entity\",\n dataType: \"text\",\n nullable: true,\n },\n ],\n};\n","import type { TableLayout } from \"./types.js\";\n\nexport const countriesLayout: TableLayout = {\n key: \"countries\",\n tableName: \"countries\",\n sourceName: \"PAÍSES\",\n description: \"Country domain table.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n\nexport const citiesLayout: TableLayout = {\n key: \"cities\",\n tableName: \"cities\",\n sourceName: \"MUNICÍPIOS\",\n description: \"City domain table.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n\nexport const partnerQualificationsLayout: TableLayout = {\n key: \"partner_qualifications\",\n tableName: \"partner_qualifications\",\n sourceName: \"QUALIFICAÇÕES DE SÓCIOS\",\n description: \"Partner qualification domain table.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n\nexport const legalNaturesLayout: TableLayout = {\n key: \"legal_natures\",\n tableName: \"legal_natures\",\n sourceName: \"NATUREZAS JURÍDICAS\",\n description: \"Legal nature domain table.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n\nexport const cnaesLayout: TableLayout = {\n key: \"cnaes\",\n tableName: \"cnaes\",\n sourceName: \"CNAEs\",\n description: \"Economic activity domain table.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n\nexport const reasonsLayout: TableLayout = {\n key: \"reasons\",\n tableName: \"reasons\",\n sourceName: \"MOTIVOS\",\n description: \"Registration status reason domain table.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n\nexport const companySizesLayout: TableLayout = {\n key: \"company_sizes\",\n tableName: \"company_sizes\",\n sourceName: \"INTERNAL COMPANY SIZE LOOKUP\",\n description:\n \"Internal lookup table for company size codes defined by the Receita layout.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n\nexport const branchTypesLayout: TableLayout = {\n key: \"branch_types\",\n tableName: \"branch_types\",\n sourceName: \"INTERNAL BRANCH TYPE LOOKUP\",\n description:\n \"Internal lookup table for matriz/filial codes defined by the Receita layout.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n\nexport const registrationStatusesLayout: TableLayout = {\n key: \"registration_statuses\",\n tableName: \"registration_statuses\",\n sourceName: \"INTERNAL REGISTRATION STATUS LOOKUP\",\n description:\n \"Internal lookup table for establishment registration status codes defined by the Receita layout.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n\nexport const partnerTypesLayout: TableLayout = {\n key: \"partner_types\",\n tableName: \"partner_types\",\n sourceName: \"INTERNAL PARTNER TYPE LOOKUP\",\n description:\n \"Internal lookup table for partner identifier codes defined by the Receita layout.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n\nexport const ageGroupsLayout: TableLayout = {\n key: \"age_groups\",\n tableName: \"age_groups\",\n sourceName: \"INTERNAL AGE GROUP LOOKUP\",\n description:\n \"Internal lookup table for partner age group codes defined by the Receita layout.\",\n fields: [\n { sourceLabel: \"CÓDIGO\", columnName: \"code\", dataType: \"text\" },\n { sourceLabel: \"DESCRIÇÃO\", columnName: \"description\", dataType: \"text\" },\n ],\n};\n","import type { TableLayout } from \"./types.js\";\n\nexport const establishmentsLayout: TableLayout = {\n key: \"establishments\",\n tableName: \"establishments\",\n sourceName: \"ESTABELECIMENTOS\",\n description: \"Establishment registration block.\",\n fields: [\n { sourceLabel: \"CNPJ BÁSICO\", columnName: \"cnpj_root\", dataType: \"text\" },\n { sourceLabel: \"CNPJ ORDEM\", columnName: \"cnpj_order\", dataType: \"text\" },\n {\n sourceLabel: \"CNPJ DV\",\n columnName: \"cnpj_check_digits\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"IDENTIFICADOR MATRIZ/FILIAL\",\n columnName: \"branch_type_code\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"NOME FANTASIA\",\n columnName: \"trade_name\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"SITUAÇÃO CADASTRAL\",\n columnName: \"registration_status_code\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"DATA SITUAÇÃO CADASTRAL\",\n columnName: \"registration_status_date\",\n dataType: \"date\",\n nullable: true,\n },\n {\n sourceLabel: \"MOTIVO SITUAÇÃO CADASTRAL\",\n columnName: \"registration_status_reason_code\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"NOME DA CIDADE NO EXTERIOR\",\n columnName: \"foreign_city_name\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"PAIS\",\n columnName: \"country_code\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"DATA DE INÍCIO ATIVIDADE\",\n columnName: \"activity_start_date\",\n dataType: \"date\",\n nullable: true,\n },\n {\n sourceLabel: \"CNAE FISCAL PRINCIPAL\",\n columnName: \"main_cnae_code\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"CNAE FISCAL SECUNDÁRIA\",\n columnName: \"secondary_cnaes_raw\",\n dataType: \"text\",\n nullable: true,\n notes: \"Comma-separated occurrences in the source file.\",\n },\n {\n sourceLabel: \"TIPO DE LOGRADOURO\",\n columnName: \"street_type\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"LOGRADOURO\",\n columnName: \"street_name\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"NÚMERO\",\n columnName: \"street_number\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"COMPLEMENTO\",\n columnName: \"address_complement\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"BAIRRO\",\n columnName: \"district\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"CEP\",\n columnName: \"postal_code\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"UF\",\n columnName: \"state_code\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"MUNICÍPIO\",\n columnName: \"city_code\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"DDD 1\",\n columnName: \"phone_area_code_1\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"TELEFONE 1\",\n columnName: \"phone_number_1\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"DDD 2\",\n columnName: \"phone_area_code_2\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"TELEFONE 2\",\n columnName: \"phone_number_2\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"DDD DO FAX\",\n columnName: \"fax_area_code\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"FAX\",\n columnName: \"fax_number\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"CORREIO ELETRÔNICO\",\n columnName: \"email\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"SITUAÇÃO ESPECIAL\",\n columnName: \"special_status\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"DATA DA SITUAÇÃO ESPECIAL\",\n columnName: \"special_status_date\",\n dataType: \"date\",\n nullable: true,\n },\n ],\n};\n","import type { TableLayout } from \"./types.js\";\n\nexport const partnersLayout: TableLayout = {\n key: \"partners\",\n tableName: \"partners\",\n sourceName: \"SÓCIOS\",\n description:\n \"Partners block, including masked CPF/CNPJ fields according to the official layout.\",\n fields: [\n { sourceLabel: \"CNPJ BÁSICO\", columnName: \"cnpj_root\", dataType: \"text\" },\n {\n sourceLabel: \"IDENTIFICADOR DE SÓCIO\",\n columnName: \"partner_type_code\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"NOME DO SÓCIO / RAZÃO SOCIAL\",\n columnName: \"partner_name\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"CNPJ/CPF DO SÓCIO\",\n columnName: \"partner_document\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"QUALIFICAÇÃO DO SÓCIO\",\n columnName: \"partner_qualification_code\",\n dataType: \"text\",\n },\n {\n sourceLabel: \"DATA DE ENTRADA SOCIEDADE\",\n columnName: \"entry_date\",\n dataType: \"date\",\n nullable: true,\n },\n {\n sourceLabel: \"PAIS\",\n columnName: \"country_code\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"REPRESENTANTE LEGAL\",\n columnName: \"legal_representative_document\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"NOME DO REPRESENTANTE\",\n columnName: \"legal_representative_name\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"QUALIFICAÇÃO DO REPRESENTANTE LEGAL\",\n columnName: \"legal_representative_qualification_code\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"FAIXA ETÁRIA\",\n columnName: \"age_group_code\",\n dataType: \"text\",\n nullable: true,\n },\n ],\n};\n","import type { TableLayout } from \"./types.js\";\n\nexport const simplesLayout: TableLayout = {\n key: \"simples_options\",\n tableName: \"simples_options\",\n sourceName: \"DADOS DO SIMPLES\",\n description: \"Simples Nacional and MEI option block.\",\n fields: [\n { sourceLabel: \"CNPJ BÁSICO\", columnName: \"cnpj_root\", dataType: \"text\" },\n {\n sourceLabel: \"OPÇÃO PELO SIMPLES\",\n columnName: \"simples_option_flag\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"DATA DE OPÇÃO PELO SIMPLES\",\n columnName: \"simples_option_date\",\n dataType: \"date\",\n nullable: true,\n },\n {\n sourceLabel: \"DATA DE EXCLUSÃO DO SIMPLES\",\n columnName: \"simples_exclusion_date\",\n dataType: \"date\",\n nullable: true,\n },\n {\n sourceLabel: \"OPÇÃO PELO MEI\",\n columnName: \"mei_option_flag\",\n dataType: \"text\",\n nullable: true,\n },\n {\n sourceLabel: \"DATA DE OPÇÃO PELO MEI\",\n columnName: \"mei_option_date\",\n dataType: \"date\",\n nullable: true,\n },\n {\n sourceLabel: \"DATA DE EXCLUSÃO DO MEI\",\n columnName: \"mei_exclusion_date\",\n dataType: \"date\",\n nullable: true,\n },\n ],\n};\n","import type { TableLayout } from \"../../dictionary/layouts/index.js\";\nimport {\n citiesLayout,\n cnaesLayout,\n companiesLayout,\n countriesLayout,\n establishmentsLayout,\n legalNaturesLayout,\n partnerQualificationsLayout,\n partnersLayout,\n reasonsLayout,\n simplesLayout,\n} from \"../../dictionary/layouts/index.js\";\nimport type { DatasetType } from \"../inspect.service.js\";\n\nexport type ImportDatasetType = Exclude<DatasetType, \"zip-archive\" | \"unknown\">;\n\nexport type ImportCheckpointStatus =\n | \"pending\"\n | \"in_progress\"\n | \"completed\"\n | \"failed\";\n\nexport type ImportCheckpointRecord = {\n dataset: ImportDatasetType;\n filePath: string;\n fileSize: number;\n fileMtime: Date;\n byteOffset: number;\n rowsCommitted: number;\n status: ImportCheckpointStatus;\n lastError?: string | null;\n};\n\nexport type ImportFilePlan = {\n dataset: ImportDatasetType;\n absolutePath: string;\n displayPath: string;\n fileSize: number;\n fileMtime: Date;\n totalRows: number;\n totalBatches: number;\n checkpoint?: ImportCheckpointRecord;\n};\n\nexport type ImportSourceFile = {\n dataset: ImportDatasetType;\n absolutePath: string;\n relativePath: string;\n displayPath: string;\n fileSize: number;\n fileMtime: Date;\n};\n\nexport type BatchRow = {\n values: unknown[];\n rawLine: string;\n nextOffset: number;\n sourceRowNumber: number;\n secondaryRows: Array<[string, string, number]>;\n};\n\nexport type ImportDatasetPlan = {\n dataset: ImportDatasetType;\n files: ImportFilePlan[];\n totalRows: number;\n totalBatches: number;\n};\n\nexport type ImportPlanStatus =\n | \"planned\"\n | \"in_progress\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\";\n\nexport type ImportPhaseStatus =\n | \"pending\"\n | \"in_progress\"\n | \"completed\"\n | \"failed\";\n\nexport type ImportPlanRecord = {\n id: number;\n sourceFingerprint: string;\n inputPath: string;\n validatedPath: string;\n batchSize: number;\n targetDatabase: string;\n totalDatasets: number;\n totalFiles: number;\n totalRows: number;\n totalBatches: number;\n executionOrder: ImportDatasetType[];\n status: ImportPlanStatus;\n loadStatus: ImportPhaseStatus;\n materializationStatus: ImportPhaseStatus;\n lastPhase: string | null;\n lastError: string | null;\n createdAt: Date;\n updatedAt: Date;\n lastUsedAt: Date;\n};\n\nexport type ImportWriteTarget = \"final\" | \"staging\";\n\nexport type ImportSchemaCapabilities = {\n includeEstablishmentCnpjFullInInsert: boolean;\n includeEstablishmentSecondaryCnaesTable: boolean;\n includePartnerDedupeKeyInInsert: boolean;\n requiresLookupReconciliation: boolean;\n};\n\nexport type ImportDatasetPerformanceSummary = {\n dataset: ImportDatasetType;\n files: number;\n plannedRows: number;\n importedRows: number;\n plannedBatches: number;\n committedBatches: number;\n resumedFiles: number;\n skippedCompletedFiles: number;\n retriedRows: number;\n retriedBatches: number;\n quarantinedRows: number;\n scanDurationMs: number;\n importDurationMs: number;\n insertDurationMs: number;\n retryDurationMs: number;\n quarantineDurationMs: number;\n materializationDurationMs: number;\n rowsPerSecond: number;\n batchesPerMinute: number;\n};\n\nexport type ImportPerformanceSummary = {\n planReused: boolean;\n totalDurationMs: number;\n scanDurationMs: number;\n executionDurationMs: number;\n lookupLoadDurationMs: number;\n insertDurationMs: number;\n retryDurationMs: number;\n quarantineDurationMs: number;\n materializationDurationMs: number;\n rowsPerSecond: number;\n batchesPerMinute: number;\n datasets: ImportDatasetPerformanceSummary[];\n};\n\nexport type ImportProgressEvent =\n | {\n kind: \"preparing_start\";\n inputPath: string;\n validatedPath: string;\n totalDatasets: number;\n totalFiles: number;\n batchSize: number;\n loadBatchSize?: number;\n materializeBatchSize?: number;\n targetDatabase: string;\n }\n | {\n kind: \"preparing_progress\";\n scannedFiles: number;\n totalFiles: number;\n countedRows: number;\n currentFileDisplayPath: string;\n }\n | {\n kind: \"plan_ready\";\n totalDatasets: number;\n totalFiles: number;\n batchSize: number;\n loadBatchSize?: number;\n materializeBatchSize?: number;\n totalRows: number;\n totalBatches: number;\n targetDatabase: string;\n executionOrder: ImportDatasetType[];\n reused: boolean;\n planId: number | null;\n }\n | {\n kind: \"start\";\n inputPath: string;\n validatedPath: string;\n totalDatasets: number;\n totalFiles: number;\n targetDatabase: string;\n totalRows: number;\n totalBatches: number;\n committedRows: number;\n committedBatches: number;\n }\n | {\n kind: \"progress\";\n dataset: ImportDatasetType;\n datasetIndex: number;\n totalDatasets: number;\n currentFilePath: string;\n currentFileDisplayPath: string;\n fileIndex: number;\n completedFiles: number;\n totalFiles: number;\n currentFileRowsCommitted: number;\n currentFileRowsTotal: number;\n committedRows: number;\n committedBatches: number;\n totalBatches: number;\n currentBatch: number;\n batchSize: number;\n checkpointOffset: number;\n currentFileSize: number;\n verboseProgress: boolean;\n }\n | {\n kind: \"materialization_start\";\n totalDatasets: number;\n datasets: ImportDatasetType[];\n completedFiles: number;\n totalFiles: number;\n processedRows: number;\n totalRows: number;\n committedBatches: number;\n totalBatches: number;\n }\n | {\n kind: \"materialization_progress\";\n dataset: ImportDatasetType;\n datasetIndex: number;\n totalDatasets: number;\n completedDatasets: number;\n targetTable: string;\n stepLabel: string;\n completedFiles: number;\n totalFiles: number;\n processedRows: number;\n totalRows: number;\n committedBatches: number;\n totalBatches: number;\n elapsedMs?: number;\n reason?: string;\n chunkSize?: number;\n rowsMaterialized?: number;\n datasetRowCount?: number;\n chunksCompleted?: number;\n estimatedChunks?: number;\n lastStagingId?: number;\n }\n | {\n kind: \"materialization_finish\";\n totalDatasets: number;\n completedDatasets: number;\n }\n | {\n kind: \"finish\";\n totalDatasets: number;\n totalFiles: number;\n completedFiles: number;\n processedRows: number;\n totalRows: number;\n committedBatches: number;\n totalBatches: number;\n quarantinedRows: number;\n };\n\nexport type ImportProgressListener = (event: ImportProgressEvent) => void;\n\nexport type ImportOptions = {\n dbUrl?: string;\n dataset?: ImportDatasetType | undefined;\n batchSize?: number | undefined;\n loadBatchSize?: number | undefined;\n materializeBatchSize?: number | undefined;\n verboseProgress?: boolean | undefined;\n onProgress?: ImportProgressListener | undefined;\n};\n\nexport type ImportExecutionMode = \"full\" | \"load\" | \"materialize\";\n\nexport type ImportSummary = {\n executionMode: ImportExecutionMode;\n inputPath: string;\n validatedPath: string;\n targetDatabase: string;\n importPlanId: number | null;\n reusedImportPlan: boolean;\n importedDatasets: ImportDatasetType[];\n importedFiles: number;\n processedRows: number;\n plannedRows: number;\n committedBatches: number;\n plannedBatches: number;\n quarantinedRows: number;\n resumedFiles: number;\n skippedCompletedFiles: number;\n datasetSummaries: Array<{\n dataset: ImportDatasetType;\n files: number;\n rows: number;\n }>;\n performance: ImportPerformanceSummary;\n warnings: string[];\n progressLogPath: string;\n};\n\nexport const IMPORT_ORDER: ImportDatasetType[] = [\n \"partner_qualifications\",\n \"legal_natures\",\n \"countries\",\n \"cities\",\n \"reasons\",\n \"cnaes\",\n \"companies\",\n \"establishments\",\n \"partners\",\n \"simples_options\",\n];\n\nexport const DATASET_LAYOUTS: Record<ImportDatasetType, TableLayout> = {\n companies: companiesLayout,\n establishments: establishmentsLayout,\n partners: partnersLayout,\n simples_options: simplesLayout,\n countries: countriesLayout,\n cities: citiesLayout,\n partner_qualifications: partnerQualificationsLayout,\n legal_natures: legalNaturesLayout,\n cnaes: cnaesLayout,\n reasons: reasonsLayout,\n};\n\nexport type LookupTableName =\n | \"partner_qualifications\"\n | \"legal_natures\"\n | \"company_sizes\"\n | \"branch_types\"\n | \"registration_statuses\"\n | \"reasons\"\n | \"countries\"\n | \"cnaes\"\n | \"cities\"\n | \"partner_types\"\n | \"age_groups\";\n\nexport type LookupCacheMap = Map<LookupTableName, Set<string>>;\n\nexport const LOOKUP_TABLES: LookupTableName[] = [\n \"partner_qualifications\",\n \"legal_natures\",\n \"company_sizes\",\n \"branch_types\",\n \"registration_statuses\",\n \"reasons\",\n \"countries\",\n \"cnaes\",\n \"cities\",\n \"partner_types\",\n \"age_groups\",\n];\n\nexport const LOOKUP_PLACEHOLDER_LABEL: Record<LookupTableName, string> = {\n partner_qualifications: \"Imported placeholder qualification\",\n legal_natures: \"Imported placeholder legal nature\",\n company_sizes: \"Imported placeholder company size\",\n branch_types: \"Imported placeholder branch type\",\n registration_statuses: \"Imported placeholder registration status\",\n reasons: \"Imported placeholder registration reason\",\n countries: \"Imported placeholder country\",\n cnaes: \"Imported placeholder CNAE\",\n cities: \"Imported placeholder city\",\n partner_types: \"Imported placeholder partner type\",\n age_groups: \"Imported placeholder age group\",\n};\n\nexport function isImportDatasetType(value: string): value is ImportDatasetType {\n return IMPORT_ORDER.includes(value as ImportDatasetType);\n}\n\nexport function maskDatabaseLabel(url: string): string {\n try {\n const parsed = new URL(url);\n const databaseName = parsed.pathname.replace(/^\\//, \"\") || \"database\";\n return `${parsed.hostname}/${databaseName}`;\n } catch {\n return \"configured database\";\n }\n}\n","import type { Client } from \"pg\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport type { ImportDatasetType } from \"../import/types.js\";\nimport { ensureCheckpointTable } from \"../import/checkpoints.js\";\nimport { ensureMaterializationCheckpointTable } from \"../import/materialization-checkpoints.js\";\nimport { ensureImportPlanTables } from \"../import/plan-store.js\";\nimport { resetStagingTablesForFreshPlan } from \"../import/staging-schema.js\";\nimport { isImportDatasetType, maskDatabaseLabel } from \"../import/types.js\";\n\nexport type DatabaseCleanupScope =\n | \"staging\"\n | \"materialized\"\n | \"checkpoints\"\n | \"plans\";\n\nexport type CheckpointCleanupPhase = \"load\" | \"materialization\" | \"all\";\n\nexport type DatabaseCleanupSummary = {\n scope: DatabaseCleanupScope;\n targetDatabase: string;\n dataset?: ImportDatasetType | undefined;\n phase?: CheckpointCleanupPhase | undefined;\n validatedPath?: string | undefined;\n planId?: number | undefined;\n truncatedTables: string[];\n deletedLoadCheckpoints: number;\n deletedMaterializationCheckpoints: number;\n deletedPlans: number;\n notes: string[];\n};\n\nconst MATERIALIZED_DATASET_TABLES: Readonly<\n Partial<Record<ImportDatasetType, readonly string[]>>\n> = {\n companies: [\n \"simples_options\",\n \"partners\",\n \"establishment_secondary_cnaes\",\n \"establishments\",\n \"companies\",\n ],\n establishments: [\"establishment_secondary_cnaes\", \"establishments\"],\n partners: [\"partners\"],\n simples_options: [\"simples_options\"],\n} as const;\n\nfunction assertSupportedCleanupDataset(\n dataset: string | undefined,\n scopes: readonly DatabaseCleanupScope[],\n): asserts dataset is ImportDatasetType | undefined {\n if (dataset === undefined) {\n return;\n }\n\n if (!isImportDatasetType(dataset)) {\n throw new ValidationError(`Unsupported dataset type: ${dataset}.`);\n }\n\n if (scopes.includes(\"staging\") || scopes.includes(\"materialized\")) {\n const supported = Object.keys(\n MATERIALIZED_DATASET_TABLES,\n ) as ImportDatasetType[];\n if (!supported.includes(dataset)) {\n throw new ValidationError(\n `Dataset ${dataset} is not supported for this cleanup scope. Supported datasets: ${supported.join(\", \")}.`,\n );\n }\n }\n}\n\nfunction createBaseSummary(\n input: Pick<\n DatabaseCleanupSummary,\n | \"scope\"\n | \"targetDatabase\"\n | \"dataset\"\n | \"phase\"\n | \"validatedPath\"\n | \"planId\"\n >,\n): DatabaseCleanupSummary {\n return {\n ...input,\n truncatedTables: [],\n deletedLoadCheckpoints: 0,\n deletedMaterializationCheckpoints: 0,\n deletedPlans: 0,\n notes: [],\n };\n}\n\nfunction collectMaterializedTables(dataset?: ImportDatasetType): string[] {\n if (dataset) {\n return [...(MATERIALIZED_DATASET_TABLES[dataset] ?? [])];\n }\n\n const orderedTables = new Set<string>();\n for (const tableNames of Object.values(MATERIALIZED_DATASET_TABLES)) {\n for (const tableName of tableNames ?? []) {\n orderedTables.add(tableName);\n }\n }\n\n return [...orderedTables];\n}\n\nasync function tableExists(\n client: Client,\n tableName: string,\n): Promise<boolean> {\n const result = await client.query<{ exists: string | null }>(\n \"select to_regclass(current_schema() || '.' || $1) as exists\",\n [tableName],\n );\n\n return Boolean(result.rows[0]?.exists);\n}\n\nasync function filterExistingTables(\n client: Client,\n tableNames: readonly string[],\n): Promise<string[]> {\n const existingTables: string[] = [];\n\n for (const tableName of tableNames) {\n if (await tableExists(client, tableName)) {\n existingTables.push(tableName);\n }\n }\n\n return existingTables;\n}\n\nasync function deleteLoadCheckpoints(\n client: Client,\n dataset?: ImportDatasetType,\n): Promise<number> {\n await ensureCheckpointTable(client);\n\n const result = dataset\n ? await client.query(`delete from import_checkpoints where dataset = $1`, [\n dataset,\n ])\n : await client.query(`delete from import_checkpoints`);\n\n return result.rowCount ?? 0;\n}\n\nasync function resolvePlanIdsForCleanup(\n client: Client,\n input: {\n targetDatabase: string;\n planId?: number | undefined;\n validatedPath?: string | undefined;\n },\n): Promise<number[]> {\n await ensureImportPlanTables(client);\n\n if (input.planId !== undefined) {\n return [input.planId];\n }\n\n if (!input.validatedPath) {\n const result = await client.query<{ id: string }>(\n `select id from import_plans order by id asc`,\n );\n return result.rows.map((row) => Number.parseInt(row.id, 10));\n }\n\n const result = await client.query<{ id: string }>(\n `select id\n from import_plans\n where validated_path = $1\n and target_database = $2\n order by id asc`,\n [input.validatedPath, input.targetDatabase],\n );\n\n return result.rows.map((row) => Number.parseInt(row.id, 10));\n}\n\nasync function deleteMaterializationCheckpoints(\n client: Client,\n input: {\n targetDatabase: string;\n planId?: number | undefined;\n validatedPath?: string | undefined;\n dataset?: ImportDatasetType | undefined;\n },\n): Promise<number> {\n await ensureMaterializationCheckpointTable(client);\n const planIds = await resolvePlanIdsForCleanup(client, input);\n\n if (planIds.length === 0) {\n return 0;\n }\n\n if (input.dataset) {\n const result = await client.query(\n `delete from import_materialization_checkpoints\n where plan_id = any($1::bigint[])\n and dataset = $2`,\n [planIds, input.dataset],\n );\n return result.rowCount ?? 0;\n }\n\n const result = await client.query(\n `delete from import_materialization_checkpoints\n where plan_id = any($1::bigint[])`,\n [planIds],\n );\n return result.rowCount ?? 0;\n}\n\nasync function deleteImportPlans(\n client: Client,\n input: {\n targetDatabase: string;\n planId?: number | undefined;\n validatedPath?: string | undefined;\n },\n): Promise<number> {\n await ensureImportPlanTables(client);\n\n if (input.planId !== undefined) {\n const result = await client.query(\n `delete from import_plans where id = $1`,\n [input.planId],\n );\n return result.rowCount ?? 0;\n }\n\n if (input.validatedPath) {\n const result = await client.query(\n `delete from import_plans\n where validated_path = $1\n and target_database = $2`,\n [input.validatedPath, input.targetDatabase],\n );\n return result.rowCount ?? 0;\n }\n\n const result = await client.query(`delete from import_plans`);\n return result.rowCount ?? 0;\n}\n\nexport async function cleanupDatabaseStaging(\n client: Client,\n input: {\n dbUrl: string;\n dataset?: ImportDatasetType | undefined;\n validatedPath?: string | undefined;\n },\n): Promise<DatabaseCleanupSummary> {\n assertSupportedCleanupDataset(input.dataset, [\"staging\"]);\n\n const targetDatabase = maskDatabaseLabel(input.dbUrl);\n const summary = createBaseSummary({\n scope: \"staging\",\n targetDatabase,\n dataset: input.dataset,\n validatedPath: input.validatedPath,\n });\n\n const datasets: ImportDatasetType[] = input.dataset\n ? [input.dataset]\n : [\"companies\", \"establishments\", \"partners\", \"simples_options\"];\n\n summary.truncatedTables = await resetStagingTablesForFreshPlan(\n client,\n datasets,\n );\n\n if (input.validatedPath) {\n summary.deletedMaterializationCheckpoints =\n await deleteMaterializationCheckpoints(client, {\n targetDatabase,\n validatedPath: input.validatedPath,\n dataset: input.dataset,\n });\n summary.notes.push(\n \"Materialization checkpoints for the selected validated path were cleared so the next materialization can restart cleanly.\",\n );\n }\n\n return summary;\n}\n\nexport async function cleanupDatabaseMaterializedTables(\n client: Client,\n input: {\n dbUrl: string;\n dataset?: ImportDatasetType | undefined;\n },\n): Promise<DatabaseCleanupSummary> {\n assertSupportedCleanupDataset(input.dataset, [\"materialized\"]);\n\n const targetDatabase = maskDatabaseLabel(input.dbUrl);\n const summary = createBaseSummary({\n scope: \"materialized\",\n targetDatabase,\n dataset: input.dataset,\n });\n\n const tableNames = await filterExistingTables(\n client,\n collectMaterializedTables(input.dataset),\n );\n if (tableNames.length > 0) {\n await client.query(`truncate ${tableNames.join(\", \")}`);\n }\n summary.truncatedTables = tableNames;\n summary.notes.push(\n \"Simplified final materialized tables were truncated in safe order for the current schema. Clear materialization checkpoints separately if you want the import plan to rebuild these tables from scratch.\",\n );\n\n return summary;\n}\n\nexport async function cleanupDatabaseCheckpoints(\n client: Client,\n input: {\n dbUrl: string;\n phase: CheckpointCleanupPhase;\n dataset?: ImportDatasetType | undefined;\n validatedPath?: string | undefined;\n planId?: number | undefined;\n },\n): Promise<DatabaseCleanupSummary> {\n assertSupportedCleanupDataset(input.dataset, []);\n\n if (input.planId !== undefined && input.planId <= 0) {\n throw new ValidationError(\"The plan id must be a positive integer.\");\n }\n\n const targetDatabase = maskDatabaseLabel(input.dbUrl);\n const summary = createBaseSummary({\n scope: \"checkpoints\",\n targetDatabase,\n dataset: input.dataset,\n phase: input.phase,\n validatedPath: input.validatedPath,\n planId: input.planId,\n });\n\n if (input.phase === \"load\" || input.phase === \"all\") {\n summary.deletedLoadCheckpoints = await deleteLoadCheckpoints(\n client,\n input.dataset,\n );\n }\n\n if (input.phase === \"materialization\" || input.phase === \"all\") {\n summary.deletedMaterializationCheckpoints =\n await deleteMaterializationCheckpoints(client, {\n targetDatabase,\n planId: input.planId,\n validatedPath: input.validatedPath,\n dataset: input.dataset,\n });\n }\n\n if (\n input.phase !== \"load\" &&\n input.planId === undefined &&\n input.validatedPath === undefined\n ) {\n summary.notes.push(\n \"Without --plan-id or --validated-path, materialization checkpoint cleanup affects all saved import plans for this database.\",\n );\n }\n\n return summary;\n}\n\nexport async function cleanupDatabasePlans(\n client: Client,\n input: {\n dbUrl: string;\n validatedPath?: string | undefined;\n planId?: number | undefined;\n },\n): Promise<DatabaseCleanupSummary> {\n if (input.planId !== undefined && input.planId <= 0) {\n throw new ValidationError(\"The plan id must be a positive integer.\");\n }\n\n const targetDatabase = maskDatabaseLabel(input.dbUrl);\n const summary = createBaseSummary({\n scope: \"plans\",\n targetDatabase,\n validatedPath: input.validatedPath,\n planId: input.planId,\n });\n\n summary.deletedPlans = await deleteImportPlans(client, {\n targetDatabase,\n validatedPath: input.validatedPath,\n planId: input.planId,\n });\n summary.notes.push(\n \"Deleting import plans also removes linked plan files and materialization checkpoints through database cascades.\",\n );\n\n return summary;\n}\n","import {\n ageGroupsLayout,\n branchTypesLayout,\n cnaesLayout,\n citiesLayout,\n companiesLayout,\n companySizesLayout,\n countriesLayout,\n establishmentsLayout,\n legalNaturesLayout,\n partnerQualificationsLayout,\n partnerTypesLayout,\n partnersLayout,\n reasonsLayout,\n registrationStatusesLayout,\n simplesLayout,\n type TableLayout,\n} from \"../dictionary/layouts/index.js\";\n\nconst layouts: TableLayout[] = [\n companiesLayout,\n establishmentsLayout,\n partnersLayout,\n simplesLayout,\n countriesLayout,\n citiesLayout,\n partnerQualificationsLayout,\n legalNaturesLayout,\n cnaesLayout,\n reasonsLayout,\n companySizesLayout,\n branchTypesLayout,\n registrationStatusesLayout,\n partnerTypesLayout,\n ageGroupsLayout,\n];\n\nexport function getAllLayouts(): TableLayout[] {\n return layouts;\n}\n\nexport function getLayoutSummary(): Array<\n Pick<TableLayout, \"key\" | \"tableName\" | \"sourceName\">\n> {\n return layouts.map(({ key, tableName, sourceName }) => ({\n key,\n tableName,\n sourceName,\n }));\n}\n","import { access } from \"node:fs/promises\";\n\nimport {\n resolveDatabaseUrl,\n testDatabaseConnection,\n} from \"./database.service.js\";\n\nexport async function runDoctor(\n inputPath?: string,\n dbUrl?: string,\n): Promise<string[]> {\n const report: string[] = [];\n\n if (inputPath) {\n try {\n await access(inputPath);\n report.push(`Input path reachable: ${inputPath}`);\n } catch {\n report.push(`Input path not reachable: ${inputPath}`);\n }\n }\n\n try {\n const resolvedDbUrl = await resolveDatabaseUrl(dbUrl);\n await testDatabaseConnection(resolvedDbUrl);\n report.push(\"Database connection succeeded.\");\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n report.push(`Database check failed: ${message}`);\n }\n\n return report;\n}\n","import { readdir, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport type DatasetType =\n | \"companies\"\n | \"establishments\"\n | \"partners\"\n | \"simples_options\"\n | \"countries\"\n | \"cities\"\n | \"partner_qualifications\"\n | \"legal_natures\"\n | \"cnaes\"\n | \"reasons\"\n | \"zip-archive\"\n | \"unknown\";\n\nexport type InputDetectionMode =\n | \"zip-archives-only\"\n | \"extracted-tree\"\n | \"mixed\"\n | \"empty\";\n\nexport type FileInspection = {\n relativePath: string;\n entryName: string;\n entryKind: \"file\" | \"directory\";\n size: number;\n inferredType: DatasetType;\n requiresExtraction: boolean;\n};\n\nexport type InspectSummary = {\n inputPath: string;\n detectedInputMode: InputDetectionMode;\n totalEntries: number;\n zipArchivesFound: number;\n extractedEntriesFound: number;\n recognizedByType: Record<string, number>;\n recognizedDatasets: Partial<Record<DatasetType, number>>;\n warnings: string[];\n nextStep?: string | undefined;\n entries: FileInspection[];\n};\n\nconst DATASET_TYPES: DatasetType[] = [\n \"companies\",\n \"establishments\",\n \"partners\",\n \"simples_options\",\n \"countries\",\n \"cities\",\n \"partner_qualifications\",\n \"legal_natures\",\n \"cnaes\",\n \"reasons\",\n];\n\nconst DATASET_ALIASES: Record<string, DatasetType> = {\n empresas: \"companies\",\n estabelecimentos: \"establishments\",\n socios: \"partners\",\n simples: \"simples_options\",\n paises: \"countries\",\n municipios: \"cities\",\n qualificacoes: \"partner_qualifications\",\n naturezas: \"legal_natures\",\n cnaes: \"cnaes\",\n motivos: \"reasons\",\n emprecsv: \"companies\",\n estabelece: \"establishments\",\n sociocsv: \"partners\",\n simplescsv: \"simples_options\",\n paiscsv: \"countries\",\n municcsv: \"cities\",\n qualscsv: \"partner_qualifications\",\n natjucsv: \"legal_natures\",\n cnaecsv: \"cnaes\",\n moticsv: \"reasons\",\n};\n\nfunction normalizeEntryName(name: string): string {\n return name\n .normalize(\"NFD\")\n .replace(/[̀-ͯ]/g, \"\")\n .toLowerCase()\n .replace(/\\.zip$/i, \"\")\n .replace(/[\\\\/]/g, \"\")\n .replace(/[\\s._-]+/g, \"\")\n .replace(/\\d+$/g, \"\");\n}\n\nfunction inferDatasetAlias(name: string): DatasetType | undefined {\n const normalized = normalizeEntryName(name);\n\n if (DATASET_ALIASES[normalized]) {\n return DATASET_ALIASES[normalized];\n }\n\n if (normalized.startsWith(\"empresas\")) return \"companies\";\n if (normalized.startsWith(\"estabelecimentos\")) return \"establishments\";\n if (normalized.startsWith(\"socios\")) return \"partners\";\n if (normalized.startsWith(\"simples\")) return \"simples_options\";\n if (normalized.startsWith(\"paises\")) return \"countries\";\n if (normalized.startsWith(\"municipios\")) return \"cities\";\n if (normalized.startsWith(\"qualificacoes\")) return \"partner_qualifications\";\n if (normalized.startsWith(\"naturezas\")) return \"legal_natures\";\n if (normalized.startsWith(\"cnaes\")) return \"cnaes\";\n if (normalized.startsWith(\"motivos\")) return \"reasons\";\n\n if (normalized.includes(\"emprecsv\")) return \"companies\";\n if (normalized.includes(\"estabele\")) return \"establishments\";\n if (normalized.includes(\"sociocsv\")) return \"partners\";\n if (normalized.includes(\"simplescsv\")) return \"simples_options\";\n if (normalized.includes(\"paiscsv\")) return \"countries\";\n if (normalized.includes(\"municcsv\")) return \"cities\";\n if (normalized.includes(\"qualscsv\")) return \"partner_qualifications\";\n if (normalized.includes(\"natjucsv\")) return \"legal_natures\";\n if (normalized.includes(\"cnaecsv\")) return \"cnaes\";\n if (normalized.includes(\"moticsv\")) return \"reasons\";\n\n return undefined;\n}\n\nfunction inferType(relativePath: string, name: string): DatasetType {\n if (name.toLowerCase().endsWith(\".zip\")) {\n return \"zip-archive\";\n }\n\n const alias = inferDatasetAlias(relativePath) ?? inferDatasetAlias(name);\n if (alias) {\n return alias;\n }\n\n return \"unknown\";\n}\n\nasync function walk(\n rootPath: string,\n currentPath = rootPath,\n): Promise<FileInspection[]> {\n const entries = await readdir(currentPath, { withFileTypes: true });\n const inspections: FileInspection[] = [];\n\n for (const entry of entries) {\n const fullPath = path.join(currentPath, entry.name);\n const entryStat = await stat(fullPath);\n const relativePath = path.relative(rootPath, fullPath) || entry.name;\n const inferredType = inferType(relativePath, entry.name);\n\n inspections.push({\n relativePath,\n entryName: entry.name,\n entryKind: entry.isDirectory() ? \"directory\" : \"file\",\n size: entryStat.size,\n inferredType,\n requiresExtraction:\n entry.isFile() && entry.name.toLowerCase().endsWith(\".zip\"),\n });\n\n if (entry.isDirectory()) {\n inspections.push(...(await walk(rootPath, fullPath)));\n }\n }\n\n return inspections;\n}\n\nfunction detectInputMode(\n entries: FileInspection[],\n zipArchivesFound: number,\n extractedEntriesFound: number,\n): InputDetectionMode {\n if (entries.length === 0) {\n return \"empty\";\n }\n\n if (zipArchivesFound > 0 && extractedEntriesFound === 0) {\n return \"zip-archives-only\";\n }\n\n if (zipArchivesFound === 0 && extractedEntriesFound > 0) {\n return \"extracted-tree\";\n }\n\n return \"mixed\";\n}\n\nfunction inferNextStep(\n inputPath: string,\n mode: InputDetectionMode,\n): string | undefined {\n const normalized = inputPath.replace(/\\\\/g, \"/\");\n\n if (mode === \"zip-archives-only\") {\n return `cnpj-db-loader extract ${normalized}`;\n }\n\n if (mode === \"extracted-tree\") {\n return `cnpj-db-loader validate ${normalized}`;\n }\n\n if (mode === \"mixed\") {\n return `cnpj-db-loader validate ${normalized}`;\n }\n\n return undefined;\n}\n\nexport async function inspectFiles(inputPath: string): Promise<InspectSummary> {\n const resolvedInputPath = path.resolve(inputPath);\n const entries = await walk(resolvedInputPath);\n const zipArchivesFound = entries.filter((entry) =>\n entry.entryName.toLowerCase().endsWith(\".zip\"),\n ).length;\n const extractedEntriesFound = entries.filter(\n (entry) =>\n entry.inferredType !== \"zip-archive\" && entry.inferredType !== \"unknown\",\n ).length;\n\n const detectedInputMode = detectInputMode(\n entries,\n zipArchivesFound,\n extractedEntriesFound,\n );\n\n const recognizedByType = entries.reduce<Record<string, number>>(\n (accumulator, entry) => {\n accumulator[entry.inferredType] =\n (accumulator[entry.inferredType] ?? 0) + 1;\n return accumulator;\n },\n {},\n );\n\n const recognizedDatasets = DATASET_TYPES.reduce<\n Partial<Record<DatasetType, number>>\n >((accumulator, datasetType) => {\n const count = entries.filter(\n (entry) => entry.inferredType === datasetType,\n ).length;\n\n if (count > 0) {\n accumulator[datasetType] = count;\n }\n\n return accumulator;\n }, {});\n\n const warnings: string[] = [];\n\n if (detectedInputMode === \"zip-archives-only\") {\n for (const expectedType of DATASET_TYPES) {\n const expectedPrefixFound = entries.some(\n (entry) => inferDatasetAlias(entry.relativePath) === expectedType,\n );\n\n if (!expectedPrefixFound) {\n warnings.push(`Expected ZIP dataset block not found: ${expectedType}.`);\n }\n }\n\n if (zipArchivesFound > 0) {\n warnings.push(\n `Input contains ${zipArchivesFound} ZIP archive(s). Extract them before running validation on the dataset contents.`,\n );\n }\n } else {\n for (const expectedType of DATASET_TYPES) {\n if (!entries.some((entry) => entry.inferredType === expectedType)) {\n warnings.push(\n `Expected extracted dataset block not found: ${expectedType}.`,\n );\n }\n }\n\n if (detectedInputMode === \"mixed\") {\n warnings.push(\n \"Input contains both ZIP archives and extracted content. Consider using a clean extracted directory.\",\n );\n }\n }\n\n return {\n inputPath: resolvedInputPath,\n detectedInputMode,\n totalEntries: entries.length,\n zipArchivesFound,\n extractedEntriesFound,\n recognizedByType,\n recognizedDatasets,\n warnings,\n nextStep: inferNextStep(resolvedInputPath, detectedInputMode),\n entries,\n };\n}\n","import { writeFile } from \"node:fs/promises\";\n\nimport { generateSchemaParts } from \"./schema/builders.js\";\nimport {\n normalizeSchemaProfile,\n type SchemaGenerationOptions,\n type SchemaProfile,\n} from \"./schema/types.js\";\n\nexport function generateSchemaSql(options?: SchemaGenerationOptions): string {\n const profile = options?.profile ?? \"full\";\n return generateSchemaParts(profile).join(\"\\n\\n\");\n}\n\nexport async function writeSchemaFile(\n outFile: string,\n options?: SchemaGenerationOptions,\n): Promise<void> {\n await writeFile(outFile, `${generateSchemaSql(options)}\\n`, \"utf8\");\n}\n\nexport function resolveSchemaProfile(profile?: string): SchemaProfile {\n return normalizeSchemaProfile(profile);\n}\n\nexport type { SchemaGenerationOptions, SchemaProfile } from \"./schema/types.js\";\n","export function createImportPlansSql(): string {\n return [\n \"create table if not exists import_plans (\",\n \" id bigserial primary key,\",\n \" source_fingerprint text not null unique,\",\n \" input_path text not null,\",\n \" validated_path text not null,\",\n \" batch_size integer not null,\",\n \" target_database text not null,\",\n \" total_datasets integer not null,\",\n \" total_files integer not null,\",\n \" total_rows bigint not null,\",\n \" total_batches bigint not null,\",\n \" execution_order jsonb not null,\",\n \" status text not null default 'planned',\",\n \" load_status text not null default 'pending',\",\n \" materialization_status text not null default 'pending',\",\n \" last_phase text,\",\n \" last_error text,\",\n \" created_at timestamp with time zone not null default now(),\",\n \" updated_at timestamp with time zone not null default now(),\",\n \" last_used_at timestamp with time zone not null default now()\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createImportPlanFilesSql(): string {\n return [\n \"create table if not exists import_plan_files (\",\n \" id bigserial primary key,\",\n \" plan_id bigint not null references import_plans (id) on delete cascade,\",\n \" dataset text not null,\",\n \" dataset_index integer not null,\",\n \" file_index integer not null,\",\n \" file_path text not null,\",\n \" file_display_path text not null,\",\n \" file_size bigint not null,\",\n \" file_mtime timestamp with time zone not null,\",\n \" total_rows bigint not null,\",\n \" total_batches bigint not null,\",\n \" unique (plan_id, file_path)\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createImportCheckpointsSql(): string {\n return [\n \"create table if not exists import_checkpoints (\",\n \" id bigserial primary key,\",\n \" dataset text not null,\",\n \" file_path text not null,\",\n \" file_size bigint not null,\",\n \" file_mtime timestamp with time zone not null,\",\n \" byte_offset bigint not null default 0,\",\n \" rows_committed bigint not null default 0,\",\n \" status text not null default 'pending',\",\n \" last_error text,\",\n \" updated_at timestamp with time zone not null default now(),\",\n \" unique (dataset, file_path)\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createImportMaterializationCheckpointsSql(): string {\n return [\n \"create table if not exists import_materialization_checkpoints (\",\n \" id bigserial primary key,\",\n \" plan_id bigint not null references import_plans (id) on delete cascade,\",\n \" dataset text not null,\",\n \" target_table text not null,\",\n \" status text not null default 'pending',\",\n \" rows_materialized bigint not null default 0,\",\n \" last_staging_id bigint not null default 0,\",\n \" chunks_completed bigint not null default 0,\",\n \" last_error text,\",\n \" started_at timestamp with time zone,\",\n \" completed_at timestamp with time zone,\",\n \" updated_at timestamp with time zone not null default now(),\",\n \" staging_row_count_verified bigint,\",\n \" staging_max_staging_id_verified bigint,\",\n \" staging_validated_at timestamp with time zone,\",\n \" lookup_reconciliation_status text not null default 'pending',\",\n \" lookup_reconciliation_row_count_verified bigint,\",\n \" lookup_reconciliation_max_staging_id_verified bigint,\",\n \" lookup_reconciliation_completed_at timestamp with time zone,\",\n \" last_chunk_first_staging_id bigint not null default 0,\",\n \" last_chunk_last_staging_id bigint not null default 0,\",\n \" last_chunk_rows bigint not null default 0,\",\n \" unique (plan_id, dataset)\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createImportQuarantineSql(): string {\n return [\n \"create table if not exists import_quarantine (\",\n \" id bigserial primary key,\",\n \" dataset text not null,\",\n \" file_path text not null,\",\n \" row_number bigint,\",\n \" checkpoint_offset bigint,\",\n \" error_code text,\",\n \" error_category text,\",\n \" error_stage text,\",\n \" error_message text not null,\",\n \" raw_line text not null,\",\n \" parsed_payload jsonb,\",\n \" sanitizations_applied jsonb,\",\n \" retry_count integer not null default 0,\",\n \" can_retry_later boolean not null default false,\",\n \" created_at timestamp with time zone not null default now()\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createControlSchemaParts(): string[] {\n return [\n \"-- Import control tables\",\n createImportPlansSql(),\n createImportPlanFilesSql(),\n createImportCheckpointsSql(),\n createImportMaterializationCheckpointsSql(),\n createImportQuarantineSql(),\n ];\n}\n","import type {\n FieldDefinition,\n TableLayout,\n} from \"../../dictionary/layouts/index.js\";\n\nexport function mapType(dataType: FieldDefinition[\"dataType\"]): string {\n switch (dataType) {\n case \"integer\":\n return \"integer\";\n case \"numeric\":\n return \"numeric(18,2)\";\n case \"date\":\n return \"date\";\n case \"boolean\":\n return \"boolean\";\n default:\n return \"text\";\n }\n}\n\nexport function createColumnSql(field: FieldDefinition): string {\n return ` ${field.columnName} ${mapType(field.dataType)}${field.nullable ? \"\" : \" not null\"}`;\n}\n\nexport function createSimpleDomainTableSql(layout: TableLayout): string {\n const columns = layout.fields.map(createColumnSql).join(\",\\n\");\n return [\n `create table if not exists ${layout.tableName} (`,\n columns + \",\",\n \" primary key (code)\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createLookupSeedSql(\n tableName: string,\n rows: Array<[string, string]>,\n): string {\n const values = rows\n .map(\n ([code, description]) =>\n ` ('${code.replace(/'/g, \"''\")}', '${description.replace(/'/g, \"''\")}')`,\n )\n .join(\",\\n\");\n\n return [\n `insert into ${tableName} (code, description) values`,\n values,\n \"on conflict (code) do update set description = excluded.description;\",\n ].join(\"\\n\");\n}\n","import {\n ageGroupsLayout,\n branchTypesLayout,\n citiesLayout,\n cnaesLayout,\n companySizesLayout,\n countriesLayout,\n legalNaturesLayout,\n partnerQualificationsLayout,\n partnerTypesLayout,\n reasonsLayout,\n registrationStatusesLayout,\n} from \"../../dictionary/layouts/index.js\";\nimport { createLookupSeedSql, createSimpleDomainTableSql } from \"./shared.js\";\n\nconst domainTables = [\n countriesLayout,\n citiesLayout,\n partnerQualificationsLayout,\n legalNaturesLayout,\n cnaesLayout,\n reasonsLayout,\n companySizesLayout,\n branchTypesLayout,\n registrationStatusesLayout,\n partnerTypesLayout,\n ageGroupsLayout,\n];\n\nexport function createDomainSchemaParts(): string[] {\n return [\"-- Domain tables\", ...domainTables.map(createSimpleDomainTableSql)];\n}\n\nexport function createDomainSeedParts(): string[] {\n return [\n \"-- Domain seed data\",\n createLookupSeedSql(\"company_sizes\", [\n [\"00\", \"Not informed\"],\n [\"01\", \"Micro company\"],\n [\"03\", \"Small business\"],\n [\"05\", \"Other\"],\n ]),\n createLookupSeedSql(\"branch_types\", [\n [\"1\", \"Headquarters\"],\n [\"2\", \"Branch\"],\n ]),\n createLookupSeedSql(\"registration_statuses\", [\n [\"01\", \"Null\"],\n [\"2\", \"Active\"],\n [\"3\", \"Suspended\"],\n [\"4\", \"Inactive\"],\n [\"08\", \"Closed\"],\n ]),\n createLookupSeedSql(\"partner_types\", [\n [\"1\", \"Legal entity\"],\n [\"2\", \"Natural person\"],\n [\"3\", \"Foreign person/entity\"],\n ]),\n createLookupSeedSql(\"age_groups\", [\n [\"0\", \"Not applicable\"],\n [\"1\", \"0 to 12 years\"],\n [\"2\", \"13 to 20 years\"],\n [\"3\", \"21 to 30 years\"],\n [\"4\", \"31 to 40 years\"],\n [\"5\", \"41 to 50 years\"],\n [\"6\", \"51 to 60 years\"],\n [\"7\", \"61 to 70 years\"],\n [\"8\", \"71 to 80 years\"],\n [\"9\", \"Over 80 years\"],\n ]),\n ];\n}\n","export function createIndexesSql(): string {\n return [\n \"-- Operational indexes\",\n \"create index if not exists idx_establishments_cnpj_root on establishments (cnpj_root);\",\n \"create index if not exists idx_establishment_secondary_cnaes_cnae_code on establishment_secondary_cnaes (cnae_code);\",\n \"create index if not exists idx_partners_cnpj_root on partners (cnpj_root);\",\n \"create index if not exists idx_import_plans_status on import_plans (status);\",\n \"create index if not exists idx_import_plans_load_status on import_plans (load_status);\",\n \"create index if not exists idx_import_plans_materialization_status on import_plans (materialization_status);\",\n \"create index if not exists idx_import_plan_files_plan_id on import_plan_files (plan_id);\",\n \"create index if not exists idx_import_plan_files_dataset on import_plan_files (dataset);\",\n \"create index if not exists idx_import_checkpoints_status on import_checkpoints (status);\",\n \"create index if not exists idx_import_materialization_checkpoints_status on import_materialization_checkpoints (status);\",\n \"create index if not exists idx_import_materialization_checkpoints_plan_id on import_materialization_checkpoints (plan_id);\",\n \"create index if not exists idx_import_materialization_checkpoints_dataset on import_materialization_checkpoints (dataset);\",\n \"create index if not exists idx_import_checkpoints_dataset on import_checkpoints (dataset);\",\n \"create index if not exists idx_import_quarantine_dataset on import_quarantine (dataset);\",\n \"create index if not exists idx_import_quarantine_file_path on import_quarantine (file_path);\",\n \"create index if not exists idx_import_quarantine_error_category on import_quarantine (error_category);\",\n \"create index if not exists idx_import_quarantine_can_retry_later on import_quarantine (can_retry_later);\",\n ].join(\"\\n\");\n}\n","import {\n companiesLayout,\n establishmentsLayout,\n partnersLayout,\n simplesLayout,\n} from \"../../dictionary/layouts/index.js\";\nimport { createColumnSql } from \"./shared.js\";\n\nexport function createCompaniesSql(): string {\n return [\n \"create table if not exists companies (\",\n companiesLayout.fields.map(createColumnSql).join(\",\\n\") + \",\",\n \" created_at timestamp without time zone not null default now(),\",\n \" updated_at timestamp without time zone not null default now(),\",\n \" primary key (cnpj_root)\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createEstablishmentsSql(): string {\n const baseColumns = establishmentsLayout.fields\n .map(createColumnSql)\n .join(\",\\n\");\n\n return [\n \"create table if not exists establishments (\",\n baseColumns + \",\",\n \" cnpj_full text not null,\",\n \" created_at timestamp without time zone not null default now(),\",\n \" updated_at timestamp without time zone not null default now(),\",\n \" primary key (cnpj_full)\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createPartnersSql(): string {\n return [\n \"create table if not exists partners (\",\n \" id bigserial primary key,\",\n partnersLayout.fields.map(createColumnSql).join(\",\\n\") + \",\",\n \" partner_dedupe_key text not null,\",\n \" created_at timestamp without time zone not null default now(),\",\n \" updated_at timestamp without time zone not null default now(),\",\n \" unique (partner_dedupe_key)\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createEstablishmentSecondaryCnaesSql(): string {\n return [\n \"create table if not exists establishment_secondary_cnaes (\",\n \" cnpj_full text not null,\",\n \" cnae_code text not null,\",\n \" primary key (cnpj_full, cnae_code)\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createSimplesSql(): string {\n return [\n \"create table if not exists simples_options (\",\n simplesLayout.fields.map(createColumnSql).join(\",\\n\") + \",\",\n \" created_at timestamp without time zone not null default now(),\",\n \" updated_at timestamp without time zone not null default now(),\",\n \" primary key (cnpj_root),\",\n \" constraint chk_simples_flag check (simples_option_flag in ('S', 'N') or simples_option_flag is null or simples_option_flag = ''),\",\n \" constraint chk_mei_flag check (mei_option_flag in ('S', 'N') or mei_option_flag is null or mei_option_flag = '')\",\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createOperationalSchemaParts(): string[] {\n return [\n \"-- Final operational tables (simplified for fast first-load materialization)\",\n createCompaniesSql(),\n createEstablishmentsSql(),\n createEstablishmentSecondaryCnaesSql(),\n createPartnersSql(),\n createSimplesSql(),\n ];\n}\n","import {\n companiesLayout,\n establishmentsLayout,\n partnersLayout,\n simplesLayout,\n} from \"../../dictionary/layouts/index.js\";\nimport { createColumnSql } from \"./shared.js\";\n\nfunction createUnloggedStagingTableSql(\n tableName: string,\n columnsSql: string,\n): string {\n return [\n `create unlogged table if not exists ${tableName} (`,\n \" staging_id bigserial primary key,\",\n columnsSql,\n \");\",\n ].join(\"\\n\");\n}\n\nexport function createStagingCompaniesSql(): string {\n return createUnloggedStagingTableSql(\n \"staging_companies\",\n companiesLayout.fields.map(createColumnSql).join(\",\\n\"),\n );\n}\n\nexport function createStagingEstablishmentsSql(): string {\n return createUnloggedStagingTableSql(\n \"staging_establishments\",\n establishmentsLayout.fields.map(createColumnSql).join(\",\\n\"),\n );\n}\n\nexport function createStagingPartnersSql(): string {\n return createUnloggedStagingTableSql(\n \"staging_partners\",\n partnersLayout.fields.map(createColumnSql).join(\",\\n\"),\n );\n}\n\nexport function createStagingSimplesSql(): string {\n return createUnloggedStagingTableSql(\n \"staging_simples_options\",\n simplesLayout.fields.map(createColumnSql).join(\",\\n\"),\n );\n}\n\nexport function createStagingSchemaParts(): string[] {\n return [\n \"-- Staging tables for bulk-oriented imports\",\n createStagingCompaniesSql(),\n createStagingEstablishmentsSql(),\n createStagingPartnersSql(),\n createStagingSimplesSql(),\n ];\n}\n","import { createControlSchemaParts } from \"./control.js\";\nimport { createDomainSchemaParts, createDomainSeedParts } from \"./domain.js\";\nimport { createIndexesSql } from \"./indexes.js\";\nimport { createOperationalSchemaParts } from \"./operational.js\";\nimport { createStagingSchemaParts } from \"./staging.js\";\nimport type { SchemaProfile } from \"./types.js\";\n\nfunction createSchemaBody(profile: SchemaProfile): string[] {\n switch (profile) {\n case \"staging\":\n return createStagingSchemaParts();\n case \"final\":\n return [\n ...createDomainSchemaParts(),\n ...createOperationalSchemaParts(),\n ...createControlSchemaParts(),\n ...createDomainSeedParts(),\n createIndexesSql(),\n ];\n case \"full\":\n default:\n return [\n ...createDomainSchemaParts(),\n ...createOperationalSchemaParts(),\n ...createControlSchemaParts(),\n ...createStagingSchemaParts(),\n ...createDomainSeedParts(),\n createIndexesSql(),\n ];\n }\n}\n\nfunction createSchemaHeader(profile: SchemaProfile): string[] {\n return [\n \"-- CNPJ DB Loader PostgreSQL schema\",\n `-- Profile: ${profile}`,\n \"-- Generated from the internal Receita Federal model.\",\n \"begin;\",\n ];\n}\n\nexport function generateSchemaParts(profile: SchemaProfile): string[] {\n return [\n ...createSchemaHeader(profile),\n ...createSchemaBody(profile),\n \"commit;\",\n ];\n}\n","import { ValidationError } from \"../../core/errors/index.js\";\n\nexport const SCHEMA_PROFILES = [\"full\", \"final\", \"staging\"] as const;\n\nexport type SchemaProfile = (typeof SCHEMA_PROFILES)[number];\n\nexport type SchemaGenerationOptions = {\n profile?: SchemaProfile;\n};\n\nconst SCHEMA_PROFILE_ALIASES: Record<string, SchemaProfile> = {\n all: \"full\",\n combined: \"full\",\n full: \"full\",\n final: \"final\",\n \"final-load\": \"final\",\n load: \"final\",\n minimal: \"final\",\n operational: \"final\",\n production: \"final\",\n stage: \"staging\",\n staging: \"staging\",\n};\n\nexport function normalizeSchemaProfile(input?: string): SchemaProfile {\n const normalized = input?.trim().toLowerCase();\n\n if (!normalized) {\n return \"full\";\n }\n\n const profile = SCHEMA_PROFILE_ALIASES[normalized];\n if (profile) {\n return profile;\n }\n\n throw new ValidationError(\n `Invalid schema profile \"${input}\". Expected one of: full, final, or staging. Aliases such as final-load, load, operational, and stage are also accepted.`,\n );\n}\n","import path from \"node:path\";\n\nimport type {\n DatasetType,\n FileInspection,\n InspectSummary,\n} from \"./inspect.service.js\";\nimport { inspectFiles } from \"./inspect.service.js\";\n\nconst EXPECTED_DATASETS: DatasetType[] = [\n \"companies\",\n \"establishments\",\n \"partners\",\n \"simples_options\",\n \"countries\",\n \"cities\",\n \"partner_qualifications\",\n \"legal_natures\",\n \"cnaes\",\n \"reasons\",\n];\n\nexport type ValidationSummary = {\n ok: boolean;\n errors: string[];\n warnings: string[];\n inspected: InspectSummary;\n validatedPath: string;\n presentDatasets: DatasetType[];\n missingDatasets: DatasetType[];\n nextStep?: string | undefined;\n};\n\nfunction isRecognizedDataset(\n entry: FileInspection,\n): entry is FileInspection & { inferredType: DatasetType } {\n return (\n entry.inferredType !== \"zip-archive\" && entry.inferredType !== \"unknown\"\n );\n}\n\nfunction uniqueDatasets(entries: FileInspection[]): DatasetType[] {\n return [\n ...new Set(\n entries.filter(isRecognizedDataset).map((entry) => entry.inferredType),\n ),\n ].sort();\n}\n\nfunction summarizeUnknownEntries(unknownEntries: FileInspection[]): string[] {\n if (unknownEntries.length === 0) {\n return [];\n }\n\n const preview = unknownEntries.slice(0, 5).map((entry) => entry.relativePath);\n const warnings = [\n `Found ${unknownEntries.length} unrecognized file(s) inside the validated tree.`,\n ];\n\n for (const item of preview) {\n warnings.push(`Unrecognized file: ${item}`);\n }\n\n if (unknownEntries.length > preview.length) {\n warnings.push(\n `Additional unrecognized files were omitted from the terminal output. Check the log file for the complete list.`,\n );\n }\n\n return warnings;\n}\n\nfunction selectEntriesForValidation(inspected: InspectSummary): {\n validatedPath: string;\n entries: FileInspection[];\n} {\n if (inspected.detectedInputMode !== \"mixed\") {\n return {\n validatedPath: inspected.inputPath,\n entries: inspected.entries,\n };\n }\n\n const extractedPrefix = `extracted${path.sep}`;\n const extractedEntries = inspected.entries.filter(\n (entry) =>\n entry.relativePath === \"extracted\" ||\n entry.relativePath.startsWith(extractedPrefix),\n );\n\n if (extractedEntries.length > 0) {\n return {\n validatedPath: path.join(inspected.inputPath, \"extracted\"),\n entries: extractedEntries.map((entry) => ({\n ...entry,\n relativePath:\n entry.relativePath === \"extracted\"\n ? \".\"\n : entry.relativePath.slice(extractedPrefix.length),\n })),\n };\n }\n\n return {\n validatedPath: inspected.inputPath,\n entries: inspected.entries.filter(\n (entry) => !entry.relativePath.toLowerCase().endsWith(\".zip\"),\n ),\n };\n}\n\nfunction inferNextStep(summary: {\n ok: boolean;\n detectedInputMode: InspectSummary[\"detectedInputMode\"];\n inputPath: string;\n validatedPath: string;\n missingDatasets: DatasetType[];\n zipArchivesFound: number;\n presentDatasets: DatasetType[];\n}): string | undefined {\n const normalizedInputPath = summary.inputPath.replace(/\\\\/g, \"/\");\n\n if (summary.detectedInputMode === \"zip-archives-only\") {\n return `cnpj-db-loader extract ${normalizedInputPath}`;\n }\n\n if (\n !summary.ok &&\n summary.zipArchivesFound > 0 &&\n summary.presentDatasets.length === 0\n ) {\n return `cnpj-db-loader extract ${normalizedInputPath}`;\n }\n\n if (!summary.ok && summary.missingDatasets.length > 0) {\n return `Review the extracted files and ensure all expected dataset blocks are present.`;\n }\n\n if (summary.ok) {\n const normalizedValidatedPath = summary.validatedPath.replace(/\\\\/g, \"/\");\n const validatedBaseName = path\n .basename(summary.validatedPath)\n .toLowerCase();\n if (\n validatedBaseName === \"sanitized\" ||\n validatedBaseName.endsWith(\"-sanitized\")\n ) {\n return `cnpj-db-loader database config show`;\n }\n\n return `cnpj-db-loader sanitize ${normalizedValidatedPath}`;\n }\n\n return undefined;\n}\n\nexport async function validateInputDirectory(\n inputPath: string,\n): Promise<ValidationSummary> {\n const inspected = await inspectFiles(inputPath);\n const errors: string[] = [];\n const warnings: string[] = [];\n\n if (inspected.totalEntries === 0) {\n errors.push(\n \"No files or directories were found in the provided input path.\",\n );\n }\n\n const selected = selectEntriesForValidation(inspected);\n const recognizedEntries = selected.entries.filter(isRecognizedDataset);\n const presentDatasets = uniqueDatasets(recognizedEntries);\n const missingDatasets = EXPECTED_DATASETS.filter(\n (dataset) => !presentDatasets.includes(dataset),\n );\n\n const unknownEntries = selected.entries.filter(\n (entry) => entry.entryKind === \"file\" && entry.inferredType === \"unknown\",\n );\n\n if (inspected.detectedInputMode === \"zip-archives-only\") {\n warnings.push(\n `No extracted dataset tree was found in ${inspected.inputPath}. Extraction is required before validation can check dataset completeness.`,\n );\n } else {\n if (presentDatasets.length === 0) {\n errors.push(\n `No recognized extracted dataset files were found in ${selected.validatedPath}.`,\n );\n }\n\n if (missingDatasets.length > 0) {\n errors.push(\n `The extracted dataset tree is incomplete. Missing dataset block(s): ${missingDatasets.join(\", \")}.`,\n );\n }\n\n if (\n inspected.detectedInputMode === \"mixed\" &&\n presentDatasets.length > 0 &&\n missingDatasets.length === 0\n ) {\n warnings.push(\n `A valid extracted dataset tree was found at ${selected.validatedPath}. ZIP archives are also present in the parent directory, but extraction does not need to be run again.`,\n );\n }\n }\n\n warnings.push(...summarizeUnknownEntries(unknownEntries));\n\n const nextStep = inferNextStep({\n ok: errors.length === 0,\n detectedInputMode: inspected.detectedInputMode,\n inputPath: inspected.inputPath,\n validatedPath: selected.validatedPath,\n missingDatasets,\n zipArchivesFound: inspected.zipArchivesFound,\n presentDatasets,\n });\n\n return {\n ok: errors.length === 0,\n errors,\n warnings,\n inspected,\n validatedPath: selected.validatedPath,\n presentDatasets,\n missingDatasets,\n nextStep,\n };\n}\n","import { mkdir, readdir, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport extract from \"extract-zip\";\n\nimport { detectOs, defaultExtractedOutputPath } from \"../core/utils/index.js\";\n\nexport type ExtractionEntry = {\n archivePath: string;\n archiveName: string;\n destinationPath: string;\n success: boolean;\n sizeInBytes: number;\n errorMessage?: string;\n};\n\nexport type ExtractionSummary = {\n inputPath: string;\n outputPath: string;\n operatingSystem: string;\n zipFilesFound: number;\n extractedArchives: string[];\n skippedEntries: string[];\n failedArchives: string[];\n totalArchiveBytes: number;\n extractedArchiveBytes: number;\n entries: ExtractionEntry[];\n};\n\nexport type ExtractionProgressEvent =\n | {\n kind: \"start\";\n totalArchives: number;\n totalBytes: number;\n inputPath: string;\n outputPath: string;\n }\n | {\n kind: \"archive-start\";\n currentArchiveName: string;\n currentArchivePath: string;\n archiveSizeInBytes: number;\n archiveIndex: number;\n totalArchives: number;\n completedArchives: number;\n extractedBytes: number;\n totalBytes: number;\n }\n | {\n kind: \"archive-complete\";\n currentArchiveName: string;\n currentArchivePath: string;\n archiveSizeInBytes: number;\n archiveIndex: number;\n totalArchives: number;\n completedArchives: number;\n extractedBytes: number;\n totalBytes: number;\n }\n | {\n kind: \"archive-failed\";\n currentArchiveName: string;\n currentArchivePath: string;\n archiveSizeInBytes: number;\n archiveIndex: number;\n totalArchives: number;\n completedArchives: number;\n extractedBytes: number;\n totalBytes: number;\n errorMessage: string;\n }\n | {\n kind: \"finish\";\n totalArchives: number;\n completedArchives: number;\n failedArchives: number;\n extractedBytes: number;\n totalBytes: number;\n outputPath: string;\n };\n\nexport type ExtractionProgressListener = (\n event: ExtractionProgressEvent,\n) => void;\n\nasync function findZipFiles(rootPath: string): Promise<string[]> {\n const entries = await readdir(rootPath, { withFileTypes: true });\n const found: string[] = [];\n\n for (const entry of entries) {\n const fullPath = path.join(rootPath, entry.name);\n\n if (entry.isDirectory()) {\n if (entry.name.toLowerCase() === \"extracted\") {\n continue;\n }\n\n found.push(...(await findZipFiles(fullPath)));\n continue;\n }\n\n if (entry.isFile() && entry.name.toLowerCase().endsWith(\".zip\")) {\n found.push(fullPath);\n }\n }\n\n return found.sort((left, right) => left.localeCompare(right));\n}\n\nasync function extractSingleArchive(\n zipPath: string,\n outputRootPath: string,\n archiveSizeInBytes: number,\n): Promise<ExtractionEntry> {\n const archiveName = path.basename(zipPath);\n const folderName = path.basename(zipPath, path.extname(zipPath));\n const destinationPath = path.join(outputRootPath, folderName);\n\n try {\n await mkdir(destinationPath, { recursive: true });\n await extract(zipPath, { dir: destinationPath });\n\n return {\n archivePath: zipPath,\n archiveName,\n destinationPath,\n success: true,\n sizeInBytes: archiveSizeInBytes,\n };\n } catch (error) {\n return {\n archivePath: zipPath,\n archiveName,\n destinationPath,\n success: false,\n sizeInBytes: archiveSizeInBytes,\n errorMessage: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nexport async function extractArchives(\n inputPath: string,\n outputPath?: string,\n onProgress?: ExtractionProgressListener,\n): Promise<ExtractionSummary> {\n const resolvedInputPath = path.resolve(inputPath);\n const resolvedOutputPath = path.resolve(\n outputPath ?? defaultExtractedOutputPath(resolvedInputPath),\n );\n await mkdir(resolvedOutputPath, { recursive: true });\n\n const zipFiles = await findZipFiles(resolvedInputPath);\n const zipFileStats = await Promise.all(\n zipFiles.map(async (zipFile) => ({ zipFile, stat: await stat(zipFile) })),\n );\n const totalArchiveBytes = zipFileStats.reduce(\n (sum, item) => sum + item.stat.size,\n 0,\n );\n\n onProgress?.({\n kind: \"start\",\n totalArchives: zipFiles.length,\n totalBytes: totalArchiveBytes,\n inputPath: resolvedInputPath,\n outputPath: resolvedOutputPath,\n });\n\n const extractedArchives: string[] = [];\n const failedArchives: string[] = [];\n const entries: ExtractionEntry[] = [];\n let extractedArchiveBytes = 0;\n let completedArchivesCount = 0;\n\n for (const [index, item] of zipFileStats.entries()) {\n const archiveName = path.basename(item.zipFile);\n\n onProgress?.({\n kind: \"archive-start\",\n currentArchiveName: archiveName,\n currentArchivePath: item.zipFile,\n archiveSizeInBytes: item.stat.size,\n archiveIndex: index + 1,\n totalArchives: zipFiles.length,\n completedArchives: completedArchivesCount,\n extractedBytes: extractedArchiveBytes,\n totalBytes: totalArchiveBytes,\n });\n\n const result = await extractSingleArchive(\n item.zipFile,\n resolvedOutputPath,\n item.stat.size,\n );\n entries.push(result);\n\n if (result.success) {\n extractedArchives.push(result.archiveName);\n extractedArchiveBytes += result.sizeInBytes;\n completedArchivesCount += 1;\n\n onProgress?.({\n kind: \"archive-complete\",\n currentArchiveName: result.archiveName,\n currentArchivePath: result.archivePath,\n archiveSizeInBytes: result.sizeInBytes,\n archiveIndex: index + 1,\n totalArchives: zipFiles.length,\n completedArchives: completedArchivesCount,\n extractedBytes: extractedArchiveBytes,\n totalBytes: totalArchiveBytes,\n });\n } else {\n failedArchives.push(result.archiveName);\n onProgress?.({\n kind: \"archive-failed\",\n currentArchiveName: result.archiveName,\n currentArchivePath: result.archivePath,\n archiveSizeInBytes: result.sizeInBytes,\n archiveIndex: index + 1,\n totalArchives: zipFiles.length,\n completedArchives: completedArchivesCount,\n extractedBytes: extractedArchiveBytes,\n totalBytes: totalArchiveBytes,\n errorMessage: result.errorMessage ?? \"Unknown extraction error\",\n });\n }\n }\n\n const skippedEntries: string[] = [];\n const outputEntries = await readdir(resolvedOutputPath);\n\n for (const entry of outputEntries) {\n const fullPath = path.join(resolvedOutputPath, entry);\n const entryStat = await stat(fullPath);\n if (!entryStat.isFile() && !entryStat.isDirectory()) {\n skippedEntries.push(entry);\n }\n }\n\n onProgress?.({\n kind: \"finish\",\n totalArchives: zipFiles.length,\n completedArchives: completedArchivesCount,\n failedArchives: failedArchives.length,\n extractedBytes: extractedArchiveBytes,\n totalBytes: totalArchiveBytes,\n outputPath: resolvedOutputPath,\n });\n\n return {\n inputPath: resolvedInputPath,\n outputPath: resolvedOutputPath,\n operatingSystem: detectOs(),\n zipFilesFound: zipFiles.length,\n extractedArchives,\n skippedEntries,\n failedArchives,\n totalArchiveBytes,\n extractedArchiveBytes,\n entries,\n };\n}\n","export type InputMode = \"unzip\" | \"already-extracted\";\n\nexport function resolveInputMode(options: {\n unzip?: boolean;\n alreadyExtracted?: boolean;\n}): InputMode {\n if (options.unzip && options.alreadyExtracted) {\n throw new Error(\n 'Choose only one input mode: use either \"--unzip\" or \"--already-extracted\".',\n );\n }\n\n if (options.unzip) {\n return \"unzip\";\n }\n\n return \"already-extracted\";\n}\n","import { appendFile, mkdir, writeFile } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nimport {\n buildStructuredLogEntry,\n serializeErrorDetails,\n} from \"./logging/entry.js\";\nimport type {\n LogLevel,\n LogStatus,\n StructuredLogEntry,\n} from \"./logging/types.js\";\n\nconst DEFAULT_APP_DIRECTORY_NAME = \".cnpjdbloader\";\nconst DEFAULT_LOGS_DIRECTORY_NAME = \"logs\";\n\ntype WriteLogOptions = {\n baseDirectory?: string;\n event?: string;\n level?: LogLevel;\n status?: LogStatus;\n message?: string;\n};\n\nfunction sanitizeSegment(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\nfunction createTimestamp(): string {\n const now = new Date();\n const parts = [\n now.getFullYear(),\n String(now.getMonth() + 1).padStart(2, \"0\"),\n String(now.getDate()).padStart(2, \"0\"),\n String(now.getHours()).padStart(2, \"0\"),\n String(now.getMinutes()).padStart(2, \"0\"),\n String(now.getSeconds()).padStart(2, \"0\"),\n ];\n\n return `${parts[0]}${parts[1]}${parts[2]}-${parts[3]}${parts[4]}${parts[5]}`;\n}\n\nexport function getUserAppDirectoryPath(): string {\n return path.join(os.homedir(), DEFAULT_APP_DIRECTORY_NAME);\n}\n\nexport function getLogsDirectoryPath(\n baseDirectory = getUserAppDirectoryPath(),\n): string {\n return path.join(baseDirectory, DEFAULT_LOGS_DIRECTORY_NAME);\n}\n\nasync function ensureLogsDirectory(baseDirectory?: string): Promise<string> {\n const logsDirectory = getLogsDirectoryPath(baseDirectory);\n await mkdir(logsDirectory, { recursive: true });\n return logsDirectory;\n}\n\nfunction buildCommandLogEntry(\n commandName: string,\n payload: unknown,\n options?: Omit<WriteLogOptions, \"baseDirectory\">,\n): StructuredLogEntry {\n return buildStructuredLogEntry({\n payload,\n defaultEvent: options?.event ?? \"command_completed\",\n defaultLevel: options?.level ?? \"info\",\n command: commandName,\n status: options?.status ?? \"success\",\n ...(options?.message ? { message: options.message } : {}),\n });\n}\n\nexport async function writeCommandLog(\n commandName: string,\n payload: unknown,\n baseDirectoryOrOptions?: string | WriteLogOptions,\n maybeOptions?: Omit<WriteLogOptions, \"baseDirectory\">,\n): Promise<string> {\n const options: WriteLogOptions =\n typeof baseDirectoryOrOptions === \"string\"\n ? { ...maybeOptions, baseDirectory: baseDirectoryOrOptions }\n : (baseDirectoryOrOptions ?? {});\n\n const logsDirectory = await ensureLogsDirectory(options.baseDirectory);\n const fileName = `${createTimestamp()}-${sanitizeSegment(commandName)}.json`;\n const filePath = path.join(logsDirectory, fileName);\n const entry = buildCommandLogEntry(commandName, payload, options);\n\n await writeFile(filePath, `${JSON.stringify(entry, null, 2)}\\n`, \"utf8\");\n return filePath;\n}\n\nexport async function writeCommandFailureLog(\n commandName: string,\n error: unknown,\n input?: {\n argv?: string[];\n context?: Record<string, unknown>;\n baseDirectory?: string;\n fatal?: boolean;\n },\n): Promise<string> {\n return writeCommandLog(\n commandName,\n {\n error: serializeErrorDetails(error),\n ...(input?.argv ? { argv: input.argv } : {}),\n ...(input?.context ? { context: input.context } : {}),\n },\n {\n ...(input?.baseDirectory ? { baseDirectory: input.baseDirectory } : {}),\n event: \"command_failed\",\n level: input?.fatal ? \"fatal\" : \"error\",\n status: \"failure\",\n message: \"Command execution failed.\",\n },\n );\n}\n\nexport async function createJsonLinesLog(\n commandName: string,\n baseDirectory?: string,\n): Promise<string> {\n const logsDirectory = await ensureLogsDirectory(baseDirectory);\n const fileName = `${createTimestamp()}-${sanitizeSegment(commandName)}.jsonl`;\n const filePath = path.join(logsDirectory, fileName);\n await writeFile(filePath, \"\", \"utf8\");\n return filePath;\n}\n\nexport async function appendJsonLinesLog(\n filePath: string,\n payload: unknown,\n options?: Omit<WriteLogOptions, \"baseDirectory\" | \"status\"> & {\n command?: string;\n status?: LogStatus;\n },\n): Promise<void> {\n const entry = buildStructuredLogEntry({\n payload,\n defaultEvent: options?.event ?? \"log_entry\",\n defaultLevel: options?.level ?? \"info\",\n ...(options?.command ? { command: options.command } : {}),\n ...(options?.status ? { status: options.status } : {}),\n ...(options?.message ? { message: options.message } : {}),\n });\n\n await appendFile(filePath, `${JSON.stringify(entry)}\\n`, \"utf8\");\n}\n\nexport type { LogLevel, LogStatus, StructuredLogEntry };\n","export const LOG_LEVELS = [\n \"trace\",\n \"debug\",\n \"info\",\n \"warning\",\n \"error\",\n \"critical\",\n \"fatal\",\n] as const;\n\nexport type LogLevel = (typeof LOG_LEVELS)[number];\n\nexport const LOG_STATUSES = [\"success\", \"failure\"] as const;\n\nexport type LogStatus = (typeof LOG_STATUSES)[number];\n\nexport type LogRecord = Record<string, unknown>;\n\nexport type StructuredLogEntry = LogRecord & {\n timestamp: string;\n level: LogLevel;\n severity: LogLevel;\n event: string;\n kind: string;\n command?: string;\n status?: LogStatus;\n message?: string;\n};\n","import {\n LOG_LEVELS,\n LOG_STATUSES,\n type LogLevel,\n type LogRecord,\n type LogStatus,\n type StructuredLogEntry,\n} from \"./types.js\";\n\ntype BuildStructuredLogEntryInput = {\n payload: unknown;\n defaultEvent: string;\n defaultLevel: LogLevel;\n command?: string;\n status?: LogStatus;\n message?: string;\n};\n\nconst EVENT_LEVEL_MAP: Record<string, LogLevel> = {\n archive_complete: \"info\",\n archive_failed: \"error\",\n archive_start: \"info\",\n batch_committed: \"debug\",\n batch_retry_fallback: \"warning\",\n command_completed: \"info\",\n command_failed: \"error\",\n dataset_completed: \"info\",\n dataset_started: \"info\",\n file_failed: \"error\",\n file_metrics: \"info\",\n import_failed: \"error\",\n import_finished: \"info\",\n import_plan_ready: \"info\",\n import_plan_reused: \"info\",\n import_started: \"info\",\n log_entry: \"info\",\n materialization_completed: \"info\",\n materialization_dataset_completed: \"info\",\n materialization_dataset_failed: \"error\",\n materialization_dataset_heartbeat: \"debug\",\n materialization_dataset_started: \"info\",\n materialization_finished: \"info\",\n materialization_started: \"info\",\n preparing_progress: \"debug\",\n preparing_start: \"info\",\n row_quarantined: \"warning\",\n};\n\nfunction isRecord(value: unknown): value is LogRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isLogLevel(value: unknown): value is LogLevel {\n return typeof value === \"string\" && LOG_LEVELS.includes(value as LogLevel);\n}\n\nfunction isLogStatus(value: unknown): value is LogStatus {\n return typeof value === \"string\" && LOG_STATUSES.includes(value as LogStatus);\n}\n\nfunction readOptionalString(\n record: LogRecord,\n key: string,\n): string | undefined {\n const value = record[key];\n return typeof value === \"string\" && value.trim() !== \"\" ? value : undefined;\n}\n\nfunction normalizeEventName(value: string): string {\n return value.trim().replace(/-/g, \"_\");\n}\n\nfunction resolveLogLevel(\n explicitLevel: LogLevel | undefined,\n event: string,\n fallbackLevel: LogLevel,\n): LogLevel {\n if (explicitLevel) {\n return explicitLevel;\n }\n\n return EVENT_LEVEL_MAP[event] ?? fallbackLevel;\n}\n\nfunction buildPrimitivePayloadEntry(\n input: BuildStructuredLogEntryInput,\n): StructuredLogEntry {\n const event = normalizeEventName(input.defaultEvent);\n const level = resolveLogLevel(undefined, event, input.defaultLevel);\n\n return {\n timestamp: new Date().toISOString(),\n level,\n severity: level,\n event,\n kind: event,\n ...(input.command ? { command: input.command } : {}),\n ...(input.status ? { status: input.status } : {}),\n ...(input.message ? { message: input.message } : {}),\n payload: input.payload,\n };\n}\n\nexport function buildStructuredLogEntry(\n input: BuildStructuredLogEntryInput,\n): StructuredLogEntry {\n if (!isRecord(input.payload)) {\n return buildPrimitivePayloadEntry(input);\n }\n\n const payload = { ...input.payload };\n const rawEvent =\n readOptionalString(payload, \"event\") ??\n readOptionalString(payload, \"kind\") ??\n input.defaultEvent;\n const event = normalizeEventName(rawEvent);\n const explicitLevel =\n (isLogLevel(payload.level) ? payload.level : undefined) ??\n (isLogLevel(payload.severity) ? payload.severity : undefined);\n const level = resolveLogLevel(explicitLevel, event, input.defaultLevel);\n const timestamp =\n readOptionalString(payload, \"timestamp\") ?? new Date().toISOString();\n const command = readOptionalString(payload, \"command\") ?? input.command;\n const status =\n (isLogStatus(payload.status) ? payload.status : undefined) ?? input.status;\n const message = readOptionalString(payload, \"message\") ?? input.message;\n const kind = normalizeEventName(readOptionalString(payload, \"kind\") ?? event);\n\n return {\n ...payload,\n timestamp,\n level,\n severity: level,\n event,\n kind,\n ...(command ? { command } : {}),\n ...(status ? { status } : {}),\n ...(message ? { message } : {}),\n };\n}\n\nexport function serializeErrorDetails(error: unknown): LogRecord {\n if (error instanceof Error) {\n const details: LogRecord = {\n name: error.name,\n message: error.message,\n };\n\n if (typeof error.stack === \"string\" && error.stack.trim() !== \"\") {\n details.stack = error.stack;\n }\n\n const errorWithCode = error as Error & { code?: unknown; cause?: unknown };\n\n if (typeof errorWithCode.code === \"string\") {\n details.code = errorWithCode.code;\n }\n\n if (errorWithCode.cause !== undefined) {\n details.cause =\n errorWithCode.cause instanceof Error\n ? serializeErrorDetails(errorWithCode.cause)\n : errorWithCode.cause;\n }\n\n return details;\n }\n\n return {\n message: String(error),\n };\n}\n","import path from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\n\nimport { Client } from \"pg\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport { appendJsonLinesLog, createJsonLinesLog } from \"../logging.service.js\";\nimport {\n buildImportPerformanceSummary,\n buildImportWarnings,\n createDatasetPerformanceTracker,\n finalizeDatasetPerformance,\n summarizeImportedDatasets,\n type MutableDatasetPerformance,\n} from \"./finalizer.js\";\nimport { importDatasetFile } from \"./file-import.js\";\nimport {\n ensureImportCheckpointSupport,\n hydrateImportPlanWithCheckpoints,\n} from \"./checkpoint-manager.js\";\nimport {\n ensureMaterializationCheckpointTable,\n resetMaterializationCheckpoints,\n} from \"./materialization-checkpoints.js\";\nimport { materializeStagedDatasets } from \"./materializer.js\";\nimport { isMaterializationDataset } from \"./materialization-sql.js\";\nimport {\n collectDatasetEntriesForImport,\n prepareImportPlan,\n resolveRequestedDatasets,\n type PreparedImportPlan,\n} from \"./planner.js\";\nimport {\n updateImportPlanPhaseState,\n updateImportPlanStatus,\n readLatestImportPlanForValidatedPath,\n} from \"./plan-store.js\";\nimport { ensureImportQuarantineSupport } from \"./quarantine-writer.js\";\nimport { detectImportSchemaCapabilities } from \"./schema-capabilities.js\";\nimport {\n ensureStagingSchemaSupport,\n resetStagingTablesForFreshPlan,\n} from \"./staging-schema.js\";\nimport type { InspectSummary } from \"../inspect.service.js\";\nimport type {\n ImportDatasetPlan,\n ImportDatasetType,\n ImportOptions,\n ImportPerformanceSummary,\n ImportSummary,\n} from \"./types.js\";\n\ntype DatasetTrackerMap = Map<ImportDatasetType, MutableDatasetPerformance>;\n\ntype SharedPipelineInput = {\n inputPath: string;\n validatedPath: string;\n inspection: InspectSummary;\n dbUrl: string;\n options?: ImportOptions;\n targetDatabase: string;\n};\n\ntype PipelineCounters = {\n committedRows: number;\n committedBatches: number;\n completedFiles: number;\n secondaryCnaesRows: number;\n quarantinedRows: number;\n resumedFiles: number;\n skippedCompletedFiles: number;\n};\n\ntype PreparedExecution = {\n client: Client;\n progressLogPath: string;\n planId: number | null;\n planReused: boolean;\n plan: PreparedImportPlan[\"plan\"];\n datasetPerformanceTrackers: DatasetTrackerMap;\n scanDurationMs: number;\n sourceFingerprint: string;\n loadBatchSize: number;\n materializeBatchSize: number;\n counters: PipelineCounters;\n checkpointBaselineRows: number;\n checkpointBaselineBatches: number;\n schemaCapabilities: Awaited<\n ReturnType<typeof detectImportSchemaCapabilities>\n >;\n};\n\nfunction createCounters(): PipelineCounters {\n return {\n committedRows: 0,\n committedBatches: 0,\n completedFiles: 0,\n secondaryCnaesRows: 0,\n quarantinedRows: 0,\n resumedFiles: 0,\n skippedCompletedFiles: 0,\n };\n}\n\nfunction createDatasetTrackers(\n datasets: readonly ImportDatasetPlan[],\n scanDurations: Partial<Record<ImportDatasetType, number>>,\n): DatasetTrackerMap {\n const trackers = new Map<ImportDatasetType, MutableDatasetPerformance>();\n\n for (const datasetPlan of datasets) {\n trackers.set(\n datasetPlan.dataset,\n createDatasetPerformanceTracker(\n datasetPlan,\n scanDurations[datasetPlan.dataset] ?? 0,\n ),\n );\n }\n\n return trackers;\n}\n\nfunction applyCheckpointMetricsToTrackers(\n datasets: readonly ImportDatasetPlan[],\n trackers: DatasetTrackerMap,\n): void {\n for (const datasetPlan of datasets) {\n const tracker = trackers.get(datasetPlan.dataset);\n if (!tracker) {\n continue;\n }\n\n for (const filePlan of datasetPlan.files) {\n if (\n filePlan.checkpoint?.status === \"completed\" &&\n filePlan.checkpoint.byteOffset >= filePlan.fileSize\n ) {\n tracker.skippedCompletedFiles += 1;\n continue;\n }\n\n if (\n filePlan.checkpoint &&\n (filePlan.checkpoint.byteOffset > 0 ||\n filePlan.checkpoint.rowsCommitted > 0)\n ) {\n tracker.resumedFiles += 1;\n }\n }\n }\n}\n\nfunction resolveLoadBatchSize(options: ImportOptions | undefined): number {\n return Math.max(1, options?.loadBatchSize ?? options?.batchSize ?? 500);\n}\n\nfunction resolveMaterializeBatchSize(\n options: ImportOptions | undefined,\n): number {\n return Math.max(1, options?.materializeBatchSize ?? 50_000);\n}\n\nfunction buildExpectedStagedRowsByDataset(\n datasets: readonly ImportDatasetPlan[],\n): ReadonlyMap<ImportDatasetType, number> {\n return new Map(\n datasets\n .filter((datasetPlan) => isMaterializationDataset(datasetPlan.dataset))\n .map((datasetPlan) => [\n datasetPlan.dataset,\n datasetPlan.files.reduce(\n (sum, filePlan) => sum + (filePlan.checkpoint?.rowsCommitted ?? 0),\n 0,\n ),\n ]),\n );\n}\n\nasync function prepareExecutionForLoad(\n input: SharedPipelineInput,\n): Promise<PreparedExecution> {\n const selectedDatasets = resolveRequestedDatasets(input.options?.dataset);\n const datasetEntries = collectDatasetEntriesForImport(\n input.inspection,\n selectedDatasets,\n );\n const loadBatchSize = resolveLoadBatchSize(input.options);\n const materializeBatchSize = resolveMaterializeBatchSize(input.options);\n const progressLogPath = await createJsonLinesLog(\"import-progress\");\n const client = new Client({ connectionString: input.dbUrl });\n\n await client.connect();\n await ensureImportCheckpointSupport(client);\n await ensureMaterializationCheckpointTable(client);\n await ensureImportQuarantineSupport(client);\n\n const preparedPlan = await prepareImportPlan({\n client,\n inputPath: input.inputPath,\n validatedPath: input.validatedPath,\n batchSize: loadBatchSize,\n datasetEntries,\n targetDatabase: input.targetDatabase,\n progressLogPath,\n ...(input.options?.onProgress\n ? { onProgress: input.options.onProgress }\n : {}),\n });\n\n const datasetPerformanceTrackers = createDatasetTrackers(\n preparedPlan.plan.datasets,\n preparedPlan.datasetScanDurationsMs,\n );\n\n const schemaCapabilities = await detectImportSchemaCapabilities(client);\n await ensureStagingSchemaSupport(\n client,\n preparedPlan.plan.datasets.map((datasetPlan) => datasetPlan.dataset),\n );\n\n const checkpointTotals = await hydrateImportPlanWithCheckpoints(\n client,\n preparedPlan.plan.datasets,\n loadBatchSize,\n );\n\n const counters = createCounters();\n counters.committedRows = checkpointTotals.committedRows;\n counters.committedBatches = checkpointTotals.committedBatches;\n counters.completedFiles = checkpointTotals.completedFiles;\n counters.resumedFiles = checkpointTotals.resumedFiles;\n counters.skippedCompletedFiles = checkpointTotals.skippedCompletedFiles;\n\n applyCheckpointMetricsToTrackers(\n preparedPlan.plan.datasets,\n datasetPerformanceTrackers,\n );\n\n if (preparedPlan.planId !== null && !preparedPlan.planReused) {\n await resetMaterializationCheckpoints(client, preparedPlan.planId);\n await updateImportPlanPhaseState(client, {\n planId: preparedPlan.planId,\n loadStatus: \"pending\",\n materializationStatus: \"pending\",\n lastPhase: \"planning\",\n lastError: null,\n });\n }\n\n return {\n client,\n progressLogPath,\n planId: preparedPlan.planId,\n planReused: preparedPlan.planReused,\n plan: preparedPlan.plan,\n datasetPerformanceTrackers,\n scanDurationMs: preparedPlan.scanDurationMs,\n sourceFingerprint: preparedPlan.sourceFingerprint,\n loadBatchSize,\n materializeBatchSize,\n counters,\n checkpointBaselineRows: checkpointTotals.committedRows,\n checkpointBaselineBatches: checkpointTotals.committedBatches,\n schemaCapabilities,\n };\n}\n\nasync function prepareExecutionForMaterialization(\n input: SharedPipelineInput,\n): Promise<PreparedExecution> {\n const progressLogPath = await createJsonLinesLog(\"import-progress\");\n const client = new Client({ connectionString: input.dbUrl });\n await client.connect();\n await ensureImportCheckpointSupport(client);\n await ensureMaterializationCheckpointTable(client);\n await ensureImportQuarantineSupport(client);\n\n const savedPlan = await readLatestImportPlanForValidatedPath(\n client,\n input.validatedPath,\n input.targetDatabase,\n );\n\n if (!savedPlan) {\n throw new ValidationError(\n 'No saved import plan was found for this validated input path. Run \"cnpj-db-loader import load\" or \"cnpj-db-loader import\" first.',\n );\n }\n\n const requestedDatasets = resolveRequestedDatasets(input.options?.dataset);\n const requestedSet = new Set(requestedDatasets);\n const filteredDatasets = savedPlan.datasets.filter((datasetPlan) =>\n requestedSet.has(datasetPlan.dataset),\n );\n\n if (filteredDatasets.length === 0) {\n throw new ValidationError(\n \"No datasets from the requested selection are available in the saved import plan.\",\n );\n }\n\n const plan = {\n datasets: filteredDatasets,\n totalFiles: filteredDatasets.reduce(\n (sum, datasetPlan) => sum + datasetPlan.files.length,\n 0,\n ),\n totalRows: filteredDatasets.reduce(\n (sum, datasetPlan) => sum + datasetPlan.totalRows,\n 0,\n ),\n totalBatches: filteredDatasets.reduce(\n (sum, datasetPlan) => sum + datasetPlan.totalBatches,\n 0,\n ),\n };\n\n const datasetPerformanceTrackers = createDatasetTrackers(plan.datasets, {});\n const schemaCapabilities = await detectImportSchemaCapabilities(client);\n await ensureStagingSchemaSupport(\n client,\n plan.datasets.map((datasetPlan) => datasetPlan.dataset),\n );\n\n const checkpointTotals = await hydrateImportPlanWithCheckpoints(\n client,\n plan.datasets,\n savedPlan.plan.batchSize,\n );\n\n const counters = createCounters();\n counters.committedRows = checkpointTotals.committedRows;\n counters.committedBatches = checkpointTotals.committedBatches;\n counters.completedFiles = checkpointTotals.completedFiles;\n counters.resumedFiles = checkpointTotals.resumedFiles;\n counters.skippedCompletedFiles = checkpointTotals.skippedCompletedFiles;\n applyCheckpointMetricsToTrackers(plan.datasets, datasetPerformanceTrackers);\n\n input.options?.onProgress?.({\n kind: \"plan_ready\",\n totalDatasets: plan.datasets.length,\n totalFiles: plan.totalFiles,\n batchSize: savedPlan.plan.batchSize,\n loadBatchSize: savedPlan.plan.batchSize,\n materializeBatchSize: resolveMaterializeBatchSize(input.options),\n totalRows: plan.totalRows,\n totalBatches: plan.totalBatches,\n targetDatabase: input.targetDatabase,\n executionOrder: plan.datasets.map((item) => item.dataset),\n reused: true,\n planId: savedPlan.plan.id,\n });\n\n await appendJsonLinesLog(progressLogPath, {\n kind: \"materialization_plan_reused\",\n planId: savedPlan.plan.id,\n sourceFingerprint: savedPlan.plan.sourceFingerprint,\n inputPath: path.resolve(input.inputPath),\n validatedPath: input.validatedPath,\n targetDatabase: input.targetDatabase,\n totalDatasets: plan.datasets.length,\n totalFiles: plan.totalFiles,\n totalRows: plan.totalRows,\n totalBatches: plan.totalBatches,\n materializeBatchSize: resolveMaterializeBatchSize(input.options),\n executionOrder: plan.datasets.map((item) => item.dataset),\n timestamp: new Date().toISOString(),\n });\n\n return {\n client,\n progressLogPath,\n planId: savedPlan.plan.id,\n planReused: true,\n plan,\n datasetPerformanceTrackers,\n scanDurationMs: 0,\n sourceFingerprint: savedPlan.plan.sourceFingerprint,\n loadBatchSize: savedPlan.plan.batchSize,\n materializeBatchSize: resolveMaterializeBatchSize(input.options),\n counters,\n checkpointBaselineRows: checkpointTotals.committedRows,\n checkpointBaselineBatches: checkpointTotals.committedBatches,\n schemaCapabilities,\n };\n}\n\nasync function runLoadStage(\n input: SharedPipelineInput,\n execution: PreparedExecution,\n stageLabel: \"import\" | \"load\",\n): Promise<void> {\n if (!execution.planReused) {\n const resetTables = await resetStagingTablesForFreshPlan(\n execution.client,\n execution.plan.datasets.map((datasetPlan) => datasetPlan.dataset),\n );\n\n if (resetTables.length > 0) {\n await appendJsonLinesLog(execution.progressLogPath, {\n kind: \"staging_reset\",\n tables: resetTables,\n timestamp: new Date().toISOString(),\n });\n }\n }\n\n if (execution.planId !== null) {\n await updateImportPlanStatus(\n execution.client,\n execution.planId,\n \"in_progress\",\n );\n await updateImportPlanPhaseState(execution.client, {\n planId: execution.planId,\n loadStatus: \"in_progress\",\n lastPhase: \"load\",\n lastError: null,\n });\n }\n\n input.options?.onProgress?.({\n kind: \"start\",\n inputPath: path.resolve(input.inputPath),\n validatedPath: input.validatedPath,\n totalDatasets: execution.plan.datasets.length,\n totalFiles: execution.plan.totalFiles,\n targetDatabase: input.targetDatabase,\n totalRows: execution.plan.totalRows,\n totalBatches: execution.plan.totalBatches,\n committedRows: execution.counters.committedRows,\n committedBatches: execution.counters.committedBatches,\n });\n\n await appendJsonLinesLog(execution.progressLogPath, {\n kind: `${stageLabel}_started`,\n planId: execution.planId,\n sourceFingerprint: execution.sourceFingerprint,\n inputPath: path.resolve(input.inputPath),\n validatedPath: input.validatedPath,\n targetDatabase: input.targetDatabase,\n totalDatasets: execution.plan.datasets.length,\n totalFiles: execution.plan.totalFiles,\n totalRows: execution.plan.totalRows,\n totalBatches: execution.plan.totalBatches,\n loadBatchSize: execution.loadBatchSize,\n materializeBatchSize: execution.materializeBatchSize,\n resumedFiles: execution.counters.resumedFiles,\n skippedCompletedFiles: execution.counters.skippedCompletedFiles,\n committedRows: execution.counters.committedRows,\n committedBatches: execution.counters.committedBatches,\n timestamp: new Date().toISOString(),\n });\n\n let globalFileIndex = 0;\n for (const [datasetIndex, datasetPlan] of execution.plan.datasets.entries()) {\n const datasetTracker = execution.datasetPerformanceTrackers.get(\n datasetPlan.dataset,\n );\n if (!datasetTracker) {\n continue;\n }\n\n await appendJsonLinesLog(execution.progressLogPath, {\n kind: \"dataset_started\",\n dataset: datasetPlan.dataset,\n datasetIndex: datasetIndex + 1,\n totalDatasets: execution.plan.datasets.length,\n plannedRows: datasetPlan.totalRows,\n plannedBatches: datasetPlan.totalBatches,\n resumedFiles: datasetTracker.resumedFiles,\n skippedCompletedFiles: datasetTracker.skippedCompletedFiles,\n timestamp: new Date().toISOString(),\n });\n\n for (const filePlan of datasetPlan.files) {\n globalFileIndex += 1;\n\n const rowsBefore = execution.counters.committedRows;\n const batchesBefore = execution.counters.committedBatches;\n const fileStartedAt = performance.now();\n const filePerformanceBefore = {\n insertDurationMs: datasetTracker.insertDurationMs,\n retryDurationMs: datasetTracker.retryDurationMs,\n quarantineDurationMs: datasetTracker.quarantineDurationMs,\n retriedRows: datasetTracker.retriedRows,\n retriedBatches: datasetTracker.retriedBatches,\n quarantinedRows: datasetTracker.quarantinedRows,\n };\n\n await importDatasetFile(\n execution.client,\n filePlan,\n execution.schemaCapabilities,\n execution.counters,\n {\n datasetIndex: datasetIndex + 1,\n totalDatasets: execution.plan.datasets.length,\n totalFiles: execution.plan.totalFiles,\n totalBatches: execution.plan.totalBatches,\n fileIndex: globalFileIndex,\n onProgress: input.options?.onProgress,\n progressLogPath: execution.progressLogPath,\n batchSize: execution.loadBatchSize,\n verboseProgress: input.options?.verboseProgress ?? false,\n performance: datasetTracker,\n },\n );\n\n datasetTracker.importDurationMs += performance.now() - fileStartedAt;\n datasetTracker.importedRows +=\n execution.counters.committedRows - rowsBefore;\n datasetTracker.committedBatches +=\n execution.counters.committedBatches - batchesBefore;\n\n await appendJsonLinesLog(execution.progressLogPath, {\n kind: \"file_metrics\",\n dataset: datasetPlan.dataset,\n datasetIndex: datasetIndex + 1,\n filePath: filePlan.absolutePath,\n fileDisplayPath: filePlan.displayPath,\n fileIndex: globalFileIndex,\n importedRows: execution.counters.committedRows - rowsBefore,\n committedBatches: execution.counters.committedBatches - batchesBefore,\n insertDurationMs:\n datasetTracker.insertDurationMs -\n filePerformanceBefore.insertDurationMs,\n retryDurationMs:\n datasetTracker.retryDurationMs -\n filePerformanceBefore.retryDurationMs,\n quarantineDurationMs:\n datasetTracker.quarantineDurationMs -\n filePerformanceBefore.quarantineDurationMs,\n retriedRows:\n datasetTracker.retriedRows - filePerformanceBefore.retriedRows,\n retriedBatches:\n datasetTracker.retriedBatches - filePerformanceBefore.retriedBatches,\n quarantinedRows:\n datasetTracker.quarantinedRows -\n filePerformanceBefore.quarantinedRows,\n durationMs: performance.now() - fileStartedAt,\n timestamp: new Date().toISOString(),\n });\n }\n\n await appendJsonLinesLog(execution.progressLogPath, {\n kind: \"dataset_completed\",\n dataset: datasetPlan.dataset,\n datasetIndex: datasetIndex + 1,\n totalDatasets: execution.plan.datasets.length,\n metrics: finalizeDatasetPerformance(datasetTracker),\n timestamp: new Date().toISOString(),\n });\n }\n\n if (execution.planId !== null) {\n await updateImportPlanPhaseState(execution.client, {\n planId: execution.planId,\n loadStatus: \"completed\",\n lastPhase: \"load_completed\",\n lastError: null,\n });\n }\n}\n\nasync function runMaterializationStage(\n execution: PreparedExecution,\n onProgress: ImportOptions[\"onProgress\"],\n): Promise<void> {\n if (execution.planId === null) {\n throw new ValidationError(\n \"The materialization stage requires a persisted import plan.\",\n );\n }\n\n await updateImportPlanStatus(\n execution.client,\n execution.planId,\n \"in_progress\",\n );\n await updateImportPlanPhaseState(execution.client, {\n planId: execution.planId,\n materializationStatus: \"in_progress\",\n lastPhase: \"materialization\",\n lastError: null,\n });\n\n await hydrateImportPlanWithCheckpoints(\n execution.client,\n execution.plan.datasets,\n execution.loadBatchSize,\n );\n\n const materializationSummary = await materializeStagedDatasets({\n client: execution.client,\n planId: execution.planId,\n datasets: execution.plan.datasets.map((datasetPlan) => datasetPlan.dataset),\n schemaCapabilities: execution.schemaCapabilities,\n progressLogPath: execution.progressLogPath,\n datasetPerformanceTrackers: execution.datasetPerformanceTrackers,\n expectedRowsByDataset: new Map(\n execution.plan.datasets.map((datasetPlan) => [\n datasetPlan.dataset,\n datasetPlan.totalRows,\n ]),\n ),\n expectedStagedRowsByDataset: buildExpectedStagedRowsByDataset(\n execution.plan.datasets,\n ),\n onProgress,\n completedFiles: execution.counters.completedFiles,\n totalFiles: execution.plan.totalFiles,\n processedRows: execution.counters.committedRows,\n totalRows: execution.plan.totalRows,\n committedBatches: execution.counters.committedBatches,\n totalBatches: execution.plan.totalBatches,\n chunkSize: execution.materializeBatchSize,\n });\n\n void materializationSummary;\n\n await updateImportPlanPhaseState(execution.client, {\n planId: execution.planId,\n materializationStatus: \"completed\",\n lastPhase: \"materialization_completed\",\n lastError: null,\n });\n}\n\nasync function buildSummary(\n input: SharedPipelineInput,\n execution: PreparedExecution,\n overallStartedAt: number,\n executionMode: \"full\" | \"load\" | \"materialize\",\n): Promise<ImportSummary> {\n const executionDurationMs =\n performance.now() - overallStartedAt - execution.scanDurationMs;\n const datasetPerformance = execution.plan.datasets\n .map((datasetPlan) =>\n execution.datasetPerformanceTrackers.get(datasetPlan.dataset),\n )\n .filter((item): item is MutableDatasetPerformance => item !== undefined);\n const executionRowsCommitted = Math.max(\n 0,\n execution.counters.committedRows - execution.checkpointBaselineRows,\n );\n const executionBatchesCommitted = Math.max(\n 0,\n execution.counters.committedBatches - execution.checkpointBaselineBatches,\n );\n\n const performanceSummary: ImportPerformanceSummary =\n buildImportPerformanceSummary({\n planReused: execution.planReused,\n totalDurationMs: performance.now() - overallStartedAt,\n scanDurationMs: execution.scanDurationMs,\n executionDurationMs,\n lookupLoadDurationMs: 0,\n executionRowsCommitted,\n executionBatchesCommitted,\n datasets: datasetPerformance,\n });\n\n input.options?.onProgress?.({\n kind: \"finish\",\n totalDatasets: execution.plan.datasets.length,\n totalFiles: execution.plan.totalFiles,\n completedFiles: execution.counters.completedFiles,\n processedRows: execution.counters.committedRows,\n totalRows: execution.plan.totalRows,\n committedBatches: execution.counters.committedBatches,\n totalBatches: execution.plan.totalBatches,\n quarantinedRows: execution.counters.quarantinedRows,\n });\n\n await appendJsonLinesLog(execution.progressLogPath, {\n kind: \"import_finished\",\n totalDatasets: execution.plan.datasets.length,\n totalFiles: execution.plan.totalFiles,\n completedFiles: execution.counters.completedFiles,\n processedRows: execution.counters.committedRows,\n totalRows: execution.plan.totalRows,\n committedBatches: execution.counters.committedBatches,\n totalBatches: execution.plan.totalBatches,\n quarantinedRows: execution.counters.quarantinedRows,\n resumedFiles: execution.counters.resumedFiles,\n skippedCompletedFiles: execution.counters.skippedCompletedFiles,\n performance: performanceSummary,\n timestamp: new Date().toISOString(),\n });\n\n const datasetSummaries = summarizeImportedDatasets(execution.plan.datasets);\n\n return {\n executionMode,\n inputPath: path.resolve(input.inputPath),\n validatedPath: input.validatedPath,\n targetDatabase: input.targetDatabase,\n importPlanId: execution.planId,\n reusedImportPlan: execution.planReused,\n importedDatasets: datasetSummaries.map((item) => item.dataset),\n importedFiles: execution.counters.completedFiles,\n processedRows: execution.counters.committedRows,\n plannedRows: execution.plan.totalRows,\n committedBatches: execution.counters.committedBatches,\n plannedBatches: execution.plan.totalBatches,\n quarantinedRows: execution.counters.quarantinedRows,\n resumedFiles: execution.counters.resumedFiles,\n skippedCompletedFiles: execution.counters.skippedCompletedFiles,\n datasetSummaries,\n performance: performanceSummary,\n warnings: buildImportWarnings(),\n progressLogPath: execution.progressLogPath,\n };\n}\n\nasync function finalizePlanCompletion(\n execution: PreparedExecution,\n): Promise<void> {\n if (execution.planId === null) {\n return;\n }\n\n await updateImportPlanStatus(execution.client, execution.planId, \"completed\");\n await updateImportPlanPhaseState(execution.client, {\n planId: execution.planId,\n loadStatus: \"completed\",\n materializationStatus: \"completed\",\n lastPhase: \"completed\",\n lastError: null,\n });\n}\n\nasync function closeClient(client: Client): Promise<void> {\n await client.end().catch(() => undefined);\n}\n\nexport async function runImportPipeline(\n input: SharedPipelineInput,\n): Promise<ImportSummary> {\n const overallStartedAt = performance.now();\n let execution: PreparedExecution | null = null;\n\n try {\n execution = await prepareExecutionForLoad(input);\n await runLoadStage(input, execution, \"import\");\n await runMaterializationStage(execution, input.options?.onProgress);\n await finalizePlanCompletion(execution);\n return await buildSummary(input, execution, overallStartedAt, \"full\");\n } catch (error) {\n if (execution && execution.planId !== null) {\n await updateImportPlanStatus(\n execution.client,\n execution.planId,\n \"failed\",\n ).catch(() => undefined);\n await updateImportPlanPhaseState(execution.client, {\n planId: execution.planId,\n lastError: error instanceof Error ? error.message : String(error),\n }).catch(() => undefined);\n }\n\n if (execution) {\n await appendJsonLinesLog(execution.progressLogPath, {\n kind: \"import_failed\",\n planId: execution.planId,\n sourceFingerprint: execution.sourceFingerprint,\n inputPath: path.resolve(input.inputPath),\n validatedPath: input.validatedPath,\n targetDatabase: input.targetDatabase,\n error: error instanceof Error ? error.message : String(error),\n timestamp: new Date().toISOString(),\n }).catch(() => undefined);\n }\n throw error;\n } finally {\n if (execution) {\n await closeClient(execution.client);\n }\n }\n}\n\nexport async function runImportLoadPipeline(\n input: SharedPipelineInput,\n): Promise<ImportSummary> {\n const overallStartedAt = performance.now();\n let execution: PreparedExecution | null = null;\n\n try {\n execution = await prepareExecutionForLoad(input);\n await runLoadStage(input, execution, \"load\");\n if (execution.planId !== null) {\n await updateImportPlanStatus(\n execution.client,\n execution.planId,\n \"in_progress\",\n );\n }\n return await buildSummary(input, execution, overallStartedAt, \"load\");\n } catch (error) {\n if (execution && execution.planId !== null) {\n await updateImportPlanStatus(\n execution.client,\n execution.planId,\n \"failed\",\n ).catch(() => undefined);\n await updateImportPlanPhaseState(execution.client, {\n planId: execution.planId,\n loadStatus: \"failed\",\n lastPhase: \"load_failed\",\n lastError: error instanceof Error ? error.message : String(error),\n }).catch(() => undefined);\n }\n throw error;\n } finally {\n if (execution) {\n await closeClient(execution.client);\n }\n }\n}\n\nexport async function runImportMaterializationPipeline(\n input: SharedPipelineInput,\n): Promise<ImportSummary> {\n const overallStartedAt = performance.now();\n let execution: PreparedExecution | null = null;\n\n try {\n execution = await prepareExecutionForMaterialization(input);\n await runMaterializationStage(execution, input.options?.onProgress);\n await finalizePlanCompletion(execution);\n return await buildSummary(\n input,\n execution,\n overallStartedAt,\n \"materialize\",\n );\n } catch (error) {\n if (execution && execution.planId !== null) {\n await updateImportPlanStatus(\n execution.client,\n execution.planId,\n \"failed\",\n ).catch(() => undefined);\n await updateImportPlanPhaseState(execution.client, {\n planId: execution.planId,\n materializationStatus: \"failed\",\n lastPhase: \"materialization_failed\",\n lastError: error instanceof Error ? error.message : String(error),\n }).catch(() => undefined);\n }\n throw error;\n } finally {\n if (execution) {\n await closeClient(execution.client);\n }\n }\n}\n","import type {\n ImportDatasetPerformanceSummary,\n ImportDatasetPlan,\n ImportDatasetType,\n ImportPerformanceSummary,\n} from \"./types.js\";\n\nexport type MutableDatasetPerformance = Omit<\n ImportDatasetPerformanceSummary,\n \"rowsPerSecond\" | \"batchesPerMinute\"\n>;\n\nexport function calculateRowsPerSecond(\n rows: number,\n durationMs: number,\n): number {\n if (rows <= 0 || durationMs <= 0) {\n return 0;\n }\n\n return rows / (durationMs / 1000);\n}\n\nexport function calculateBatchesPerMinute(\n batches: number,\n durationMs: number,\n): number {\n if (batches <= 0 || durationMs <= 0) {\n return 0;\n }\n\n return batches / (durationMs / 60000);\n}\n\nexport function createDatasetPerformanceTracker(\n datasetPlan: ImportDatasetPlan,\n scanDurationMs: number,\n): MutableDatasetPerformance {\n return {\n dataset: datasetPlan.dataset,\n files: datasetPlan.files.length,\n plannedRows: datasetPlan.totalRows,\n importedRows: 0,\n plannedBatches: datasetPlan.totalBatches,\n committedBatches: 0,\n resumedFiles: 0,\n skippedCompletedFiles: 0,\n retriedRows: 0,\n retriedBatches: 0,\n quarantinedRows: 0,\n scanDurationMs,\n importDurationMs: 0,\n insertDurationMs: 0,\n retryDurationMs: 0,\n quarantineDurationMs: 0,\n materializationDurationMs: 0,\n };\n}\n\nexport function finalizeDatasetPerformance(\n tracker: MutableDatasetPerformance,\n): ImportDatasetPerformanceSummary {\n return {\n ...tracker,\n rowsPerSecond: calculateRowsPerSecond(\n tracker.importedRows,\n tracker.importDurationMs,\n ),\n batchesPerMinute: calculateBatchesPerMinute(\n tracker.committedBatches,\n tracker.importDurationMs,\n ),\n };\n}\n\nexport function buildImportPerformanceSummary(input: {\n planReused: boolean;\n totalDurationMs: number;\n scanDurationMs: number;\n executionDurationMs: number;\n lookupLoadDurationMs: number;\n executionRowsCommitted: number;\n executionBatchesCommitted: number;\n datasets: MutableDatasetPerformance[];\n}): ImportPerformanceSummary {\n const finalizedDatasets = input.datasets.map(finalizeDatasetPerformance);\n\n return {\n planReused: input.planReused,\n totalDurationMs: input.totalDurationMs,\n scanDurationMs: input.scanDurationMs,\n executionDurationMs: input.executionDurationMs,\n lookupLoadDurationMs: input.lookupLoadDurationMs,\n insertDurationMs: finalizedDatasets.reduce(\n (sum, item) => sum + item.insertDurationMs,\n 0,\n ),\n retryDurationMs: finalizedDatasets.reduce(\n (sum, item) => sum + item.retryDurationMs,\n 0,\n ),\n quarantineDurationMs: finalizedDatasets.reduce(\n (sum, item) => sum + item.quarantineDurationMs,\n 0,\n ),\n materializationDurationMs: finalizedDatasets.reduce(\n (sum, item) => sum + item.materializationDurationMs,\n 0,\n ),\n rowsPerSecond: calculateRowsPerSecond(\n input.executionRowsCommitted,\n input.executionDurationMs,\n ),\n batchesPerMinute: calculateBatchesPerMinute(\n input.executionBatchesCommitted,\n input.executionDurationMs,\n ),\n datasets: finalizedDatasets,\n };\n}\n\nexport function buildImportWarnings(): string[] {\n return [\n \"The importer uses exact file planning, checkpointed batch commits, and byte-offset resume. If a load unit fails, rerunning the same command resumes from the last committed checkpoint instead of restarting the full load.\",\n \"Import plans are persisted in the database and reused for the same validated input, source files, and load batch size so resumed imports do not recount rows unnecessarily.\",\n \"Large datasets now land in lightweight staging tables through PostgreSQL COPY with only light normalization on the write hot path. Materialization into the simplified final schema keeps the first load focused on fast persistence instead of eager relational enrichment.\",\n \"When a new import plan starts, the selected staging tables are truncated before loading so staged bulk loads stay clean and predictable. Resumed plans keep the staged rows that already match the saved checkpoints.\",\n \"Rows that fail parsing, normalization, COPY fallback, or row-level inserts are moved to import_quarantine and the import continues from the next row.\",\n \"The import summary includes baseline timing and throughput metrics for scan, execution, staging writes, materialization, retry, and quarantine paths so future performance changes can be measured against a stable reference.\",\n \"The load batch size defines the staging load unit size, while the materialization batch size defines how many staged rows each consolidation chunk processes before saving a materialization checkpoint.\",\n ];\n}\n\nexport function summarizeImportedDatasets(\n datasets: ImportDatasetPlan[],\n): Array<{\n dataset: ImportDatasetType;\n files: number;\n rows: number;\n}> {\n return datasets.map((datasetPlan) => ({\n dataset: datasetPlan.dataset,\n files: datasetPlan.files.length,\n rows: datasetPlan.totalRows,\n }));\n}\n","import { performance } from \"node:perf_hooks\";\n\nimport { Client } from \"pg\";\n\nimport { appendJsonLinesLog } from \"../logging.service.js\";\nimport {\n DATASET_LAYOUTS,\n type ImportCheckpointStatus,\n type ImportFilePlan,\n type ImportProgressListener,\n type ImportSchemaCapabilities,\n} from \"./types.js\";\nimport {\n markImportCheckpointFailed,\n readImportCheckpoint,\n writeImportCheckpoint,\n} from \"./checkpoint-manager.js\";\nimport { parseImportSourceLine } from \"./parser.js\";\nimport { createImportRowNormalizer } from \"./normalizer.js\";\nimport { readImportSourceLines } from \"./source-reader.js\";\nimport {\n writeImportBatchToTarget,\n writeImportRowToTarget,\n} from \"./staging-writer.js\";\nimport { resolveImportWriteTarget } from \"./targets.js\";\nimport { writeImportQuarantineRow } from \"./quarantine-writer.js\";\nimport { buildParsedPayload } from \"./transform.js\";\n\nexport async function importDatasetFile(\n client: Client,\n filePlan: ImportFilePlan,\n schemaCapabilities: ImportSchemaCapabilities,\n counters: {\n committedRows: number;\n committedBatches: number;\n completedFiles: number;\n secondaryCnaesRows: number;\n quarantinedRows: number;\n },\n progress: {\n datasetIndex: number;\n totalDatasets: number;\n totalFiles: number;\n totalBatches: number;\n fileIndex: number;\n onProgress: ImportProgressListener | undefined;\n progressLogPath: string;\n batchSize: number;\n verboseProgress: boolean;\n performance: {\n insertDurationMs: number;\n retryDurationMs: number;\n quarantineDurationMs: number;\n retriedRows: number;\n retriedBatches: number;\n quarantinedRows: number;\n };\n },\n): Promise<number> {\n const dataset = filePlan.dataset;\n const filePath = filePlan.absolutePath;\n const layout = DATASET_LAYOUTS[dataset];\n const writeTarget = resolveImportWriteTarget(dataset);\n let checkpoint =\n filePlan.checkpoint ??\n (await readImportCheckpoint(\n client,\n dataset,\n filePath,\n filePlan.fileSize,\n filePlan.fileMtime,\n ));\n\n const emitProgress = (): void => {\n progress.onProgress?.({\n kind: \"progress\",\n dataset,\n datasetIndex: progress.datasetIndex,\n totalDatasets: progress.totalDatasets,\n currentFilePath: filePath,\n currentFileDisplayPath: filePlan.displayPath,\n fileIndex: progress.fileIndex,\n completedFiles: counters.completedFiles,\n totalFiles: progress.totalFiles,\n currentFileRowsCommitted: checkpoint.rowsCommitted,\n currentFileRowsTotal: filePlan.totalRows,\n committedRows: counters.committedRows,\n committedBatches: counters.committedBatches,\n totalBatches: progress.totalBatches,\n currentBatch:\n filePlan.totalBatches === 0\n ? 0\n : Math.min(\n filePlan.totalBatches,\n Math.max(\n 1,\n Math.ceil(\n Math.max(checkpoint.rowsCommitted, 1) / progress.batchSize,\n ),\n ),\n ),\n batchSize: progress.batchSize,\n checkpointOffset: checkpoint.byteOffset,\n currentFileSize: filePlan.fileSize,\n verboseProgress: progress.verboseProgress,\n });\n };\n\n if (\n checkpoint.status === \"completed\" &&\n checkpoint.byteOffset >= filePlan.fileSize\n ) {\n emitProgress();\n return checkpoint.rowsCommitted;\n }\n\n const rowNormalizer = createImportRowNormalizer({\n dataset,\n filePath,\n layout,\n schemaCapabilities,\n });\n const columns = rowNormalizer.columns;\n\n let fileRowsCommitted = checkpoint.rowsCommitted;\n let batchRows: ReturnType<typeof rowNormalizer.normalize>[] = [];\n let batchLastOffset = checkpoint.byteOffset;\n\n const persistCheckpoint = async (\n status: ImportCheckpointStatus,\n byteOffset: number,\n rowsCommitted: number,\n ): Promise<void> => {\n checkpoint = {\n ...checkpoint,\n byteOffset,\n rowsCommitted,\n status,\n lastError: null,\n };\n await writeImportCheckpoint(client, checkpoint);\n };\n\n const runInTransaction = async (\n callback: () => Promise<void>,\n ): Promise<void> => {\n await client.query(\"begin\");\n try {\n await callback();\n await client.query(\"commit\");\n } catch (error) {\n await client.query(\"rollback\");\n throw error;\n }\n };\n\n const quarantineRow = async (input: {\n rowNumber: number;\n checkpointOffset: number;\n rawLine: string;\n error: unknown;\n parsedPayload: Record<string, unknown> | null;\n }): Promise<void> => {\n const quarantineStartedAt = performance.now();\n\n await runInTransaction(async () => {\n await writeImportQuarantineRow(client, {\n dataset,\n filePath,\n rowNumber: input.rowNumber,\n checkpointOffset: input.checkpointOffset,\n rawLine: input.rawLine,\n error: input.error,\n parsedPayload: input.parsedPayload,\n });\n await persistCheckpoint(\n \"in_progress\",\n input.checkpointOffset,\n input.rowNumber,\n );\n });\n\n progress.performance.quarantineDurationMs +=\n performance.now() - quarantineStartedAt;\n progress.performance.quarantinedRows += 1;\n counters.quarantinedRows += 1;\n\n await appendJsonLinesLog(progress.progressLogPath, {\n kind: \"row_quarantined\",\n dataset,\n datasetIndex: progress.datasetIndex,\n filePath,\n fileDisplayPath: filePlan.displayPath,\n fileIndex: progress.fileIndex,\n rowNumber: input.rowNumber,\n checkpointOffset: input.checkpointOffset,\n error:\n input.error instanceof Error\n ? input.error.message\n : String(input.error),\n durationMs: performance.now() - quarantineStartedAt,\n timestamp: new Date().toISOString(),\n });\n };\n\n const commitBatch = async (markCompleted: boolean): Promise<void> => {\n if (batchRows.length === 0) {\n if (markCompleted) {\n await runInTransaction(async () => {\n await persistCheckpoint(\n \"completed\",\n filePlan.fileSize,\n fileRowsCommitted,\n );\n });\n emitProgress();\n }\n return;\n }\n\n const batchStartedAt = performance.now();\n\n try {\n const batchResult = await (async () => {\n let result:\n | Awaited<ReturnType<typeof writeImportBatchToTarget>>\n | undefined;\n\n await runInTransaction(async () => {\n result = await writeImportBatchToTarget({\n client,\n dataset,\n rows: batchRows,\n schemaCapabilities,\n });\n await persistCheckpoint(\n markCompleted ? \"completed\" : \"in_progress\",\n markCompleted ? filePlan.fileSize : batchLastOffset,\n fileRowsCommitted,\n );\n });\n\n return result;\n })();\n\n progress.performance.insertDurationMs +=\n performance.now() - batchStartedAt;\n counters.committedRows += batchRows.length;\n counters.committedBatches += 1;\n counters.secondaryCnaesRows += batchResult?.writtenSecondaryRows ?? 0;\n\n await appendJsonLinesLog(progress.progressLogPath, {\n kind: \"batch_committed\",\n dataset,\n datasetIndex: progress.datasetIndex,\n filePath,\n fileDisplayPath: filePlan.displayPath,\n fileIndex: progress.fileIndex,\n batchNumber: counters.committedBatches,\n batchSize: progress.batchSize,\n batchRows: batchRows.length,\n fileRowsCommitted,\n fileRowsTotal: filePlan.totalRows,\n totalRowsCommitted: counters.committedRows,\n totalBatchesCommitted: counters.committedBatches,\n totalBatchesPlanned: progress.totalBatches,\n checkpointOffset: checkpoint.byteOffset,\n fileSize: filePlan.fileSize,\n secondaryCnaesRows: batchResult?.writtenSecondaryRows ?? 0,\n writeTarget: batchResult?.writeTarget ?? writeTarget,\n writeMode: batchResult?.writeMode ?? \"insert\",\n targetTable: batchResult?.targetTable ?? null,\n durationMs: performance.now() - batchStartedAt,\n timestamp: new Date().toISOString(),\n });\n } catch (batchError) {\n progress.performance.insertDurationMs +=\n performance.now() - batchStartedAt;\n progress.performance.retriedBatches += 1;\n\n await appendJsonLinesLog(progress.progressLogPath, {\n kind: \"batch_retry_fallback\",\n dataset,\n datasetIndex: progress.datasetIndex,\n filePath,\n fileDisplayPath: filePlan.displayPath,\n fileIndex: progress.fileIndex,\n batchRows: batchRows.length,\n checkpointOffset: checkpoint.byteOffset,\n writeTarget,\n error:\n batchError instanceof Error ? batchError.message : String(batchError),\n timestamp: new Date().toISOString(),\n });\n\n for (const row of batchRows) {\n const retryStartedAt = performance.now();\n\n try {\n const rowResult = await (async () => {\n let result:\n | Awaited<ReturnType<typeof writeImportRowToTarget>>\n | undefined;\n\n await runInTransaction(async () => {\n result = await writeImportRowToTarget({\n client,\n dataset,\n row,\n schemaCapabilities,\n });\n await persistCheckpoint(\n \"in_progress\",\n row.nextOffset,\n row.sourceRowNumber,\n );\n });\n\n return result;\n })();\n\n progress.performance.retryDurationMs +=\n performance.now() - retryStartedAt;\n progress.performance.retriedRows += 1;\n counters.committedRows += 1;\n counters.secondaryCnaesRows += rowResult?.writtenSecondaryRows ?? 0;\n } catch (rowError) {\n progress.performance.retryDurationMs +=\n performance.now() - retryStartedAt;\n progress.performance.retriedRows += 1;\n await quarantineRow({\n rowNumber: row.sourceRowNumber,\n checkpointOffset: row.nextOffset,\n rawLine: row.rawLine,\n error: rowError,\n parsedPayload: buildParsedPayload(columns, row.values),\n });\n }\n }\n\n counters.committedBatches += 1;\n if (markCompleted) {\n await runInTransaction(async () => {\n await persistCheckpoint(\n \"completed\",\n filePlan.fileSize,\n fileRowsCommitted,\n );\n });\n }\n }\n\n batchRows = [];\n emitProgress();\n };\n\n emitProgress();\n\n try {\n for await (const sourceLine of readImportSourceLines(\n filePath,\n checkpoint.byteOffset,\n )) {\n if (sourceLine.rawLine.trim() === \"\") {\n checkpoint.byteOffset = sourceLine.nextOffset;\n continue;\n }\n\n try {\n const nextSourceRowNumber = fileRowsCommitted + 1;\n const parsedLine = parseImportSourceLine(sourceLine);\n const normalizedRow = rowNormalizer.normalize(\n parsedLine,\n nextSourceRowNumber,\n );\n\n batchRows.push(normalizedRow);\n fileRowsCommitted = nextSourceRowNumber;\n batchLastOffset = sourceLine.nextOffset;\n\n if (batchRows.length >= progress.batchSize) {\n await commitBatch(false);\n }\n } catch (rowError) {\n fileRowsCommitted += 1;\n batchLastOffset = sourceLine.nextOffset;\n await quarantineRow({\n rowNumber: fileRowsCommitted,\n checkpointOffset: sourceLine.nextOffset,\n rawLine: sourceLine.rawLine,\n error: rowError,\n parsedPayload: null,\n });\n emitProgress();\n }\n }\n\n if (batchRows.length > 0 || checkpoint.byteOffset < filePlan.fileSize) {\n await commitBatch(true);\n }\n\n counters.completedFiles += 1;\n emitProgress();\n\n return fileRowsCommitted;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n await markImportCheckpointFailed(client, checkpoint, message);\n await appendJsonLinesLog(progress.progressLogPath, {\n kind: \"file_failed\",\n dataset,\n datasetIndex: progress.datasetIndex,\n filePath,\n fileDisplayPath: filePlan.displayPath,\n fileIndex: progress.fileIndex,\n fileRowsCommitted: checkpoint.rowsCommitted,\n fileRowsTotal: filePlan.totalRows,\n checkpointOffset: checkpoint.byteOffset,\n fileSize: filePlan.fileSize,\n error: message,\n timestamp: new Date().toISOString(),\n });\n throw error;\n }\n}\n","import type { Client } from \"pg\";\n\nimport {\n ensureCheckpointTable,\n hydratePlanWithCheckpoints,\n markCheckpointFailed,\n readCheckpoint,\n writeCheckpoint,\n} from \"./checkpoints.js\";\n\nexport {\n ensureCheckpointTable as ensureImportCheckpointTable,\n hydratePlanWithCheckpoints as hydrateImportPlanWithCheckpoints,\n markCheckpointFailed as markImportCheckpointFailed,\n readCheckpoint as readImportCheckpoint,\n writeCheckpoint as writeImportCheckpoint,\n};\n\nexport async function ensureImportCheckpointSupport(\n client: Client,\n): Promise<void> {\n await ensureCheckpointTable(client);\n}\n","import { ValidationError } from \"../../core/errors/index.js\";\nimport type { TableLayout } from \"../../dictionary/layouts/index.js\";\nimport type {\n ImportDatasetType,\n ImportSchemaCapabilities,\n ImportWriteTarget,\n} from \"./types.js\";\n\nexport type FieldValueParser = (rawValue: string) => unknown;\n\nexport type PartnerDedupeKeyIndices = {\n cnpjRoot: number;\n partnerTypeCode: number;\n partnerName: number;\n partnerDocument: number;\n partnerQualificationCode: number;\n entryDate: number;\n countryCode: number;\n legalRepresentativeDocument: number;\n legalRepresentativeName: number;\n legalRepresentativeQualificationCode: number;\n ageGroupCode: number;\n};\n\nexport type EstablishmentCnpjFullIndices = {\n cnpjRoot: number;\n cnpjOrder: number;\n cnpjCheckDigits: number;\n};\n\nexport function parseDelimitedLine(line: string): string[] {\n const fields: string[] = [];\n let current = \"\";\n let inQuotes = false;\n\n for (let index = 0; index < line.length; index += 1) {\n const char = line[index];\n const next = line[index + 1];\n\n if (char === '\"') {\n if (inQuotes && next === '\"') {\n current += '\"';\n index += 1;\n continue;\n }\n\n inQuotes = !inQuotes;\n continue;\n }\n\n if (char === \";\" && !inQuotes) {\n fields.push(current);\n current = \"\";\n continue;\n }\n\n current += char;\n }\n\n fields.push(current);\n return fields;\n}\n\nexport function normalizeFieldCount(\n fields: string[],\n expectedLength: number,\n filePath: string,\n lineNumber: number,\n): string[] {\n const normalized = [...fields];\n\n while (\n normalized.length > expectedLength &&\n normalized[normalized.length - 1]?.trim() === \"\"\n ) {\n normalized.pop();\n }\n\n if (normalized.length < expectedLength) {\n while (normalized.length < expectedLength) {\n normalized.push(\"\");\n }\n }\n\n if (normalized.length !== expectedLength) {\n throw new ValidationError(\n `Unexpected field count in ${filePath} at line ${lineNumber}. Expected ${expectedLength}, received ${normalized.length}.`,\n );\n }\n\n return normalized;\n}\n\nexport function createFieldValueParser(\n dataType: TableLayout[\"fields\"][number][\"dataType\"],\n): FieldValueParser {\n switch (dataType) {\n case \"integer\":\n return (rawValue) => {\n const trimmed = rawValue.trim();\n if (trimmed === \"\") {\n return null;\n }\n\n return /^-?\\d+$/.test(trimmed) ? Number.parseInt(trimmed, 10) : null;\n };\n case \"numeric\":\n return (rawValue) => {\n const trimmed = rawValue.trim();\n if (trimmed === \"\") {\n return null;\n }\n\n if (trimmed.includes(\",\") && trimmed.includes(\".\")) {\n return trimmed.replace(/\\./g, \"\").replace(/,/g, \".\");\n }\n\n if (trimmed.includes(\",\")) {\n return trimmed.replace(/,/g, \".\");\n }\n\n return trimmed;\n };\n case \"date\":\n return (rawValue) => {\n const trimmed = rawValue.trim();\n if (trimmed === \"\" || trimmed === \"00000000\") {\n return null;\n }\n\n if (!/^\\d{8}$/.test(trimmed)) {\n return null;\n }\n\n return `${trimmed.slice(0, 4)}-${trimmed.slice(4, 6)}-${trimmed.slice(6, 8)}`;\n };\n case \"boolean\":\n return (rawValue) => {\n const trimmed = rawValue.trim();\n if (trimmed === \"\") {\n return null;\n }\n\n const normalized = trimmed.toLowerCase();\n if ([\"1\", \"true\", \"t\", \"y\", \"yes\", \"s\"].includes(normalized)) {\n return true;\n }\n if ([\"0\", \"false\", \"f\", \"n\", \"no\"].includes(normalized)) {\n return false;\n }\n return null;\n };\n default:\n return (rawValue) => {\n const trimmed = rawValue.trim();\n return trimmed === \"\" ? null : trimmed;\n };\n }\n}\n\nexport function toDatabaseValue(\n dataType: TableLayout[\"fields\"][number][\"dataType\"],\n rawValue: string,\n): unknown {\n return createFieldValueParser(dataType)(rawValue);\n}\n\nfunction normalizeCode(value: unknown, fallback: string): string {\n if (typeof value === \"string\" && value.trim() !== \"\") {\n return value.trim();\n }\n\n return fallback;\n}\n\nexport function createPartnerDedupeKeyBuilder(\n indices: PartnerDedupeKeyIndices,\n): (record: readonly unknown[]) => string {\n const orderedIndices = [\n indices.cnpjRoot,\n indices.partnerTypeCode,\n indices.partnerName,\n indices.partnerDocument,\n indices.partnerQualificationCode,\n indices.entryDate,\n indices.countryCode,\n indices.legalRepresentativeDocument,\n indices.legalRepresentativeName,\n indices.legalRepresentativeQualificationCode,\n indices.ageGroupCode,\n ];\n\n return (record) =>\n orderedIndices\n .map((index) => {\n const value = record[index];\n return value == null ? \"\" : String(value).trim();\n })\n .join(\"|\");\n}\n\nexport function createEstablishmentCnpjFullBuilder(\n indices: EstablishmentCnpjFullIndices,\n): (record: readonly unknown[]) => string {\n return (record) => {\n const root = String(record[indices.cnpjRoot] ?? \"\").trim();\n const order = String(record[indices.cnpjOrder] ?? \"\").trim();\n const digits = String(record[indices.cnpjCheckDigits] ?? \"\").trim();\n return `${root}${order}${digits}`;\n };\n}\n\nfunction buildPartnerDedupeKey(\n recordByColumn: Record<string, unknown>,\n): string {\n return [\n recordByColumn.cnpj_root,\n recordByColumn.partner_type_code,\n recordByColumn.partner_name,\n recordByColumn.partner_document,\n recordByColumn.partner_qualification_code,\n recordByColumn.entry_date,\n recordByColumn.country_code,\n recordByColumn.legal_representative_document,\n recordByColumn.legal_representative_name,\n recordByColumn.legal_representative_qualification_code,\n recordByColumn.age_group_code,\n ]\n .map((value) => (value == null ? \"\" : String(value).trim()))\n .join(\"|\");\n}\n\nexport function transformRecord(\n dataset: ImportDatasetType,\n layout: TableLayout,\n rawFields: string[],\n schemaCapabilities: ImportSchemaCapabilities,\n writeTarget: ImportWriteTarget,\n): unknown[] {\n const values = layout.fields.map((field, index) =>\n toDatabaseValue(field.dataType, rawFields[index] ?? \"\"),\n );\n\n const recordByColumn = Object.fromEntries(\n layout.fields.map((field, index) => [field.columnName, values[index]]),\n ) as Record<string, unknown>;\n\n if (dataset === \"companies\") {\n recordByColumn.company_size_code = normalizeCode(\n recordByColumn.company_size_code,\n \"00\",\n );\n }\n\n if (dataset === \"establishments\") {\n recordByColumn.branch_type_code = normalizeCode(\n recordByColumn.branch_type_code,\n \"1\",\n );\n recordByColumn.registration_status_code = normalizeCode(\n recordByColumn.registration_status_code,\n \"01\",\n );\n }\n\n const normalizedValues = layout.fields.map(\n (field) => recordByColumn[field.columnName],\n );\n\n if (writeTarget === \"final\") {\n if (\n dataset === \"establishments\" &&\n schemaCapabilities.includeEstablishmentCnpjFullInInsert\n ) {\n return [\n ...normalizedValues,\n `${recordByColumn.cnpj_root ?? \"\"}${recordByColumn.cnpj_order ?? \"\"}${recordByColumn.cnpj_check_digits ?? \"\"}`,\n ];\n }\n\n if (\n dataset === \"partners\" &&\n schemaCapabilities.includePartnerDedupeKeyInInsert\n ) {\n return [...normalizedValues, buildPartnerDedupeKey(recordByColumn)];\n }\n }\n\n return normalizedValues;\n}\n\nexport function buildParsedPayload(\n columns: string[],\n values: unknown[],\n): Record<string, unknown> {\n return Object.fromEntries(\n columns.map((column, index) => [column, values[index] ?? null]),\n );\n}\n\nexport function extractSecondaryCnaes(\n record: unknown[],\n columns: string[],\n): Array<[string, string, number]> {\n void record;\n void columns;\n return [];\n}\n","import { parseDelimitedLine } from \"./transform.js\";\nimport type { ImportSourceLine } from \"./source-reader.js\";\n\nexport type ParsedImportSourceLine = ImportSourceLine & {\n fields: string[];\n};\n\nexport function parseImportSourceLine(\n sourceLine: ImportSourceLine,\n): ParsedImportSourceLine {\n return {\n ...sourceLine,\n fields: parseDelimitedLine(sourceLine.rawLine),\n };\n}\n","import { Client } from \"pg\";\n\nimport { DATASET_LAYOUTS } from \"./types.js\";\nimport type {\n ImportDatasetType,\n ImportSchemaCapabilities,\n ImportWriteTarget,\n} from \"./types.js\";\n\nexport function getInsertColumns(\n dataset: ImportDatasetType,\n schemaCapabilities: ImportSchemaCapabilities,\n writeTarget: ImportWriteTarget = \"final\",\n): string[] {\n const columns = DATASET_LAYOUTS[dataset].fields.map(\n (field) => field.columnName,\n );\n\n if (writeTarget === \"final\") {\n if (\n dataset === \"establishments\" &&\n schemaCapabilities.includeEstablishmentCnpjFullInInsert\n ) {\n return [...columns, \"cnpj_full\"];\n }\n\n if (\n dataset === \"partners\" &&\n schemaCapabilities.includePartnerDedupeKeyInInsert\n ) {\n return [...columns, \"partner_dedupe_key\"];\n }\n }\n\n return columns;\n}\n\nexport function getConflictClause(\n dataset: ImportDatasetType,\n columns: string[],\n schemaCapabilities?: ImportSchemaCapabilities,\n): string {\n switch (dataset) {\n case \"countries\":\n case \"cities\":\n case \"partner_qualifications\":\n case \"legal_natures\":\n case \"cnaes\":\n case \"reasons\":\n return \"on conflict (code) do update set description = excluded.description\";\n case \"companies\": {\n const updateColumns = columns\n .filter((column) => column !== \"cnpj_root\")\n .map((column) => `${column} = excluded.${column}`)\n .concat([\"updated_at = now()\"])\n .join(\", \");\n return `on conflict (cnpj_root) do update set ${updateColumns}`;\n }\n case \"establishments\": {\n const updateColumns = columns\n .filter(\n (column) =>\n ![\n \"cnpj_root\",\n \"cnpj_order\",\n \"cnpj_check_digits\",\n \"cnpj_full\",\n ].includes(column),\n )\n .map((column) => `${column} = excluded.${column}`)\n .concat([\"updated_at = now()\"])\n .join(\", \");\n const conflictTarget =\n schemaCapabilities?.includeEstablishmentCnpjFullInInsert\n ? \"cnpj_full\"\n : \"cnpj_root, cnpj_order, cnpj_check_digits\";\n return `on conflict (${conflictTarget}) do update set ${updateColumns}`;\n }\n case \"simples_options\": {\n const updateColumns = columns\n .filter((column) => column !== \"cnpj_root\")\n .map((column) => `${column} = excluded.${column}`)\n .concat([\"updated_at = now()\"])\n .join(\", \");\n return `on conflict (cnpj_root) do update set ${updateColumns}`;\n }\n case \"partners\": {\n const updateColumns = columns\n .filter((column) => column !== \"partner_dedupe_key\")\n .map((column) => `${column} = excluded.${column}`)\n .concat([\"updated_at = now()\"])\n .join(\", \");\n return `on conflict (partner_dedupe_key) do update set ${updateColumns}`;\n }\n default:\n return \"\";\n }\n}\n\nexport function buildInsertQuery(\n tableName: string,\n columns: string[],\n rows: readonly unknown[][],\n conflictClause = \"\",\n): { text: string; values: unknown[] } {\n const values: unknown[] = [];\n\n const valueGroups = rows.map((row, rowIndex) => {\n const placeholders = row.map((_, columnIndex) => {\n const placeholderIndex = rowIndex * columns.length + columnIndex + 1;\n values.push(row[columnIndex]);\n return `$${placeholderIndex}`;\n });\n\n return `(${placeholders.join(\", \")})`;\n });\n\n const parts = [\n `insert into ${tableName} (${columns.join(\", \")})`,\n `values ${valueGroups.join(\", \")}`,\n ];\n\n if (conflictClause) {\n parts.push(conflictClause);\n }\n\n return {\n text: parts.join(\" \"),\n values,\n };\n}\n\nexport function buildSecondaryInsertQuery(\n tableName: string,\n rows: ReadonlyArray<[string, string, number]>,\n conflictClause = \"\",\n): {\n text: string;\n values: unknown[];\n} {\n return buildInsertQuery(\n tableName,\n [\"establishment_cnpj_full\", \"cnae_code\", \"source_order\"],\n rows,\n conflictClause,\n );\n}\n\nexport async function flushInsertQuery(\n client: Client,\n query: { text: string; values: unknown[] },\n): Promise<void> {\n await client.query(query);\n}\n","import { ValidationError } from \"../../core/errors/index.js\";\nimport type { TableLayout } from \"../../dictionary/layouts/index.js\";\nimport { getInsertColumns } from \"./sql.js\";\nimport { resolveImportWriteTarget } from \"./targets.js\";\nimport {\n createEstablishmentCnpjFullBuilder,\n createFieldValueParser,\n createPartnerDedupeKeyBuilder,\n normalizeFieldCount,\n} from \"./transform.js\";\nimport type { ParsedImportSourceLine } from \"./parser.js\";\nimport type {\n BatchRow,\n ImportDatasetType,\n ImportSchemaCapabilities,\n} from \"./types.js\";\n\nexport type NormalizeImportRowInput = {\n dataset: ImportDatasetType;\n filePath: string;\n layout: TableLayout;\n parsedLine: ParsedImportSourceLine;\n schemaCapabilities: ImportSchemaCapabilities;\n sourceRowNumber: number;\n};\n\nexport type ImportRowNormalizer = {\n columns: string[];\n normalize: (\n parsedLine: ParsedImportSourceLine,\n sourceRowNumber: number,\n ) => BatchRow;\n};\n\nfunction validateRequiredColumns(\n requiredIndexes: readonly number[],\n values: readonly unknown[],\n layout: TableLayout,\n): void {\n for (const index of requiredIndexes) {\n if (values[index] !== null) {\n continue;\n }\n\n throw new ValidationError(\n `Missing required value for ${layout.fields[index]?.columnName ?? \"unknown column\"}.`,\n );\n }\n}\n\nfunction resolveLayoutColumnIndex(\n layout: TableLayout,\n columnName: string,\n): number {\n return layout.fields.findIndex((field) => field.columnName === columnName);\n}\n\nexport function createImportRowNormalizer(input: {\n dataset: ImportDatasetType;\n filePath: string;\n layout: TableLayout;\n schemaCapabilities: ImportSchemaCapabilities;\n}): ImportRowNormalizer {\n const writeTarget = resolveImportWriteTarget(input.dataset);\n const columns = getInsertColumns(\n input.dataset,\n input.schemaCapabilities,\n writeTarget,\n );\n const expectedLength = input.layout.fields.length;\n const requiredIndexes = input.layout.fields\n .map((field, index) => (field.nullable ? -1 : index))\n .filter((index) => index >= 0);\n const fieldParsers = input.layout.fields.map((field) =>\n createFieldValueParser(field.dataType),\n );\n const companySizeIndex =\n input.dataset === \"companies\"\n ? resolveLayoutColumnIndex(input.layout, \"company_size_code\")\n : -1;\n const branchTypeIndex =\n input.dataset === \"establishments\"\n ? resolveLayoutColumnIndex(input.layout, \"branch_type_code\")\n : -1;\n const registrationStatusIndex =\n input.dataset === \"establishments\"\n ? resolveLayoutColumnIndex(input.layout, \"registration_status_code\")\n : -1;\n const appendEstablishmentCnpjFull =\n input.dataset === \"establishments\" &&\n writeTarget === \"final\" &&\n input.schemaCapabilities.includeEstablishmentCnpjFullInInsert;\n const appendPartnerDedupeKey =\n input.dataset === \"partners\" &&\n writeTarget === \"final\" &&\n input.schemaCapabilities.includePartnerDedupeKeyInInsert;\n const buildEstablishmentCnpjFull = appendEstablishmentCnpjFull\n ? createEstablishmentCnpjFullBuilder({\n cnpjRoot: resolveLayoutColumnIndex(input.layout, \"cnpj_root\"),\n cnpjOrder: resolveLayoutColumnIndex(input.layout, \"cnpj_order\"),\n cnpjCheckDigits: resolveLayoutColumnIndex(\n input.layout,\n \"cnpj_check_digits\",\n ),\n })\n : null;\n const buildPartnerDedupeKey = appendPartnerDedupeKey\n ? createPartnerDedupeKeyBuilder({\n cnpjRoot: resolveLayoutColumnIndex(input.layout, \"cnpj_root\"),\n partnerTypeCode: resolveLayoutColumnIndex(\n input.layout,\n \"partner_type_code\",\n ),\n partnerName: resolveLayoutColumnIndex(input.layout, \"partner_name\"),\n partnerDocument: resolveLayoutColumnIndex(\n input.layout,\n \"partner_document\",\n ),\n partnerQualificationCode: resolveLayoutColumnIndex(\n input.layout,\n \"partner_qualification_code\",\n ),\n entryDate: resolveLayoutColumnIndex(input.layout, \"entry_date\"),\n countryCode: resolveLayoutColumnIndex(input.layout, \"country_code\"),\n legalRepresentativeDocument: resolveLayoutColumnIndex(\n input.layout,\n \"legal_representative_document\",\n ),\n legalRepresentativeName: resolveLayoutColumnIndex(\n input.layout,\n \"legal_representative_name\",\n ),\n legalRepresentativeQualificationCode: resolveLayoutColumnIndex(\n input.layout,\n \"legal_representative_qualification_code\",\n ),\n ageGroupCode: resolveLayoutColumnIndex(input.layout, \"age_group_code\"),\n })\n : null;\n\n return {\n columns,\n normalize(parsedLine, sourceRowNumber) {\n const normalizedFields = normalizeFieldCount(\n parsedLine.fields,\n expectedLength,\n input.filePath,\n parsedLine.lineNumber,\n );\n const values = new Array<unknown>(expectedLength);\n\n for (let index = 0; index < expectedLength; index += 1) {\n values[index] =\n fieldParsers[index]?.(normalizedFields[index] ?? \"\") ?? null;\n }\n\n if (companySizeIndex >= 0) {\n const currentValue = values[companySizeIndex];\n values[companySizeIndex] =\n typeof currentValue === \"string\" && currentValue.trim() !== \"\"\n ? currentValue.trim()\n : \"00\";\n }\n\n if (branchTypeIndex >= 0) {\n const currentValue = values[branchTypeIndex];\n values[branchTypeIndex] =\n typeof currentValue === \"string\" && currentValue.trim() !== \"\"\n ? currentValue.trim()\n : \"1\";\n }\n\n if (registrationStatusIndex >= 0) {\n const currentValue = values[registrationStatusIndex];\n values[registrationStatusIndex] =\n typeof currentValue === \"string\" && currentValue.trim() !== \"\"\n ? currentValue.trim()\n : \"01\";\n }\n\n validateRequiredColumns(requiredIndexes, values, input.layout);\n\n if (buildEstablishmentCnpjFull) {\n values.push(buildEstablishmentCnpjFull(values));\n }\n\n if (buildPartnerDedupeKey) {\n values.push(buildPartnerDedupeKey(values));\n }\n\n return {\n values,\n rawLine: parsedLine.rawLine,\n nextOffset: parsedLine.nextOffset,\n sourceRowNumber,\n secondaryRows: [],\n };\n },\n };\n}\n\nexport function normalizeImportRow({\n dataset,\n filePath,\n layout,\n parsedLine,\n schemaCapabilities,\n sourceRowNumber,\n}: NormalizeImportRowInput): BatchRow {\n return createImportRowNormalizer({\n dataset,\n filePath,\n layout,\n schemaCapabilities,\n }).normalize(parsedLine, sourceRowNumber);\n}\n","import { createHash } from \"node:crypto\";\nimport { createReadStream } from \"node:fs\";\nimport { stat } from \"node:fs/promises\";\nimport { performance } from \"node:perf_hooks\";\nimport path from \"node:path\";\n\nimport type { FileInspection } from \"../inspect.service.js\";\nimport type {\n ImportDatasetPlan,\n ImportProgressListener,\n ImportSourceFile,\n} from \"./types.js\";\nimport type { ImportDatasetType } from \"./types.js\";\n\nexport type IteratedLine = {\n line: string;\n nextOffset: number;\n};\n\nexport type ImportPlanBuildResult = {\n datasets: ImportDatasetPlan[];\n totalFiles: number;\n totalRows: number;\n totalBatches: number;\n scanDurationMs: number;\n datasetScanDurationsMs: Partial<Record<ImportDatasetType, number>>;\n};\n\nexport function resolveAbsolutePath(\n validatedPath: string,\n entry: FileInspection,\n): string {\n return path.join(validatedPath, entry.relativePath);\n}\n\nexport function buildDisplayPath(filePath: string): string {\n return `${path.basename(path.dirname(filePath))} > ${path.basename(filePath)}`;\n}\n\nexport async function* iterateFileLines(\n filePath: string,\n startOffset = 0,\n): AsyncGenerator<IteratedLine> {\n const stream = createReadStream(filePath, { start: startOffset });\n let buffered = Buffer.alloc(0);\n let offset = startOffset;\n\n try {\n for await (const chunk of stream) {\n const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n buffered = buffered.length\n ? Buffer.concat([buffered, chunkBuffer])\n : chunkBuffer;\n\n while (true) {\n const newlineIndex = buffered.indexOf(0x0a);\n if (newlineIndex === -1) {\n break;\n }\n\n let lineBuffer = buffered.subarray(0, newlineIndex);\n const consumed = newlineIndex + 1;\n\n if (\n lineBuffer.length > 0 &&\n lineBuffer[lineBuffer.length - 1] === 0x0d\n ) {\n lineBuffer = lineBuffer.subarray(0, lineBuffer.length - 1);\n }\n\n offset += consumed;\n yield {\n line: lineBuffer.toString(\"utf8\"),\n nextOffset: offset,\n };\n\n buffered = buffered.subarray(consumed);\n }\n }\n\n if (buffered.length > 0) {\n offset += buffered.length;\n yield {\n line: buffered.toString(\"utf8\"),\n nextOffset: offset,\n };\n }\n } finally {\n stream.close();\n }\n}\n\nexport async function countFileRowsExact(filePath: string): Promise<number> {\n let count = 0;\n\n for await (const item of iterateFileLines(filePath, 0)) {\n if (item.line.trim() !== \"\") {\n count += 1;\n }\n }\n\n return count;\n}\n\nexport function sortEntries(\n left: FileInspection,\n right: FileInspection,\n): number {\n return left.relativePath.localeCompare(right.relativePath, undefined, {\n numeric: true,\n sensitivity: \"base\",\n });\n}\n\nexport async function collectImportSourceFiles(\n validatedPath: string,\n datasetEntries: Array<{\n dataset: ImportDatasetType;\n files: FileInspection[];\n }>,\n): Promise<\n Array<{\n dataset: ImportDatasetType;\n files: ImportSourceFile[];\n }>\n> {\n const collected: Array<{\n dataset: ImportDatasetType;\n files: ImportSourceFile[];\n }> = [];\n\n for (const item of datasetEntries) {\n const files: ImportSourceFile[] = [];\n\n for (const entry of item.files.sort(sortEntries)) {\n const absolutePath = resolveAbsolutePath(validatedPath, entry);\n const fileStats = await stat(absolutePath);\n files.push({\n dataset: item.dataset,\n absolutePath,\n relativePath: entry.relativePath,\n displayPath: buildDisplayPath(absolutePath),\n fileSize: fileStats.size,\n fileMtime: fileStats.mtime,\n });\n }\n\n collected.push({\n dataset: item.dataset,\n files,\n });\n }\n\n return collected;\n}\n\nexport function buildImportPlanFingerprint(\n validatedPath: string,\n batchSize: number,\n datasetEntries: Array<{\n dataset: ImportDatasetType;\n files: ImportSourceFile[];\n }>,\n): string {\n const hash = createHash(\"sha256\");\n hash.update(\n JSON.stringify({\n validatedPath: path.resolve(validatedPath),\n batchSize,\n datasets: datasetEntries.map((item) => ({\n dataset: item.dataset,\n files: item.files.map((file) => ({\n relativePath: file.relativePath,\n fileSize: file.fileSize,\n fileMtime: file.fileMtime.toISOString(),\n })),\n })),\n }),\n );\n return hash.digest(\"hex\");\n}\n\nexport async function buildImportPlan(\n inputPath: string,\n validatedPath: string,\n datasetEntries: Array<{\n dataset: ImportDatasetType;\n files: ImportSourceFile[];\n }>,\n batchSize: number,\n onProgress: ImportProgressListener | undefined,\n targetDatabase: string,\n): Promise<ImportPlanBuildResult> {\n const totalFiles = datasetEntries.reduce(\n (sum, item) => sum + item.files.length,\n 0,\n );\n let scannedFiles = 0;\n let countedRows = 0;\n const planBuildStartedAt = performance.now();\n\n onProgress?.({\n kind: \"preparing_start\",\n inputPath: path.resolve(inputPath),\n validatedPath,\n totalDatasets: datasetEntries.length,\n totalFiles,\n batchSize,\n loadBatchSize: batchSize,\n targetDatabase,\n });\n\n const datasets: ImportDatasetPlan[] = [];\n const datasetScanDurationsMs: Partial<Record<ImportDatasetType, number>> = {};\n\n for (const item of datasetEntries) {\n const files = [];\n let datasetRows = 0;\n let datasetBatches = 0;\n const datasetScanStartedAt = performance.now();\n\n for (const sourceFile of item.files) {\n const totalRows = await countFileRowsExact(sourceFile.absolutePath);\n const totalBatches =\n totalRows === 0 ? 0 : Math.ceil(totalRows / batchSize);\n\n files.push({\n dataset: item.dataset,\n absolutePath: sourceFile.absolutePath,\n displayPath: sourceFile.displayPath,\n fileSize: sourceFile.fileSize,\n fileMtime: sourceFile.fileMtime,\n totalRows,\n totalBatches,\n });\n\n scannedFiles += 1;\n countedRows += totalRows;\n datasetRows += totalRows;\n datasetBatches += totalBatches;\n\n onProgress?.({\n kind: \"preparing_progress\",\n scannedFiles,\n totalFiles,\n countedRows,\n currentFileDisplayPath: sourceFile.displayPath,\n });\n }\n\n datasetScanDurationsMs[item.dataset] =\n performance.now() - datasetScanStartedAt;\n\n datasets.push({\n dataset: item.dataset,\n files,\n totalRows: datasetRows,\n totalBatches: datasetBatches,\n });\n }\n\n const totalRows = datasets.reduce((sum, item) => sum + item.totalRows, 0);\n const totalBatches = datasets.reduce(\n (sum, item) => sum + item.totalBatches,\n 0,\n );\n\n return {\n datasets,\n totalFiles,\n totalRows,\n totalBatches,\n scanDurationMs: performance.now() - planBuildStartedAt,\n datasetScanDurationsMs,\n };\n}\n","import { iterateFileLines } from \"./planning.js\";\n\nexport type ImportSourceLine = {\n rawLine: string;\n nextOffset: number;\n lineNumber: number;\n};\n\nexport async function* readImportSourceLines(\n filePath: string,\n startOffset = 0,\n startLineNumber = 0,\n): AsyncGenerator<ImportSourceLine> {\n let lineNumber = startLineNumber;\n\n for await (const item of iterateFileLines(filePath, startOffset)) {\n lineNumber += 1;\n yield {\n rawLine: item.line,\n nextOffset: item.nextOffset,\n lineNumber,\n };\n }\n}\n","import { Query, escapeIdentifier, type Client } from \"pg\";\n\nfunction escapeCopyTextValue(value: unknown): string {\n if (value == null) {\n return \"\\\\N\";\n }\n\n const text =\n typeof value === \"boolean\"\n ? value\n ? \"t\"\n : \"f\"\n : value instanceof Date\n ? value.toISOString()\n : String(value);\n\n return text\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\t/g, \"\\\\t\")\n .replace(/\\n/g, \"\\\\n\")\n .replace(/\\r/g, \"\\\\r\")\n .replace(/\\f/g, \"\\\\f\")\n .split(String.fromCharCode(8))\n .join(\"\\\\b\")\n .replace(/\\v/g, \"\\\\v\");\n}\n\nfunction serializeCopyRows(rows: readonly unknown[][]): Buffer {\n const body = rows\n .map((row) => row.map((value) => escapeCopyTextValue(value)).join(\"\\t\"))\n .join(\"\\n\");\n\n return Buffer.from(`${body}\\n`, \"utf8\");\n}\n\nfunction buildCopyStatement(\n tableName: string,\n columns: readonly string[],\n): string {\n const escapedColumns = columns.map((column) => escapeIdentifier(column));\n return `copy ${escapeIdentifier(tableName)} (${escapedColumns.join(\", \")}) from stdin with (format text, null '\\\\N')`;\n}\n\nclass CopyFromTextQuery extends Query {\n private readonly payload: Buffer;\n\n constructor(\n text: string,\n payload: Buffer,\n callback: (error?: Error) => void,\n ) {\n super(text, undefined, callback);\n this.payload = payload;\n }\n\n handleCopyInResponse(connection: {\n sendCopyFromChunk: (chunk: Buffer) => void;\n endCopyFrom: () => void;\n sendCopyFail: (message: string) => void;\n }): void {\n try {\n if (this.payload.length > 0) {\n connection.sendCopyFromChunk(this.payload);\n }\n connection.endCopyFrom();\n } catch (error) {\n connection.sendCopyFail(\n error instanceof Error ? error.message : String(error),\n );\n }\n }\n}\n\nexport async function copyRowsToTable(\n client: Client,\n tableName: string,\n columns: readonly string[],\n rows: readonly unknown[][],\n): Promise<void> {\n if (rows.length === 0) {\n return;\n }\n\n const statement = buildCopyStatement(tableName, columns);\n const payload = serializeCopyRows(rows);\n\n await new Promise<void>((resolve, reject) => {\n const query = new CopyFromTextQuery(statement, payload, (error) => {\n if (error) {\n reject(error);\n return;\n }\n\n resolve();\n });\n\n client.query(query);\n });\n}\n","import type { Client } from \"pg\";\n\nimport { copyRowsToTable } from \"./copy-from.js\";\nimport {\n buildInsertQuery,\n buildSecondaryInsertQuery,\n flushInsertQuery,\n getConflictClause,\n getInsertColumns,\n} from \"./sql.js\";\nimport {\n getSecondaryTargetTableName,\n getTargetTableName,\n resolveImportWriteTarget,\n usesStagingWriteTarget,\n} from \"./targets.js\";\nimport type {\n BatchRow,\n ImportDatasetType,\n ImportSchemaCapabilities,\n} from \"./types.js\";\n\nexport type ImportBatchWriteInput = {\n client: Client;\n dataset: ImportDatasetType;\n rows: BatchRow[];\n schemaCapabilities: ImportSchemaCapabilities;\n};\n\nexport type ImportBatchWriteResult = {\n writtenRows: number;\n writtenSecondaryRows: number;\n writeTarget: \"final\" | \"staging\";\n writeMode: \"copy\" | \"insert\";\n targetTable: string;\n};\n\nasync function writeBatchToFinalTarget(\n client: Client,\n dataset: ImportDatasetType,\n rows: BatchRow[],\n schemaCapabilities: ImportSchemaCapabilities,\n): Promise<ImportBatchWriteResult> {\n const targetTable = getTargetTableName(dataset);\n const columns = getInsertColumns(dataset, schemaCapabilities, \"final\");\n const batchValues = rows.map((row) => row.values);\n const secondaryRows = rows.flatMap((row) => row.secondaryRows);\n\n await flushInsertQuery(\n client,\n buildInsertQuery(\n targetTable,\n columns,\n batchValues,\n getConflictClause(dataset, columns),\n ),\n );\n\n const secondaryTargetTable = getSecondaryTargetTableName(dataset);\n if (secondaryTargetTable && secondaryRows.length > 0) {\n await flushInsertQuery(\n client,\n buildSecondaryInsertQuery(\n secondaryTargetTable,\n secondaryRows,\n \"on conflict (establishment_cnpj_full, cnae_code) do update set source_order = excluded.source_order\",\n ),\n );\n }\n\n return {\n writtenRows: rows.length,\n writtenSecondaryRows: secondaryRows.length,\n writeTarget: \"final\",\n writeMode: \"insert\",\n targetTable,\n };\n}\n\nasync function writeBatchToStagingTarget(\n client: Client,\n dataset: ImportDatasetType,\n rows: BatchRow[],\n schemaCapabilities: ImportSchemaCapabilities,\n): Promise<ImportBatchWriteResult> {\n const targetTable = getTargetTableName(dataset);\n const columns = getInsertColumns(dataset, schemaCapabilities, \"staging\");\n const batchValues = rows.map((row) => row.values);\n const secondaryRows = rows.flatMap((row) => row.secondaryRows);\n\n await copyRowsToTable(client, targetTable, columns, batchValues);\n\n const secondaryTargetTable = getSecondaryTargetTableName(dataset);\n if (secondaryTargetTable && secondaryRows.length > 0) {\n await copyRowsToTable(\n client,\n secondaryTargetTable,\n [\"establishment_cnpj_full\", \"cnae_code\", \"source_order\"],\n secondaryRows,\n );\n }\n\n return {\n writtenRows: rows.length,\n writtenSecondaryRows: secondaryRows.length,\n writeTarget: \"staging\",\n writeMode: \"copy\",\n targetTable,\n };\n}\n\nasync function writeRowInsertFallback(\n client: Client,\n dataset: ImportDatasetType,\n row: BatchRow,\n schemaCapabilities: ImportSchemaCapabilities,\n): Promise<ImportBatchWriteResult> {\n const writeTarget = resolveImportWriteTarget(dataset);\n const targetTable = getTargetTableName(dataset);\n const columns = getInsertColumns(dataset, schemaCapabilities, writeTarget);\n const conflictClause =\n writeTarget === \"final\" ? getConflictClause(dataset, columns) : \"\";\n\n await flushInsertQuery(\n client,\n buildInsertQuery(targetTable, columns, [row.values], conflictClause),\n );\n\n const secondaryTargetTable = getSecondaryTargetTableName(dataset);\n if (secondaryTargetTable && row.secondaryRows.length > 0) {\n await flushInsertQuery(\n client,\n buildSecondaryInsertQuery(\n secondaryTargetTable,\n row.secondaryRows,\n writeTarget === \"final\"\n ? \"on conflict (establishment_cnpj_full, cnae_code) do update set source_order = excluded.source_order\"\n : \"\",\n ),\n );\n }\n\n return {\n writtenRows: 1,\n writtenSecondaryRows: row.secondaryRows.length,\n writeTarget,\n writeMode: \"insert\",\n targetTable,\n };\n}\n\nexport async function writeImportBatchToTarget({\n client,\n dataset,\n rows,\n schemaCapabilities,\n}: ImportBatchWriteInput): Promise<ImportBatchWriteResult> {\n if (rows.length === 0) {\n return {\n writtenRows: 0,\n writtenSecondaryRows: 0,\n writeTarget: resolveImportWriteTarget(dataset),\n writeMode: usesStagingWriteTarget(dataset) ? \"copy\" : \"insert\",\n targetTable: getTargetTableName(dataset),\n };\n }\n\n if (usesStagingWriteTarget(dataset)) {\n return writeBatchToStagingTarget(client, dataset, rows, schemaCapabilities);\n }\n\n return writeBatchToFinalTarget(client, dataset, rows, schemaCapabilities);\n}\n\nexport async function writeImportRowToTarget(\n input: Omit<ImportBatchWriteInput, \"rows\"> & { row: BatchRow },\n): Promise<ImportBatchWriteResult> {\n return writeRowInsertFallback(\n input.client,\n input.dataset,\n input.row,\n input.schemaCapabilities,\n );\n}\n","import { Client } from \"pg\";\n\nimport { ensureTableShape } from \"./schema-validation.js\";\nimport type { ImportDatasetType } from \"./types.js\";\n\nfunction classifyQuarantineError(error: unknown): {\n code: string;\n category: string;\n canRetryLater: boolean;\n} {\n const errorCode =\n typeof error === \"object\" && error && \"code\" in error\n ? String((error as { code?: string }).code ?? \"QUARANTINED_ROW\")\n : \"QUARANTINED_ROW\";\n const errorMessage =\n error instanceof Error ? error.message : String(error ?? \"Unknown error\");\n const normalizedMessage = errorMessage.toLowerCase();\n\n if (normalizedMessage.includes(\"invalid byte sequence for encoding\")) {\n return {\n code: errorCode,\n category: \"invalid_utf8_sequence\",\n canRetryLater: true,\n };\n }\n\n if (normalizedMessage.includes(\"violates not-null constraint\")) {\n return {\n code: errorCode,\n category: \"not_null_violation\",\n canRetryLater: false,\n };\n }\n\n if (normalizedMessage.includes(\"violates foreign key constraint\")) {\n return {\n code: errorCode,\n category: \"foreign_key_violation\",\n canRetryLater: false,\n };\n }\n\n if (normalizedMessage.includes(\"field count\")) {\n return {\n code: errorCode,\n category: \"invalid_field_count\",\n canRetryLater: true,\n };\n }\n\n if (normalizedMessage.includes(\"transform\")) {\n return {\n code: errorCode,\n category: \"transform_error\",\n canRetryLater: true,\n };\n }\n\n return {\n code: errorCode,\n category: \"unknown\",\n canRetryLater: false,\n };\n}\n\nexport async function ensureQuarantineTable(client: Client): Promise<void> {\n await ensureTableShape(client, {\n tableName: \"import_quarantine\",\n requiredColumns: [\n \"dataset\",\n \"file_path\",\n \"row_number\",\n \"checkpoint_offset\",\n \"error_code\",\n \"error_category\",\n \"error_stage\",\n \"error_message\",\n \"raw_line\",\n \"parsed_payload\",\n \"sanitizations_applied\",\n \"retry_count\",\n \"can_retry_later\",\n \"created_at\",\n ],\n helpMessage:\n 'The import quarantine schema is required. Run \"cnpj-db-loader schema generate --profile full\" and apply the SQL before importing.',\n });\n}\n\nexport type QuarantineInput = {\n dataset: ImportDatasetType;\n filePath: string;\n rowNumber: number;\n checkpointOffset: number;\n rawLine: string;\n error: unknown;\n parsedPayload?: Record<string, unknown> | null;\n errorStage?: string | null;\n sanitizationsApplied?: unknown[] | null;\n retryCount?: number;\n canRetryLater?: boolean;\n errorCategory?: string | null;\n};\n\nexport async function writeQuarantineRow(\n client: Client,\n input: QuarantineInput,\n): Promise<void> {\n const classified = classifyQuarantineError(input.error);\n const errorMessage =\n input.error instanceof Error ? input.error.message : String(input.error);\n\n await client.query(\n `insert into import_quarantine (\n dataset,\n file_path,\n row_number,\n checkpoint_offset,\n error_code,\n error_category,\n error_stage,\n error_message,\n raw_line,\n parsed_payload,\n sanitizations_applied,\n retry_count,\n can_retry_later,\n created_at\n ) values (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10::jsonb, $11::jsonb, $12, $13, now()\n )`,\n [\n input.dataset,\n input.filePath,\n input.rowNumber,\n input.checkpointOffset,\n classified.code,\n input.errorCategory ?? classified.category,\n input.errorStage ?? null,\n errorMessage,\n input.rawLine,\n input.parsedPayload ? JSON.stringify(input.parsedPayload) : null,\n input.sanitizationsApplied\n ? JSON.stringify(input.sanitizationsApplied)\n : null,\n input.retryCount ?? 0,\n input.canRetryLater ?? classified.canRetryLater,\n ],\n );\n}\n","import type { Client } from \"pg\";\n\nimport { ensureQuarantineTable, writeQuarantineRow } from \"./quarantine.js\";\n\nexport {\n ensureQuarantineTable as ensureImportQuarantineTable,\n writeQuarantineRow as writeImportQuarantineRow,\n};\n\nexport async function ensureImportQuarantineSupport(\n client: Client,\n): Promise<void> {\n await ensureQuarantineTable(client);\n}\n","import { performance } from \"node:perf_hooks\";\n\nimport type { Client } from \"pg\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport { appendJsonLinesLog } from \"../logging.service.js\";\nimport {\n readMaterializationCheckpoint,\n writeMaterializationCheckpoint,\n writeMaterializationCheckpointProgress,\n type MaterializationCheckpointRecord,\n} from \"./materialization-checkpoints.js\";\nimport {\n buildMaterializationChunkQuery,\n isMaterializationDataset,\n type MaterializationDataset,\n} from \"./materialization-sql.js\";\nimport {\n getLookupReconciliationSources,\n reconcileMaterializationLookups,\n} from \"./materialization-lookups.js\";\nimport { type MutableDatasetPerformance } from \"./finalizer.js\";\nimport { getFinalTargetTableName } from \"./targets.js\";\nimport type {\n ImportDatasetType,\n ImportProgressListener,\n ImportSchemaCapabilities,\n} from \"./types.js\";\n\nconst MATERIALIZATION_ORDER: readonly MaterializationDataset[] = [\n \"companies\",\n \"establishments\",\n \"simples_options\",\n \"partners\",\n];\n\nconst DEFAULT_MATERIALIZATION_CHUNK_SIZE = 50_000;\nconst MATERIALIZATION_HEARTBEAT_INTERVAL_MS = 15_000;\nconst MATERIALIZATION_CHECKPOINT_INTERVAL_CHUNKS = 25;\nconst MATERIALIZATION_CHUNK_LOG_INTERVAL = 50;\nconst EXACT_TARGET_COUNT_DATASETS: ReadonlySet<MaterializationDataset> =\n new Set([\"companies\", \"establishments\", \"simples_options\"]);\n\nconst STAGING_TABLE_BY_DATASET: Record<MaterializationDataset, string> = {\n companies: \"staging_companies\",\n establishments: \"staging_establishments\",\n simples_options: \"staging_simples_options\",\n partners: \"staging_partners\",\n};\n\ntype ChunkRow = {\n max_staging_id: string;\n source_rows: string;\n affected_rows: string;\n};\n\ntype CountRow = {\n total_count: string;\n};\n\ntype StagingStateRow = {\n total_count: string;\n max_staging_id: string;\n};\n\ntype StagingMaxRow = {\n max_staging_id: string;\n};\n\ntype QuarantineCountRow = {\n quarantined_rows: string;\n};\n\ntype ValidatedCheckpoint = {\n checkpoint: MaterializationCheckpointRecord;\n adjusted: boolean;\n reason: string | null;\n stagingMaxId: number;\n targetRows: number | null;\n};\n\nexport type MaterializationSummary = {\n datasets: Array<{\n dataset: MaterializationDataset;\n targetTable: string;\n affectedRows: number;\n sourceRows: number;\n chunksCompleted: number;\n durationMs: number;\n }>;\n};\n\nfunction resolveMaterializationDatasets(\n datasets: readonly ImportDatasetType[],\n): MaterializationDataset[] {\n const requested = new Set(\n datasets.filter((dataset): dataset is MaterializationDataset =>\n isMaterializationDataset(dataset),\n ),\n );\n\n return MATERIALIZATION_ORDER.filter((dataset) => requested.has(dataset));\n}\n\nfunction emitMaterializationProgress(\n listener: ImportProgressListener | undefined,\n input: {\n datasets: readonly MaterializationDataset[];\n dataset: MaterializationDataset;\n datasetIndex: number;\n targetTable: string;\n stepLabel: string;\n completedDatasets: number;\n completedFiles: number;\n totalFiles: number;\n processedRows: number;\n totalRows: number;\n committedBatches: number;\n totalBatches: number;\n elapsedMs?: number;\n reason?: string;\n chunkSize?: number;\n rowsMaterialized?: number;\n datasetRowCount?: number;\n chunksCompleted?: number;\n estimatedChunks?: number;\n lastStagingId?: number;\n },\n): void {\n listener?.({\n kind: \"materialization_progress\",\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.datasets.length,\n completedDatasets: input.completedDatasets,\n targetTable: input.targetTable,\n stepLabel: input.stepLabel,\n completedFiles: input.completedFiles,\n totalFiles: input.totalFiles,\n processedRows: input.processedRows,\n totalRows: input.totalRows,\n committedBatches: input.committedBatches,\n totalBatches: input.totalBatches,\n ...(input.elapsedMs === undefined ? {} : { elapsedMs: input.elapsedMs }),\n ...(input.reason === undefined ? {} : { reason: input.reason }),\n ...(input.chunkSize === undefined ? {} : { chunkSize: input.chunkSize }),\n ...(input.rowsMaterialized === undefined\n ? {}\n : { rowsMaterialized: input.rowsMaterialized }),\n ...(input.datasetRowCount === undefined\n ? {}\n : { datasetRowCount: input.datasetRowCount }),\n ...(input.chunksCompleted === undefined\n ? {}\n : { chunksCompleted: input.chunksCompleted }),\n ...(input.estimatedChunks === undefined\n ? {}\n : { estimatedChunks: input.estimatedChunks }),\n ...(input.lastStagingId === undefined\n ? {}\n : { lastStagingId: input.lastStagingId }),\n });\n}\n\nasync function executeChunkQuery(\n client: Client,\n text: string,\n values: readonly unknown[],\n): Promise<{ maxStagingId: number; sourceRows: number; affectedRows: number }> {\n const result = await client.query<ChunkRow>(text, [...values]);\n const row = result.rows[0];\n return {\n maxStagingId: row ? Number.parseInt(row.max_staging_id, 10) : 0,\n sourceRows: row ? Number.parseInt(row.source_rows, 10) : 0,\n affectedRows: row ? Number.parseInt(row.affected_rows, 10) : 0,\n };\n}\n\nasync function readStagingState(\n client: Client,\n stagingTable: string,\n): Promise<{ rowCount: number; maxStagingId: number }> {\n const result = await client.query<StagingStateRow>(\n `select count(*)::bigint as total_count, coalesce(max(staging_id), 0)::bigint as max_staging_id from ${stagingTable}`,\n );\n\n return {\n rowCount: Number.parseInt(result.rows[0]?.total_count ?? \"0\", 10),\n maxStagingId: Number.parseInt(result.rows[0]?.max_staging_id ?? \"0\", 10),\n };\n}\n\nasync function readStagingMaxId(\n client: Client,\n stagingTable: string,\n): Promise<number> {\n const result = await client.query<StagingMaxRow>(\n `select coalesce(max(staging_id), 0)::bigint as max_staging_id from ${stagingTable}`,\n );\n\n return Number.parseInt(result.rows[0]?.max_staging_id ?? \"0\", 10);\n}\n\nasync function readQuarantinedRowCountForPlan(input: {\n client: Client;\n planId: number;\n dataset: MaterializationDataset;\n}): Promise<number> {\n const result = await input.client.query<QuarantineCountRow>(\n `select count(*)::bigint as quarantined_rows\n from (\n select distinct q.file_path, q.row_number\n from import_quarantine q\n inner join import_plan_files pf\n on pf.plan_id = $1\n and pf.dataset = q.dataset\n and pf.file_path = q.file_path\n where q.dataset = $2\n and q.row_number is not null\n ) quarantined`,\n [input.planId, input.dataset],\n );\n\n return Number.parseInt(result.rows[0]?.quarantined_rows ?? \"0\", 10);\n}\n\nfunction buildEmptyStagingMessage(\n stagingTable: string,\n dataset: MaterializationDataset,\n expectedRows: number | undefined,\n): string {\n if (typeof expectedRows === \"number\" && expectedRows > 0) {\n return `The staging table ${stagingTable} is empty, but ${expectedRows} row(s) are expected for ${dataset} based on the saved load checkpoints. Run \"cnpj-db-loader import load\" again or clear stale checkpoint data before materializing.`;\n }\n\n return `The staging table ${stagingTable} is empty for ${dataset}. Load the dataset into staging before running materialization.`;\n}\n\nfunction buildStagingMismatchMessage(\n stagingTable: string,\n dataset: MaterializationDataset,\n expectedRows: number,\n actualRows: number,\n): string {\n return `The staging table ${stagingTable} currently contains ${actualRows} row(s), but ${expectedRows} row(s) are expected for ${dataset} based on the saved load checkpoints. The saved staging state no longer matches the persisted load progress. Reload staging or clear the stale checkpoint data before retrying materialization.`;\n}\n\nasync function validateStagingDatasetState(input: {\n client: Client;\n planId: number;\n dataset: MaterializationDataset;\n datasetIndex: number;\n totalDatasets: number;\n expectedRows: number | undefined;\n progressLogPath: string;\n}): Promise<{\n rowCount: number;\n maxStagingId: number;\n effectiveExpectedRows: number | undefined;\n quarantinedRows: number;\n reusedValidation: boolean;\n}> {\n const stagingTable = STAGING_TABLE_BY_DATASET[input.dataset];\n const checkpoint = await readMaterializationCheckpoint(\n input.client,\n input.planId,\n input.dataset,\n getFinalTargetTableName(input.dataset),\n );\n\n const canReuseValidatedStagingState =\n checkpoint.status === \"completed\" &&\n checkpoint.stagingRowCountVerified !== null &&\n checkpoint.stagingMaxStagingIdVerified !== null;\n\n if (canReuseValidatedStagingState) {\n const verifiedRowCount = checkpoint.stagingRowCountVerified;\n const verifiedMaxStagingId = checkpoint.stagingMaxStagingIdVerified;\n const liveMaxStagingId = await readStagingMaxId(input.client, stagingTable);\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_staging_validation_checked\",\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.totalDatasets,\n stagingTable,\n expectedRows: input.expectedRows ?? null,\n actualRows: verifiedRowCount,\n maxStagingId: liveMaxStagingId,\n reusedValidation:\n liveMaxStagingId === verifiedMaxStagingId && liveMaxStagingId > 0,\n timestamp: new Date().toISOString(),\n });\n\n if (liveMaxStagingId === 0) {\n throw new ValidationError(\n buildEmptyStagingMessage(\n stagingTable,\n input.dataset,\n verifiedRowCount ?? undefined,\n ),\n );\n }\n\n if (\n verifiedRowCount !== null &&\n liveMaxStagingId === verifiedMaxStagingId\n ) {\n return {\n rowCount: verifiedRowCount,\n maxStagingId: liveMaxStagingId,\n effectiveExpectedRows: verifiedRowCount,\n quarantinedRows: 0,\n reusedValidation: true,\n };\n }\n }\n\n const state = await readStagingState(input.client, stagingTable);\n const quarantinedRows = await readQuarantinedRowCountForPlan({\n client: input.client,\n planId: input.planId,\n dataset: input.dataset,\n });\n const effectiveExpectedRows =\n typeof input.expectedRows === \"number\"\n ? Math.max(0, input.expectedRows - quarantinedRows)\n : undefined;\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_staging_validation_completed\",\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.totalDatasets,\n stagingTable,\n expectedRows: input.expectedRows ?? null,\n quarantinedRows,\n effectiveExpectedRows: effectiveExpectedRows ?? null,\n actualRows: state.rowCount,\n maxStagingId: state.maxStagingId,\n timestamp: new Date().toISOString(),\n });\n\n if (state.rowCount === 0) {\n throw new ValidationError(\n buildEmptyStagingMessage(\n stagingTable,\n input.dataset,\n effectiveExpectedRows ?? input.expectedRows,\n ),\n );\n }\n\n if (\n typeof effectiveExpectedRows === \"number\" &&\n effectiveExpectedRows > 0 &&\n state.rowCount !== effectiveExpectedRows\n ) {\n throw new ValidationError(\n buildStagingMismatchMessage(\n stagingTable,\n input.dataset,\n effectiveExpectedRows,\n state.rowCount,\n ),\n );\n }\n\n return {\n ...state,\n effectiveExpectedRows,\n quarantinedRows,\n reusedValidation: false,\n };\n}\n\nasync function readRowCount(\n client: Client,\n tableName: string,\n): Promise<number> {\n const result = await client.query<CountRow>(\n `select count(*)::bigint as total_count from ${tableName}`,\n );\n\n return Number.parseInt(result.rows[0]?.total_count ?? \"0\", 10);\n}\n\nasync function persistCheckpoint(\n client: Client,\n checkpoint: MaterializationCheckpointRecord,\n): Promise<void> {\n await writeMaterializationCheckpoint(client, checkpoint);\n}\n\nasync function persistCheckpointProgress(\n client: Client,\n checkpoint: MaterializationCheckpointRecord,\n): Promise<void> {\n await writeMaterializationCheckpointProgress(client, checkpoint);\n}\n\nfunction shouldFlushChunkCheckpoint(chunksCompleted: number): boolean {\n return (\n chunksCompleted === 1 ||\n chunksCompleted % MATERIALIZATION_CHECKPOINT_INTERVAL_CHUNKS === 0\n );\n}\n\nfunction shouldLogChunkCompletion(chunksCompleted: number): boolean {\n return (\n chunksCompleted === 1 ||\n chunksCompleted % MATERIALIZATION_CHUNK_LOG_INTERVAL === 0\n );\n}\n\nfunction withValidatedStagingState(\n checkpoint: MaterializationCheckpointRecord,\n stagingState: { rowCount: number; maxStagingId: number },\n): MaterializationCheckpointRecord {\n return {\n ...checkpoint,\n stagingRowCountVerified: stagingState.rowCount,\n stagingMaxStagingIdVerified: stagingState.maxStagingId,\n stagingValidatedAt: new Date(),\n };\n}\n\nfunction clearLookupReconciliationState(\n checkpoint: MaterializationCheckpointRecord,\n): MaterializationCheckpointRecord {\n return {\n ...checkpoint,\n lookupReconciliationStatus: \"pending\",\n lookupReconciliationRowCountVerified: null,\n lookupReconciliationMaxStagingIdVerified: null,\n lookupReconciliationCompletedAt: null,\n };\n}\n\nfunction shouldReuseLookupReconciliation(input: {\n checkpoint: MaterializationCheckpointRecord;\n stagingState: { rowCount: number; maxStagingId: number };\n}): boolean {\n return (\n input.checkpoint.lookupReconciliationStatus === \"completed\" &&\n input.checkpoint.lookupReconciliationRowCountVerified ===\n input.stagingState.rowCount &&\n input.checkpoint.lookupReconciliationMaxStagingIdVerified ===\n input.stagingState.maxStagingId\n );\n}\n\nfunction resetCheckpointForReplay(\n checkpoint: MaterializationCheckpointRecord,\n): MaterializationCheckpointRecord {\n return clearLookupReconciliationState({\n ...checkpoint,\n status: \"pending\",\n rowsMaterialized: 0,\n lastStagingId: 0,\n chunksCompleted: 0,\n lastError: null,\n startedAt: null,\n completedAt: null,\n lastChunkFirstStagingId: 0,\n lastChunkLastStagingId: 0,\n lastChunkRows: 0,\n });\n}\n\nasync function validateDatasetCheckpoint(input: {\n client: Client;\n planId: number;\n dataset: MaterializationDataset;\n targetTable: string;\n expectedRows?: number;\n stagingMaxId: number;\n skipCompletedTargetValidation?: boolean;\n}): Promise<ValidatedCheckpoint> {\n let checkpoint = await readMaterializationCheckpoint(\n input.client,\n input.planId,\n input.dataset,\n input.targetTable,\n );\n const stagingMaxId = input.stagingMaxId;\n\n let adjusted = false;\n let reason: string | null = null;\n let targetRows: number | null = null;\n\n if (checkpoint.lastStagingId > stagingMaxId && stagingMaxId > 0) {\n checkpoint = resetCheckpointForReplay(checkpoint);\n adjusted = true;\n reason =\n \"Checkpoint references a staging range beyond the current staging table. The dataset will be rematerialized from the beginning.\";\n } else if (\n checkpoint.status === \"completed\" &&\n checkpoint.lastStagingId < stagingMaxId\n ) {\n checkpoint = {\n ...checkpoint,\n status: \"in_progress\",\n completedAt: null,\n lastError: null,\n };\n adjusted = true;\n reason =\n \"Checkpoint was marked as completed before the current staging tail. The dataset will resume materialization from the saved staging cursor.\";\n }\n\n if (\n EXACT_TARGET_COUNT_DATASETS.has(input.dataset) &&\n input.expectedRows !== undefined &&\n !input.skipCompletedTargetValidation &&\n (checkpoint.status === \"completed\" ||\n checkpoint.lastStagingId >= stagingMaxId)\n ) {\n targetRows = await readRowCount(input.client, input.targetTable);\n\n if (targetRows < input.expectedRows) {\n checkpoint = resetCheckpointForReplay(checkpoint);\n adjusted = true;\n reason = `The target table currently has ${targetRows} row(s), but ${input.expectedRows} row(s) are expected for ${input.dataset}. The dataset will be rematerialized from the beginning.`;\n }\n }\n\n if (adjusted) {\n await persistCheckpoint(input.client, checkpoint);\n }\n\n return {\n checkpoint,\n adjusted,\n reason,\n stagingMaxId,\n targetRows,\n };\n}\n\ntype EstablishmentSecondaryCnaesCountRow = {\n total_count: string;\n};\n\ntype EstablishmentSecondaryCnaesExistsRow = {\n exists: boolean;\n};\n\nasync function readEstablishmentSecondaryCnaesCount(\n client: Client,\n): Promise<number> {\n const result = await client.query<EstablishmentSecondaryCnaesCountRow>(\n `select count(*)::bigint as total_count from establishment_secondary_cnaes`,\n );\n\n return Number.parseInt(result.rows[0]?.total_count ?? \"0\", 10);\n}\n\nasync function hasEstablishmentsWithSecondaryCnaes(\n client: Client,\n): Promise<boolean> {\n const result = await client.query<EstablishmentSecondaryCnaesExistsRow>(\n `select exists (\n select 1\n from establishments\n where secondary_cnaes_raw is not null\n and secondary_cnaes_raw <> ''\n limit 1\n ) as exists`,\n );\n\n return result.rows[0]?.exists ?? false;\n}\n\nasync function backfillEstablishmentSecondaryCnaesFromFinal(input: {\n client: Client;\n progressLogPath: string;\n}): Promise<number> {\n const existingRows = await readEstablishmentSecondaryCnaesCount(input.client);\n\n if (existingRows > 0) {\n return 0;\n }\n\n if (!(await hasEstablishmentsWithSecondaryCnaes(input.client))) {\n return 0;\n }\n\n const startedAt = performance.now();\n const result = await input.client.query(\n `insert into establishment_secondary_cnaes (cnpj_full, cnae_code)\n select distinct\n e.cnpj_full,\n btrim(cnae_code) as cnae_code\n from establishments e\n cross join lateral unnest(\n string_to_array(e.secondary_cnaes_raw, ',')\n ) as cnae_code\n where e.secondary_cnaes_raw is not null\n and e.secondary_cnaes_raw <> ''\n and btrim(cnae_code) <> ''\n on conflict (cnpj_full, cnae_code) do nothing`,\n );\n\n const insertedRows = result.rowCount ?? 0;\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"establishment_secondary_cnaes_backfilled\",\n targetTable: \"establishment_secondary_cnaes\",\n insertedRows,\n durationMs: performance.now() - startedAt,\n timestamp: new Date().toISOString(),\n });\n\n return insertedRows;\n}\n\nasync function materializeDatasetByChunks(input: {\n client: Client;\n planId: number;\n dataset: MaterializationDataset;\n datasetIndex: number;\n datasets: readonly MaterializationDataset[];\n targetTable: string;\n chunkSize: number;\n expectedRows?: number;\n expectedStagedRows?: number;\n schemaCapabilities: ImportSchemaCapabilities;\n progressLogPath: string;\n onProgress?: ImportProgressListener | undefined;\n completedFiles: number;\n totalFiles: number;\n processedRows: number;\n totalRows: number;\n committedBatches: number;\n totalBatches: number;\n completedDatasets: number;\n}): Promise<{\n affectedRows: number;\n sourceRows: number;\n chunksCompleted: number;\n durationMs: number;\n}> {\n const startedAt = performance.now();\n const validationReason =\n \"Validating the live staging row count and staging cursor before resuming materialization.\";\n\n emitMaterializationProgress(input.onProgress, {\n datasets: input.datasets,\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n targetTable: input.targetTable,\n stepLabel: \"Validating staging state\",\n reason: validationReason,\n chunkSize: input.chunkSize,\n completedDatasets: input.completedDatasets,\n completedFiles: input.completedFiles,\n totalFiles: input.totalFiles,\n processedRows: input.processedRows,\n totalRows: input.totalRows,\n committedBatches: input.committedBatches,\n totalBatches: input.totalBatches,\n });\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_staging_validation_started\",\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.datasets.length,\n targetTable: input.targetTable,\n expectedRows: input.expectedStagedRows ?? null,\n timestamp: new Date().toISOString(),\n });\n\n const stagingState = await validateStagingDatasetState({\n client: input.client,\n planId: input.planId,\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.datasets.length,\n expectedRows: input.expectedStagedRows,\n progressLogPath: input.progressLogPath,\n });\n const estimatedChunks = Math.max(\n 1,\n Math.ceil(stagingState.rowCount / input.chunkSize),\n );\n\n const validated = await validateDatasetCheckpoint({\n client: input.client,\n planId: input.planId,\n dataset: input.dataset,\n targetTable: input.targetTable,\n stagingMaxId: stagingState.maxStagingId,\n skipCompletedTargetValidation: stagingState.reusedValidation,\n ...(input.expectedRows === undefined\n ? {}\n : { expectedRows: input.expectedRows }),\n });\n let checkpoint = withValidatedStagingState(\n validated.checkpoint,\n stagingState,\n );\n await persistCheckpoint(input.client, checkpoint);\n\n if (validated.adjusted && validated.reason) {\n emitMaterializationProgress(input.onProgress, {\n datasets: input.datasets,\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n targetTable: input.targetTable,\n stepLabel: \"Checkpoint reconciled — resuming safely\",\n reason: validated.reason,\n chunkSize: input.chunkSize,\n rowsMaterialized: checkpoint.rowsMaterialized,\n datasetRowCount: stagingState.rowCount,\n chunksCompleted: checkpoint.chunksCompleted,\n estimatedChunks,\n lastStagingId: checkpoint.lastStagingId,\n completedDatasets: input.completedDatasets,\n completedFiles: input.completedFiles,\n totalFiles: input.totalFiles,\n processedRows: input.processedRows,\n totalRows: input.totalRows,\n committedBatches: input.committedBatches,\n totalBatches: input.totalBatches,\n });\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_checkpoint_reconciled\",\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.datasets.length,\n targetTable: input.targetTable,\n reason: validated.reason,\n stagingMaxId: validated.stagingMaxId,\n targetRows: validated.targetRows,\n expectedRows: input.expectedRows ?? null,\n timestamp: new Date().toISOString(),\n });\n }\n\n if (checkpoint.status === \"completed\") {\n emitMaterializationProgress(input.onProgress, {\n datasets: input.datasets,\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n targetTable: input.targetTable,\n stepLabel: `Checkpoint complete — verified ${checkpoint.chunksCompleted} chunk(s)`,\n reason:\n \"The live staging state matches the last verified materialization checkpoint.\",\n chunkSize: input.chunkSize,\n rowsMaterialized: checkpoint.rowsMaterialized,\n datasetRowCount: stagingState.rowCount,\n chunksCompleted: checkpoint.chunksCompleted,\n estimatedChunks,\n lastStagingId: checkpoint.lastStagingId,\n completedDatasets: input.completedDatasets,\n completedFiles: input.completedFiles,\n totalFiles: input.totalFiles,\n processedRows: input.processedRows,\n totalRows: input.totalRows,\n committedBatches: input.committedBatches,\n totalBatches: input.totalBatches,\n });\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_dataset_skipped\",\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.datasets.length,\n targetTable: input.targetTable,\n rowsMaterialized: checkpoint.rowsMaterialized,\n chunksCompleted: checkpoint.chunksCompleted,\n verified: true,\n timestamp: new Date().toISOString(),\n });\n\n return {\n affectedRows: checkpoint.rowsMaterialized,\n sourceRows: checkpoint.rowsMaterialized,\n chunksCompleted: checkpoint.chunksCompleted,\n durationMs: performance.now() - startedAt,\n };\n }\n\n const lookupSources = input.schemaCapabilities.requiresLookupReconciliation\n ? getLookupReconciliationSources(input.dataset)\n : [];\n if (lookupSources.length === 0) {\n checkpoint = {\n ...checkpoint,\n lookupReconciliationStatus: \"completed\",\n lookupReconciliationRowCountVerified: stagingState.rowCount,\n lookupReconciliationMaxStagingIdVerified: stagingState.maxStagingId,\n lookupReconciliationCompletedAt:\n checkpoint.lookupReconciliationCompletedAt ?? new Date(),\n };\n await persistCheckpoint(input.client, checkpoint);\n } else if (shouldReuseLookupReconciliation({ checkpoint, stagingState })) {\n emitMaterializationProgress(input.onProgress, {\n datasets: input.datasets,\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n targetTable: input.targetTable,\n stepLabel: \"Reusing lookup reconciliation\",\n reason:\n \"Staging row count and staging cursor are unchanged since the last completed lookup reconciliation.\",\n chunkSize: input.chunkSize,\n rowsMaterialized: checkpoint.rowsMaterialized,\n datasetRowCount: stagingState.rowCount,\n chunksCompleted: checkpoint.chunksCompleted,\n estimatedChunks,\n lastStagingId: checkpoint.lastStagingId,\n completedDatasets: input.completedDatasets,\n completedFiles: input.completedFiles,\n totalFiles: input.totalFiles,\n processedRows: input.processedRows,\n totalRows: input.totalRows,\n committedBatches: input.committedBatches,\n totalBatches: input.totalBatches,\n });\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_lookup_reconciliation_reused\",\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.datasets.length,\n targetTable: input.targetTable,\n stagingRowCount: stagingState.rowCount,\n stagingMaxId: stagingState.maxStagingId,\n timestamp: new Date().toISOString(),\n });\n } else {\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_lookup_reconciliation_started\",\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.datasets.length,\n targetTable: input.targetTable,\n lookupTables: lookupSources,\n timestamp: new Date().toISOString(),\n });\n\n const reconciliation = await reconcileMaterializationLookups({\n client: input.client,\n dataset: input.dataset,\n onLookupStart: (lookupTable, lookupIndex, lookupTotal) => {\n emitMaterializationProgress(input.onProgress, {\n datasets: input.datasets,\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n targetTable: input.targetTable,\n stepLabel: `Reconciling lookup dependencies (${lookupIndex}/${lookupTotal})`,\n reason: `Checking ${lookupTable} for missing lookup codes and placeholder rows.`,\n chunkSize: input.chunkSize,\n rowsMaterialized: checkpoint.rowsMaterialized,\n datasetRowCount: stagingState.rowCount,\n chunksCompleted: checkpoint.chunksCompleted,\n estimatedChunks,\n lastStagingId: checkpoint.lastStagingId,\n completedDatasets: input.completedDatasets,\n completedFiles: input.completedFiles,\n totalFiles: input.totalFiles,\n processedRows: input.processedRows,\n totalRows: input.totalRows,\n committedBatches: input.committedBatches,\n totalBatches: input.totalBatches,\n });\n },\n });\n\n checkpoint = {\n ...checkpoint,\n lookupReconciliationStatus: \"completed\",\n lookupReconciliationRowCountVerified: stagingState.rowCount,\n lookupReconciliationMaxStagingIdVerified: stagingState.maxStagingId,\n lookupReconciliationCompletedAt: new Date(),\n };\n await persistCheckpoint(input.client, checkpoint);\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_lookup_reconciliation_completed\",\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.datasets.length,\n targetTable: input.targetTable,\n totalInsertedCodes: reconciliation.totalInsertedCodes,\n results: reconciliation.results.map((item) => ({\n lookupTable: item.lookupTable,\n insertedCodes: item.insertedCodes,\n })),\n durationMs: reconciliation.durationMs,\n timestamp: new Date().toISOString(),\n });\n }\n\n checkpoint = {\n ...checkpoint,\n status: \"in_progress\",\n targetTable: input.targetTable,\n startedAt: checkpoint.startedAt ?? new Date(),\n completedAt: null,\n lastError: null,\n };\n await persistCheckpoint(input.client, checkpoint);\n\n let affectedRows = checkpoint.rowsMaterialized;\n let sourceRows = checkpoint.rowsMaterialized;\n let chunksCompleted = checkpoint.chunksCompleted;\n const targetHasRows =\n checkpoint.rowsMaterialized > 0 ||\n (await readRowCount(input.client, input.targetTable)) > 0;\n const useConflictClause = targetHasRows || input.dataset === \"partners\";\n\n const heartbeatTimer = setInterval(() => {\n const elapsedMs = performance.now() - startedAt;\n emitMaterializationProgress(input.onProgress, {\n datasets: input.datasets,\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n targetTable: input.targetTable,\n stepLabel: `Materializing chunk ${chunksCompleted + 1}`,\n reason: `Writing rows into ${input.targetTable} from the current staging range.`,\n completedDatasets: input.completedDatasets,\n completedFiles: input.completedFiles,\n totalFiles: input.totalFiles,\n processedRows: input.processedRows,\n totalRows: input.totalRows,\n committedBatches: input.committedBatches,\n totalBatches: input.totalBatches,\n elapsedMs,\n chunkSize: input.chunkSize,\n rowsMaterialized: affectedRows,\n datasetRowCount: stagingState.rowCount,\n chunksCompleted,\n estimatedChunks,\n lastStagingId: checkpoint.lastStagingId,\n });\n }, MATERIALIZATION_HEARTBEAT_INTERVAL_MS);\n\n try {\n while (true) {\n emitMaterializationProgress(input.onProgress, {\n datasets: input.datasets,\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n targetTable: input.targetTable,\n stepLabel: `Materializing chunk ${chunksCompleted + 1}`,\n reason: `Writing rows into ${input.targetTable} from the current staging range.`,\n completedDatasets: input.completedDatasets,\n completedFiles: input.completedFiles,\n totalFiles: input.totalFiles,\n processedRows: input.processedRows,\n totalRows: input.totalRows,\n committedBatches: input.committedBatches,\n totalBatches: input.totalBatches,\n chunkSize: input.chunkSize,\n rowsMaterialized: affectedRows,\n datasetRowCount: stagingState.rowCount,\n chunksCompleted,\n estimatedChunks,\n lastStagingId: checkpoint.lastStagingId,\n });\n\n const query = buildMaterializationChunkQuery({\n dataset: input.dataset,\n schemaCapabilities: input.schemaCapabilities,\n lastStagingId: checkpoint.lastStagingId,\n chunkSize: input.chunkSize,\n useConflictClause,\n });\n const chunkStartedAt = performance.now();\n const chunkFirstStagingId = checkpoint.lastStagingId + 1;\n\n let chunkResult: {\n maxStagingId: number;\n sourceRows: number;\n affectedRows: number;\n };\n\n await input.client.query(\"begin\");\n try {\n chunkResult = await executeChunkQuery(\n input.client,\n query.text,\n query.values,\n );\n\n if (chunkResult.sourceRows === 0) {\n checkpoint = {\n ...checkpoint,\n status: \"completed\",\n completedAt: new Date(),\n lastError: null,\n };\n await persistCheckpoint(input.client, checkpoint);\n await input.client.query(\"commit\");\n break;\n }\n\n checkpoint = {\n ...checkpoint,\n lastStagingId: chunkResult.maxStagingId,\n rowsMaterialized:\n checkpoint.rowsMaterialized + chunkResult.affectedRows,\n chunksCompleted: checkpoint.chunksCompleted + 1,\n lastError: null,\n lastChunkFirstStagingId: chunkFirstStagingId,\n lastChunkLastStagingId: chunkResult.maxStagingId,\n lastChunkRows: chunkResult.sourceRows,\n };\n if (shouldFlushChunkCheckpoint(checkpoint.chunksCompleted)) {\n await persistCheckpointProgress(input.client, checkpoint);\n }\n await input.client.query(\"commit\");\n } catch (error) {\n await input.client.query(\"rollback\");\n const message = error instanceof Error ? error.message : String(error);\n checkpoint = {\n ...checkpoint,\n status: \"failed\",\n lastError: message,\n };\n await persistCheckpoint(input.client, checkpoint);\n throw error;\n }\n\n affectedRows = checkpoint.rowsMaterialized;\n sourceRows += chunkResult.sourceRows;\n chunksCompleted = checkpoint.chunksCompleted;\n\n if (shouldLogChunkCompletion(chunksCompleted)) {\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_chunk_completed\",\n dataset: input.dataset,\n datasetIndex: input.datasetIndex,\n totalDatasets: input.datasets.length,\n targetTable: input.targetTable,\n chunkNumber: chunksCompleted,\n chunkSize: input.chunkSize,\n chunkFirstStagingId,\n sourceRows: chunkResult.sourceRows,\n affectedRows: chunkResult.affectedRows,\n lastStagingId: checkpoint.lastStagingId,\n totalRowsMaterialized: affectedRows,\n durationMs: performance.now() - chunkStartedAt,\n timestamp: new Date().toISOString(),\n });\n }\n }\n } finally {\n clearInterval(heartbeatTimer);\n }\n\n return {\n affectedRows,\n sourceRows,\n chunksCompleted,\n durationMs: performance.now() - startedAt,\n };\n}\n\nexport async function materializeStagedDatasets(input: {\n client: Client;\n planId: number;\n datasets: readonly ImportDatasetType[];\n schemaCapabilities: ImportSchemaCapabilities;\n progressLogPath: string;\n datasetPerformanceTrackers: Map<ImportDatasetType, MutableDatasetPerformance>;\n expectedRowsByDataset: ReadonlyMap<ImportDatasetType, number>;\n expectedStagedRowsByDataset: ReadonlyMap<ImportDatasetType, number>;\n onProgress?: ImportProgressListener | undefined;\n completedFiles: number;\n totalFiles: number;\n processedRows: number;\n totalRows: number;\n committedBatches: number;\n totalBatches: number;\n chunkSize?: number;\n}): Promise<MaterializationSummary> {\n const materializationDatasets = resolveMaterializationDatasets(\n input.datasets,\n );\n const chunkSize = Math.max(\n 1,\n input.chunkSize ?? DEFAULT_MATERIALIZATION_CHUNK_SIZE,\n );\n\n const summary: MaterializationSummary = {\n datasets: [],\n };\n\n if (materializationDatasets.length === 0) {\n return summary;\n }\n\n input.onProgress?.({\n kind: \"materialization_start\",\n totalDatasets: materializationDatasets.length,\n datasets: [...materializationDatasets],\n completedFiles: input.completedFiles,\n totalFiles: input.totalFiles,\n processedRows: input.processedRows,\n totalRows: input.totalRows,\n committedBatches: input.committedBatches,\n totalBatches: input.totalBatches,\n });\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_started\",\n datasets: materializationDatasets,\n chunkSize,\n timestamp: new Date().toISOString(),\n });\n\n for (const [datasetIndex, dataset] of materializationDatasets.entries()) {\n const targetTable = getFinalTargetTableName(dataset);\n const datasetPosition = datasetIndex + 1;\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_dataset_started\",\n dataset,\n datasetIndex: datasetPosition,\n totalDatasets: materializationDatasets.length,\n targetTable,\n chunkSize,\n timestamp: new Date().toISOString(),\n });\n\n try {\n const expectedRows = input.expectedRowsByDataset.get(dataset);\n const expectedStagedRows = input.expectedStagedRowsByDataset.get(dataset);\n const result = await materializeDatasetByChunks({\n client: input.client,\n planId: input.planId,\n dataset,\n datasetIndex: datasetPosition,\n datasets: materializationDatasets,\n targetTable,\n chunkSize,\n ...(expectedRows === undefined ? {} : { expectedRows }),\n ...(expectedStagedRows === undefined ? {} : { expectedStagedRows }),\n schemaCapabilities: input.schemaCapabilities,\n progressLogPath: input.progressLogPath,\n onProgress: input.onProgress,\n completedFiles: input.completedFiles,\n totalFiles: input.totalFiles,\n processedRows: input.processedRows,\n totalRows: input.totalRows,\n committedBatches: input.committedBatches,\n totalBatches: input.totalBatches,\n completedDatasets: summary.datasets.length,\n });\n\n if (\n dataset === \"establishments\" &&\n input.schemaCapabilities.includeEstablishmentSecondaryCnaesTable\n ) {\n await backfillEstablishmentSecondaryCnaesFromFinal({\n client: input.client,\n progressLogPath: input.progressLogPath,\n });\n }\n\n const tracker = input.datasetPerformanceTrackers.get(dataset);\n if (tracker) {\n tracker.materializationDurationMs += result.durationMs;\n }\n\n summary.datasets.push({\n dataset,\n targetTable,\n affectedRows: result.affectedRows,\n sourceRows: result.sourceRows,\n chunksCompleted: result.chunksCompleted,\n durationMs: result.durationMs,\n });\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_dataset_completed\",\n dataset,\n datasetIndex: datasetPosition,\n totalDatasets: materializationDatasets.length,\n targetTable,\n affectedRows: result.affectedRows,\n sourceRows: result.sourceRows,\n chunksCompleted: result.chunksCompleted,\n durationMs: result.durationMs,\n timestamp: new Date().toISOString(),\n });\n } catch (error) {\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_dataset_failed\",\n dataset,\n datasetIndex: datasetPosition,\n totalDatasets: materializationDatasets.length,\n targetTable,\n error: error instanceof Error ? error.message : String(error),\n timestamp: new Date().toISOString(),\n });\n throw error;\n }\n }\n\n input.onProgress?.({\n kind: \"materialization_finish\",\n totalDatasets: materializationDatasets.length,\n completedDatasets: summary.datasets.length,\n });\n\n await appendJsonLinesLog(input.progressLogPath, {\n kind: \"materialization_completed\",\n datasets: summary.datasets.map((item) => ({\n dataset: item.dataset,\n targetTable: item.targetTable,\n affectedRows: item.affectedRows,\n sourceRows: item.sourceRows,\n chunksCompleted: item.chunksCompleted,\n durationMs: item.durationMs,\n })),\n timestamp: new Date().toISOString(),\n });\n\n return summary;\n}\n","import {\n companiesLayout,\n establishmentsLayout,\n partnersLayout,\n simplesLayout,\n} from \"../../dictionary/layouts/index.js\";\nimport { getConflictClause } from \"./sql.js\";\nimport type { ImportDatasetType, ImportSchemaCapabilities } from \"./types.js\";\n\nexport type MaterializationDataset =\n | \"companies\"\n | \"establishments\"\n | \"partners\"\n | \"simples_options\";\n\ntype MaterializationChunkQuery = {\n text: string;\n values: readonly unknown[];\n};\n\nconst MATERIALIZATION_COLUMNS: Record<\n MaterializationDataset,\n readonly string[]\n> = {\n companies: companiesLayout.fields.map((field) => field.columnName),\n establishments: establishmentsLayout.fields.map((field) => field.columnName),\n partners: partnersLayout.fields.map((field) => field.columnName),\n simples_options: simplesLayout.fields.map((field) => field.columnName),\n};\n\nfunction buildPartnerDedupeExpression(alias: string): string {\n return [\n `md5(`,\n ` coalesce(${alias}.cnpj_root, '') || '|' ||`,\n ` coalesce(${alias}.partner_type_code, '') || '|' ||`,\n ` coalesce(${alias}.partner_name, '') || '|' ||`,\n ` coalesce(${alias}.partner_document, '') || '|' ||`,\n ` coalesce(${alias}.partner_qualification_code, '') || '|' ||`,\n ` coalesce((${alias}.entry_date - date '2000-01-01')::text, '') || '|' ||`,\n ` coalesce(${alias}.country_code, '') || '|' ||`,\n ` coalesce(${alias}.legal_representative_document, '') || '|' ||`,\n ` coalesce(${alias}.legal_representative_name, '') || '|' ||`,\n ` coalesce(${alias}.legal_representative_qualification_code, '') || '|' ||`,\n ` coalesce(${alias}.age_group_code, '')`,\n ` )`,\n ].join(\"\\n\");\n}\n\nfunction buildEstablishmentCnpjFullExpression(alias: string): string {\n return `${alias}.cnpj_root || ${alias}.cnpj_order || ${alias}.cnpj_check_digits`;\n}\n\nfunction buildChunkInsertSql(input: {\n stagingTable: string;\n targetTable: string;\n insertColumns: readonly string[];\n selectColumns: readonly string[];\n conflictClause: string;\n lastStagingId: number;\n chunkSize: number;\n extraSelects?: readonly string[];\n}): MaterializationChunkQuery {\n const extraSelects = input.extraSelects ?? [];\n const chunkSelectList = [\n \"source.staging_id\",\n ...input.selectColumns.map((column) => `source.${column}`),\n ...extraSelects,\n ].join(\",\\n \");\n const insertSelectList = input.insertColumns.join(\", \");\n\n return {\n text: [\n \"with chunked as (\",\n ` select\\n ${chunkSelectList}`,\n ` from ${input.stagingTable} source`,\n \" where source.staging_id > $1\",\n \" order by source.staging_id asc\",\n \" limit $2\",\n \"),\",\n \"inserted as (\",\n ` insert into ${input.targetTable} (${input.insertColumns.join(\", \")})`,\n ` select ${insertSelectList}`,\n \" from chunked\",\n ...(input.conflictClause ? [input.conflictClause] : []),\n \")\",\n \"select\",\n \" coalesce(max(staging_id), $1::bigint)::bigint as max_staging_id,\",\n \" count(*)::bigint as source_rows,\",\n \" count(*)::bigint as affected_rows\",\n \"from chunked;\",\n ].join(\"\\n\"),\n values: [input.lastStagingId, input.chunkSize],\n };\n}\n\nfunction buildEstablishmentsChunkInsertSql(input: {\n insertColumns: readonly string[];\n selectColumns: readonly string[];\n conflictClause: string;\n lastStagingId: number;\n chunkSize: number;\n includeSecondaryCnaesTable: boolean;\n}): MaterializationChunkQuery {\n const chunkSelectList = [\n \"source.staging_id\",\n ...input.selectColumns.map((column) => `source.${column}`),\n `${buildEstablishmentCnpjFullExpression(\"source\")} as cnpj_full`,\n ].join(\",\\n \");\n const insertSelectList = input.insertColumns.join(\", \");\n const secondaryCnaesCtes = input.includeSecondaryCnaesTable\n ? [\n \",\",\n \"deleted_secondary_cnaes as (\",\n \" delete from establishment_secondary_cnaes target\",\n \" using (select distinct cnpj_full from inserted_establishments) source_keys\",\n \" where target.cnpj_full = source_keys.cnpj_full\",\n \" returning 1\",\n \"),\",\n \"secondary_cnaes_source as (\",\n \" select distinct\",\n \" chunked.cnpj_full,\",\n \" btrim(cnae_code) as cnae_code\",\n \" from chunked\",\n \" inner join inserted_establishments inserted\",\n \" on inserted.cnpj_full = chunked.cnpj_full\",\n \" cross join lateral unnest(string_to_array(chunked.secondary_cnaes_raw, ',')) as cnae_code\",\n \" where chunked.secondary_cnaes_raw is not null\",\n \" and chunked.secondary_cnaes_raw <> ''\",\n \" and btrim(cnae_code) <> ''\",\n \"),\",\n \"inserted_secondary_cnaes as (\",\n \" insert into establishment_secondary_cnaes (cnpj_full, cnae_code)\",\n \" select cnpj_full, cnae_code\",\n \" from secondary_cnaes_source\",\n \" on conflict (cnpj_full, cnae_code) do nothing\",\n \" returning 1\",\n \")\",\n ]\n : [];\n\n return {\n text: [\n \"with chunked as (\",\n ` select\\n ${chunkSelectList}`,\n \" from staging_establishments source\",\n \" where source.staging_id > $1\",\n \" order by source.staging_id asc\",\n \" limit $2\",\n \"),\",\n \"inserted_establishments as (\",\n ` insert into establishments (${input.insertColumns.join(\", \")})`,\n ` select ${insertSelectList}`,\n \" from chunked\",\n ...(input.conflictClause ? [input.conflictClause] : []),\n \" returning cnpj_full\",\n \")\",\n ...secondaryCnaesCtes,\n \"select\",\n \" coalesce(max(staging_id), $1::bigint)::bigint as max_staging_id,\",\n \" count(*)::bigint as source_rows,\",\n \" count(*)::bigint as affected_rows\",\n \"from chunked;\",\n ].join(\"\\n\"),\n values: [input.lastStagingId, input.chunkSize],\n };\n}\n\nfunction buildPartnersChunkInsertSql(input: {\n insertColumns: readonly string[];\n lastStagingId: number;\n chunkSize: number;\n includePartnerDedupeKeyInInsert: boolean;\n schemaCapabilities: ImportSchemaCapabilities;\n}): MaterializationChunkQuery {\n const baseColumns = MATERIALIZATION_COLUMNS.partners;\n const chunkSelectList = [\n \"source.staging_id\",\n ...baseColumns.map((column) => `source.${column}`),\n ...(input.includePartnerDedupeKeyInInsert\n ? [`${buildPartnerDedupeExpression(\"source\")} as partner_dedupe_key`]\n : []),\n ].join(\",\\n \");\n const insertSelectList = input.insertColumns.join(\", \");\n const conflictClause = getConflictClause(\n \"partners\",\n [...input.insertColumns],\n input.schemaCapabilities,\n );\n\n return {\n text: [\n \"with chunked as (\",\n ` select\\n ${chunkSelectList}`,\n \" from staging_partners source\",\n \" where source.staging_id > $1\",\n \" order by source.staging_id asc\",\n \" limit $2\",\n \"),\",\n \"deduped as (\",\n \" select *\",\n \" from (\",\n \" select\",\n \" chunked.*,\",\n \" row_number() over (partition by partner_dedupe_key order by staging_id asc) as dedupe_rank\",\n \" from chunked\",\n \" ) ranked\",\n \" where dedupe_rank = 1\",\n \"),\",\n \"inserted as (\",\n ` insert into partners (${input.insertColumns.join(\", \")})`,\n ` select ${insertSelectList}`,\n \" from deduped\",\n conflictClause,\n \")\",\n \"select\",\n \" coalesce((select max(staging_id) from chunked), $1::bigint)::bigint as max_staging_id,\",\n \" coalesce((select count(*) from chunked), 0)::bigint as source_rows,\",\n \" coalesce((select count(*) from deduped), 0)::bigint as affected_rows;\",\n ].join(\"\\n\"),\n values: [input.lastStagingId, input.chunkSize],\n };\n}\n\nexport function buildMaterializationChunkQuery(input: {\n dataset: MaterializationDataset;\n schemaCapabilities: ImportSchemaCapabilities;\n lastStagingId: number;\n chunkSize: number;\n useConflictClause?: boolean;\n}): MaterializationChunkQuery {\n const baseColumns = MATERIALIZATION_COLUMNS[input.dataset];\n const useConflictClause = input.useConflictClause ?? true;\n\n switch (input.dataset) {\n case \"partners\": {\n const insertColumns = input.schemaCapabilities\n .includePartnerDedupeKeyInInsert\n ? [...baseColumns, \"partner_dedupe_key\"]\n : [...baseColumns];\n return buildPartnersChunkInsertSql({\n insertColumns,\n lastStagingId: input.lastStagingId,\n chunkSize: input.chunkSize,\n includePartnerDedupeKeyInInsert:\n input.schemaCapabilities.includePartnerDedupeKeyInInsert,\n schemaCapabilities: input.schemaCapabilities,\n });\n }\n case \"companies\":\n return buildChunkInsertSql({\n stagingTable: \"staging_companies\",\n targetTable: \"companies\",\n insertColumns: baseColumns,\n selectColumns: baseColumns,\n conflictClause: useConflictClause\n ? getConflictClause(\n \"companies\",\n [...baseColumns],\n input.schemaCapabilities,\n )\n : \"\",\n lastStagingId: input.lastStagingId,\n chunkSize: input.chunkSize,\n });\n case \"establishments\": {\n const insertColumns = input.schemaCapabilities\n .includeEstablishmentCnpjFullInInsert\n ? [...baseColumns, \"cnpj_full\"]\n : [...baseColumns];\n return buildEstablishmentsChunkInsertSql({\n insertColumns,\n selectColumns: baseColumns,\n conflictClause: useConflictClause\n ? getConflictClause(\n \"establishments\",\n [...insertColumns],\n input.schemaCapabilities,\n )\n : \"\",\n lastStagingId: input.lastStagingId,\n chunkSize: input.chunkSize,\n includeSecondaryCnaesTable:\n input.schemaCapabilities.includeEstablishmentSecondaryCnaesTable,\n });\n }\n case \"simples_options\":\n return buildChunkInsertSql({\n stagingTable: \"staging_simples_options\",\n targetTable: \"simples_options\",\n insertColumns: baseColumns,\n selectColumns: baseColumns,\n conflictClause: useConflictClause\n ? getConflictClause(\n \"simples_options\",\n [...baseColumns],\n input.schemaCapabilities,\n )\n : \"\",\n lastStagingId: input.lastStagingId,\n chunkSize: input.chunkSize,\n });\n }\n}\n\nexport function isMaterializationDataset(\n dataset: ImportDatasetType,\n): dataset is MaterializationDataset {\n return [\n \"companies\",\n \"establishments\",\n \"partners\",\n \"simples_options\",\n ].includes(dataset);\n}\n","import { performance } from \"node:perf_hooks\";\n\nimport type { Client } from \"pg\";\n\nimport { LOOKUP_PLACEHOLDER_LABEL, type LookupTableName } from \"./types.js\";\nimport type { MaterializationDataset } from \"./materialization-sql.js\";\n\ntype LookupReconciliationSource = {\n lookupTable: LookupTableName;\n sourceSql: string;\n};\n\ntype LookupReconciliationResult = {\n lookupTable: LookupTableName;\n insertedCodes: number;\n};\n\nexport type MaterializationLookupReconciliationSummary = {\n dataset: MaterializationDataset;\n results: LookupReconciliationResult[];\n totalInsertedCodes: number;\n durationMs: number;\n};\n\ntype CountRow = {\n inserted_count: string;\n};\n\nconst COMPANIES_LOOKUP_SOURCES: readonly LookupReconciliationSource[] = [\n {\n lookupTable: \"legal_natures\",\n sourceSql:\n \"select source.legal_nature_code as code from staging_companies source\",\n },\n {\n lookupTable: \"partner_qualifications\",\n sourceSql:\n \"select source.responsible_qualification_code as code from staging_companies source\",\n },\n {\n lookupTable: \"company_sizes\",\n sourceSql:\n \"select source.company_size_code as code from staging_companies source\",\n },\n];\n\nconst ESTABLISHMENTS_LOOKUP_SOURCES: readonly LookupReconciliationSource[] = [\n {\n lookupTable: \"branch_types\",\n sourceSql:\n \"select source.branch_type_code as code from staging_establishments source\",\n },\n {\n lookupTable: \"registration_statuses\",\n sourceSql:\n \"select source.registration_status_code as code from staging_establishments source\",\n },\n {\n lookupTable: \"reasons\",\n sourceSql:\n \"select source.registration_status_reason_code as code from staging_establishments source\",\n },\n {\n lookupTable: \"countries\",\n sourceSql:\n \"select source.country_code as code from staging_establishments source\",\n },\n {\n lookupTable: \"cnaes\",\n sourceSql:\n \"select source.main_cnae_code as code from staging_establishments source\",\n },\n {\n lookupTable: \"cities\",\n sourceSql:\n \"select source.city_code as code from staging_establishments source\",\n },\n];\n\nconst PARTNERS_LOOKUP_SOURCES: readonly LookupReconciliationSource[] = [\n {\n lookupTable: \"partner_types\",\n sourceSql:\n \"select source.partner_type_code as code from staging_partners source\",\n },\n {\n lookupTable: \"partner_qualifications\",\n sourceSql:\n \"select source.partner_qualification_code as code from staging_partners source\",\n },\n {\n lookupTable: \"countries\",\n sourceSql:\n \"select source.country_code as code from staging_partners source\",\n },\n {\n lookupTable: \"partner_qualifications\",\n sourceSql:\n \"select source.legal_representative_qualification_code as code from staging_partners source\",\n },\n {\n lookupTable: \"age_groups\",\n sourceSql:\n \"select source.age_group_code as code from staging_partners source\",\n },\n];\n\nconst LOOKUP_SOURCES_BY_DATASET: Readonly<\n Record<MaterializationDataset, readonly LookupReconciliationSource[]>\n> = {\n companies: COMPANIES_LOOKUP_SOURCES,\n establishments: ESTABLISHMENTS_LOOKUP_SOURCES,\n partners: PARTNERS_LOOKUP_SOURCES,\n simples_options: [],\n};\n\nexport function getLookupReconciliationSources(\n dataset: MaterializationDataset,\n): readonly LookupTableName[] {\n return LOOKUP_SOURCES_BY_DATASET[dataset].map((source) => source.lookupTable);\n}\n\nasync function ensureLookupCodesFromSource(input: {\n client: Client;\n lookupTable: LookupTableName;\n sourceSql: string;\n}): Promise<number> {\n const result = await input.client.query<CountRow>(\n [\n \"with distinct_codes as (\",\n \" select distinct trim(source_codes.code) as code\",\n ` from (${input.sourceSql}) source_codes`,\n \" where trim(source_codes.code) <> ''\",\n \"),\",\n \"missing_codes as (\",\n \" select distinct distinct_codes.code\",\n \" from distinct_codes\",\n ` left join ${input.lookupTable} lookup_table on lookup_table.code = distinct_codes.code`,\n \" where lookup_table.code is null\",\n \"),\",\n \"inserted as (\",\n ` insert into ${input.lookupTable} (code, description)`,\n \" select\",\n \" missing_codes.code,\",\n \" $1 || ' (' || missing_codes.code || ')'\",\n \" from missing_codes\",\n \" on conflict (code) do nothing\",\n \" returning code\",\n \")\",\n \"select count(*)::bigint as inserted_count from inserted;\",\n ].join(\"\\n\"),\n [LOOKUP_PLACEHOLDER_LABEL[input.lookupTable]],\n );\n\n return Number.parseInt(result.rows[0]?.inserted_count ?? \"0\", 10);\n}\n\nexport async function reconcileMaterializationLookups(input: {\n client: Client;\n dataset: MaterializationDataset;\n onLookupStart?:\n | ((lookupTable: LookupTableName, index: number, total: number) => void)\n | undefined;\n}): Promise<MaterializationLookupReconciliationSummary> {\n const startedAt = performance.now();\n const sources = LOOKUP_SOURCES_BY_DATASET[input.dataset];\n const aggregate = new Map<LookupTableName, number>();\n\n for (const [index, source] of sources.entries()) {\n input.onLookupStart?.(source.lookupTable, index + 1, sources.length);\n\n const insertedCodes = await ensureLookupCodesFromSource({\n client: input.client,\n lookupTable: source.lookupTable,\n sourceSql: source.sourceSql,\n });\n\n aggregate.set(\n source.lookupTable,\n (aggregate.get(source.lookupTable) ?? 0) + insertedCodes,\n );\n }\n\n const results = [...aggregate.entries()].map(\n ([lookupTable, insertedCodes]) => ({\n lookupTable,\n insertedCodes,\n }),\n );\n\n return {\n dataset: input.dataset,\n results,\n totalInsertedCodes: results.reduce(\n (sum, item) => sum + item.insertedCodes,\n 0,\n ),\n durationMs: performance.now() - startedAt,\n };\n}\n","import path from \"node:path\";\n\nimport type { Client } from \"pg\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport type { FileInspection, InspectSummary } from \"../inspect.service.js\";\nimport { appendJsonLinesLog } from \"../logging.service.js\";\nimport {\n ensureImportPlanTables,\n readSavedImportPlan,\n saveImportPlan,\n} from \"./plan-store.js\";\nimport {\n buildImportPlan,\n buildImportPlanFingerprint,\n collectImportSourceFiles,\n} from \"./planning.js\";\nimport {\n IMPORT_ORDER,\n isImportDatasetType,\n type ImportDatasetPlan,\n type ImportDatasetType,\n type ImportProgressListener,\n} from \"./types.js\";\n\nexport type ImportDatasetEntry = {\n dataset: ImportDatasetType;\n files: FileInspection[];\n};\n\nexport type PreparedImportPlan = {\n planId: number | null;\n planReused: boolean;\n plan: {\n datasets: ImportDatasetPlan[];\n totalFiles: number;\n totalRows: number;\n totalBatches: number;\n };\n scanDurationMs: number;\n datasetScanDurationsMs: Partial<Record<ImportDatasetType, number>>;\n sourceFingerprint: string;\n};\n\nexport function resolveRequestedDatasets(\n requestedDataset: string | undefined,\n): ImportDatasetType[] {\n if (!requestedDataset) {\n return IMPORT_ORDER;\n }\n\n if (!isImportDatasetType(requestedDataset)) {\n throw new ValidationError(`Unsupported dataset type: ${requestedDataset}.`);\n }\n\n return IMPORT_ORDER.filter((dataset) => dataset === requestedDataset);\n}\n\nexport function collectDatasetEntriesForImport(\n inspection: InspectSummary,\n selectedDatasets: ImportDatasetType[],\n): ImportDatasetEntry[] {\n return selectedDatasets\n .map((dataset) => ({\n dataset,\n files: inspection.entries.filter(\n (entry) => entry.entryKind === \"file\" && entry.inferredType === dataset,\n ),\n }))\n .filter((entry) => entry.files.length > 0);\n}\n\nexport async function prepareImportPlan(input: {\n client: Client;\n inputPath: string;\n validatedPath: string;\n batchSize: number;\n datasetEntries: ImportDatasetEntry[];\n targetDatabase: string;\n progressLogPath: string;\n onProgress?: ImportProgressListener;\n}): Promise<PreparedImportPlan> {\n const {\n client,\n inputPath,\n validatedPath,\n batchSize,\n datasetEntries,\n targetDatabase,\n progressLogPath,\n onProgress,\n } = input;\n\n if (datasetEntries.length === 0) {\n throw new ValidationError(\n \"No validated dataset files were found for the requested import.\",\n );\n }\n\n await ensureImportPlanTables(client);\n\n const sourceFiles = await collectImportSourceFiles(\n validatedPath,\n datasetEntries,\n );\n const sourceFingerprint = buildImportPlanFingerprint(\n validatedPath,\n batchSize,\n sourceFiles,\n );\n const savedPlan = await readSavedImportPlan(client, sourceFingerprint);\n\n if (savedPlan) {\n const plan = {\n datasets: savedPlan.datasets,\n totalFiles: savedPlan.plan.totalFiles,\n totalRows: savedPlan.plan.totalRows,\n totalBatches: savedPlan.plan.totalBatches,\n };\n\n onProgress?.({\n kind: \"plan_ready\",\n totalDatasets: plan.datasets.length,\n totalFiles: plan.totalFiles,\n batchSize,\n loadBatchSize: batchSize,\n totalRows: plan.totalRows,\n totalBatches: plan.totalBatches,\n targetDatabase,\n executionOrder: plan.datasets.map((item) => item.dataset),\n reused: true,\n planId: savedPlan.plan.id,\n });\n\n await appendJsonLinesLog(progressLogPath, {\n kind: \"import_plan_reused\",\n planId: savedPlan.plan.id,\n sourceFingerprint,\n inputPath: path.resolve(inputPath),\n validatedPath,\n targetDatabase,\n totalDatasets: plan.datasets.length,\n totalFiles: plan.totalFiles,\n totalRows: plan.totalRows,\n totalBatches: plan.totalBatches,\n batchSize,\n executionOrder: plan.datasets.map((item) => item.dataset),\n scanDurationMs: 0,\n timestamp: new Date().toISOString(),\n });\n\n return {\n planId: savedPlan.plan.id,\n planReused: true,\n plan,\n scanDurationMs: 0,\n datasetScanDurationsMs: {},\n sourceFingerprint,\n };\n }\n\n const builtPlan = await buildImportPlan(\n inputPath,\n validatedPath,\n sourceFiles,\n batchSize,\n onProgress,\n targetDatabase,\n );\n const plan = {\n datasets: builtPlan.datasets,\n totalFiles: builtPlan.totalFiles,\n totalRows: builtPlan.totalRows,\n totalBatches: builtPlan.totalBatches,\n };\n const persistedPlan = await saveImportPlan(client, {\n sourceFingerprint,\n inputPath: path.resolve(inputPath),\n validatedPath,\n batchSize,\n targetDatabase,\n datasets: plan.datasets,\n totalFiles: plan.totalFiles,\n totalRows: plan.totalRows,\n totalBatches: plan.totalBatches,\n });\n\n onProgress?.({\n kind: \"plan_ready\",\n totalDatasets: plan.datasets.length,\n totalFiles: plan.totalFiles,\n batchSize,\n loadBatchSize: batchSize,\n totalRows: plan.totalRows,\n totalBatches: plan.totalBatches,\n targetDatabase,\n executionOrder: plan.datasets.map((item) => item.dataset),\n reused: false,\n planId: persistedPlan.id,\n });\n\n await appendJsonLinesLog(progressLogPath, {\n kind: \"import_plan_ready\",\n planId: persistedPlan.id,\n sourceFingerprint,\n inputPath: path.resolve(inputPath),\n validatedPath,\n targetDatabase,\n totalDatasets: plan.datasets.length,\n totalFiles: plan.totalFiles,\n totalRows: plan.totalRows,\n totalBatches: plan.totalBatches,\n batchSize,\n executionOrder: plan.datasets.map((item) => item.dataset),\n scanDurationMs: builtPlan.scanDurationMs,\n datasetScanDurationsMs: builtPlan.datasetScanDurationsMs,\n timestamp: new Date().toISOString(),\n });\n\n return {\n planId: persistedPlan.id,\n planReused: false,\n plan,\n scanDurationMs: builtPlan.scanDurationMs,\n datasetScanDurationsMs: builtPlan.datasetScanDurationsMs,\n sourceFingerprint,\n };\n}\n","import { Client } from \"pg\";\n\nimport type { ImportSchemaCapabilities } from \"./types.js\";\n\ntype ColumnCapabilityRow = {\n table_name: string;\n column_name: string;\n is_generated: string;\n};\n\ntype LookupConstraintRow = {\n requires_lookup_reconciliation: boolean;\n};\n\nfunction canInsertIntoColumn(\n rows: readonly ColumnCapabilityRow[],\n tableName: string,\n columnName: string,\n): boolean {\n const row = rows.find(\n (item) => item.table_name === tableName && item.column_name === columnName,\n );\n\n if (!row) {\n return false;\n }\n\n return row.is_generated.toUpperCase() !== \"ALWAYS\";\n}\n\nfunction hasRequiredColumns(\n rows: readonly ColumnCapabilityRow[],\n tableName: string,\n columnNames: readonly string[],\n): boolean {\n const availableColumns = new Set(\n rows\n .filter((item) => item.table_name === tableName)\n .map((item) => item.column_name),\n );\n\n return columnNames.every((columnName) => availableColumns.has(columnName));\n}\n\nexport async function detectImportSchemaCapabilities(\n client: Client,\n): Promise<ImportSchemaCapabilities> {\n const [columnResult, lookupConstraintResult] = await Promise.all([\n client.query<ColumnCapabilityRow>(\n `select table_name, column_name, is_generated\n from information_schema.columns\n where table_schema = current_schema()\n and (\n (table_name = 'establishments' and column_name = 'cnpj_full') or\n (table_name = 'establishment_secondary_cnaes' and column_name in ('cnpj_full', 'cnae_code')) or\n (table_name = 'partners' and column_name = 'partner_dedupe_key')\n )`,\n ),\n client.query<LookupConstraintRow>(\n `select exists (\n select 1\n from pg_constraint constraint_item\n inner join pg_class source_table on source_table.oid = constraint_item.conrelid\n inner join pg_namespace source_namespace on source_namespace.oid = source_table.relnamespace\n inner join pg_class target_table on target_table.oid = constraint_item.confrelid\n where constraint_item.contype = 'f'\n and source_namespace.nspname = current_schema()\n and source_table.relname in ('companies', 'establishments', 'partners', 'establishment_secondary_cnaes')\n and target_table.relname in (\n 'countries',\n 'cities',\n 'partner_qualifications',\n 'legal_natures',\n 'cnaes',\n 'reasons',\n 'company_sizes',\n 'branch_types',\n 'registration_statuses',\n 'partner_types',\n 'age_groups'\n )\n ) as requires_lookup_reconciliation`,\n ),\n ]);\n\n return {\n includeEstablishmentCnpjFullInInsert: canInsertIntoColumn(\n columnResult.rows,\n \"establishments\",\n \"cnpj_full\",\n ),\n includeEstablishmentSecondaryCnaesTable: hasRequiredColumns(\n columnResult.rows,\n \"establishment_secondary_cnaes\",\n [\"cnpj_full\", \"cnae_code\"],\n ),\n includePartnerDedupeKeyInInsert: canInsertIntoColumn(\n columnResult.rows,\n \"partners\",\n \"partner_dedupe_key\",\n ),\n requiresLookupReconciliation:\n lookupConstraintResult.rows[0]?.requires_lookup_reconciliation ?? false,\n };\n}\n","import { ValidationError } from \"../core/errors/index.js\";\nimport { resolveDatabaseUrl } from \"./database.service.js\";\nimport { inspectFiles } from \"./inspect.service.js\";\nimport { validateInputDirectory } from \"./validate.service.js\";\nimport {\n runImportLoadPipeline,\n runImportMaterializationPipeline,\n runImportPipeline,\n} from \"./import/runner.js\";\nimport {\n maskDatabaseLabel,\n isImportDatasetType,\n type ImportOptions,\n type ImportSummary,\n} from \"./import/types.js\";\n\nexport type {\n ImportCheckpointRecord,\n ImportCheckpointStatus,\n ImportDatasetPlan,\n ImportDatasetType,\n ImportFilePlan,\n ImportOptions,\n ImportPerformanceSummary,\n ImportPlanRecord,\n ImportPhaseStatus,\n ImportProgressEvent,\n ImportProgressListener,\n ImportSchemaCapabilities,\n ImportSummary,\n} from \"./import/types.js\";\n\nfunction validateRequestedDataset(dataset: string | undefined): void {\n if (dataset && !isImportDatasetType(dataset)) {\n throw new ValidationError(`Unsupported dataset type: ${dataset}.`);\n }\n}\n\nasync function prepareImportInput(\n inputPath: string,\n options: ImportOptions,\n): Promise<{\n inputPath: string;\n validatedPath: string;\n inspection: Awaited<ReturnType<typeof inspectFiles>>;\n dbUrl: string;\n targetDatabase: string;\n options: ImportOptions;\n}> {\n validateRequestedDataset(options.dataset);\n\n const validation = await validateInputDirectory(inputPath);\n if (!validation.ok) {\n throw new ValidationError(\n `The input directory is not ready for import. ${validation.errors.join(\" \")}`,\n );\n }\n\n const inspection = await inspectFiles(validation.validatedPath);\n const dbUrl = await resolveDatabaseUrl(options.dbUrl);\n\n return {\n inputPath,\n validatedPath: validation.validatedPath,\n inspection,\n dbUrl,\n options,\n targetDatabase: maskDatabaseLabel(dbUrl),\n };\n}\n\nexport async function importDataToDatabase(\n inputPath: string,\n options: ImportOptions = {},\n): Promise<ImportSummary> {\n const prepared = await prepareImportInput(inputPath, options);\n return runImportPipeline(prepared);\n}\n\nexport async function loadImportDataToStaging(\n inputPath: string,\n options: ImportOptions = {},\n): Promise<ImportSummary> {\n const prepared = await prepareImportInput(inputPath, options);\n return runImportLoadPipeline(prepared);\n}\n\nexport async function materializeImportedData(\n inputPath: string,\n options: ImportOptions = {},\n): Promise<ImportSummary> {\n const prepared = await prepareImportInput(inputPath, options);\n return runImportMaterializationPipeline(prepared);\n}\n","import { Client } from \"pg\";\n\nimport { ServiceError, ValidationError } from \"../core/errors/index.js\";\nimport { resolveDatabaseUrl } from \"./database.service.js\";\nimport { ensureQuarantineTable } from \"./import/quarantine.js\";\nimport {\n readQuarantineList,\n readQuarantineRecordById,\n readQuarantineStats,\n} from \"./quarantine/queries.js\";\nimport type {\n QuarantineListFilters,\n QuarantineListSummary,\n QuarantineRecord,\n QuarantineStatsFilters,\n QuarantineStatsSummary,\n} from \"./quarantine/types.js\";\n\nasync function withQuarantineClient<T>(\n dbUrl: string | undefined,\n action: (client: Client) => Promise<T>,\n): Promise<T> {\n const url = await resolveDatabaseUrl(dbUrl);\n const client = new Client({ connectionString: url });\n\n try {\n await client.connect();\n await ensureQuarantineTable(client);\n return await action(client);\n } catch (error) {\n if (error instanceof ValidationError) {\n throw error;\n }\n\n throw new ServiceError(\n \"The quarantine command failed while querying PostgreSQL.\",\n error,\n );\n } finally {\n await client.end().catch(() => undefined);\n }\n}\n\nexport async function getQuarantineStats(\n filters: QuarantineStatsFilters & { dbUrl?: string },\n): Promise<QuarantineStatsSummary> {\n return withQuarantineClient(filters.dbUrl, async (client) =>\n readQuarantineStats(client, filters),\n );\n}\n\nexport async function listQuarantineRows(\n filters: QuarantineListFilters & { dbUrl?: string },\n): Promise<QuarantineListSummary> {\n if (!Number.isInteger(filters.limit) || filters.limit <= 0) {\n throw new ValidationError(\n 'The \"--limit\" option must be a positive integer.',\n );\n }\n\n if (\n typeof filters.afterId === \"number\" &&\n (!Number.isInteger(filters.afterId) || filters.afterId < 0)\n ) {\n throw new ValidationError(\n 'The \"--after-id\" option must be a non-negative integer.',\n );\n }\n\n return withQuarantineClient(filters.dbUrl, async (client) =>\n readQuarantineList(client, filters),\n );\n}\n\nexport async function showQuarantineRow(\n id: number,\n options?: { dbUrl?: string },\n): Promise<QuarantineRecord> {\n if (!Number.isInteger(id) || id <= 0) {\n throw new ValidationError(\n \"The quarantine row id must be a positive integer.\",\n );\n }\n\n const record = await withQuarantineClient(options?.dbUrl, async (client) =>\n readQuarantineRecordById(client, id),\n );\n\n if (!record) {\n throw new ValidationError(`No quarantine row was found with id ${id}.`);\n }\n\n return record;\n}\n\nexport type {\n QuarantineListFilters,\n QuarantineListSummary,\n QuarantineRecord,\n QuarantineStatsFilters,\n QuarantineStatsSummary,\n} from \"./quarantine/types.js\";\n","import type { Client } from \"pg\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport type {\n QuarantineListFilters,\n QuarantineListRow,\n QuarantineListSummary,\n QuarantineRecord,\n QuarantineStatsCount,\n QuarantineStatsFilters,\n QuarantineStatsSummary,\n} from \"./types.js\";\n\ntype WhereClause = {\n sql: string;\n values: unknown[];\n};\n\nfunction buildWhereClause(filters: QuarantineStatsFilters): WhereClause {\n const conditions: string[] = [];\n const values: unknown[] = [];\n\n const pushCondition = (condition: string, value: unknown): void => {\n values.push(value);\n conditions.push(condition.replace(\"$VALUE$\", `$${values.length}`));\n };\n\n if (filters.dataset) {\n pushCondition(\"dataset = $VALUE$\", filters.dataset);\n }\n\n if (filters.category) {\n pushCondition(\"coalesce(error_category, '') = $VALUE$\", filters.category);\n }\n\n if (filters.stage) {\n pushCondition(\"coalesce(error_stage, '') = $VALUE$\", filters.stage);\n }\n\n if (filters.retryable && filters.terminal) {\n throw new ValidationError(\n 'Use either \"--retryable\" or \"--terminal\", but not both together.',\n );\n }\n\n if (filters.retryable) {\n conditions.push(\"can_retry_later = true\");\n }\n\n if (filters.terminal) {\n conditions.push(\"can_retry_later = false\");\n }\n\n return {\n sql: conditions.length > 0 ? `where ${conditions.join(\" and \")}` : \"\",\n values,\n };\n}\n\nfunction mapCountRows(\n rows: Array<Record<string, unknown>>,\n keyName: string,\n): QuarantineStatsCount[] {\n return rows.map((row) => ({\n key: String(row[keyName] ?? \"unknown\"),\n count: Number(row.count ?? 0),\n }));\n}\n\nexport async function readQuarantineStats(\n client: Client,\n filters: QuarantineStatsFilters,\n): Promise<QuarantineStatsSummary> {\n const where = buildWhereClause(filters);\n\n const totalRowsResult = await client.query(\n `select\n count(*)::bigint as total_rows,\n count(*) filter (where can_retry_later = true)::bigint as retryable_rows,\n count(*) filter (where can_retry_later = false)::bigint as terminal_rows\n from import_quarantine\n ${where.sql}`,\n where.values,\n );\n\n const rowsByDatasetResult = await client.query(\n `select dataset, count(*)::bigint as count\n from import_quarantine\n ${where.sql}\n group by dataset\n order by count desc, dataset asc`,\n where.values,\n );\n\n const rowsByCategoryResult = await client.query(\n `select coalesce(error_category, 'unknown') as error_category, count(*)::bigint as count\n from import_quarantine\n ${where.sql}\n group by coalesce(error_category, 'unknown')\n order by count desc, error_category asc`,\n where.values,\n );\n\n const rowsByStageResult = await client.query(\n `select coalesce(error_stage, 'unknown') as error_stage, count(*)::bigint as count\n from import_quarantine\n ${where.sql}\n group by coalesce(error_stage, 'unknown')\n order by count desc, error_stage asc`,\n where.values,\n );\n\n const totals = totalRowsResult.rows[0] ?? {};\n\n return {\n totalRows: Number(totals.total_rows ?? 0),\n retryableRows: Number(totals.retryable_rows ?? 0),\n terminalRows: Number(totals.terminal_rows ?? 0),\n rowsByDataset: mapCountRows(rowsByDatasetResult.rows, \"dataset\"),\n rowsByCategory: mapCountRows(rowsByCategoryResult.rows, \"error_category\"),\n rowsByStage: mapCountRows(rowsByStageResult.rows, \"error_stage\"),\n appliedFilters: filters,\n };\n}\n\nexport async function readQuarantineList(\n client: Client,\n filters: QuarantineListFilters,\n): Promise<QuarantineListSummary> {\n const where = buildWhereClause(filters);\n const conditions = where.sql ? [where.sql.replace(/^where\\s+/i, \"\")] : [];\n const values = [...where.values];\n\n if (typeof filters.afterId === \"number\") {\n values.push(filters.afterId);\n conditions.push(`id > $${values.length}`);\n }\n\n values.push(filters.limit);\n\n const query = `select\n id,\n dataset,\n file_path,\n row_number,\n checkpoint_offset,\n error_code,\n error_category,\n error_stage,\n error_message,\n retry_count,\n can_retry_later,\n created_at\n from import_quarantine\n ${conditions.length > 0 ? `where ${conditions.join(\" and \")}` : \"\"}\n order by id asc\n limit $${values.length}`;\n\n const result = await client.query(query, values);\n\n return {\n rows: result.rows.map(\n (row) =>\n ({\n id: Number(row.id),\n dataset: String(row.dataset),\n filePath: String(row.file_path),\n rowNumber: row.row_number === null ? null : Number(row.row_number),\n checkpointOffset:\n row.checkpoint_offset === null\n ? null\n : Number(row.checkpoint_offset),\n errorCode: row.error_code === null ? null : String(row.error_code),\n errorCategory:\n row.error_category === null ? null : String(row.error_category),\n errorStage: row.error_stage === null ? null : String(row.error_stage),\n errorMessage: String(row.error_message),\n retryCount: Number(row.retry_count ?? 0),\n canRetryLater: Boolean(row.can_retry_later),\n createdAt: new Date(row.created_at).toISOString(),\n }) satisfies QuarantineListRow,\n ),\n appliedFilters: filters,\n };\n}\n\nexport async function readQuarantineRecordById(\n client: Client,\n id: number,\n): Promise<QuarantineRecord | null> {\n const result = await client.query(\n `select\n id,\n dataset,\n file_path,\n row_number,\n checkpoint_offset,\n error_code,\n error_category,\n error_stage,\n error_message,\n raw_line,\n parsed_payload,\n sanitizations_applied,\n retry_count,\n can_retry_later,\n created_at\n from import_quarantine\n where id = $1`,\n [id],\n );\n\n const row = result.rows[0];\n if (!row) {\n return null;\n }\n\n return {\n id: Number(row.id),\n dataset: String(row.dataset),\n filePath: String(row.file_path),\n rowNumber: row.row_number === null ? null : Number(row.row_number),\n checkpointOffset:\n row.checkpoint_offset === null ? null : Number(row.checkpoint_offset),\n errorCode: row.error_code === null ? null : String(row.error_code),\n errorCategory:\n row.error_category === null ? null : String(row.error_category),\n errorStage: row.error_stage === null ? null : String(row.error_stage),\n errorMessage: String(row.error_message),\n rawLine: String(row.raw_line),\n parsedPayload:\n row.parsed_payload && typeof row.parsed_payload === \"object\"\n ? (row.parsed_payload as Record<string, unknown>)\n : null,\n sanitizationsApplied: Array.isArray(row.sanitizations_applied)\n ? (row.sanitizations_applied as unknown[])\n : [],\n retryCount: Number(row.retry_count ?? 0),\n canRetryLater: Boolean(row.can_retry_later),\n createdAt: new Date(row.created_at).toISOString(),\n };\n}\n","import { ValidationError } from \"../../core/errors/index.js\";\nimport type {\n FederalRevenueClientOptions,\n FederalRevenueFile,\n FederalRevenueReference,\n FederalRevenueReferenceSelection,\n} from \"./types.js\";\n\nexport const DEFAULT_FEDERAL_REVENUE_SHARE_TOKEN = \"YggdBLfdninEJX9\";\nexport const DEFAULT_FEDERAL_REVENUE_WEBDAV_URL =\n \"https://arquivos.receitafederal.gov.br/public.php/webdav\";\nexport const DEFAULT_FEDERAL_REVENUE_USER_AGENT =\n \"cnpj-db-loader federal-revenue-client\";\n\nconst REFERENCE_PATTERN = /^\\d{4}-\\d{2}$/;\n\nfunction trimTrailingSlash(value: string): string {\n return value.replace(/\\/+$/g, \"\");\n}\n\nfunction normalizeBaseUrl(value?: string): string {\n return trimTrailingSlash(value ?? DEFAULT_FEDERAL_REVENUE_WEBDAV_URL);\n}\n\nfunction getShareToken(value?: string): string {\n return value ?? DEFAULT_FEDERAL_REVENUE_SHARE_TOKEN;\n}\n\nfunction encodePathSegment(value: string): string {\n return encodeURIComponent(value).replace(/%2F/gi, \"/\");\n}\n\nfunction decodeXml(value: string): string {\n return value\n .replace(/&amp;/g, \"&\")\n .replace(/&lt;/g, \"<\")\n .replace(/&gt;/g, \">\")\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\");\n}\n\nfunction decodeHrefSegment(value: string): string {\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n}\n\nfunction getAuthHeader(shareToken: string): string {\n return `Basic ${Buffer.from(`${shareToken}:`).toString(\"base64\")}`;\n}\n\nfunction buildUrl(baseUrl: string, segments: string[] = []): string {\n if (segments.length === 0) {\n return `${baseUrl}/`;\n }\n\n return `${baseUrl}/${segments.map(encodePathSegment).join(\"/\")}`;\n}\n\nfunction extractFirst(block: string, tagName: string): string | undefined {\n const pattern = new RegExp(\n `<(?:[a-zA-Z0-9_-]+:)?${tagName}\\\\b[^>]*>([\\\\s\\\\S]*?)<\\\\/(?:[a-zA-Z0-9_-]+:)?${tagName}>`,\n \"i\",\n );\n const match = block.match(pattern);\n return match?.[1] ? decodeXml(match[1].trim()) : undefined;\n}\n\nfunction isCollectionResponse(block: string): boolean {\n return /<(?:[a-zA-Z0-9_-]+:)?collection\\b/i.test(block);\n}\n\nfunction getNameFromHref(href: string): string {\n const cleanHref = href.split(\"?\")[0] ?? href;\n const withoutTrailingSlash = cleanHref.replace(/\\/+$/g, \"\");\n const rawName = withoutTrailingSlash.split(\"/\").pop() ?? withoutTrailingSlash;\n return decodeHrefSegment(rawName);\n}\n\ntype PropfindEntry = {\n href: string;\n name: string;\n isCollection: boolean;\n sizeInBytes?: number | undefined;\n lastModified?: string | undefined;\n etag?: string | undefined;\n};\n\nfunction parsePropfindXml(xml: string): PropfindEntry[] {\n const responseBlocks = xml.match(\n /<(?:[a-zA-Z0-9_-]+:)?response\\b[\\s\\S]*?<\\/(?:[a-zA-Z0-9_-]+:)?response>/gi,\n );\n\n if (!responseBlocks) {\n return [];\n }\n\n return responseBlocks\n .map<PropfindEntry | undefined>((block) => {\n const href = extractFirst(block, \"href\");\n if (!href) {\n return undefined;\n }\n\n const size = extractFirst(block, \"getcontentlength\");\n const parsedSize = size ? Number.parseInt(size, 10) : undefined;\n const lastModified = extractFirst(block, \"getlastmodified\");\n const etag = extractFirst(block, \"getetag\");\n\n return {\n href,\n name: getNameFromHref(href),\n isCollection: isCollectionResponse(block),\n ...(Number.isFinite(parsedSize) ? { sizeInBytes: parsedSize } : {}),\n ...(lastModified ? { lastModified } : {}),\n ...(etag ? { etag } : {}),\n };\n })\n .filter((entry): entry is PropfindEntry => entry !== undefined);\n}\n\nasync function propfind(\n pathSegments: string[],\n options: FederalRevenueClientOptions = {},\n): Promise<{ entries: PropfindEntry[]; baseUrl: string; shareToken: string }> {\n const baseUrl = normalizeBaseUrl(options.baseUrl);\n const shareToken = getShareToken(options.shareToken);\n let response: Response;\n\n try {\n response = await fetch(buildUrl(baseUrl, pathSegments), {\n method: \"PROPFIND\",\n headers: {\n Accept: \"application/xml,text/xml,*/*\",\n Authorization: getAuthHeader(shareToken),\n Depth: \"1\",\n \"User-Agent\": options.userAgent ?? DEFAULT_FEDERAL_REVENUE_USER_AGENT,\n },\n });\n } catch (error) {\n throw new ValidationError(\n `Federal Revenue WebDAV request failed before receiving a response: ${error instanceof Error ? error.message : String(error)}.`,\n { baseUrl, pathSegments },\n );\n }\n\n if (!response.ok) {\n throw new ValidationError(\n `Federal Revenue WebDAV request failed with status ${response.status} ${response.statusText}.`,\n { status: response.status, statusText: response.statusText },\n );\n }\n\n const xml = await response.text();\n return {\n entries: parsePropfindXml(xml),\n baseUrl,\n shareToken,\n };\n}\n\nexport function validateFederalRevenueReference(reference: string): void {\n if (!REFERENCE_PATTERN.test(reference)) {\n throw new ValidationError(\n `Federal Revenue reference is invalid: ${reference}. Expected YYYY-MM.`,\n );\n }\n}\n\nexport function getCurrentFederalRevenueReference(date = new Date()): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n return `${year}-${month}`;\n}\n\nexport async function listFederalRevenueReferences(\n options: FederalRevenueClientOptions = {},\n): Promise<{ references: FederalRevenueReference[]; remoteBaseUrl: string }> {\n const result = await propfind([], options);\n const references = result.entries\n .filter((entry) => entry.isCollection && REFERENCE_PATTERN.test(entry.name))\n .map<FederalRevenueReference>((entry) => ({\n reference: entry.name,\n href: entry.href,\n }))\n .sort((left, right) => left.reference.localeCompare(right.reference));\n\n return {\n references,\n remoteBaseUrl: result.baseUrl,\n };\n}\n\nexport async function resolveFederalRevenueReference(\n input: {\n reference?: string | undefined;\n current?: boolean | undefined;\n } & FederalRevenueClientOptions = {},\n): Promise<FederalRevenueReferenceSelection> {\n const { references } = await listFederalRevenueReferences(input);\n const availableReferences = references.map((item) => item.reference);\n const latest = availableReferences.at(-1);\n\n if (!latest) {\n throw new ValidationError(\n \"Federal Revenue reference discovery failed: no monthly references were found in the public share.\",\n );\n }\n\n if (input.reference) {\n validateFederalRevenueReference(input.reference);\n\n if (!availableReferences.includes(input.reference)) {\n throw new ValidationError(\n `Federal Revenue reference not found: ${input.reference}. Latest available reference is ${latest}.`,\n {\n requestedReference: input.reference,\n latestAvailableReference: latest,\n availableReferences,\n },\n );\n }\n\n return {\n mode: \"explicit\",\n selectedReference: input.reference,\n availableReferences,\n };\n }\n\n if (input.current) {\n const currentReference = getCurrentFederalRevenueReference();\n\n if (!availableReferences.includes(currentReference)) {\n throw new ValidationError(\n `Federal Revenue current reference is not available yet: ${currentReference}. Latest available reference is ${latest}.`,\n {\n requestedReference: currentReference,\n latestAvailableReference: latest,\n availableReferences,\n },\n );\n }\n\n return {\n mode: \"current\",\n selectedReference: currentReference,\n availableReferences,\n };\n }\n\n return {\n mode: \"latest\",\n selectedReference: latest,\n availableReferences,\n };\n}\n\nexport async function listFederalRevenueFiles(\n reference: string,\n options: FederalRevenueClientOptions = {},\n): Promise<{ files: FederalRevenueFile[]; remoteBaseUrl: string }> {\n validateFederalRevenueReference(reference);\n const result = await propfind([reference], options);\n const files = result.entries\n .filter(\n (entry) =>\n !entry.isCollection && entry.name.toLowerCase().endsWith(\".zip\"),\n )\n .map<FederalRevenueFile>((entry) => ({\n name: entry.name,\n href: entry.href,\n downloadUrl: buildUrl(result.baseUrl, [reference, entry.name]),\n ...(entry.sizeInBytes !== undefined\n ? { sizeInBytes: entry.sizeInBytes }\n : {}),\n ...(entry.lastModified ? { lastModified: entry.lastModified } : {}),\n ...(entry.etag ? { etag: entry.etag } : {}),\n }))\n .sort((left, right) => left.name.localeCompare(right.name));\n\n return {\n files,\n remoteBaseUrl: result.baseUrl,\n };\n}\n\nexport function buildFederalRevenueDownloadHeaders(\n options: FederalRevenueClientOptions = {},\n): Record<string, string> {\n return {\n Authorization: getAuthHeader(getShareToken(options.shareToken)),\n \"User-Agent\": options.userAgent ?? DEFAULT_FEDERAL_REVENUE_USER_AGENT,\n };\n}\n","import { createWriteStream } from \"node:fs\";\nimport { mkdir, rename, stat, unlink } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { Readable } from \"node:stream\";\nimport type { ReadableStream as NodeReadableStream } from \"node:stream/web\";\nimport { pipeline } from \"node:stream/promises\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport {\n buildFederalRevenueDownloadHeaders,\n listFederalRevenueFiles,\n resolveFederalRevenueReference,\n} from \"./client.js\";\nimport {\n buildFederalRevenueReferenceOutputPath,\n createFederalRevenueManifest,\n evaluateFederalRevenueManifestFiles,\n finalizeFederalRevenueManifest,\n getFederalRevenueManifestPath,\n readFederalRevenueManifest,\n updateFederalRevenueManifestFile,\n} from \"./manifest.js\";\nimport type {\n FederalRevenueCheckOptions,\n FederalRevenueCheckSummary,\n FederalRevenueDownloadEntry,\n FederalRevenueDownloadOptions,\n FederalRevenueDownloadSummary,\n FederalRevenueFile,\n FederalRevenueLocalFileStatus,\n} from \"./types.js\";\n\nconst DEFAULT_DOWNLOAD_RETRIES = 3;\n\nfunction resolveRetryCount(value: number | undefined): number {\n if (value === undefined || Number.isNaN(value)) {\n return DEFAULT_DOWNLOAD_RETRIES;\n }\n\n return Math.max(1, Math.floor(value));\n}\n\nasync function safeStat(filePath: string): Promise<{\n exists: boolean;\n size: number;\n}> {\n try {\n const fileStat = await stat(filePath);\n return {\n exists: fileStat.isFile(),\n size: fileStat.size,\n };\n } catch {\n return {\n exists: false,\n size: 0,\n };\n }\n}\n\nasync function safeUnlink(filePath: string): Promise<void> {\n try {\n await unlink(filePath);\n } catch {\n // Ignore cleanup errors. A later write attempt will surface any real issue.\n }\n}\n\nfunction isCompletedLocalFile(localSize: number, remoteSize?: number): boolean {\n if (remoteSize === undefined) {\n return localSize > 0;\n }\n\n return localSize === remoteSize;\n}\n\nfunction toLocalStatus(\n entry: FederalRevenueDownloadEntry,\n): FederalRevenueLocalFileStatus {\n if (entry.status === \"failed\") {\n return \"failed\";\n }\n\n return \"downloaded\";\n}\n\nasync function downloadSingleFile(\n file: FederalRevenueFile,\n outputPath: string,\n options: FederalRevenueDownloadOptions,\n): Promise<FederalRevenueDownloadEntry> {\n const filePath = path.join(outputPath, file.name);\n const partialFilePath = `${filePath}.part`;\n const localFile = await safeStat(filePath);\n\n if (\n !options.overwrite &&\n localFile.exists &&\n isCompletedLocalFile(localFile.size, file.sizeInBytes)\n ) {\n return {\n fileName: file.name,\n filePath,\n status: \"skipped\",\n sizeInBytes: localFile.size,\n remoteSizeInBytes: file.sizeInBytes,\n };\n }\n\n const retries = resolveRetryCount(options.retries);\n let lastError: unknown;\n\n for (let attempt = 1; attempt <= retries; attempt += 1) {\n await safeUnlink(partialFilePath);\n\n try {\n const response = await fetch(file.downloadUrl, {\n method: \"GET\",\n headers: buildFederalRevenueDownloadHeaders(options),\n });\n\n if (!response.ok) {\n throw new ValidationError(\n `Federal Revenue download failed for ${file.name}: HTTP ${response.status} ${response.statusText}.`,\n {\n fileName: file.name,\n status: response.status,\n statusText: response.statusText,\n attempt,\n },\n );\n }\n\n if (!response.body) {\n throw new ValidationError(\n `Federal Revenue download failed for ${file.name}: response body is empty.`,\n {\n fileName: file.name,\n attempt,\n },\n );\n }\n\n await pipeline(\n Readable.fromWeb(response.body as NodeReadableStream<Uint8Array>),\n createWriteStream(partialFilePath),\n );\n\n const downloadedFile = await safeStat(partialFilePath);\n if (\n file.sizeInBytes !== undefined &&\n downloadedFile.size !== file.sizeInBytes\n ) {\n throw new ValidationError(\n `Federal Revenue download failed for ${file.name}: local size does not match the remote size.`,\n {\n fileName: file.name,\n expectedSize: file.sizeInBytes,\n actualSize: downloadedFile.size,\n attempt,\n },\n );\n }\n\n await safeUnlink(filePath);\n await rename(partialFilePath, filePath);\n\n return {\n fileName: file.name,\n filePath,\n status: \"downloaded\",\n sizeInBytes: downloadedFile.size,\n remoteSizeInBytes: file.sizeInBytes,\n };\n } catch (error) {\n lastError = error;\n }\n }\n\n return {\n fileName: file.name,\n filePath,\n status: \"failed\",\n remoteSizeInBytes: file.sizeInBytes,\n errorMessage:\n lastError instanceof Error ? lastError.message : String(lastError),\n };\n}\n\nfunction shouldDownloadFile(\n file: FederalRevenueFile,\n incompleteFileNames: Set<string> | undefined,\n): boolean {\n if (!incompleteFileNames) {\n return true;\n }\n\n return incompleteFileNames.has(file.name);\n}\n\nexport async function checkFederalRevenueDataset(\n options: FederalRevenueCheckOptions = {},\n): Promise<FederalRevenueCheckSummary> {\n const selection = await resolveFederalRevenueReference(options);\n const { files, remoteBaseUrl } = await listFederalRevenueFiles(\n selection.selectedReference,\n options,\n );\n const totalBytes = files.reduce(\n (sum, file) => sum + (file.sizeInBytes ?? 0),\n 0,\n );\n\n return {\n selectedReference: selection.selectedReference,\n selectionMode: selection.mode,\n availableReferences: selection.availableReferences,\n files,\n totalFiles: files.length,\n totalBytes,\n remoteBaseUrl,\n };\n}\n\nexport async function downloadFederalRevenueDataset(\n options: FederalRevenueDownloadOptions = {},\n): Promise<FederalRevenueDownloadSummary> {\n const startedAt = new Date().toISOString();\n const check = await checkFederalRevenueDataset(options);\n const outputPath = buildFederalRevenueReferenceOutputPath(\n check.selectedReference,\n options.outputPath,\n );\n const manifestPath = getFederalRevenueManifestPath(outputPath);\n\n await mkdir(outputPath, { recursive: true });\n await createFederalRevenueManifest({\n reference: check.selectedReference,\n outputPath,\n remoteBaseUrl: check.remoteBaseUrl,\n files: check.files,\n lastCommand: options.manifestCommand ?? \"download\",\n });\n\n const manifest = await readFederalRevenueManifest(outputPath);\n const evaluatedFiles = manifest\n ? await evaluateFederalRevenueManifestFiles(manifest.files)\n : [];\n const incompleteFileNames = options.incompleteOnly\n ? new Set(\n evaluatedFiles\n .filter((entry) => entry.status !== \"downloaded\")\n .map((entry) => entry.fileName),\n )\n : undefined;\n const filesToProcess = check.files.filter((file) =>\n shouldDownloadFile(file, incompleteFileNames),\n );\n\n options.onProgress?.({\n kind: \"start\",\n reference: check.selectedReference,\n outputPath,\n totalFiles: filesToProcess.length,\n totalBytes: check.totalBytes,\n });\n\n const entries: FederalRevenueDownloadEntry[] = [];\n let downloadedBytes = 0;\n let downloadedFiles = 0;\n let skippedFiles = 0;\n let failedFiles = 0;\n\n for (const [index, file] of filesToProcess.entries()) {\n options.onProgress?.({\n kind: \"file-start\",\n reference: check.selectedReference,\n fileName: file.name,\n fileIndex: index + 1,\n totalFiles: filesToProcess.length,\n completedFiles: entries.length,\n downloadedBytes,\n totalBytes: check.totalBytes,\n fileSizeInBytes: file.sizeInBytes,\n });\n\n const entry = await downloadSingleFile(file, outputPath, options);\n entries.push(entry);\n\n await updateFederalRevenueManifestFile(outputPath, {\n fileName: entry.fileName,\n status: toLocalStatus(entry),\n localSizeInBytes: entry.sizeInBytes,\n errorMessage: entry.errorMessage,\n downloadedAt:\n entry.status === \"downloaded\" || entry.status === \"skipped\"\n ? new Date().toISOString()\n : undefined,\n });\n\n if (entry.status === \"downloaded\") {\n downloadedFiles += 1;\n downloadedBytes += entry.sizeInBytes ?? file.sizeInBytes ?? 0;\n options.onProgress?.({\n kind: \"file-complete\",\n reference: check.selectedReference,\n fileName: file.name,\n fileIndex: index + 1,\n totalFiles: filesToProcess.length,\n completedFiles: entries.length,\n downloadedBytes,\n totalBytes: check.totalBytes,\n fileSizeInBytes: file.sizeInBytes,\n });\n continue;\n }\n\n if (entry.status === \"skipped\") {\n skippedFiles += 1;\n downloadedBytes += entry.sizeInBytes ?? file.sizeInBytes ?? 0;\n options.onProgress?.({\n kind: \"file-skipped\",\n reference: check.selectedReference,\n fileName: file.name,\n fileIndex: index + 1,\n totalFiles: filesToProcess.length,\n completedFiles: entries.length,\n downloadedBytes,\n totalBytes: check.totalBytes,\n fileSizeInBytes: file.sizeInBytes,\n });\n continue;\n }\n\n failedFiles += 1;\n options.onProgress?.({\n kind: \"file-failed\",\n reference: check.selectedReference,\n fileName: file.name,\n fileIndex: index + 1,\n totalFiles: filesToProcess.length,\n completedFiles: entries.length,\n downloadedBytes,\n totalBytes: check.totalBytes,\n errorMessage: entry.errorMessage ?? \"Unknown download error\",\n fileSizeInBytes: file.sizeInBytes,\n });\n }\n\n await finalizeFederalRevenueManifest(\n outputPath,\n failedFiles > 0 ? \"failed\" : \"completed\",\n );\n\n const finalManifest = await readFederalRevenueManifest(outputPath);\n const finalFiles = finalManifest\n ? await evaluateFederalRevenueManifestFiles(finalManifest.files)\n : [];\n const partialFiles = finalFiles.filter(\n (entry) => entry.status === \"partial\",\n ).length;\n const missingFiles = finalFiles.filter(\n (entry) => entry.status === \"missing\",\n ).length;\n\n options.onProgress?.({\n kind: \"finish\",\n reference: check.selectedReference,\n outputPath,\n totalFiles: filesToProcess.length,\n downloadedFiles,\n skippedFiles,\n failedFiles,\n downloadedBytes,\n totalBytes: check.totalBytes,\n });\n\n const warnings: string[] = [];\n\n if (options.incompleteOnly && filesToProcess.length === 0) {\n warnings.push(\"No incomplete Federal Revenue files were found for retry.\");\n }\n\n if (failedFiles > 0) {\n warnings.push(\n \"Some Federal Revenue files could not be downloaded. Check the log file and use retry after fixing the cause.\",\n );\n }\n\n return {\n reference: check.selectedReference,\n selectionMode: check.selectionMode,\n outputPath,\n manifestPath,\n remoteBaseUrl: check.remoteBaseUrl,\n filesFound: check.totalFiles,\n downloadedFiles,\n skippedFiles,\n failedFiles,\n partialFiles,\n missingFiles,\n totalBytes: check.totalBytes,\n downloadedBytes,\n entries,\n startedAt,\n finishedAt: new Date().toISOString(),\n warnings,\n nextStep: `cnpj-db-loader extract ${outputPath.replace(/\\\\/g, \"/\")}`,\n };\n}\n\nexport async function retryFederalRevenueDataset(\n options: FederalRevenueDownloadOptions = {},\n): Promise<FederalRevenueDownloadSummary> {\n return downloadFederalRevenueDataset({\n ...options,\n incompleteOnly: true,\n manifestCommand: \"retry\",\n });\n}\n","import { mkdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { validateFederalRevenueReference } from \"./client.js\";\nimport type {\n FederalRevenueFile,\n FederalRevenueLocalFileStatus,\n FederalRevenueManifest,\n FederalRevenueManifestFile,\n FederalRevenueManifestLastCommand,\n} from \"./types.js\";\n\nexport const FEDERAL_REVENUE_MANIFEST_VERSION = 1;\nexport const FEDERAL_REVENUE_CONTROL_DIR = \".cnpj-db-loader\";\nexport const FEDERAL_REVENUE_CONTROL_SCOPE = \"federal-revenue\";\nexport const DEFAULT_FEDERAL_REVENUE_DOWNLOAD_ROOT = path.join(\n process.cwd(),\n \"downloads\",\n \"federal-revenue\",\n);\n\nexport function buildFederalRevenueReferenceOutputPath(\n reference: string,\n outputPath?: string,\n): string {\n validateFederalRevenueReference(reference);\n return path.resolve(\n outputPath ?? DEFAULT_FEDERAL_REVENUE_DOWNLOAD_ROOT,\n reference,\n );\n}\n\nexport function getFederalRevenueControlDirectory(outputPath: string): string {\n return path.join(\n outputPath,\n FEDERAL_REVENUE_CONTROL_DIR,\n FEDERAL_REVENUE_CONTROL_SCOPE,\n );\n}\n\nexport function getFederalRevenueManifestPath(outputPath: string): string {\n return path.join(\n getFederalRevenueControlDirectory(outputPath),\n \"manifest.json\",\n );\n}\n\nexport function getFederalRevenueSyncLockPath(outputPath: string): string {\n return path.join(getFederalRevenueControlDirectory(outputPath), \"sync.lock\");\n}\n\nasync function safeFileStat(filePath: string): Promise<{\n exists: boolean;\n size: number;\n}> {\n try {\n const fileStat = await stat(filePath);\n return {\n exists: fileStat.isFile(),\n size: fileStat.size,\n };\n } catch {\n return {\n exists: false,\n size: 0,\n };\n }\n}\n\nfunction isCompleteSize(localSize: number, remoteSize?: number): boolean {\n if (remoteSize === undefined) {\n return localSize > 0;\n }\n\n return localSize === remoteSize;\n}\n\nfunction buildManifestFile(\n file: FederalRevenueFile,\n outputPath: string,\n previous?: FederalRevenueManifestFile,\n): FederalRevenueManifestFile {\n const filePath = path.join(outputPath, file.name);\n const partialFilePath = `${filePath}.part`;\n const entry: FederalRevenueManifestFile = {\n fileName: file.name,\n filePath,\n partialFilePath,\n href: file.href,\n downloadUrl: file.downloadUrl,\n status: previous?.status ?? \"missing\",\n updatedAt: previous?.updatedAt ?? new Date().toISOString(),\n };\n\n if (file.sizeInBytes !== undefined) {\n entry.remoteSizeInBytes = file.sizeInBytes;\n }\n\n if (file.lastModified !== undefined) {\n entry.lastModified = file.lastModified;\n }\n\n if (file.etag !== undefined) {\n entry.etag = file.etag;\n }\n\n if (previous?.localSizeInBytes !== undefined) {\n entry.localSizeInBytes = previous.localSizeInBytes;\n }\n\n if (previous?.downloadedAt !== undefined) {\n entry.downloadedAt = previous.downloadedAt;\n }\n\n if (previous?.errorMessage !== undefined) {\n entry.errorMessage = previous.errorMessage;\n }\n\n return entry;\n}\n\nexport async function readFederalRevenueManifest(\n outputPath: string,\n): Promise<FederalRevenueManifest | undefined> {\n try {\n const manifestContent = await readFile(\n getFederalRevenueManifestPath(outputPath),\n \"utf8\",\n );\n return JSON.parse(manifestContent) as FederalRevenueManifest;\n } catch {\n return undefined;\n }\n}\n\nexport async function writeFederalRevenueManifest(\n manifest: FederalRevenueManifest,\n): Promise<void> {\n await mkdir(getFederalRevenueControlDirectory(manifest.outputPath), {\n recursive: true,\n });\n await writeFile(\n getFederalRevenueManifestPath(manifest.outputPath),\n `${JSON.stringify(manifest, null, 2)}\\n`,\n \"utf8\",\n );\n}\n\nexport async function createFederalRevenueManifest(input: {\n reference: string;\n outputPath: string;\n remoteBaseUrl: string;\n files: FederalRevenueFile[];\n lastCommand: FederalRevenueManifestLastCommand;\n}): Promise<FederalRevenueManifest> {\n const existingManifest = await readFederalRevenueManifest(input.outputPath);\n const previousByName = new Map(\n existingManifest?.files.map((file) => [file.fileName, file]) ?? [],\n );\n const now = new Date().toISOString();\n\n const manifest: FederalRevenueManifest = {\n version: FEDERAL_REVENUE_MANIFEST_VERSION,\n reference: input.reference,\n remoteBaseUrl: input.remoteBaseUrl,\n outputPath: input.outputPath,\n createdAt: existingManifest?.createdAt ?? now,\n updatedAt: now,\n lastCommand: input.lastCommand,\n lastStatus: \"running\",\n files: input.files.map((file) =>\n buildManifestFile(file, input.outputPath, previousByName.get(file.name)),\n ),\n };\n\n await writeFederalRevenueManifest(manifest);\n return manifest;\n}\n\nexport async function evaluateFederalRevenueManifestFile(\n entry: FederalRevenueManifestFile,\n): Promise<FederalRevenueManifestFile> {\n const localFile = await safeFileStat(entry.filePath);\n const partialFile = await safeFileStat(entry.partialFilePath);\n const nextEntry: FederalRevenueManifestFile = {\n ...entry,\n updatedAt: new Date().toISOString(),\n };\n\n delete nextEntry.localSizeInBytes;\n\n if (\n localFile.exists &&\n isCompleteSize(localFile.size, entry.remoteSizeInBytes)\n ) {\n nextEntry.status = \"downloaded\";\n nextEntry.localSizeInBytes = localFile.size;\n delete nextEntry.errorMessage;\n return nextEntry;\n }\n\n if (partialFile.exists) {\n nextEntry.status = \"partial\";\n nextEntry.localSizeInBytes = partialFile.size;\n return nextEntry;\n }\n\n if (localFile.exists) {\n nextEntry.status = \"partial\";\n nextEntry.localSizeInBytes = localFile.size;\n nextEntry.errorMessage = `Local file size does not match the remote size. Expected ${entry.remoteSizeInBytes ?? \"unknown\"} byte(s), found ${localFile.size} byte(s).`;\n return nextEntry;\n }\n\n if (entry.status === \"failed\") {\n return nextEntry;\n }\n\n nextEntry.status = \"missing\";\n return nextEntry;\n}\n\nexport async function evaluateFederalRevenueManifestFiles(\n entries: FederalRevenueManifestFile[],\n): Promise<FederalRevenueManifestFile[]> {\n const evaluated: FederalRevenueManifestFile[] = [];\n\n for (const entry of entries) {\n evaluated.push(await evaluateFederalRevenueManifestFile(entry));\n }\n\n return evaluated;\n}\n\nexport async function updateFederalRevenueManifestFile(\n outputPath: string,\n input: {\n fileName: string;\n status: FederalRevenueLocalFileStatus;\n localSizeInBytes?: number | undefined;\n errorMessage?: string | undefined;\n downloadedAt?: string | undefined;\n },\n): Promise<void> {\n const manifest = await readFederalRevenueManifest(outputPath);\n if (!manifest) {\n return;\n }\n\n const updatedAt = new Date().toISOString();\n manifest.updatedAt = updatedAt;\n manifest.files = manifest.files.map((file) => {\n if (file.fileName !== input.fileName) {\n return file;\n }\n\n const updatedFile: FederalRevenueManifestFile = {\n ...file,\n status: input.status,\n updatedAt,\n };\n\n delete updatedFile.errorMessage;\n delete updatedFile.localSizeInBytes;\n delete updatedFile.downloadedAt;\n\n if (input.localSizeInBytes !== undefined) {\n updatedFile.localSizeInBytes = input.localSizeInBytes;\n }\n\n if (input.errorMessage !== undefined) {\n updatedFile.errorMessage = input.errorMessage;\n }\n\n if (input.downloadedAt !== undefined) {\n updatedFile.downloadedAt = input.downloadedAt;\n }\n\n return updatedFile;\n });\n\n await writeFederalRevenueManifest(manifest);\n}\n\nexport async function finalizeFederalRevenueManifest(\n outputPath: string,\n lastStatus: FederalRevenueManifest[\"lastStatus\"],\n): Promise<void> {\n const manifest = await readFederalRevenueManifest(outputPath);\n if (!manifest) {\n return;\n }\n\n manifest.updatedAt = new Date().toISOString();\n manifest.lastStatus = lastStatus;\n manifest.files = await evaluateFederalRevenueManifestFiles(manifest.files);\n await writeFederalRevenueManifest(manifest);\n}\n","import { ValidationError } from \"../../core/errors/index.js\";\nimport {\n getCurrentFederalRevenueReference,\n resolveFederalRevenueReference,\n validateFederalRevenueReference,\n} from \"./client.js\";\nimport {\n buildFederalRevenueReferenceOutputPath,\n evaluateFederalRevenueManifestFiles,\n getFederalRevenueManifestPath,\n readFederalRevenueManifest,\n} from \"./manifest.js\";\nimport type {\n FederalRevenueClientOptions,\n FederalRevenueLocalStatusEntry,\n FederalRevenueReferenceMode,\n FederalRevenueStatusOptions,\n FederalRevenueStatusSummary,\n} from \"./types.js\";\n\nfunction toStatusEntry(\n file: Awaited<ReturnType<typeof evaluateFederalRevenueManifestFiles>>[number],\n): FederalRevenueLocalStatusEntry {\n const entry: FederalRevenueLocalStatusEntry = {\n fileName: file.fileName,\n filePath: file.filePath,\n partialFilePath: file.partialFilePath,\n status: file.status,\n };\n\n if (file.remoteSizeInBytes !== undefined) {\n entry.remoteSizeInBytes = file.remoteSizeInBytes;\n }\n\n if (file.localSizeInBytes !== undefined) {\n entry.localSizeInBytes = file.localSizeInBytes;\n }\n\n if (file.errorMessage !== undefined) {\n entry.errorMessage = file.errorMessage;\n }\n\n return entry;\n}\n\nasync function resolveLocalReference(\n options: FederalRevenueStatusOptions,\n): Promise<{\n reference: string;\n mode: FederalRevenueReferenceMode;\n availableReferences: string[];\n}> {\n if (options.reference) {\n validateFederalRevenueReference(options.reference);\n return {\n reference: options.reference,\n mode: \"explicit\",\n availableReferences: [],\n };\n }\n\n if (options.current) {\n return {\n reference: getCurrentFederalRevenueReference(),\n mode: \"current\",\n availableReferences: [],\n };\n }\n\n const selection = await resolveFederalRevenueReference(\n options as FederalRevenueClientOptions,\n );\n\n return {\n reference: selection.selectedReference,\n mode: selection.mode,\n availableReferences: selection.availableReferences,\n };\n}\n\nexport async function getFederalRevenueStatus(\n options: FederalRevenueStatusOptions = {},\n): Promise<FederalRevenueStatusSummary> {\n const selection = await resolveLocalReference(options);\n const outputPath = buildFederalRevenueReferenceOutputPath(\n selection.reference,\n options.outputPath,\n );\n const manifestPath = getFederalRevenueManifestPath(outputPath);\n const manifest = await readFederalRevenueManifest(outputPath);\n\n if (!manifest) {\n return {\n reference: selection.reference,\n selectionMode: selection.mode,\n outputPath,\n manifestPath,\n manifestFound: false,\n filesFound: 0,\n downloadedFiles: 0,\n failedFiles: 0,\n partialFiles: 0,\n missingFiles: 0,\n totalBytes: 0,\n localBytes: 0,\n isComplete: false,\n entries: [],\n warnings: [\n \"No local Federal Revenue manifest was found for this reference. Run download or sync first.\",\n ],\n };\n }\n\n if (manifest.reference !== selection.reference) {\n throw new ValidationError(\n `Federal Revenue manifest mismatch: expected ${selection.reference}, found ${manifest.reference}.`,\n { outputPath, manifestPath },\n );\n }\n\n const evaluatedFiles = await evaluateFederalRevenueManifestFiles(\n manifest.files,\n );\n const entries = evaluatedFiles.map(toStatusEntry);\n const downloadedFiles = entries.filter(\n (entry) => entry.status === \"downloaded\",\n ).length;\n const failedFiles = entries.filter(\n (entry) => entry.status === \"failed\",\n ).length;\n const partialFiles = entries.filter(\n (entry) => entry.status === \"partial\",\n ).length;\n const missingFiles = entries.filter(\n (entry) => entry.status === \"missing\",\n ).length;\n const totalBytes = entries.reduce(\n (sum, entry) => sum + (entry.remoteSizeInBytes ?? 0),\n 0,\n );\n const localBytes = entries.reduce(\n (sum, entry) => sum + (entry.localSizeInBytes ?? 0),\n 0,\n );\n const warnings: string[] = [];\n\n if (failedFiles > 0 || partialFiles > 0 || missingFiles > 0) {\n warnings.push(\n \"The local Federal Revenue reference is not complete. Use retry to resume incomplete or failed files.\",\n );\n }\n\n return {\n reference: selection.reference,\n selectionMode: selection.mode,\n outputPath,\n manifestPath,\n manifestFound: true,\n filesFound: entries.length,\n downloadedFiles,\n failedFiles,\n partialFiles,\n missingFiles,\n totalBytes,\n localBytes,\n isComplete:\n entries.length > 0 &&\n failedFiles === 0 &&\n partialFiles === 0 &&\n missingFiles === 0,\n entries,\n warnings,\n updatedAt: manifest.updatedAt,\n lastCommand: manifest.lastCommand,\n lastStatus: manifest.lastStatus,\n };\n}\n","import { readdir, rm, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport {\n getCurrentFederalRevenueReference,\n resolveFederalRevenueReference,\n validateFederalRevenueReference,\n} from \"./client.js\";\nimport {\n buildFederalRevenueReferenceOutputPath,\n getFederalRevenueManifestPath,\n readFederalRevenueManifest,\n writeFederalRevenueManifest,\n} from \"./manifest.js\";\nimport type {\n FederalRevenueCleanMode,\n FederalRevenueCleanOptions,\n FederalRevenueCleanSummary,\n FederalRevenueClientOptions,\n FederalRevenueManifestFile,\n FederalRevenueReferenceMode,\n} from \"./types.js\";\n\nasync function safeStat(filePath: string): Promise<{\n exists: boolean;\n size: number;\n isDirectory: boolean;\n}> {\n try {\n const fileStat = await stat(filePath);\n return {\n exists: true,\n size: fileStat.size,\n isDirectory: fileStat.isDirectory(),\n };\n } catch {\n return {\n exists: false,\n size: 0,\n isDirectory: false,\n };\n }\n}\n\nasync function listPartialFiles(rootPath: string): Promise<string[]> {\n const rootStat = await safeStat(rootPath);\n if (!rootStat.exists || !rootStat.isDirectory) {\n return [];\n }\n\n const result: string[] = [];\n const entries = await readdir(rootPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const entryPath = path.join(rootPath, entry.name);\n\n if (entry.isDirectory()) {\n result.push(...(await listPartialFiles(entryPath)));\n continue;\n }\n\n if (entry.isFile() && entry.name.endsWith(\".part\")) {\n result.push(entryPath);\n }\n }\n\n return result;\n}\n\nasync function removeFileIfExists(filePath: string): Promise<{\n removed: boolean;\n size: number;\n}> {\n const fileStat = await safeStat(filePath);\n if (!fileStat.exists || fileStat.isDirectory) {\n return { removed: false, size: 0 };\n }\n\n await rm(filePath, { force: true });\n return { removed: true, size: fileStat.size };\n}\n\nasync function resolveCleanReference(\n options: FederalRevenueCleanOptions,\n): Promise<{ reference: string; mode: FederalRevenueReferenceMode }> {\n if (options.reference) {\n validateFederalRevenueReference(options.reference);\n return { reference: options.reference, mode: \"explicit\" };\n }\n\n if (options.current) {\n return { reference: getCurrentFederalRevenueReference(), mode: \"current\" };\n }\n\n const selection = await resolveFederalRevenueReference(\n options as FederalRevenueClientOptions,\n );\n\n return { reference: selection.selectedReference, mode: selection.mode };\n}\n\nfunction resolveCleanMode(\n options: FederalRevenueCleanOptions,\n): FederalRevenueCleanMode {\n const modes: FederalRevenueCleanMode[] = [];\n\n if (options.partials) {\n modes.push(\"partials\");\n }\n\n if (options.failed) {\n modes.push(\"failed\");\n }\n\n if (options.all) {\n modes.push(\"all\");\n }\n\n if (modes.length !== 1) {\n throw new ValidationError(\n \"Federal Revenue cleanup requires exactly one cleanup mode: --partials, --failed, or --all.\",\n );\n }\n\n return modes[0]!;\n}\n\nfunction shouldCleanFailedEntry(file: FederalRevenueManifestFile): boolean {\n return file.status === \"failed\" || file.status === \"partial\";\n}\n\nexport async function cleanFederalRevenueDataset(\n options: FederalRevenueCleanOptions = {},\n): Promise<FederalRevenueCleanSummary> {\n const startedAt = new Date().toISOString();\n const cleanMode = resolveCleanMode(options);\n const selection = await resolveCleanReference(options);\n const outputPath = buildFederalRevenueReferenceOutputPath(\n selection.reference,\n options.outputPath,\n );\n const manifestPath = getFederalRevenueManifestPath(outputPath);\n const removedPaths: string[] = [];\n let removedBytes = 0;\n const warnings: string[] = [];\n\n if (cleanMode === \"all\") {\n const outputStat = await safeStat(outputPath);\n if (outputStat.exists) {\n await rm(outputPath, { recursive: true, force: true });\n removedPaths.push(outputPath);\n removedBytes += outputStat.size;\n } else {\n warnings.push(\n \"The selected Federal Revenue reference folder does not exist locally.\",\n );\n }\n\n return {\n reference: selection.reference,\n selectionMode: selection.mode,\n outputPath,\n manifestPath,\n mode: cleanMode,\n removedFiles: removedPaths.length,\n removedBytes,\n removedPaths,\n warnings,\n startedAt,\n finishedAt: new Date().toISOString(),\n };\n }\n\n if (cleanMode === \"partials\") {\n const partialFiles = await listPartialFiles(outputPath);\n\n for (const partialFile of partialFiles) {\n const result = await removeFileIfExists(partialFile);\n if (result.removed) {\n removedPaths.push(partialFile);\n removedBytes += result.size;\n }\n }\n\n if (partialFiles.length === 0) {\n warnings.push(\"No partial Federal Revenue download files were found.\");\n }\n }\n\n if (cleanMode === \"failed\") {\n const manifest = await readFederalRevenueManifest(outputPath);\n\n if (!manifest) {\n warnings.push(\n \"No local Federal Revenue manifest was found for this reference.\",\n );\n } else {\n for (const file of manifest.files.filter(shouldCleanFailedEntry)) {\n for (const candidate of [file.filePath, file.partialFilePath]) {\n const result = await removeFileIfExists(candidate);\n if (result.removed) {\n removedPaths.push(candidate);\n removedBytes += result.size;\n }\n }\n }\n\n manifest.updatedAt = new Date().toISOString();\n manifest.files = manifest.files.map((file) => {\n if (!shouldCleanFailedEntry(file)) {\n return file;\n }\n\n const updatedFile: FederalRevenueManifestFile = {\n ...file,\n status: \"missing\",\n updatedAt: manifest.updatedAt,\n };\n delete updatedFile.localSizeInBytes;\n delete updatedFile.errorMessage;\n delete updatedFile.downloadedAt;\n return updatedFile;\n });\n await writeFederalRevenueManifest(manifest);\n }\n\n if (removedPaths.length === 0 && warnings.length === 0) {\n warnings.push(\"No failed or partial Federal Revenue files were found.\");\n }\n }\n\n return {\n reference: selection.reference,\n selectionMode: selection.mode,\n outputPath,\n manifestPath,\n mode: cleanMode,\n removedFiles: removedPaths.length,\n removedBytes,\n removedPaths,\n warnings,\n startedAt,\n finishedAt: new Date().toISOString(),\n };\n}\n","import { mkdir, open, readFile, unlink } from \"node:fs/promises\";\nimport { randomUUID } from \"node:crypto\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport {\n getFederalRevenueControlDirectory,\n getFederalRevenueSyncLockPath,\n} from \"./manifest.js\";\nimport type {\n FederalRevenueLockFile,\n FederalRevenueSyncLockOptions,\n} from \"./types.js\";\n\nasync function readLock(\n lockPath: string,\n): Promise<FederalRevenueLockFile | undefined> {\n try {\n return JSON.parse(\n await readFile(lockPath, \"utf8\"),\n ) as FederalRevenueLockFile;\n } catch {\n return undefined;\n }\n}\n\nasync function removeLock(lockPath: string): Promise<void> {\n try {\n await unlink(lockPath);\n } catch {\n // Ignore missing lock files. The next exclusive write still validates the lock state.\n }\n}\n\nexport async function withFederalRevenueSyncLock<T>(\n input: {\n reference: string;\n outputPath: string;\n options?: FederalRevenueSyncLockOptions | undefined;\n },\n callback: () => Promise<T>,\n): Promise<T> {\n const lockPath = getFederalRevenueSyncLockPath(input.outputPath);\n const token = randomUUID();\n const lockFile: FederalRevenueLockFile = {\n reference: input.reference,\n outputPath: input.outputPath,\n lockPath,\n pid: process.pid,\n token,\n startedAt: new Date().toISOString(),\n };\n\n await mkdir(getFederalRevenueControlDirectory(input.outputPath), {\n recursive: true,\n });\n\n if (input.options?.forceLock) {\n await removeLock(lockPath);\n }\n\n let handle: Awaited<ReturnType<typeof open>> | undefined;\n\n try {\n handle = await open(lockPath, \"wx\");\n await handle.writeFile(`${JSON.stringify(lockFile, null, 2)}\\n`, \"utf8\");\n } catch {\n const existingLock = await readLock(lockPath);\n throw new ValidationError(\n `Federal Revenue sync is already running for ${existingLock?.reference ?? input.reference}. Use --force-lock only if the previous process is no longer active.`,\n {\n lockPath,\n pid: existingLock?.pid,\n startedAt: existingLock?.startedAt,\n },\n );\n } finally {\n await handle?.close();\n }\n\n try {\n return await callback();\n } finally {\n const currentLock = await readLock(lockPath);\n if (currentLock?.token === token) {\n await removeLock(lockPath);\n }\n }\n}\n","export type {\n SanitizeDatasetType,\n SanitizeOptions,\n SanitizePlan,\n SanitizeProgressEvent,\n SanitizeProgressListener,\n SanitizeSourceEncoding,\n SanitizeSummary,\n} from \"./sanitize/types.js\";\n\nimport path from \"node:path\";\n\nimport { ValidationError } from \"../core/errors/index.js\";\nimport { inspectFiles } from \"./inspect.service.js\";\nimport { validateInputDirectory } from \"./validate.service.js\";\nimport { buildDisplayPath } from \"./import/planning.js\";\nimport type {\n SanitizeDatasetType,\n SanitizeFilePlan,\n SanitizeOptions,\n SanitizePlan,\n SanitizeSummary,\n} from \"./sanitize/types.js\";\nimport {\n isRecognizedSanitizeEntry,\n isSanitizeDatasetType,\n} from \"./sanitize/types.js\";\nimport { normalizeSanitizeSourceEncoding } from \"./sanitize/encoding.js\";\nimport { sanitizeDatasetFile } from \"./sanitize/runner.js\";\n\nfunction defaultSanitizedOutputPath(validatedPath: string): string {\n const baseName = path.basename(validatedPath);\n if (baseName.toLowerCase() === \"extracted\") {\n return path.join(path.dirname(validatedPath), \"sanitized\");\n }\n\n return path.join(path.dirname(validatedPath), `${baseName}-sanitized`);\n}\n\nfunction inferNextStep(outputPath: string): string {\n return `cnpj-db-loader import ${outputPath.replace(/\\\\/g, \"/\")}`;\n}\n\nfunction buildSanitizePlan(\n validatedPath: string,\n outputPath: string,\n inspectedPath: Awaited<ReturnType<typeof inspectFiles>>,\n selectedDataset?: SanitizeDatasetType,\n): SanitizePlan {\n const files = inspectedPath.entries\n .filter(isRecognizedSanitizeEntry)\n .filter(\n (entry) => !selectedDataset || entry.inferredType === selectedDataset,\n )\n .map<SanitizeFilePlan>((entry) => ({\n dataset: entry.inferredType,\n relativePath: entry.relativePath,\n absolutePath: path.join(validatedPath, entry.relativePath),\n outputPath: path.join(outputPath, entry.relativePath),\n displayPath: buildDisplayPath(\n path.join(validatedPath, entry.relativePath),\n ),\n fileSize: entry.size,\n }));\n\n return {\n validatedPath,\n outputPath,\n totalFiles: files.length,\n totalBytes: files.reduce((sum, item) => sum + item.fileSize, 0),\n datasets: [...new Set(files.map((item) => item.dataset))],\n files,\n };\n}\n\nexport async function sanitizeInputDirectory(\n inputPath: string,\n options: SanitizeOptions = {},\n): Promise<SanitizeSummary> {\n if (options.dataset && !isSanitizeDatasetType(options.dataset)) {\n throw new ValidationError(`Unsupported dataset type: ${options.dataset}.`);\n }\n\n const validation = await validateInputDirectory(inputPath);\n if (!validation.ok) {\n throw new ValidationError(\n `The input directory is not ready for sanitization. ${validation.errors.join(\" \")}`,\n );\n }\n\n const validatedPath = validation.validatedPath;\n const outputPath = path.resolve(\n options.outputPath ?? defaultSanitizedOutputPath(validatedPath),\n );\n const inspectedValidatedPath = await inspectFiles(validatedPath);\n const plan = buildSanitizePlan(\n validatedPath,\n outputPath,\n inspectedValidatedPath,\n options.dataset,\n );\n\n if (plan.totalFiles === 0) {\n throw new ValidationError(\n \"No recognized validated dataset files were found for sanitization.\",\n );\n }\n\n const sourceEncoding = normalizeSanitizeSourceEncoding(\n options.sourceEncoding,\n );\n\n options.onProgress?.({\n kind: \"start\",\n validatedPath,\n outputPath,\n totalFiles: plan.totalFiles,\n totalBytes: plan.totalBytes,\n datasets: plan.datasets,\n sourceEncoding,\n });\n\n let processedFiles = 0;\n let processedRows = 0;\n let processedBytes = 0;\n let nulBytesRemoved = 0;\n let invalidBytesRemoved = 0;\n let controlCharsRemoved = 0;\n let changedFiles = 0;\n const fileSummaries: SanitizeSummary[\"files\"] = [];\n\n for (const [index, filePlan] of plan.files.entries()) {\n const fileResult = await sanitizeDatasetFile(\n filePlan,\n (chunk) => {\n options.onProgress?.({\n kind: \"progress\",\n currentFileDisplayPath: filePlan.displayPath,\n fileIndex: index + 1,\n totalFiles: plan.totalFiles,\n bytesProcessed: processedBytes + chunk.fileBytesProcessed,\n totalBytes: plan.totalBytes,\n fileBytesProcessed: chunk.fileBytesProcessed,\n currentFileSize: chunk.currentFileSize,\n processedRows: processedRows + chunk.processedRows,\n nulBytesRemoved: nulBytesRemoved + chunk.nulBytesRemoved,\n invalidBytesRemoved: invalidBytesRemoved + chunk.invalidBytesRemoved,\n controlCharsRemoved: controlCharsRemoved + chunk.controlCharsRemoved,\n changedFiles,\n });\n },\n { sourceEncoding },\n );\n\n processedFiles += 1;\n processedRows += fileResult.lineCount;\n processedBytes += fileResult.totalBytesRead;\n nulBytesRemoved += fileResult.nulBytesRemoved;\n invalidBytesRemoved += fileResult.invalidBytesRemoved;\n controlCharsRemoved += fileResult.controlCharsRemoved;\n changedFiles += fileResult.changed ? 1 : 0;\n\n fileSummaries.push({\n dataset: filePlan.dataset,\n relativePath: filePlan.relativePath,\n outputPath: filePlan.outputPath,\n lineCount: fileResult.lineCount,\n changed: fileResult.changed,\n nulBytesRemoved: fileResult.nulBytesRemoved,\n invalidBytesRemoved: fileResult.invalidBytesRemoved,\n controlCharsRemoved: fileResult.controlCharsRemoved,\n });\n }\n\n options.onProgress?.({\n kind: \"finish\",\n totalFiles: plan.totalFiles,\n processedRows,\n nulBytesRemoved,\n invalidBytesRemoved,\n controlCharsRemoved,\n changedFiles,\n totalBytes: plan.totalBytes,\n });\n\n return {\n inputPath: path.resolve(inputPath),\n validatedPath,\n outputPath,\n totalFiles: plan.totalFiles,\n totalBytes: plan.totalBytes,\n processedFiles,\n processedRows,\n sourceEncoding,\n nulBytesRemoved,\n invalidBytesRemoved,\n controlCharsRemoved,\n changedFiles,\n unchangedFiles: plan.totalFiles - changedFiles,\n datasets: plan.datasets,\n files: fileSummaries,\n warnings: [\n \"Sanitization now writes UTF-8 output and removes invalid bytes plus problematic control characters before PostgreSQL loading begins.\",\n \"The PostgreSQL direct import path can use --source-encoding UTF8 when reading files generated by this sanitization command.\",\n \"The import command still keeps quarantine and row-level recovery for unexpected issues, but sanitizing first reduces the amount of slow fallback work during import.\",\n ],\n nextStep: inferNextStep(outputPath),\n };\n}\n","import type { DatasetType, FileInspection } from \"../inspect.service.js\";\nimport type { SanitizeSourceEncoding } from \"./encoding.js\";\nexport type { SanitizeSourceEncoding } from \"./encoding.js\";\n\nexport type SanitizeDatasetType = Exclude<\n DatasetType,\n \"zip-archive\" | \"unknown\"\n>;\n\nexport type SanitizeFilePlan = {\n dataset: SanitizeDatasetType;\n relativePath: string;\n absolutePath: string;\n outputPath: string;\n displayPath: string;\n fileSize: number;\n};\n\nexport type SanitizePlan = {\n validatedPath: string;\n outputPath: string;\n totalFiles: number;\n totalBytes: number;\n datasets: SanitizeDatasetType[];\n files: SanitizeFilePlan[];\n};\n\nexport type SanitizedFileResult = {\n plan: SanitizeFilePlan;\n totalBytesRead: number;\n totalBytesWritten: number;\n sourceEncoding: SanitizeSourceEncoding;\n nulBytesRemoved: number;\n invalidBytesRemoved: number;\n controlCharsRemoved: number;\n lineCount: number;\n changed: boolean;\n};\n\nexport type SanitizeSummary = {\n inputPath: string;\n validatedPath: string;\n outputPath: string;\n totalFiles: number;\n totalBytes: number;\n processedFiles: number;\n processedRows: number;\n sourceEncoding: SanitizeSourceEncoding;\n nulBytesRemoved: number;\n invalidBytesRemoved: number;\n controlCharsRemoved: number;\n changedFiles: number;\n unchangedFiles: number;\n datasets: SanitizeDatasetType[];\n files: Array<{\n dataset: SanitizeDatasetType;\n relativePath: string;\n outputPath: string;\n lineCount: number;\n changed: boolean;\n nulBytesRemoved: number;\n invalidBytesRemoved: number;\n controlCharsRemoved: number;\n }>;\n warnings: string[];\n nextStep?: string | undefined;\n};\n\nexport type SanitizeProgressEvent =\n | {\n kind: \"start\";\n validatedPath: string;\n outputPath: string;\n totalFiles: number;\n totalBytes: number;\n datasets: SanitizeDatasetType[];\n sourceEncoding: SanitizeSourceEncoding;\n }\n | {\n kind: \"progress\";\n currentFileDisplayPath: string;\n fileIndex: number;\n totalFiles: number;\n bytesProcessed: number;\n totalBytes: number;\n fileBytesProcessed: number;\n currentFileSize: number;\n processedRows: number;\n nulBytesRemoved: number;\n invalidBytesRemoved: number;\n controlCharsRemoved: number;\n changedFiles: number;\n }\n | {\n kind: \"finish\";\n totalFiles: number;\n processedRows: number;\n nulBytesRemoved: number;\n invalidBytesRemoved: number;\n controlCharsRemoved: number;\n changedFiles: number;\n totalBytes: number;\n };\n\nexport type SanitizeProgressListener = (event: SanitizeProgressEvent) => void;\n\nexport type SanitizeOptions = {\n outputPath?: string | undefined;\n dataset?: SanitizeDatasetType | undefined;\n sourceEncoding?: string | undefined;\n onProgress?: SanitizeProgressListener | undefined;\n};\n\nexport function isSanitizeDatasetType(\n value: string,\n): value is SanitizeDatasetType {\n return [\n \"companies\",\n \"establishments\",\n \"partners\",\n \"simples_options\",\n \"countries\",\n \"cities\",\n \"partner_qualifications\",\n \"legal_natures\",\n \"cnaes\",\n \"reasons\",\n ].includes(value);\n}\n\nexport function isRecognizedSanitizeEntry(\n entry: FileInspection,\n): entry is FileInspection & { inferredType: SanitizeDatasetType } {\n return (\n entry.entryKind === \"file\" &&\n entry.inferredType !== \"zip-archive\" &&\n entry.inferredType !== \"unknown\"\n );\n}\n","import { StringDecoder } from \"node:string_decoder\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\n\nexport type SanitizeSourceEncoding = \"WIN1252\" | \"LATIN1\" | \"UTF8\";\n\nexport type SanitizedTextChunk = {\n text: string;\n nulBytesRemoved: number;\n invalidBytesRemoved: number;\n controlCharsRemoved: number;\n};\n\nconst WINDOWS_1252_C1_MAP: Record<number, string | undefined> = {\n 0x80: \"€\",\n 0x82: \"‚\",\n 0x83: \"ƒ\",\n 0x84: \"„\",\n 0x85: \"…\",\n 0x86: \"†\",\n 0x87: \"‡\",\n 0x88: \"ˆ\",\n 0x89: \"‰\",\n 0x8a: \"Š\",\n 0x8b: \"‹\",\n 0x8c: \"Œ\",\n 0x8e: \"Ž\",\n 0x91: \"‘\",\n 0x92: \"’\",\n 0x93: \"“\",\n 0x94: \"”\",\n 0x95: \"•\",\n 0x96: \"–\",\n 0x97: \"—\",\n 0x98: \"˜\",\n 0x99: \"™\",\n 0x9a: \"š\",\n 0x9b: \"›\",\n 0x9c: \"œ\",\n 0x9e: \"ž\",\n 0x9f: \"Ÿ\",\n};\n\nexport function normalizeSanitizeSourceEncoding(\n value: string | undefined,\n): SanitizeSourceEncoding {\n const normalized = (value ?? \"WIN1252\")\n .trim()\n .toUpperCase()\n .replace(/_/g, \"-\");\n\n switch (normalized) {\n case \"WIN1252\":\n case \"WINDOWS-1252\":\n case \"CP1252\":\n return \"WIN1252\";\n case \"LATIN1\":\n case \"LATIN-1\":\n case \"ISO-8859-1\":\n case \"ISO8859-1\":\n return \"LATIN1\";\n case \"UTF8\":\n case \"UTF-8\":\n return \"UTF8\";\n default:\n throw new ValidationError(\n `Unsupported sanitize source encoding: ${value}. Supported values: WIN1252, LATIN1, UTF8.`,\n );\n }\n}\n\nfunction isAllowedControlCodePoint(codePoint: number): boolean {\n return codePoint === 0x09 || codePoint === 0x0a || codePoint === 0x0d;\n}\n\nfunction isProblematicControlCodePoint(codePoint: number): boolean {\n if (isAllowedControlCodePoint(codePoint)) {\n return false;\n }\n\n return (\n (codePoint >= 0x00 && codePoint <= 0x1f) ||\n codePoint === 0x7f ||\n (codePoint >= 0x80 && codePoint <= 0x9f) ||\n codePoint === 0xfeff\n );\n}\n\nfunction sanitizeDecodedText(\n text: string,\n): Omit<SanitizedTextChunk, \"nulBytesRemoved\"> {\n const output: string[] = [];\n let invalidBytesRemoved = 0;\n let controlCharsRemoved = 0;\n\n for (const char of text) {\n const codePoint = char.codePointAt(0)!;\n\n if (codePoint === 0xfffd) {\n invalidBytesRemoved += 1;\n continue;\n }\n\n if (isProblematicControlCodePoint(codePoint)) {\n controlCharsRemoved += 1;\n continue;\n }\n\n output.push(char);\n }\n\n return {\n text: output.join(\"\"),\n invalidBytesRemoved,\n controlCharsRemoved,\n };\n}\n\nexport class SanitizeEncodingNormalizer {\n private readonly utf8Decoder: StringDecoder | undefined;\n\n constructor(private readonly sourceEncoding: SanitizeSourceEncoding) {\n this.utf8Decoder =\n sourceEncoding === \"UTF8\" ? new StringDecoder(\"utf8\") : undefined;\n }\n\n normalizeChunk(chunk: Buffer): SanitizedTextChunk {\n if (this.sourceEncoding === \"UTF8\") {\n const decoded = this.utf8Decoder!.write(chunk);\n const sanitized = sanitizeDecodedText(decoded);\n const nulBytesRemoved = [...decoded].filter(\n (char) => char === \"\\0\",\n ).length;\n\n return {\n ...sanitized,\n nulBytesRemoved,\n };\n }\n\n return this.normalizeSingleByteChunk(chunk);\n }\n\n flush(): SanitizedTextChunk {\n if (!this.utf8Decoder) {\n return {\n text: \"\",\n nulBytesRemoved: 0,\n invalidBytesRemoved: 0,\n controlCharsRemoved: 0,\n };\n }\n\n const decoded = this.utf8Decoder.end();\n const sanitized = sanitizeDecodedText(decoded);\n const nulBytesRemoved = [...decoded].filter((char) => char === \"\\0\").length;\n\n return {\n ...sanitized,\n nulBytesRemoved,\n };\n }\n\n private normalizeSingleByteChunk(chunk: Buffer): SanitizedTextChunk {\n const output: string[] = [];\n let nulBytesRemoved = 0;\n let invalidBytesRemoved = 0;\n let controlCharsRemoved = 0;\n\n for (const byte of chunk) {\n if (byte === 0x00) {\n nulBytesRemoved += 1;\n continue;\n }\n\n if (byte < 0x20 || byte === 0x7f) {\n if (isAllowedControlCodePoint(byte)) {\n output.push(String.fromCharCode(byte));\n } else {\n controlCharsRemoved += 1;\n }\n continue;\n }\n\n if (byte >= 0x80 && byte <= 0x9f) {\n if (this.sourceEncoding === \"WIN1252\") {\n const mapped = WINDOWS_1252_C1_MAP[byte];\n if (mapped === undefined) {\n invalidBytesRemoved += 1;\n } else {\n output.push(mapped);\n }\n } else {\n controlCharsRemoved += 1;\n }\n continue;\n }\n\n output.push(String.fromCharCode(byte));\n }\n\n return {\n text: output.join(\"\"),\n nulBytesRemoved,\n invalidBytesRemoved,\n controlCharsRemoved,\n };\n }\n}\n","import { createReadStream, createWriteStream } from \"node:fs\";\nimport { mkdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport {\n normalizeSanitizeSourceEncoding,\n SanitizeEncodingNormalizer,\n} from \"./encoding.js\";\nimport type { SanitizeFilePlan, SanitizedFileResult } from \"./types.js\";\n\nasync function writeUtf8(\n output: ReturnType<typeof createWriteStream>,\n value: string,\n): Promise<void> {\n if (value.length === 0) {\n return;\n }\n\n if (!output.write(value, \"utf8\")) {\n await new Promise<void>((resolve, reject) => {\n output.once(\"drain\", resolve);\n output.once(\"error\", reject);\n });\n }\n}\n\nfunction countNewlines(value: string): number {\n let count = 0;\n\n for (let index = 0; index < value.length; index += 1) {\n if (value[index] === \"\\n\") {\n count += 1;\n }\n }\n\n return count;\n}\n\nexport async function sanitizeDatasetFile(\n plan: SanitizeFilePlan,\n onChunk?: (update: {\n bytesProcessed: number;\n fileBytesProcessed: number;\n currentFileSize: number;\n processedRows: number;\n nulBytesRemoved: number;\n invalidBytesRemoved: number;\n controlCharsRemoved: number;\n }) => void,\n options: { sourceEncoding?: string | undefined } = {},\n): Promise<SanitizedFileResult> {\n await mkdir(path.dirname(plan.outputPath), { recursive: true });\n\n const sourceEncoding = normalizeSanitizeSourceEncoding(\n options.sourceEncoding,\n );\n const normalizer = new SanitizeEncodingNormalizer(sourceEncoding);\n const input = createReadStream(plan.absolutePath);\n const output = createWriteStream(plan.outputPath, { encoding: \"utf8\" });\n\n let totalBytesRead = 0;\n let totalBytesWritten = 0;\n let nulBytesRemoved = 0;\n let invalidBytesRemoved = 0;\n let controlCharsRemoved = 0;\n let lineCount = 0;\n let sawAnyCharacter = false;\n let lastCharacterWasNewline = false;\n\n const processText = async (text: string): Promise<void> => {\n if (text.length === 0) {\n return;\n }\n\n sawAnyCharacter = true;\n lineCount += countNewlines(text);\n lastCharacterWasNewline = text.endsWith(\"\\n\");\n totalBytesWritten += Buffer.byteLength(text, \"utf8\");\n await writeUtf8(output, text);\n };\n\n try {\n for await (const chunk of input) {\n const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n totalBytesRead += chunkBuffer.length;\n\n const normalized = normalizer.normalizeChunk(chunkBuffer);\n nulBytesRemoved += normalized.nulBytesRemoved;\n invalidBytesRemoved += normalized.invalidBytesRemoved;\n controlCharsRemoved += normalized.controlCharsRemoved;\n await processText(normalized.text);\n\n onChunk?.({\n bytesProcessed: chunkBuffer.length,\n fileBytesProcessed: totalBytesRead,\n currentFileSize: plan.fileSize,\n processedRows: lineCount,\n nulBytesRemoved,\n invalidBytesRemoved,\n controlCharsRemoved,\n });\n }\n\n const flushed = normalizer.flush();\n nulBytesRemoved += flushed.nulBytesRemoved;\n invalidBytesRemoved += flushed.invalidBytesRemoved;\n controlCharsRemoved += flushed.controlCharsRemoved;\n await processText(flushed.text);\n\n if (sawAnyCharacter && !lastCharacterWasNewline) {\n lineCount += 1;\n }\n } finally {\n input.close();\n output.end();\n await new Promise<void>((resolve, reject) => {\n output.on(\"finish\", () => resolve());\n output.on(\"error\", (error) => reject(error));\n });\n }\n\n return {\n plan,\n totalBytesRead,\n totalBytesWritten,\n sourceEncoding,\n nulBytesRemoved,\n invalidBytesRemoved,\n controlCharsRemoved,\n lineCount,\n changed:\n nulBytesRemoved > 0 ||\n invalidBytesRemoved > 0 ||\n controlCharsRemoved > 0 ||\n totalBytesRead !== totalBytesWritten,\n };\n}\n","import { ValidationError } from \"../../core/errors/index.js\";\nimport { extractArchives } from \"../extract.service.js\";\nimport { importDataToDatabase } from \"../import.service.js\";\nimport { sanitizeInputDirectory } from \"../sanitize.service.js\";\nimport { validateInputDirectory } from \"../validate.service.js\";\nimport {\n checkFederalRevenueDataset,\n downloadFederalRevenueDataset,\n} from \"./download.js\";\nimport { withFederalRevenueSyncLock } from \"./lock.js\";\nimport { buildFederalRevenueReferenceOutputPath } from \"./manifest.js\";\nimport type {\n FederalRevenueDownloadOptions,\n FederalRevenueSyncOptions,\n FederalRevenueSyncSummary,\n} from \"./types.js\";\n\nfunction buildLockedDownloadOptions(\n options: FederalRevenueSyncOptions,\n reference: string,\n): FederalRevenueDownloadOptions {\n const { current, forceLock, ...downloadOptions } = options;\n void current;\n void forceLock;\n\n return {\n ...downloadOptions,\n reference,\n manifestCommand: \"sync\",\n };\n}\n\nasync function runFederalRevenueSyncPipeline(\n options: FederalRevenueSyncOptions,\n reference: string,\n): Promise<FederalRevenueSyncSummary> {\n const startedAt = new Date().toISOString();\n const download = await downloadFederalRevenueDataset(\n buildLockedDownloadOptions(options, reference),\n );\n\n if (download.failedFiles > 0) {\n throw new ValidationError(\n `Federal Revenue sync cannot continue because ${download.failedFiles} file(s) failed to download. Run federal-revenue retry ${download.reference} after fixing the cause.`,\n { reference: download.reference, outputPath: download.outputPath },\n );\n }\n\n if (download.partialFiles > 0 || download.missingFiles > 0) {\n throw new ValidationError(\n `Federal Revenue sync cannot continue because the local reference is incomplete. Partial files: ${download.partialFiles}. Missing files: ${download.missingFiles}.`,\n {\n reference: download.reference,\n outputPath: download.outputPath,\n partialFiles: download.partialFiles,\n missingFiles: download.missingFiles,\n },\n );\n }\n\n const extraction = await extractArchives(\n download.outputPath,\n options.extractOutputPath,\n options.onExtractProgress,\n );\n\n if (extraction.failedArchives.length > 0) {\n throw new ValidationError(\n `Federal Revenue sync cannot continue because ${extraction.failedArchives.length} archive(s) failed to extract.`,\n {\n reference: download.reference,\n failedArchives: extraction.failedArchives,\n outputPath: extraction.outputPath,\n },\n );\n }\n\n const validation = await validateInputDirectory(extraction.outputPath);\n if (!validation.ok) {\n throw new ValidationError(\n `Federal Revenue sync cannot continue because the extracted dataset is not valid. ${validation.errors.join(\" \")}`,\n { reference: download.reference, errors: validation.errors },\n );\n }\n\n const sanitization = await sanitizeInputDirectory(extraction.outputPath, {\n ...options.sanitizeOptions,\n outputPath: options.sanitizeOutputPath,\n onProgress: options.onSanitizeProgress,\n });\n\n const importSummary = await importDataToDatabase(sanitization.outputPath, {\n ...options.importOptions,\n onProgress: options.onImportProgress,\n });\n\n return {\n reference: download.reference,\n download,\n extraction,\n validation,\n sanitization,\n import: importSummary,\n startedAt,\n finishedAt: new Date().toISOString(),\n warnings: [\n ...download.warnings,\n ...validation.warnings,\n ...sanitization.warnings,\n ...importSummary.warnings,\n ],\n };\n}\n\nexport async function syncFederalRevenueDataset(\n options: FederalRevenueSyncOptions = {},\n): Promise<FederalRevenueSyncSummary> {\n const check = await checkFederalRevenueDataset(options);\n const outputPath = buildFederalRevenueReferenceOutputPath(\n check.selectedReference,\n options.outputPath,\n );\n\n return withFederalRevenueSyncLock(\n {\n reference: check.selectedReference,\n outputPath,\n options: { forceLock: options.forceLock },\n },\n () => runFederalRevenueSyncPipeline(options, check.selectedReference),\n );\n}\n","import { createWriteStream } from \"node:fs\";\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport { inspectFiles } from \"../inspect.service.js\";\nimport { validateInputDirectory } from \"../validate.service.js\";\nimport { buildDisplayPath, sortEntries } from \"../import/planning.js\";\nimport { readImportSourceLines } from \"../import/source-reader.js\";\nimport { parseImportSourceLine } from \"../import/parser.js\";\nimport {\n DATASET_LAYOUTS,\n IMPORT_ORDER,\n isImportDatasetType,\n type ImportDatasetType,\n type ImportSchemaCapabilities,\n} from \"../import/types.js\";\nimport { normalizeFieldCount, transformRecord } from \"../import/transform.js\";\nimport { formatCsvRow } from \"./csv.js\";\nimport { generatePostgresDirectImportScript } from \"./script.js\";\nimport type {\n PostgresCsvDatasetSummary,\n PostgresCsvExportOptions,\n PostgresCsvExportSummary,\n PostgresCsvFile,\n} from \"./types.js\";\n\nconst POSTGRES_DIRECT_SCHEMA_CAPABILITIES: ImportSchemaCapabilities = {\n includeEstablishmentCnpjFullInInsert: true,\n includeEstablishmentSecondaryCnaesTable: true,\n includePartnerDedupeKeyInInsert: true,\n requiresLookupReconciliation: false,\n};\n\nfunction defaultPostgresCsvOutputPath(inputPath: string): string {\n const baseName = path.basename(inputPath);\n return path.join(path.dirname(inputPath), `${baseName}-postgres-csv`);\n}\n\nfunction normalizeOutputFileName(relativePath: string): string {\n const parsed = path.parse(relativePath);\n const baseName = parsed.name || parsed.base || \"dataset\";\n return path.join(parsed.dir, `${baseName}.csv`);\n}\n\nfunction resolveDatasetOutputPath(\n outputPath: string,\n dataset: ImportDatasetType,\n relativePath: string,\n): string {\n return path.join(outputPath, dataset, normalizeOutputFileName(relativePath));\n}\n\nfunction inferNextStep(scriptPath: string): string {\n return `psql \"postgres://postgres:postgres@localhost:5432/cnpj\" -f ${scriptPath.replace(/\\\\/g, \"/\")}`;\n}\n\nasync function writeCsvFile(input: {\n dataset: ImportDatasetType;\n inputFile: string;\n outputFile: string;\n}): Promise<number> {\n const layout = DATASET_LAYOUTS[input.dataset];\n const columns = layout.fields.map((field) => field.columnName);\n\n await mkdir(path.dirname(input.outputFile), { recursive: true });\n\n const output = createWriteStream(input.outputFile, { encoding: \"utf8\" });\n let rows = 0;\n\n try {\n output.write(`${formatCsvRow(columns)}\\n`);\n\n for await (const sourceLine of readImportSourceLines(input.inputFile)) {\n if (sourceLine.rawLine.trim() === \"\") {\n continue;\n }\n\n const parsed = parseImportSourceLine(sourceLine);\n const normalizedFields = normalizeFieldCount(\n parsed.fields,\n layout.fields.length,\n input.inputFile,\n parsed.lineNumber,\n );\n const values = transformRecord(\n input.dataset,\n layout,\n normalizedFields,\n POSTGRES_DIRECT_SCHEMA_CAPABILITIES,\n \"staging\",\n );\n\n output.write(`${formatCsvRow(values)}\\n`);\n rows += 1;\n }\n } finally {\n output.end();\n await new Promise<void>((resolve, reject) => {\n output.on(\"finish\", () => resolve());\n output.on(\"error\", (error) => reject(error));\n });\n }\n\n return rows;\n}\n\nexport async function exportPostgresCsvDataset(\n inputPath: string,\n options: PostgresCsvExportOptions = {},\n): Promise<PostgresCsvExportSummary> {\n if (options.dataset && !isImportDatasetType(options.dataset)) {\n throw new ValidationError(`Unsupported dataset type: ${options.dataset}.`);\n }\n\n const validation = await validateInputDirectory(inputPath);\n if (!validation.ok) {\n throw new ValidationError(\n `The input directory is not ready for PostgreSQL CSV export. ${validation.errors.join(\" \")}`,\n );\n }\n\n const validatedPath = validation.validatedPath;\n const outputPath = path.resolve(\n options.outputPath ?? defaultPostgresCsvOutputPath(validatedPath),\n );\n const inspected = await inspectFiles(validatedPath);\n const recognizedFiles = inspected.entries\n .filter((entry) => entry.entryKind === \"file\")\n .flatMap((entry) => {\n if (!isImportDatasetType(entry.inferredType)) {\n return [];\n }\n\n if (options.dataset && entry.inferredType !== options.dataset) {\n return [];\n }\n\n return [{ ...entry, inferredType: entry.inferredType }];\n })\n .sort(sortEntries);\n\n if (recognizedFiles.length === 0) {\n throw new ValidationError(\n \"No recognized dataset files were found for PostgreSQL CSV export.\",\n );\n }\n\n const datasets = [\n ...new Set(recognizedFiles.map((entry) => entry.inferredType)),\n ].sort(\n (left, right) => IMPORT_ORDER.indexOf(left) - IMPORT_ORDER.indexOf(right),\n );\n\n options.onProgress?.({\n kind: \"start\",\n inputPath: path.resolve(inputPath),\n validatedPath,\n outputPath,\n totalFiles: recognizedFiles.length,\n datasets,\n });\n\n const exportedFiles: PostgresCsvFile[] = [];\n const summariesByDataset = new Map<\n ImportDatasetType,\n PostgresCsvDatasetSummary\n >();\n\n for (const [index, entry] of recognizedFiles.entries()) {\n const dataset = entry.inferredType;\n const inputFile = path.join(validatedPath, entry.relativePath);\n const outputFile = resolveDatasetOutputPath(\n outputPath,\n dataset,\n entry.relativePath,\n );\n\n options.onProgress?.({\n kind: \"file_start\",\n dataset,\n fileIndex: index + 1,\n totalFiles: recognizedFiles.length,\n inputFile: buildDisplayPath(inputFile),\n outputFile,\n });\n\n const rowCount = await writeCsvFile({ dataset, inputFile, outputFile });\n\n exportedFiles.push({\n dataset,\n absolutePath: outputFile,\n relativePath: path.relative(outputPath, outputFile),\n rowCount,\n });\n\n const currentSummary = summariesByDataset.get(dataset) ?? {\n dataset,\n files: 0,\n rows: 0,\n outputFiles: [],\n };\n currentSummary.files += 1;\n currentSummary.rows += rowCount;\n currentSummary.outputFiles.push(outputFile);\n summariesByDataset.set(dataset, currentSummary);\n\n options.onProgress?.({\n kind: \"file_finish\",\n dataset,\n fileIndex: index + 1,\n totalFiles: recognizedFiles.length,\n inputFile: buildDisplayPath(inputFile),\n outputFile,\n rows: rowCount,\n });\n }\n\n const scriptName = options.scriptName ?? \"import-postgres-direct.sql\";\n const scriptPath = path.join(outputPath, scriptName);\n const script = generatePostgresDirectImportScript({ files: exportedFiles });\n await writeFile(scriptPath, script, \"utf8\");\n\n const manifestPath = path.join(outputPath, \"manifest.json\");\n const summaryDatasets = [...summariesByDataset.values()].sort(\n (left, right) =>\n IMPORT_ORDER.indexOf(left.dataset) - IMPORT_ORDER.indexOf(right.dataset),\n );\n const totalRows = summaryDatasets.reduce((sum, item) => sum + item.rows, 0);\n\n const manifest = {\n generatedAt: new Date().toISOString(),\n inputPath: path.resolve(inputPath),\n validatedPath,\n outputPath,\n scriptPath,\n totalFiles: exportedFiles.length,\n totalRows,\n datasets: summaryDatasets,\n };\n await writeFile(\n manifestPath,\n `${JSON.stringify(manifest, null, 2)}\\n`,\n \"utf8\",\n );\n\n options.onProgress?.({\n kind: \"finish\",\n outputPath,\n scriptPath,\n totalFiles: exportedFiles.length,\n totalRows,\n });\n\n return {\n inputPath: path.resolve(inputPath),\n validatedPath,\n outputPath,\n scriptPath,\n manifestPath,\n totalFiles: exportedFiles.length,\n totalRows,\n datasets: summaryDatasets,\n warnings: [\n \"PostgreSQL-ready CSV export is intended for hybrid bulk imports after extraction, validation and sanitization.\",\n \"The generated SQL script resets staging tables and then upserts final tables. Review it before running against production databases.\",\n ],\n nextStep: inferNextStep(scriptPath),\n };\n}\n","export function formatCsvValue(value: unknown): string {\n if (value === null || value === undefined) {\n return \"\";\n }\n\n if (value instanceof Date) {\n return formatCsvValue(value.toISOString());\n }\n\n const text = String(value);\n const shouldQuote = /[\",\\r\\n]/.test(text);\n\n if (!shouldQuote) {\n return text;\n }\n\n return `\"${text.replace(/\"/g, '\"\"')}\"`;\n}\n\nexport function formatCsvRow(values: readonly unknown[]): string {\n return values.map(formatCsvValue).join(\",\");\n}\n","import path from \"node:path\";\n\nimport {\n companiesLayout,\n establishmentsLayout,\n partnersLayout,\n simplesLayout,\n} from \"../../dictionary/layouts/index.js\";\nimport type { FieldDefinition } from \"../../dictionary/layouts/index.js\";\nimport type { ImportDatasetType } from \"../import/types.js\";\nimport { DATASET_LAYOUTS } from \"../import/types.js\";\nimport type { PostgresCsvFile, PostgresDirectSourceFile } from \"./types.js\";\n\ntype CsvScriptGenerationInput = {\n files: PostgresCsvFile[];\n};\n\ntype SanitizedScriptGenerationInput = {\n files: PostgresDirectSourceFile[];\n sourceEncoding: string;\n};\n\nconst STAGING_DATASETS: readonly ImportDatasetType[] = [\n \"companies\",\n \"establishments\",\n \"partners\",\n \"simples_options\",\n];\n\nconst DOMAIN_DATASETS: readonly ImportDatasetType[] = [\n \"partner_qualifications\",\n \"legal_natures\",\n \"countries\",\n \"cities\",\n \"reasons\",\n \"cnaes\",\n];\n\nconst STAGING_TABLE_BY_DATASET: Partial<Record<ImportDatasetType, string>> = {\n companies: \"staging_companies\",\n establishments: \"staging_establishments\",\n partners: \"staging_partners\",\n simples_options: \"staging_simples_options\",\n};\n\nfunction quoteSqlLiteral(value: string): string {\n return `'${value.replace(/'/g, \"''\")}'`;\n}\n\nfunction quoteIdentifier(value: string): string {\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n}\n\nfunction normalizePathForPsql(filePath: string): string {\n return path.resolve(filePath).replace(/\\\\/g, \"/\");\n}\n\nfunction csvCopyCommand(\n tableName: string,\n columns: readonly string[],\n filePath: string,\n): string {\n const normalizedFilePath = normalizePathForPsql(filePath);\n return `\\\\copy ${tableName} (${columns.join(\", \")}) from ${quoteSqlLiteral(normalizedFilePath)} with (format csv, header true, delimiter ',', quote '\"', escape '\"', null '')`;\n}\n\nfunction receitaCopyCommand(\n tableName: string,\n columns: readonly string[],\n filePath: string,\n): string {\n const normalizedFilePath = normalizePathForPsql(filePath);\n return `\\\\copy ${tableName} (${columns.join(\", \")}) from ${quoteSqlLiteral(normalizedFilePath)} with (format csv, header false, delimiter ';', quote '\"', escape '\"')`;\n}\n\nfunction datasetColumns(dataset: ImportDatasetType): string[] {\n return DATASET_LAYOUTS[dataset].fields.map((field) => field.columnName);\n}\n\nfunction updateAssignments(\n columns: readonly string[],\n excludedColumns: readonly string[],\n): string {\n return columns\n .filter((column) => !excludedColumns.includes(column))\n .map((column) => `${column} = excluded.${column}`)\n .concat([\"updated_at = now()\"])\n .join(\",\\n \");\n}\n\nfunction partnerDedupeExpression(alias: string): string {\n return [\n \"md5(\",\n ` coalesce(${alias}.cnpj_root, '') || '|' ||`,\n ` coalesce(${alias}.partner_type_code, '') || '|' ||`,\n ` coalesce(${alias}.partner_name, '') || '|' ||`,\n ` coalesce(${alias}.partner_document, '') || '|' ||`,\n ` coalesce(${alias}.partner_qualification_code, '') || '|' ||`,\n ` coalesce((${alias}.entry_date - date '2000-01-01')::text, '') || '|' ||`,\n ` coalesce(${alias}.country_code, '') || '|' ||`,\n ` coalesce(${alias}.legal_representative_document, '') || '|' ||`,\n ` coalesce(${alias}.legal_representative_name, '') || '|' ||`,\n ` coalesce(${alias}.legal_representative_qualification_code, '') || '|' ||`,\n ` coalesce(${alias}.age_group_code, '')`,\n \")\",\n ].join(\"\\n\");\n}\n\nfunction materializeCompaniesSql(): string {\n const columns = companiesLayout.fields.map((field) => field.columnName);\n\n return [\n \"\\\\echo 'Materializing companies...'\",\n \"with source as (\",\n \" select\",\n ` ${columns.map((column) => `source.${column}`).join(\",\\n \")},`,\n \" row_number() over (partition by source.cnpj_root order by source.staging_id desc) as dedupe_rank\",\n \" from staging_companies source\",\n \"),\",\n \"deduped as (\",\n \" select * from source where dedupe_rank = 1\",\n \")\",\n `insert into companies (${columns.join(\", \")})`,\n `select ${columns.join(\", \")}`,\n \"from deduped\",\n \"on conflict (cnpj_root) do update set\",\n ` ${updateAssignments(columns, [\"cnpj_root\"])};`,\n ].join(\"\\n\");\n}\n\nfunction materializeEstablishmentsSql(): string {\n const baseColumns = establishmentsLayout.fields.map(\n (field) => field.columnName,\n );\n const insertColumns = [...baseColumns, \"cnpj_full\"];\n\n return [\n \"\\\\echo 'Materializing establishments and secondary CNAEs...'\",\n \"with source as (\",\n \" select\",\n ` ${baseColumns.map((column) => `source.${column}`).join(\",\\n \")},`,\n \" source.cnpj_root || source.cnpj_order || source.cnpj_check_digits as cnpj_full,\",\n \" row_number() over (partition by source.cnpj_root || source.cnpj_order || source.cnpj_check_digits order by source.staging_id desc) as dedupe_rank\",\n \" from staging_establishments source\",\n \"),\",\n \"deduped as (\",\n \" select * from source where dedupe_rank = 1\",\n \"),\",\n \"upserted as (\",\n ` insert into establishments (${insertColumns.join(\", \")})`,\n ` select ${insertColumns.join(\", \")}`,\n \" from deduped\",\n \" on conflict (cnpj_full) do update set\",\n ` ${updateAssignments(insertColumns, [\"cnpj_root\", \"cnpj_order\", \"cnpj_check_digits\", \"cnpj_full\"])}`,\n \" returning cnpj_full\",\n \"),\",\n \"deleted_secondary_cnaes as (\",\n \" delete from establishment_secondary_cnaes target\",\n \" using (select cnpj_full from deduped) source_keys\",\n \" where target.cnpj_full = source_keys.cnpj_full\",\n \" returning 1\",\n \"),\",\n \"secondary_cnaes_source as (\",\n \" select distinct\",\n \" deduped.cnpj_full,\",\n \" btrim(cnae_code) as cnae_code\",\n \" from deduped\",\n \" cross join lateral unnest(string_to_array(deduped.secondary_cnaes_raw, ',')) as cnae_code\",\n \" where deduped.secondary_cnaes_raw is not null\",\n \" and deduped.secondary_cnaes_raw <> ''\",\n \" and btrim(cnae_code) <> ''\",\n \")\",\n \"insert into establishment_secondary_cnaes (cnpj_full, cnae_code)\",\n \"select cnpj_full, cnae_code\",\n \"from secondary_cnaes_source\",\n \"on conflict (cnpj_full, cnae_code) do nothing;\",\n ].join(\"\\n\");\n}\n\nfunction materializePartnersSql(): string {\n const baseColumns = partnersLayout.fields.map((field) => field.columnName);\n const insertColumns = [...baseColumns, \"partner_dedupe_key\"];\n\n return [\n \"\\\\echo 'Materializing partners...'\",\n \"with source as (\",\n \" select\",\n ` ${baseColumns.map((column) => `source.${column}`).join(\",\\n \")},`,\n ` ${partnerDedupeExpression(\"source\")} as partner_dedupe_key`,\n \" from staging_partners source\",\n \"),\",\n \"ranked as (\",\n \" select\",\n \" source.*,\",\n \" row_number() over (partition by source.partner_dedupe_key order by source.cnpj_root asc) as dedupe_rank\",\n \" from source\",\n \"),\",\n \"deduped as (\",\n \" select * from ranked where dedupe_rank = 1\",\n \")\",\n `insert into partners (${insertColumns.join(\", \")})`,\n `select ${insertColumns.join(\", \")}`,\n \"from deduped\",\n \"on conflict (partner_dedupe_key) do update set\",\n ` ${updateAssignments(insertColumns, [\"partner_dedupe_key\"])};`,\n ].join(\"\\n\");\n}\n\nfunction materializeSimplesSql(): string {\n const columns = simplesLayout.fields.map((field) => field.columnName);\n\n return [\n \"\\\\echo 'Materializing simples options...'\",\n \"with source as (\",\n \" select\",\n ` ${columns.map((column) => `source.${column}`).join(\",\\n \")},`,\n \" row_number() over (partition by source.cnpj_root order by source.staging_id desc) as dedupe_rank\",\n \" from staging_simples_options source\",\n \"),\",\n \"deduped as (\",\n \" select * from source where dedupe_rank = 1\",\n \")\",\n `insert into simples_options (${columns.join(\", \")})`,\n `select ${columns.join(\", \")}`,\n \"from deduped\",\n \"on conflict (cnpj_root) do update set\",\n ` ${updateAssignments(columns, [\"cnpj_root\"])};`,\n ].join(\"\\n\");\n}\n\nfunction copyDomainSql(\n dataset: ImportDatasetType,\n files: readonly PostgresCsvFile[],\n): string[] {\n if (files.length === 0) {\n return [];\n }\n\n const columns = datasetColumns(dataset);\n const tempTable = `tmp_hybrid_${dataset}`;\n const lines = [\n `\\\\echo 'Loading ${dataset} lookup data...'`,\n `drop table if exists ${tempTable};`,\n `create temporary table ${tempTable} (code text, description text);`,\n ];\n\n for (const file of files) {\n lines.push(csvCopyCommand(tempTable, columns, file.absolutePath));\n }\n\n lines.push(\n `insert into ${dataset} (${columns.join(\", \")})`,\n `select distinct on (code) ${columns.join(\", \")}`,\n `from ${tempTable}`,\n \"where code is not null and code <> ''\",\n \"order by code\",\n \"on conflict (code) do update set description = excluded.description;\",\n );\n\n return lines;\n}\n\nfunction copyStagingSql(\n dataset: ImportDatasetType,\n files: readonly PostgresCsvFile[],\n): string[] {\n if (files.length === 0) {\n return [];\n }\n\n const tableName = STAGING_TABLE_BY_DATASET[dataset];\n if (!tableName) {\n return [];\n }\n\n const columns = datasetColumns(dataset);\n return [\n `\\\\echo 'Loading ${dataset} staging data...'`,\n ...files.map((file) =>\n csvCopyCommand(tableName, columns, file.absolutePath),\n ),\n ];\n}\n\nfunction csvFilesByDataset(\n files: readonly PostgresCsvFile[],\n): Partial<Record<ImportDatasetType, PostgresCsvFile[]>> {\n const grouped: Partial<Record<ImportDatasetType, PostgresCsvFile[]>> = {};\n\n for (const file of files) {\n const items = grouped[file.dataset] ?? [];\n items.push(file);\n grouped[file.dataset] = items;\n }\n\n return grouped;\n}\n\nfunction directFilesByDataset(\n files: readonly PostgresDirectSourceFile[],\n): Partial<Record<ImportDatasetType, PostgresDirectSourceFile[]>> {\n const grouped: Partial<\n Record<ImportDatasetType, PostgresDirectSourceFile[]>\n > = {};\n\n for (const file of files) {\n const items = grouped[file.dataset] ?? [];\n items.push(file);\n grouped[file.dataset] = items;\n }\n\n return grouped;\n}\n\nfunction rawTableName(dataset: ImportDatasetType): string {\n return `tmp_hybrid_raw_${dataset}`;\n}\n\nfunction createRawTempTableSql(dataset: ImportDatasetType): string {\n const columns = DATASET_LAYOUTS[dataset].fields\n .map((field) => ` ${quoteIdentifier(field.columnName)} text`)\n .join(\",\\n\");\n\n return [\n `drop table if exists ${rawTableName(dataset)};`,\n `create temporary table ${rawTableName(dataset)} (`,\n columns,\n \");\",\n ].join(\"\\n\");\n}\n\nfunction textExpression(alias: string, column: string): string {\n return `nullif(btrim(${alias}.${quoteIdentifier(column)}), '')`;\n}\n\nfunction dateExpression(alias: string, column: string): string {\n const value = `btrim(${alias}.${quoteIdentifier(column)})`;\n return [\n \"case\",\n ` when ${value} = '' or ${value} = '00000000' then null`,\n ` when ${value} ~ '^\\\\d{8}$' then to_date(${value}, 'YYYYMMDD')`,\n \" else null\",\n \"end\",\n ].join(\" \");\n}\n\nfunction numericExpression(alias: string, column: string): string {\n const value = `btrim(${alias}.${quoteIdentifier(column)})`;\n return [\n \"case\",\n ` when ${value} = '' then null`,\n ` when ${value} like '%,%' and ${value} like '%.%' then replace(replace(${value}, '.', ''), ',', '.')::numeric`,\n ` when ${value} like '%,%' then replace(${value}, ',', '.')::numeric`,\n ` else ${value}::numeric`,\n \"end\",\n ].join(\" \");\n}\n\nfunction integerExpression(alias: string, column: string): string {\n const value = `btrim(${alias}.${quoteIdentifier(column)})`;\n return [\n \"case\",\n ` when ${value} = '' then null`,\n ` when ${value} ~ '^-?\\\\d+$' then ${value}::integer`,\n \" else null\",\n \"end\",\n ].join(\" \");\n}\n\nfunction booleanExpression(alias: string, column: string): string {\n const value = `lower(btrim(${alias}.${quoteIdentifier(column)}))`;\n return [\n \"case\",\n ` when ${value} in ('1', 'true', 't', 'y', 'yes', 's') then true`,\n ` when ${value} in ('0', 'false', 'f', 'n', 'no') then false`,\n \" else null\",\n \"end\",\n ].join(\" \");\n}\n\nfunction fieldExpression(\n dataset: ImportDatasetType,\n field: FieldDefinition,\n alias: string,\n): string {\n const column = field.columnName;\n\n if (dataset === \"companies\" && column === \"company_size_code\") {\n return `coalesce(${textExpression(alias, column)}, '00')`;\n }\n\n if (dataset === \"establishments\" && column === \"branch_type_code\") {\n return `coalesce(${textExpression(alias, column)}, '1')`;\n }\n\n if (dataset === \"establishments\" && column === \"registration_status_code\") {\n return `coalesce(${textExpression(alias, column)}, '01')`;\n }\n\n switch (field.dataType) {\n case \"date\":\n return dateExpression(alias, column);\n case \"numeric\":\n return numericExpression(alias, column);\n case \"integer\":\n return integerExpression(alias, column);\n case \"boolean\":\n return booleanExpression(alias, column);\n default:\n return textExpression(alias, column);\n }\n}\n\nfunction rawDomainSql(\n dataset: ImportDatasetType,\n files: readonly PostgresDirectSourceFile[],\n): string[] {\n if (files.length === 0) {\n return [];\n }\n\n const layout = DATASET_LAYOUTS[dataset];\n const columns = layout.fields.map((field) => field.columnName);\n const tableName = rawTableName(dataset);\n\n const lines = [\n `\\\\echo 'Loading ${dataset} lookup data directly from sanitized Receita files...'`,\n createRawTempTableSql(dataset),\n ];\n\n for (const file of files) {\n lines.push(receitaCopyCommand(tableName, columns, file.absolutePath));\n }\n\n lines.push(\n `insert into ${dataset} (${columns.join(\", \")})`,\n \"select distinct on (code)\",\n \" nullif(btrim(code), '') as code,\",\n \" nullif(btrim(description), '') as description\",\n `from ${tableName}`,\n \"where nullif(btrim(code), '') is not null\",\n \"order by code\",\n \"on conflict (code) do update set description = excluded.description;\",\n );\n\n return lines;\n}\n\nfunction rawStagingSql(\n dataset: ImportDatasetType,\n files: readonly PostgresDirectSourceFile[],\n): string[] {\n if (files.length === 0) {\n return [];\n }\n\n const targetTable = STAGING_TABLE_BY_DATASET[dataset];\n if (!targetTable) {\n return [];\n }\n\n const layout = DATASET_LAYOUTS[dataset];\n const columns = layout.fields.map((field) => field.columnName);\n const tableName = rawTableName(dataset);\n const alias = \"source\";\n const expressions = layout.fields.map(\n (field) =>\n ` ${fieldExpression(dataset, field, alias)} as ${field.columnName}`,\n );\n\n const lines = [\n `\\\\echo 'Loading ${dataset} staging data directly from sanitized Receita files...'`,\n createRawTempTableSql(dataset),\n ];\n\n for (const file of files) {\n lines.push(receitaCopyCommand(tableName, columns, file.absolutePath));\n }\n\n lines.push(\n `insert into ${targetTable} (${columns.join(\", \")})`,\n \"select\",\n expressions.join(\",\\n\"),\n `from ${tableName} ${alias};`,\n );\n\n return lines;\n}\n\nexport function generatePostgresDirectImportScript(\n input: CsvScriptGenerationInput,\n): string {\n const grouped = csvFilesByDataset(input.files);\n\n const lines = [\n \"-- CNPJ DB Loader hybrid PostgreSQL import script\",\n \"-- Generated from PostgreSQL-ready CSV files exported by cnpj-db-loader postgres export-csv.\",\n \"-- Execute with psql, for example:\",\n '-- psql \"postgres://postgres:postgres@localhost:5432/cnpj\" -f import-postgres-direct.sql',\n \"\",\n \"\\\\set ON_ERROR_STOP on\",\n \"\\\\echo 'Starting CNPJ DB Loader hybrid PostgreSQL import...'\",\n \"\",\n \"begin;\",\n \"\",\n \"-- Keep the final schema and seed data managed by sql/schema.sql.\",\n \"-- This script only resets staging tables and then upserts final data.\",\n \"truncate table staging_companies restart identity;\",\n \"truncate table staging_establishments restart identity;\",\n \"truncate table staging_partners restart identity;\",\n \"truncate table staging_simples_options restart identity;\",\n \"\",\n ];\n\n for (const dataset of DOMAIN_DATASETS) {\n lines.push(...copyDomainSql(dataset, grouped[dataset] ?? []), \"\");\n }\n\n for (const dataset of STAGING_DATASETS) {\n lines.push(...copyStagingSql(dataset, grouped[dataset] ?? []), \"\");\n }\n\n lines.push(...materializationAndAnalyzeSql());\n\n return lines.join(\"\\n\");\n}\n\nexport function generatePostgresSanitizedDirectImportScript(\n input: SanitizedScriptGenerationInput,\n): string {\n const grouped = directFilesByDataset(input.files);\n\n const lines = [\n \"-- CNPJ DB Loader direct PostgreSQL import script\",\n \"-- Generated from sanitized Receita files by cnpj-db-loader postgres generate-script.\",\n \"-- This path avoids rewriting the dataset into a second CSV tree.\",\n \"-- Execute with psql, for example:\",\n '-- psql \"postgres://postgres:postgres@localhost:5432/cnpj\" -f import-postgres-direct.sql',\n \"\",\n \"\\\\set ON_ERROR_STOP on\",\n `\\\\echo 'Using source file encoding ${input.sourceEncoding} for psql copy operations...'`,\n `set client_encoding to ${quoteSqlLiteral(input.sourceEncoding)};`,\n \"\\\\echo 'Starting CNPJ DB Loader direct PostgreSQL import from sanitized files...'\",\n \"\",\n \"begin;\",\n \"\",\n \"-- Keep the final schema and seed data managed by sql/schema.sql.\",\n \"-- This script copies sanitized Receita files into temporary raw tables,\",\n \"-- transforms values inside PostgreSQL, resets staging tables and upserts final data.\",\n \"truncate table staging_companies restart identity;\",\n \"truncate table staging_establishments restart identity;\",\n \"truncate table staging_partners restart identity;\",\n \"truncate table staging_simples_options restart identity;\",\n \"\",\n ];\n\n for (const dataset of DOMAIN_DATASETS) {\n lines.push(...rawDomainSql(dataset, grouped[dataset] ?? []), \"\");\n }\n\n for (const dataset of STAGING_DATASETS) {\n lines.push(...rawStagingSql(dataset, grouped[dataset] ?? []), \"\");\n }\n\n lines.push(...materializationAndAnalyzeSql());\n\n return lines.join(\"\\n\");\n}\n\nfunction materializationAndAnalyzeSql(): string[] {\n return [\n materializeCompaniesSql(),\n \"\",\n materializeEstablishmentsSql(),\n \"\",\n materializePartnersSql(),\n \"\",\n materializeSimplesSql(),\n \"\",\n \"\\\\echo 'Refreshing planner statistics...'\",\n \"analyze companies;\",\n \"analyze establishments;\",\n \"analyze establishment_secondary_cnaes;\",\n \"analyze partners;\",\n \"analyze simples_options;\",\n \"analyze cnaes;\",\n \"analyze cities;\",\n \"analyze countries;\",\n \"analyze legal_natures;\",\n \"analyze partner_qualifications;\",\n \"analyze reasons;\",\n \"\",\n \"commit;\",\n \"\",\n \"\\\\echo 'CNPJ DB Loader hybrid PostgreSQL import completed.'\",\n \"\",\n ];\n}\n","import { mkdir, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { ValidationError } from \"../../core/errors/index.js\";\nimport { inspectFiles } from \"../inspect.service.js\";\nimport { validateInputDirectory } from \"../validate.service.js\";\nimport { buildDisplayPath, sortEntries } from \"../import/planning.js\";\nimport {\n IMPORT_ORDER,\n isImportDatasetType,\n type ImportDatasetType,\n} from \"../import/types.js\";\nimport { generatePostgresSanitizedDirectImportScript } from \"./script.js\";\nimport type {\n PostgresDirectScriptDatasetSummary,\n PostgresDirectScriptOptions,\n PostgresDirectScriptSummary,\n PostgresDirectSourceFile,\n} from \"./types.js\";\n\nconst DEFAULT_SOURCE_ENCODING = \"UTF8\";\n\nfunction defaultPostgresDirectOutputPath(inputPath: string): string {\n const baseName = path.basename(inputPath);\n if (baseName.toLowerCase() === \"sanitized\") {\n return path.join(path.dirname(inputPath), \"postgres-direct\");\n }\n\n return path.join(path.dirname(inputPath), `${baseName}-postgres-direct`);\n}\n\nfunction inferNextStep(scriptPath: string): string {\n return `psql \"postgres://postgres:postgres@localhost:5432/cnpj\" -f ${scriptPath.replace(/\\\\/g, \"/\")}`;\n}\n\nfunction normalizeSourceEncoding(value: string | undefined): string {\n const encoding = (value ?? DEFAULT_SOURCE_ENCODING).trim();\n\n if (!/^[A-Za-z0-9_-]+$/.test(encoding)) {\n throw new ValidationError(\n `Invalid source encoding: ${value}. Use a PostgreSQL client encoding name such as UTF8, WIN1252 or LATIN1.`,\n );\n }\n\n return encoding.toUpperCase();\n}\n\nexport async function generatePostgresDirectScript(\n inputPath: string,\n options: PostgresDirectScriptOptions = {},\n): Promise<PostgresDirectScriptSummary> {\n if (options.dataset && !isImportDatasetType(options.dataset)) {\n throw new ValidationError(`Unsupported dataset type: ${options.dataset}.`);\n }\n\n const validation = await validateInputDirectory(inputPath);\n if (!validation.ok && !options.dataset) {\n throw new ValidationError(\n `The input directory is not ready for PostgreSQL direct script generation. ${validation.errors.join(\" \")}`,\n );\n }\n\n const validatedPath = validation.ok\n ? validation.validatedPath\n : path.resolve(inputPath);\n const outputPath = path.resolve(\n options.outputPath ?? defaultPostgresDirectOutputPath(validatedPath),\n );\n const sourceEncoding = normalizeSourceEncoding(options.sourceEncoding);\n const inspected = await inspectFiles(validatedPath);\n const recognizedFiles = inspected.entries\n .filter((entry) => entry.entryKind === \"file\")\n .flatMap((entry) => {\n if (!isImportDatasetType(entry.inferredType)) {\n return [];\n }\n\n if (options.dataset && entry.inferredType !== options.dataset) {\n return [];\n }\n\n return [{ ...entry, inferredType: entry.inferredType }];\n })\n .sort(sortEntries);\n\n if (recognizedFiles.length === 0) {\n throw new ValidationError(\n \"No recognized dataset files were found for PostgreSQL direct script generation.\",\n );\n }\n\n const datasets = [\n ...new Set(recognizedFiles.map((entry) => entry.inferredType)),\n ].sort(\n (left, right) => IMPORT_ORDER.indexOf(left) - IMPORT_ORDER.indexOf(right),\n );\n\n options.onProgress?.({\n kind: \"start\",\n inputPath: path.resolve(inputPath),\n validatedPath,\n outputPath,\n totalFiles: recognizedFiles.length,\n datasets,\n sourceEncoding,\n });\n\n await mkdir(outputPath, { recursive: true });\n\n const sourceFiles: PostgresDirectSourceFile[] = [];\n const summariesByDataset = new Map<\n ImportDatasetType,\n PostgresDirectScriptDatasetSummary\n >();\n\n for (const [index, entry] of recognizedFiles.entries()) {\n const dataset = entry.inferredType;\n const absolutePath = path.join(validatedPath, entry.relativePath);\n const fileStats = await stat(absolutePath);\n\n sourceFiles.push({\n dataset,\n absolutePath,\n relativePath: entry.relativePath,\n fileSize: fileStats.size,\n });\n\n const currentSummary = summariesByDataset.get(dataset) ?? {\n dataset,\n files: 0,\n totalBytes: 0,\n sourceFiles: [],\n };\n currentSummary.files += 1;\n currentSummary.totalBytes += fileStats.size;\n currentSummary.sourceFiles.push(absolutePath);\n summariesByDataset.set(dataset, currentSummary);\n\n options.onProgress?.({\n kind: \"file_registered\",\n dataset,\n fileIndex: index + 1,\n totalFiles: recognizedFiles.length,\n inputFile: buildDisplayPath(absolutePath),\n fileSize: fileStats.size,\n });\n }\n\n const scriptName = options.scriptName ?? \"import-postgres-direct.sql\";\n const scriptPath = path.join(outputPath, scriptName);\n const script = generatePostgresSanitizedDirectImportScript({\n files: sourceFiles,\n sourceEncoding,\n });\n await writeFile(scriptPath, script, \"utf8\");\n\n const manifestPath = path.join(outputPath, \"manifest.json\");\n const summaryDatasets = [...summariesByDataset.values()].sort(\n (left, right) =>\n IMPORT_ORDER.indexOf(left.dataset) - IMPORT_ORDER.indexOf(right.dataset),\n );\n const totalBytes = summaryDatasets.reduce(\n (sum, item) => sum + item.totalBytes,\n 0,\n );\n\n const manifest = {\n generatedAt: new Date().toISOString(),\n mode: \"direct-sanitized-script\",\n inputPath: path.resolve(inputPath),\n validatedPath,\n outputPath,\n scriptPath,\n sourceEncoding,\n totalFiles: sourceFiles.length,\n totalBytes,\n datasets: summaryDatasets,\n };\n await writeFile(\n manifestPath,\n `${JSON.stringify(manifest, null, 2)}\\n`,\n \"utf8\",\n );\n\n options.onProgress?.({\n kind: \"finish\",\n outputPath,\n scriptPath,\n totalFiles: sourceFiles.length,\n totalBytes,\n });\n\n return {\n inputPath: path.resolve(inputPath),\n validatedPath,\n outputPath,\n scriptPath,\n manifestPath,\n sourceEncoding,\n totalFiles: sourceFiles.length,\n totalBytes,\n datasets: summaryDatasets,\n warnings: [\n ...(validation.ok ? [] : validation.errors),\n \"This script imports sanitized Receita files directly with psql \\\\copy. It avoids rewriting the full dataset into a second CSV tree.\",\n \"The generated script expects the database schema generated by cnpj-db-loader to be applied before execution.\",\n \"The direct PostgreSQL script now defaults to UTF8 because the sanitize command writes clean UTF-8 files.\",\n \"Use --source-encoding WIN1252 or LATIN1 only when generating scripts for legacy sanitized files produced by older loader versions.\",\n ],\n nextStep: inferNextStep(scriptPath),\n };\n}\n"],"mappings":"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","names":["os","path","tableExists","tableExists","result","path","writeFile","writeFile","path","path","inferNextStep","mkdir","readdir","stat","path","readdir","path","mkdir","stat","mkdir","writeFile","os","path","path","os","mkdir","writeFile","path","performance","Client","performance","buildPartnerDedupeKey","stat","path","totalRows","totalBatches","persistCheckpoint","performance","performance","performance","performance","STAGING_TABLE_BY_DATASET","performance","path","plan","path","Client","path","performance","Client","Client","mkdir","stat","path","mkdir","readFile","stat","writeFile","path","path","stat","readFile","mkdir","writeFile","stat","path","mkdir","readdir","stat","path","safeStat","stat","readdir","path","mkdir","readFile","unlink","readFile","unlink","mkdir","path","createReadStream","createWriteStream","mkdir","path","mkdir","path","createReadStream","createWriteStream","path","inferNextStep","createWriteStream","mkdir","writeFile","path","path","STAGING_TABLE_BY_DATASET","path","path","inferNextStep","mkdir","createWriteStream","writeFile","mkdir","stat","writeFile","path","path","inferNextStep","mkdir","stat","writeFile"]}