@aglyn/tenant-data-admin 1.0.0-beta.221 → 1.0.0-beta.222
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/package.json +7 -7
- package/src/lib/server/api-keys.js +3 -3
- package/src/lib/server/api-keys.js.map +1 -1
- package/src/lib/server/api-v1-resources.d.ts +44 -3
- package/src/lib/server/api-v1-resources.js +82 -5
- package/src/lib/server/api-v1-resources.js.map +1 -1
- package/src/lib/server/collection-live-pages.d.ts +2 -2
- package/src/lib/server/collection-live-pages.js +1 -1
- package/src/lib/server/collection-live-pages.js.map +1 -1
- package/src/lib/server/email-delivery-log.d.ts +17 -73
- package/src/lib/server/email-delivery-log.js +44 -222
- package/src/lib/server/email-delivery-log.js.map +1 -1
- package/src/lib/server/email-flow-gate.js +27 -38
- package/src/lib/server/email-flow-gate.js.map +1 -1
- package/src/lib/server/erase-person.d.ts +34 -54
- package/src/lib/server/erase-person.js +44 -239
- package/src/lib/server/erase-person.js.map +1 -1
- package/src/lib/server/host-visitor-records.d.ts +12 -4
- package/src/lib/server/host-visitor-records.js +20 -10
- package/src/lib/server/host-visitor-records.js.map +1 -1
- package/src/lib/server/hosted-page-review.js +46 -33
- package/src/lib/server/hosted-page-review.js.map +1 -1
- package/src/lib/server/link-reputation-review.d.ts +6 -2
- package/src/lib/server/link-reputation-review.js +61 -20
- package/src/lib/server/link-reputation-review.js.map +1 -1
- package/src/lib/server/live-page-drops.d.ts +67 -0
- package/src/lib/server/live-page-drops.js +57 -0
- package/src/lib/server/live-page-drops.js.map +1 -0
- package/src/lib/server/media-bandwidth-cap.d.ts +78 -0
- package/src/lib/server/media-bandwidth-cap.js +180 -0
- package/src/lib/server/media-bandwidth-cap.js.map +1 -0
- package/src/lib/server/media-cdn-icon.d.ts +77 -0
- package/src/lib/server/media-cdn-icon.js +140 -0
- package/src/lib/server/media-cdn-icon.js.map +1 -0
- package/src/lib/server/media-delivery-regeneration.d.ts +132 -0
- package/src/lib/server/media-delivery-regeneration.js +216 -0
- package/src/lib/server/media-delivery-regeneration.js.map +1 -0
- package/src/lib/server/media-delivery.d.ts +2 -0
- package/src/lib/server/media-delivery.js +2 -1
- package/src/lib/server/media-delivery.js.map +1 -1
- package/src/lib/server/media-serve-count.d.ts +50 -0
- package/src/lib/server/media-serve-count.js +62 -0
- package/src/lib/server/media-serve-count.js.map +1 -0
- package/src/lib/server/media-signing.d.ts +13 -2
- package/src/lib/server/media-signing.js +12 -8
- package/src/lib/server/media-signing.js.map +1 -1
- package/src/lib/server/media-tombstone.js +7 -5
- package/src/lib/server/media-tombstone.js.map +1 -1
- package/src/lib/server/media-variants.d.ts +151 -20
- package/src/lib/server/media-variants.js +204 -27
- package/src/lib/server/media-variants.js.map +1 -1
- package/src/lib/server/organizations.d.ts +102 -2
- package/src/lib/server/organizations.js +388 -58
- package/src/lib/server/organizations.js.map +1 -1
- package/src/lib/server/outbound-send-review.js +5 -4
- package/src/lib/server/outbound-send-review.js.map +1 -1
- package/src/lib/server/paged-sweeps.d.ts +51 -0
- package/src/lib/server/paged-sweeps.js +79 -0
- package/src/lib/server/paged-sweeps.js.map +1 -0
- package/src/lib/server/platform-marketing-consent.d.ts +0 -49
- package/src/lib/server/platform-marketing-consent.js +27 -11
- package/src/lib/server/platform-marketing-consent.js.map +1 -1
- package/src/lib/server/serve-media-cdn.d.ts +69 -1
- package/src/lib/server/serve-media-cdn.js +424 -70
- package/src/lib/server/serve-media-cdn.js.map +1 -1
- package/src/lib/server/site-icon-render.d.ts +68 -0
- package/src/lib/server/site-icon-render.js +157 -0
- package/src/lib/server/site-icon-render.js.map +1 -0
- package/src/lib/server/staff-seat.d.ts +50 -0
- package/src/lib/server/staff-seat.js +118 -0
- package/src/lib/server/staff-seat.js.map +1 -0
- package/src/lib/server/transfer-export.d.ts +46 -0
- package/src/lib/server/transfer-export.js +221 -0
- package/src/lib/server/transfer-export.js.map +1 -0
- package/src/lib/server/transfer-jobs.d.ts +385 -0
- package/src/lib/server/transfer-jobs.js +2368 -0
- package/src/lib/server/transfer-jobs.js.map +1 -0
- package/src/lib/server/transfer-packages.d.ts +127 -0
- package/src/lib/server/transfer-packages.js +1036 -0
- package/src/lib/server/transfer-packages.js.map +1 -0
- package/src/lib/server/upgrade-proposal.d.ts +97 -0
- package/src/lib/server/upgrade-proposal.js +312 -0
- package/src/lib/server/upgrade-proposal.js.map +1 -0
- package/src/lib/server/upsert-contact.d.ts +17 -8
- package/src/lib/server/upsert-contact.js +82 -16
- package/src/lib/server/upsert-contact.js.map +1 -1
- package/src/lib/server/web-risk.d.ts +48 -9
- package/src/lib/server/web-risk.js +281 -143
- package/src/lib/server/web-risk.js.map +1 -1
- package/src/tenancy.d.ts +3 -1
- package/src/tenancy.js +5 -1
- package/src/tenancy.js.map +1 -1
- package/src/lib/server/campaign-attribution-store.d.ts +0 -55
- package/src/lib/server/campaign-attribution-store.js +0 -95
- package/src/lib/server/campaign-attribution-store.js.map +0 -1
- package/src/lib/server/campaign-conversion-attribution.d.ts +0 -283
- package/src/lib/server/campaign-conversion-attribution.js +0 -450
- package/src/lib/server/campaign-conversion-attribution.js.map +0 -1
- package/src/lib/server/dataset-live-pages.d.ts +0 -179
- package/src/lib/server/dataset-live-pages.js +0 -421
- package/src/lib/server/dataset-live-pages.js.map +0 -1
- package/src/lib/server/email-revenue-attribution.d.ts +0 -185
- package/src/lib/server/email-revenue-attribution.js +0 -321
- package/src/lib/server/email-revenue-attribution.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/tenant/data/admin/src/lib/server/transfer-jobs.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*==========================================\n * THE TRANSFER JOB ENGINE (AGL-3524) — an import as a durable job.\n *\n * The core (`@aglyn/aglyn/data-transfer`) says what a file means and what\n * each row would do; the resource's plugin (`plugin-transfer-resources.ts`)\n * reads and writes its own records. This module is everything between: the\n * stored file, the job document and its subcollections, the dry run over\n * every row, the chunked and idempotent apply, the result file and the\n * seven-day undo. The console's `/api/transfer/*` routes are wiring over it,\n * and the cron sweep resumes what a closed tab left behind.\n *\n * ## Where things are\n *\n * orgs/{orgId}/transferJobs/{jobId} the job (`TransferJobRecord`)\n * chunks/{n} the dry run, 200 rows a chunk\n * ledger/{jobId}:{row} a row's write, recorded the moment it lands\n * results/{n} a written chunk's per-row results\n * undo/{n} a written chunk's undo entries\n * Storage orgs/{orgId}/transfers/{jobId}/source the file, inspected before it is stored\n *\n * The engine never writes a resource's record itself. A row reaches its\n * store only through the plugin's `apply` and `revert`, on the plugin's\n * own write paths, so what a record write must derive is derived there:\n * a dataset record's `datasetIntegrityFields` / `datasetIntegrityUpdate`\n * (referenced ids and filter fields) by the data plugin, as on every other\n * path that writes `records`. The `'records'` and `values` in this file are\n * the transfer kind and planned rows in the job's own subcollections.\n *\n * Every document is written with the Admin SDK only; the rules let members\n * holding `data.manage` read the job and nobody write anything.\n *\n * ## Applying never writes a row twice\n *\n * The plugin's `apply` is handed a writer whose `markApplied` creates the\n * row's ledger document the moment its write lands, and whose\n * `alreadyApplied` answers from that ledger — so a chunk retried after a\n * crash, a timeout or a second driver skips every row it already wrote. A\n * chunk is complete when every planned write has a ledger entry; then its\n * results, its undo entries and the job's cursor commit in ONE batch, and\n * only after that are its ledger entries cleared.\n *\n * One driver at a time: a request takes a lease on the job for its time\n * budget, and a second request (a second tab, the sweep) is refused while it\n * holds. One running import per resource per workspace: starting one while\n * another of the same resource is `applying` is refused.\n *\n * ## Undo asks before it overwrites a later edit\n *\n * Undo is two calls. `planTransferJobUndo` reads every record the import\n * touched and runs the core's `planTransferUndo` — restore, delete, nothing,\n * or a conflict for a record edited since — and writes nothing.\n * `applyTransferJobUndo` hands each chunk's snapshot to the plugin's\n * `revert` with the person's decision for every record, chunk by chunk.\n *=========================================*/\n\nimport {\n TRANSFER_DEFAULT_MAX_ROWS,\n TRANSFER_DRAFT_RETENTION_MS,\n TRANSFER_ID_FIELD,\n TRANSFER_PLAN_CONFLICTS_MAX,\n TRANSFER_PLAN_PAGE_MAX,\n TRANSFER_RESULT_COLUMNS,\n TRANSFER_UNDO_PAGE_MAX,\n TRANSFER_UPLOAD_MAX_BYTES,\n TRANSFER_UPLOAD_MAX_PARTS,\n TRANSFER_UPLOAD_PART_MAX_BYTES,\n TRANSFER_WRITE_CONCURRENCY,\n canApplyTransferPlan,\n collectPicklistValues,\n createTransferPolicy,\n withTransferPolicyDefaults,\n deriveTransferCell,\n deriveTransferRow,\n mapTransferRow,\n mappingIsUsable,\n mappingProblems,\n matchHeaders,\n matchLookupRequests,\n matchPicklistValues,\n missingAcknowledgements,\n picklistChoiceProblems,\n planTransferUndo,\n proposePicklistChoice,\n readTransferSource,\n resolveMultiPicklistCell,\n resolvePicklistCell,\n resolvePicklistChoices,\n sniffTransferFormat,\n summarizeMatches,\n summarizeTransferDerivations,\n summarizeTransferResults,\n transferAmbiguities,\n transferCellText,\n transferChunkRanges,\n transferContentType,\n transferDateOrderOptions,\n transferFormatFromFileName,\n transferLedgerKey,\n transferMatchReview,\n transferMatchedRecordIds,\n transferPlanConflicts,\n transferPlanFeature,\n transferPlanSample,\n transferPolicyProblems,\n transferRowLabel,\n transferUndoAvailable,\n transferUndoExpiresAt,\n transitionTransferJob,\n transferLookupKey,\n transferResourceImports,\n transferLookupNewValue,\n mayBeTransferRecordId,\n normalizeMatchValue,\n matchLookupKey,\n isBlankTransferValue,\n isTransferLookupField,\n TRANSFER_UNDO_WINDOW_MS,\n TRANSFER_UNFINISHED_IMPORTS_MAX,\n TRANSFER_JOBS_PAGE_MAX,\n parseTransferResourceKey,\n type TransferJobSummary,\n type TransferUnfinishedImportSummary,\n type MatchKeySpec,\n type MatchLookupRequest,\n type PicklistResolution,\n type PicklistValueChoice,\n type PlannedTransferRow,\n type RowMatchOutcome,\n type TransferAnalyzeResponse,\n type TransferChunkRange,\n type TransferCsvDelimiter,\n type TransferDateOrder,\n type TransferErrorCode,\n type TransferField,\n type TransferFormat,\n type TransferJobRecord,\n type TransferJobRetention,\n type TransferLookupChoice,\n type TransferLookupReview,\n type TransferLookupSuggestion,\n type TransferPicklistAnalysis,\n type TransferPlanChoices,\n type TransferPlanInvariantFailure,\n type TransferPlanResponse,\n type TransferPlanRow,\n type TransferPlanRowsPage,\n type TransferProgress,\n type TransferResourceInfo,\n type TransferResultSummary,\n type TransferRowNote,\n type TransferRowResult,\n type TransferRowVerdict,\n type TransferSourceOptions,\n type TransferSourceTable,\n type TransferUndoConflict,\n type TransferUndoCounts,\n type TransferUndoDecision,\n type TransferUndoEntry,\n type TransferUndoPlanResponse,\n type TransferUndoSnapshot,\n type TransferUndoState,\n type TransferWarningClass,\n} from '@aglyn/aglyn/data-transfer'\nimport {\n normalizePicklistLabel,\n picklistLabelKey,\n type PicklistValue,\n} from '@aglyn/aglyn/app-utils/picklists'\nimport { createResourceUid } from '@aglyn/aglyn/app-utils/create-resource-uid'\nimport { escapeCsvCell } from '@aglyn/aglyn/app-utils/csv'\nimport { inspectUploadBytes } from '@aglyn/aglyn/app-utils/upload-inspection'\nimport {\n matchTransferResourceRows,\n planTransferResourceRows,\n transferResourcePolicyDefaults,\n resolveTransferResource,\n transferInvariantFailures,\n transferRecordsHooks,\n transferResourceCatalog,\n transferResourceLockedRules,\n transferResourceMatchKeys,\n TransferResourceUnavailableError,\n transferPlanRefusal,\n type ResolvedTransferResource,\n type TransferApplyWriter,\n type TransferPlanRefusal,\n type TransferLookupTargetHooks,\n type TransferPicklistList,\n type TransferRecordsHooks,\n type TransferResourceContext,\n} from '@aglyn/aglyn/plugin-manager/plugin-transfer-resources'\n\n/*==========================================\n * DEPENDENCIES AND ERRORS\n *=========================================*/\n\n/** The one Storage object operation set the engine uses. */\nexport interface TransferBucketFile {\n save(data: Buffer, options?: { contentType?: string; resumable?: boolean }): Promise<unknown>\n download(): Promise<[Buffer]>\n delete(options?: { ignoreNotFound?: boolean }): Promise<unknown>\n}\n\n/** The bucket the files are stored in (the Admin SDK's default bucket in production). */\nexport interface TransferBucket {\n file(path: string): TransferBucketFile\n}\n\n/** What the engine runs against; a spec hands it doubles. */\nexport interface TransferEngineDeps {\n firestore: FirebaseFirestore.Firestore\n bucket: TransferBucket\n /** Defaults to `resolveTransferResource`. */\n resolveResource?: (key: string) => Promise<ResolvedTransferResource>\n /** Defaults to `Date.now`. */\n now?: () => number\n /** Defaults to `createResourceUid()`, the id every console resource carries. */\n newJobId?: () => string\n}\n\n/** A refusal a route answers as `{ error, code, details }` with `status`. */\nexport class TransferEngineError extends Error {\n constructor(\n readonly code: TransferErrorCode,\n readonly status: number,\n message: string,\n readonly details?: unknown,\n ) {\n super(message)\n this.name = 'TransferEngineError'\n }\n}\n\n/**\n * A refusal for the workspace's plan (AGL-3555): a route answers its\n * `refusal` as it stands — the owning plugin's flat 403 body, with\n * `reason: 'plan_required'` and the plan feature as `code` — rather than\n * as `{ error, code, details }`. Its own `code` is `planRequired`, what a\n * client reads that body as.\n */\nexport class TransferPlanRefusedError extends TransferEngineError {\n constructor(readonly refusal: TransferPlanRefusal) {\n super('planRequired', refusal.status, refusal.body.error, refusal.body)\n this.name = 'TransferPlanRefusedError'\n }\n}\n\n/** The collection an organization's jobs live in. */\nexport const TRANSFER_JOBS_COLLECTION = 'transferJobs'\n\n/** How long a driver's lease outlives its budget, so a crashed request's job is resumed soon after. */\nexport const TRANSFER_LEASE_GRACE_MS = 30_000\n\n/** How long an `applying` job sits untouched before the sweep resumes it. */\nexport const TRANSFER_STALE_MS = 2 * 60 * 1000\n\n/** Below this much budget, a request stops rather than starting another chunk. */\nexport const TRANSFER_MIN_CHUNK_BUDGET_MS = 2_000\n\n/** The most ids one undo lookup asks for. */\nconst UNDO_LOOKUP_SLICE = 500\n\n/** The most values one match lookup request carries. */\nconst MATCH_LOOKUP_SLICE = 500\n\n/** The most characters of JSON one document holds before it is split into pieces. */\nconst JSON_PIECE_CHARS = 900_000\n\n/** Where an organization's jobs are. */\nexport function transferJobsCollection(\n firestore: FirebaseFirestore.Firestore,\n orgId: string,\n): FirebaseFirestore.CollectionReference {\n return firestore.collection('orgs').doc(orgId).collection(TRANSFER_JOBS_COLLECTION)\n}\n\n/** Where a job's file is stored. */\nexport function transferSourcePath(orgId: string, jobId: string): string {\n return `orgs/${orgId}/transfers/${jobId}/source`\n}\n\n/** Where one part of a file sent in parts waits until the rest arrives. */\nexport function transferPartPath(orgId: string, jobId: string, part: number): string {\n return `orgs/${orgId}/transfers/${jobId}/parts/${part}`\n}\n\nexport const clock = (deps: Pick<TransferEngineDeps, 'now'>) => (deps.now ?? Date.now)()\n\n/** A value as Firestore can store it: no `undefined`, no class instances. */\nexport function stored<T>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T\n}\n\nexport function emptyResults(): TransferResultSummary {\n return { created: 0, updated: 0, unchanged: 0, skipped: 0, failed: 0, total: 0 }\n}\n\nexport function emptyUndoCounts(): TransferUndoCounts {\n return { restore: 0, delete: 0, conflict: 0, nothing: 0 }\n}\n\n/** `fn` over `items`, at most `limit` at once. */\nexport async function eachLimited<T>(items: readonly T[], limit: number, fn: (item: T) => Promise<void>): Promise<void> {\n let next = 0\n const workers = Array.from({ length: Math.min(limit, items.length) }, async () => {\n while (next < items.length) {\n const item = items[next] as T\n next += 1\n await fn(item)\n }\n })\n await Promise.all(workers)\n}\n\nexport function isAlreadyExists(error: unknown): boolean {\n const failure = error as { code?: unknown; message?: unknown } | null\n return failure?.code === 6 || /ALREADY_EXISTS/i.test(String(failure?.message ?? ''))\n}\n\n/*------------------------------------------\n * JSON documents that may outgrow one document\n *-----------------------------------------*/\n\n/**\n * Writes `value` as JSON on `ref` beside `fields`. JSON, because a plan row\n * holds whatever the file held — a nested list from a JSON file is a value\n * Firestore refuses — and past {@link JSON_PIECE_CHARS} the text goes into\n * `pieces/{k}` documents, so a chunk of long notes is never refused for size.\n */\nexport async function writeJsonDoc(\n ref: FirebaseFirestore.DocumentReference,\n fields: Record<string, unknown>,\n value: unknown,\n): Promise<void> {\n const json = JSON.stringify(value)\n if (json.length <= JSON_PIECE_CHARS) {\n await ref.set(stored({ ...fields, json }))\n return\n }\n const pieces: string[] = []\n for (let at = 0; at < json.length; at += JSON_PIECE_CHARS) pieces.push(json.slice(at, at + JSON_PIECE_CHARS))\n await eachLimited(\n pieces.map((json, index) => ({ json, index })),\n TRANSFER_WRITE_CONCURRENCY,\n async (piece) => {\n await ref.collection('pieces').doc(String(piece.index)).set({ json: piece.json })\n },\n )\n await ref.set(stored({ ...fields, pieces: pieces.length }))\n}\n\n/** The value {@link writeJsonDoc} wrote, or `null` when the document is absent. */\nexport async function readJsonDoc<T>(ref: FirebaseFirestore.DocumentReference): Promise<T | null> {\n const snapshot = await ref.get()\n if (!snapshot.exists) return null\n const data = snapshot.data() as { json?: string; pieces?: number }\n if (typeof data.json === 'string') return JSON.parse(data.json) as T\n const count = Number(data.pieces ?? 0)\n const parts: string[] = []\n for (let index = 0; index < count; index += 1) {\n const piece = await ref.collection('pieces').doc(String(index)).get()\n parts.push(String((piece.data() as { json?: string } | undefined)?.json ?? ''))\n }\n return JSON.parse(parts.join('')) as T\n}\n\n/** Deletes every document of a collection (and a JSON document's pieces), eight at a time. */\nexport async function clearCollection(collection: FirebaseFirestore.CollectionReference): Promise<void> {\n const snapshot = await collection.get()\n await eachLimited(snapshot.docs, TRANSFER_WRITE_CONCURRENCY, async (doc) => {\n const pieces = await doc.ref.collection('pieces').get()\n for (const piece of pieces.docs) await piece.ref.delete()\n await doc.ref.delete()\n })\n}\n\n/*==========================================\n * JOBS\n *=========================================*/\n\nexport async function readJob(deps: TransferEngineDeps, orgId: string, jobId: string): Promise<TransferJobRecord> {\n if (!jobId || jobId.includes('/')) throw new TransferEngineError('invalid', 400, 'Name the import.')\n const snapshot = await transferJobsCollection(deps.firestore, orgId).doc(jobId).get()\n if (!snapshot.exists) throw new TransferEngineError('notFound', 404, 'No such import.')\n return { ...(snapshot.data() as TransferJobRecord), id: jobId }\n}\n\n/**\n * When the sweep may clean a job up, and how (see the sweep below): never\n * while it runs or undoes, nor once trimmed; a job that never wrote expires\n * {@link TRANSFER_DRAFT_RETENTION_MS} after it was last touched; one that\n * wrote is trimmed once its undo window has closed.\n */\nexport function transferJobRetention(\n job: TransferJobRecord,\n): { retention: TransferJobRetention; retainUntil: number } | null {\n if (job.trimmedAt !== undefined || job.status === 'applying' || job.undo?.status === 'running') return null\n const wrote = job.applyStartedAt !== undefined || job.status === 'applied' || job.status === 'undone'\n if (!wrote) return { retention: 'expire', retainUntil: job.updatedAt + TRANSFER_DRAFT_RETENTION_MS }\n return { retention: 'trim', retainUntil: (job.appliedAt ?? job.updatedAt) + TRANSFER_UNDO_WINDOW_MS }\n}\n\n/** A job as it is stored: Firestore-safe, with its retention stamped for the sweep's query. */\nfunction storedJob(job: TransferJobRecord): TransferJobRecord {\n const rest: TransferJobRecord = { ...job }\n delete rest.retention\n delete rest.retainUntil\n return stored({ ...rest, ...(transferJobRetention(job) ?? {}) })\n}\n\nexport async function saveJob(deps: TransferEngineDeps, job: TransferJobRecord): Promise<void> {\n await transferJobsCollection(deps.firestore, job.orgId).doc(job.id).set(storedJob(job))\n}\n\n/** The job as a route returns it. */\nexport async function readTransferJob(\n deps: TransferEngineDeps,\n input: { orgId: string; jobId: string },\n): Promise<TransferJobRecord> {\n return readJob(deps, input.orgId, input.jobId)\n}\n\n/** A `records` resource, joined to its server half, or the refusal a route answers. */\nexport async function resolveTransferRecordsResource(\n deps: Pick<TransferEngineDeps, 'resolveResource'>,\n key: string,\n): Promise<ResolvedTransferResource> {\n return resolveResource(deps, key)\n}\n\nasync function resolveResource(deps: Pick<TransferEngineDeps, 'resolveResource'>, key: string): Promise<ResolvedTransferResource> {\n try {\n const resource = await (deps.resolveResource ?? resolveTransferResource)(key)\n if (!resource.kinds.includes('records')) {\n throw new TransferEngineError('invalid', 400, `${resource.label} is moved as a package, not imported as rows.`)\n }\n return resource\n } catch (error) {\n if (error instanceof TransferResourceUnavailableError) {\n throw error.reason === 'undeclared'\n ? new TransferEngineError('notFound', 404, `Nothing called \"${key}\" can be imported.`)\n : new TransferEngineError('unavailable', 500, 'Importing this is unavailable right now. Try again in a minute.')\n }\n throw error\n }\n}\n\n/**\n * The site a transfer concerns: required for a `host` resource; for an\n * `org` resource the site the person named, or `null` — a workspace's\n * records can be read through one site's view of them and imported as\n * that site's captures (the CRM's, AGL-3541), and the gate has already\n * checked `data.manage` on that site.\n */\nexport function transferHostIdFor(resource: ResolvedTransferResource, hostId: string | null | undefined): string | null {\n const site = typeof hostId === 'string' && hostId.trim() && !hostId.includes('/') ? hostId.trim() : null\n if (resource.scope === 'host' && !site) {\n throw new TransferEngineError('invalid', 400, `${resource.label} belong to a site; name the site.`)\n }\n return site\n}\n\nexport function contextFor(job: TransferJobRecord, actorUid: string | null): TransferResourceContext {\n return {\n resource: job.resource,\n orgId: job.orgId,\n hostId: job.hostId ?? null,\n actorUid,\n jobId: job.id,\n ...(job.extras ? { extras: job.extras } : {}),\n ...(job.headers ? { headers: job.headers } : {}),\n }\n}\n\nexport function moveJob(\n job: TransferJobRecord,\n to: TransferJobRecord['status'],\n now: number,\n patch: Partial<TransferJobRecord> = {},\n): TransferJobRecord {\n try {\n return transitionTransferJob(job, to, now, patch) as TransferJobRecord\n } catch {\n throw new TransferEngineError('state', 409, `This import is ${job.status} and cannot be ${to} now.`)\n }\n}\n\n/** Where a job stands, for a progress bar. */\nexport function transferJobProgress(job: TransferJobRecord): TransferProgress {\n return {\n status: job.status,\n chunk: job.cursor?.chunk ?? 0,\n chunkCount: job.chunkCount ?? 0,\n rowsDone: job.cursor?.rowsDone ?? 0,\n rowCount: job.rowCount ?? 0,\n results: job.results ?? emptyResults(),\n }\n}\n\n/*==========================================\n * FIELDS — what a resource offers\n *=========================================*/\n\n/** The resource's starting policy as a `TransferResourceInfo` entry: absent when it starts from the core's. */\nasync function policyDefaultsEntry(\n resource: ResolvedTransferResource,\n ctx: TransferResourceContext,\n fields: readonly TransferField[],\n): Promise<Pick<TransferResourceInfo, 'defaultPolicy'>> {\n const defaultPolicy = await transferResourcePolicyDefaults(resource, ctx, fields)\n return Object.keys(defaultPolicy).length ? { defaultPolicy } : {}\n}\n\n/**\n * What a resource offers the wizard and the export dialog: its descriptor,\n * every field and group, its match keys (and the ones a person starts with,\n * which the Re-importable preset leads with), the presets' hints and its own\n * presets, its locked rules and aliases. `prefs` is the person's own\n * and is filled by the caller; a custom field cannot be created from here.\n */\nexport async function readTransferResourceInfo(\n deps: TransferEngineDeps,\n input: { orgId: string; actorUid: string; resource: string; hostId?: string | null; filter?: unknown },\n): Promise<Omit<TransferResourceInfo, 'prefs'>> {\n const resource = await resolveResource(deps, String(input.resource ?? '').trim())\n const filter = input.filter\n const ctx: TransferResourceContext = {\n resource: resource.key,\n orgId: input.orgId,\n hostId: transferHostIdFor(resource, input.hostId),\n actorUid: input.actorUid,\n ...(filter && typeof filter === 'object' && !Array.isArray(filter)\n ? { filter: filter as Readonly<Record<string, unknown>> }\n : {}),\n }\n const hooks = transferRecordsHooks(resource)\n const catalog = await transferResourceCatalog(resource, ctx)\n const offer = await transferResourceMatchKeys(resource, ctx)\n const matchKeys = offer.keys\n return {\n resource: {\n key: resource.key,\n label: resource.label,\n ...(resource.singularLabel ? { singularLabel: resource.singularLabel } : {}),\n scope: resource.scope,\n kinds: [...resource.kinds],\n formats: [...resource.formats],\n ...(resource.limits ? { limits: resource.limits } : {}),\n ...(resource.description ? { description: resource.description } : {}),\n ...(resource.exportOnly ? { exportOnly: true } : {}),\n },\n fields: catalog.fields,\n groups: catalog.groups,\n matchKeys,\n defaultMatchKeys: offer.defaults,\n presetHints: { matchKeyFieldIds: offer.defaults },\n ...(hooks.presets?.length\n ? {\n resourcePresets: hooks.presets.map((preset) => ({\n ...preset,\n // Only fields the catalog has: a preset never names a column the export would refuse.\n fieldIds: preset.fieldIds.filter((fieldId) => catalog.byId.has(fieldId)),\n })),\n }\n : {}),\n locked: [...(await transferResourceLockedRules(resource, ctx))],\n ...(await policyDefaultsEntry(resource, ctx, catalog.fields)),\n ...(hooks.aliases?.length ? { dictionaries: [...hooks.aliases] } : {}),\n canCreateCustomField: false,\n }\n}\n\n/*==========================================\n * UPLOAD\n *=========================================*/\n\nexport interface TransferUploadInput {\n orgId: string\n actorUid: string\n resource: string\n hostId?: string | null\n fileName: string\n format?: TransferFormat\n content: string\n part?: number\n parts?: number\n jobId?: string\n delimiter?: TransferCsvDelimiter\n headerRow?: boolean\n}\n\nconst CSV_DELIMITERS: readonly TransferCsvDelimiter[] = [',', ';', '\\t', '|']\n\n/** How the person said the CSV reads, or nothing for detection to decide. */\nfunction readOptionsOf(input: Pick<TransferUploadInput, 'delimiter' | 'headerRow'>): TransferSourceOptions | undefined {\n const options: TransferSourceOptions = {}\n if (input.delimiter !== undefined) {\n if (!CSV_DELIMITERS.includes(input.delimiter)) throw new TransferEngineError('invalid', 400, 'That separator is not one a CSV can use.')\n options.delimiter = input.delimiter\n }\n if (input.headerRow === false) options.headerRow = false\n return Object.keys(options).length ? options : undefined\n}\n\n/**\n * The structure check every stored upload passes (`inspectUploadBytes`):\n * an executable or a test signature named as a CSV is refused before a byte\n * of it is stored. It is a structural check, not an antivirus scan.\n */\nfunction inspectTransferBytes(bytes: Uint8Array, format: TransferFormat, fileName: string): void {\n const refusal = inspectUploadBytes({ bytes, contentType: transferContentType(format), fileName })\n if (refusal) throw new TransferEngineError('rejectedFile', 422, refusal.message, { code: refusal.code })\n}\n\nfunction textOf(bytes: Buffer): string {\n return bytes.toString('utf8')\n}\n\n/**\n * Stores a file, or one part of it, and makes the job on the first part.\n * Each part is inspected before it is stored; the whole file is inspected\n * again, read, counted against the resource's limits and stored as the\n * source once the last part lands. A part sent twice is accepted once.\n */\nexport async function uploadTransferSource(\n deps: TransferEngineDeps,\n input: TransferUploadInput,\n): Promise<{ job: TransferJobRecord; complete: boolean }> {\n const resource = await resolveResource(deps, String(input.resource ?? '').trim())\n if (!transferResourceImports(resource)) {\n throw new TransferEngineError('invalid', 400, `${resource.label} are exported, not imported.`)\n }\n const hostId = transferHostIdFor(resource, input.hostId)\n const fileName = String(input.fileName ?? '').trim().slice(0, 240) || 'import'\n const content = typeof input.content === 'string' ? input.content : ''\n const format = input.format ?? transferFormatFromFileName(fileName) ?? sniffTransferFormat(content)\n if (!resource.formats.includes(format)) {\n throw new TransferEngineError(\n 'unsupportedFormat',\n 415,\n `${resource.label} can be imported from ${resource.formats.join(', ').toUpperCase()}, not ${format.toUpperCase()}.`,\n )\n }\n const parts = input.parts ?? 1\n const part = input.part ?? 0\n if (!Number.isInteger(parts) || parts < 1 || parts > TRANSFER_UPLOAD_MAX_PARTS) {\n throw new TransferEngineError('invalid', 400, `A file is sent in 1 to ${TRANSFER_UPLOAD_MAX_PARTS} parts.`)\n }\n if (!Number.isInteger(part) || part < 0 || part >= parts) {\n throw new TransferEngineError('invalid', 400, `Part ${part} is not one of ${parts}.`)\n }\n const bytes = Buffer.from(content, 'utf8')\n if (bytes.length > TRANSFER_UPLOAD_PART_MAX_BYTES) {\n throw new TransferEngineError('tooLarge', 413, 'Send the file in parts of at most 3 MB.')\n }\n const maxBytes = Math.min(resource.limits?.maxBytes ?? TRANSFER_UPLOAD_MAX_BYTES, TRANSFER_UPLOAD_MAX_BYTES)\n inspectTransferBytes(bytes, format, fileName)\n\n const now = clock(deps)\n const jobs = transferJobsCollection(deps.firestore, input.orgId)\n let job: TransferJobRecord\n if (input.jobId) {\n job = await readJob(deps, input.orgId, input.jobId)\n if (job.status !== 'draft' || job.resource !== resource.key || !job.upload || job.upload.complete) {\n throw new TransferEngineError('state', 409, 'This import is not waiting for a file.')\n }\n if (job.upload.parts !== parts) throw new TransferEngineError('invalid', 400, 'The part count changed.')\n if (job.upload.received.includes(part)) return { job, complete: false }\n } else {\n if (part !== 0) throw new TransferEngineError('invalid', 400, 'Send the first part first.')\n const id = deps.newJobId?.() ?? createResourceUid()\n job = {\n id,\n resource: resource.key,\n kind: 'records',\n direction: 'import',\n format,\n status: 'draft',\n orgId: input.orgId,\n ...(hostId ? { hostId } : {}),\n createdBy: input.actorUid,\n createdAt: now,\n updatedAt: now,\n fileName,\n ...(format === 'csv' && readOptionsOf(input) ? { read: readOptionsOf(input) } : {}),\n upload: { parts, received: [], bytes: 0, complete: false },\n }\n }\n\n if ((job.upload?.bytes ?? 0) + bytes.length > maxBytes) {\n throw new TransferEngineError('tooLarge', 413, `A file may be at most ${Math.round(maxBytes / 1_000_000)} MB.`)\n }\n\n let whole: Buffer\n if (parts === 1) {\n whole = bytes\n } else {\n await deps.bucket.file(transferPartPath(input.orgId, job.id, part)).save(bytes, {\n contentType: 'application/octet-stream',\n resumable: false,\n })\n const received = await deps.firestore.runTransaction(async (transaction) => {\n const ref = jobs.doc(job.id)\n const snapshot = await transaction.get(ref)\n const current = snapshot.exists ? ({ ...(snapshot.data() as TransferJobRecord), id: job.id }) : job\n const upload = current.upload ?? { parts, received: [], bytes: 0, complete: false }\n const next: TransferJobRecord = {\n ...current,\n updatedAt: now,\n upload: {\n ...upload,\n received: [...new Set([...upload.received, part])].sort((a, b) => a - b),\n bytes: upload.received.includes(part) ? upload.bytes : upload.bytes + bytes.length,\n },\n }\n transaction.set(ref, storedJob(next))\n return next\n })\n job = received\n if ((job.upload?.received.length ?? 0) < parts) return { job, complete: false }\n const pieces: Buffer[] = []\n for (let index = 0; index < parts; index += 1) {\n const [piece] = await deps.bucket.file(transferPartPath(input.orgId, job.id, index)).download()\n pieces.push(piece)\n }\n whole = Buffer.concat(pieces)\n if (whole.length > maxBytes) {\n throw new TransferEngineError('tooLarge', 413, `A file may be at most ${Math.round(maxBytes / 1_000_000)} MB.`)\n }\n inspectTransferBytes(whole, format, fileName)\n }\n\n const read = readTransferSource(textOf(whole), format, job.read ?? {})\n if ('problem' in read) {\n await saveJob(deps, moveJob(job, 'failed', now, { error: { code: read.problem.code, message: read.problem.message } }))\n throw new TransferEngineError('invalid', 422, read.problem.message, read.problem)\n }\n const maxRows = resource.limits?.maxRows ?? TRANSFER_DEFAULT_MAX_ROWS\n const rowCount = read.table.rows.length\n if (rowCount > maxRows) {\n const message = `${resource.label} are imported at most ${maxRows.toLocaleString('en-US')} rows at a time; this file has ${rowCount.toLocaleString('en-US')}. Split it and import each part.`\n await saveJob(deps, moveJob(job, 'failed', now, { error: { code: 'tooManyRows', message } }))\n throw new TransferEngineError('tooLarge', 413, message)\n }\n if (!rowCount) throw new TransferEngineError('invalid', 422, 'The file has a header and no rows.')\n\n const sourcePath = transferSourcePath(input.orgId, job.id)\n await deps.bucket.file(sourcePath).save(whole, { contentType: transferContentType(format), resumable: false })\n if (parts > 1) {\n await eachLimited(\n Array.from({ length: parts }, (_unused, index) => index),\n TRANSFER_WRITE_CONCURRENCY,\n async (index) => {\n await deps.bucket.file(transferPartPath(input.orgId, job.id, index)).delete({ ignoreNotFound: true })\n },\n )\n }\n const done: TransferJobRecord = {\n ...job,\n updatedAt: now,\n sourcePath,\n rowCount,\n chunkCount: transferChunkRanges(rowCount).length,\n headers: read.table.headers,\n upload: { parts, received: Array.from({ length: parts }, (_unused, index) => index), bytes: whole.length, complete: true },\n }\n await saveJob(deps, done)\n return { job: done, complete: true }\n}\n\nasync function loadTable(deps: TransferEngineDeps, job: TransferJobRecord): Promise<TransferSourceTable> {\n if (!job.sourcePath || !job.upload?.complete) {\n throw new TransferEngineError('state', 409, 'The file has not finished uploading.')\n }\n const [bytes] = await deps.bucket.file(job.sourcePath).download()\n const read = readTransferSource(textOf(bytes), job.format, job.read ?? {})\n if ('problem' in read) throw new TransferEngineError('invalid', 422, read.problem.message, read.problem)\n return read.table\n}\n\n/*==========================================\n * ANALYZE\n *=========================================*/\n\nfunction assertBeforeWrites(job: TransferJobRecord, what: string): void {\n if (job.applyStartedAt !== undefined || job.status === 'applying' || job.status === 'applied' || job.status === 'undone') {\n throw new TransferEngineError('state', 409, `This import has started writing; it cannot be ${what} again.`)\n }\n}\n\nfunction usableMapping(mapping: Readonly<Record<number, string | null | undefined>> | undefined): Record<number, string> {\n const out: Record<number, string> = {}\n for (const [column, fieldId] of Object.entries(mapping ?? {})) {\n if (typeof fieldId === 'string' && fieldId && /^\\d+$/.test(column)) out[Number(column)] = fieldId\n }\n return out\n}\n\nfunction isPicklistField(field: TransferField | undefined): field is TransferField & { picklistId: string } {\n return Boolean(field && (field.type === 'picklist' || field.type === 'multiPicklist') && field.picklistId)\n}\n\nasync function picklistLists(\n hooks: TransferRecordsHooks,\n ctx: TransferResourceContext,\n fields: readonly TransferField[],\n): Promise<Readonly<Record<string, TransferPicklistList>>> {\n const ids = [...new Set(fields.filter(isPicklistField).map((field) => field.picklistId))]\n if (!ids.length || !hooks.picklists) return {}\n return hooks.picklists(ctx, ids)\n}\n\n/** The picklist values each mapped picklist column carries, matched to the organization's list. */\nfunction analyzePicklistColumns(\n table: TransferSourceTable,\n mapping: Record<number, string>,\n byId: ReadonlyMap<string, TransferField>,\n lists: Readonly<Record<string, TransferPicklistList>>,\n): TransferPicklistAnalysis[] {\n const analyses: TransferPicklistAnalysis[] = []\n for (const [column, fieldId] of Object.entries(mapping)) {\n const field = byId.get(fieldId)\n if (!isPicklistField(field)) continue\n const list = lists[field.picklistId]\n if (!list) continue\n const incoming = collectPicklistValues(\n table.rows.map((cells, row) => {\n const derived = deriveTransferCell(field, cells[Number(column)])\n return { row, value: derived.ok ? derived.value : null }\n }),\n )\n const result = matchPicklistValues(list.set, incoming)\n analyses.push({\n fieldId,\n picklistId: field.picklistId,\n spec: list.spec,\n set: list.set,\n matched: result.matched,\n unmatched: result.unmatched,\n proposals: Object.fromEntries(result.unmatched.map((value) => [value.key, proposePicklistChoice(list.spec, value)])),\n })\n }\n return analyses\n}\n\n/** Record id → a name for it, for the records `ids` names that `records` holds. */\nfunction recordLabelsFor(\n records: ReadonlyMap<string, Readonly<Record<string, unknown>>>,\n ids: Iterable<string>,\n): Record<string, string> {\n const labels: Record<string, string> = {}\n for (const id of ids) {\n const label = transferRowLabel(records.get(id))\n if (label) labels[id] = label\n }\n return labels\n}\n\nexport interface AnalyzeTransferInput {\n orgId: string\n jobId: string\n actorUid: string\n mapping?: Record<number, string | null>\n /** Match key field ids, in priority order; the resource's defaults when absent. */\n matchKeys?: string[]\n dateOrders?: Record<string, TransferDateOrder>\n}\n\n/**\n * Reads the file and proposes a mapping: every column against the\n * resource's catalog and aliases, with the first rows as samples, and each\n * mapped picklist column's values against the organization's list. With\n * `mapping`, the values are read under that mapping instead of the proposal,\n * and the answer adds what reading every mapped field did over the whole\n * file and how the rows match existing records under `matchKeys`.\n */\nexport async function analyzeTransferJob(\n deps: TransferEngineDeps,\n input: AnalyzeTransferInput,\n): Promise<Omit<TransferAnalyzeResponse, 'ok'>> {\n const job = await readJob(deps, input.orgId, input.jobId)\n assertBeforeWrites(job, 'analyzed')\n const resource = await resolveResource(deps, job.resource)\n const hooks = transferRecordsHooks(resource)\n const ctx = contextFor(job, input.actorUid)\n const table = await loadTable(deps, job)\n const catalog = await transferResourceCatalog(resource, ctx)\n const samples = table.rows.slice(0, 20)\n const match = matchHeaders(table.headers, catalog.fields, {\n dictionaries: hooks.aliases ?? [],\n samples,\n })\n const mapping = input.mapping ? usableMapping(input.mapping) : match.mapping\n const byId = new Map(catalog.fields.map((field) => [field.id, field]))\n const lists = await picklistLists(hooks, ctx, catalog.fields)\n const picklists = analyzePicklistColumns(table, mapping, byId, lists)\n const lockedRules = [...(await transferResourceLockedRules(resource, ctx))]\n const offer = await transferResourceMatchKeys(resource, ctx)\n\n let review: Pick<TransferAnalyzeResponse, 'derivations' | 'lookups' | 'matches' | 'recordLabels'> = {}\n if (input.mapping) {\n const fieldOptions = transferDateOrderOptions(input.dateOrders)\n const read = table.rows.map((cells, index) => {\n const mapped = mapTransferRow(cells, mapping)\n return { index, cells: mapped, ...deriveTransferRow(byId, mapped, {}, fieldOptions) }\n })\n const mappedFields = [...new Set(Object.values(mapping))]\n .map((fieldId) => byId.get(fieldId))\n .filter((field): field is TransferField => Boolean(field))\n const keys = chosenMatchKeys(offer.keys, input.matchKeys ?? offer.defaults)\n const values = read.map((row) => row.values)\n const found = keys.length\n ? await lookupAll(hooks, ctx, matchLookupRequests(values, keys))\n : { lookup: new Map<string, string[]>(), records: new Map<string, Readonly<Record<string, unknown>>>() }\n // The resource's own matching, when it has one: the Matching step shows\n // the outcome the dry run will act on.\n const matched = await matchTransferResourceRows(resource, ctx, {\n rows: values,\n keys,\n lookup: found.lookup,\n records: found.records,\n })\n const outcomes: RowMatchOutcome[] = matched.outcomes\n const lookups = await lookupReviews(await resolveLookupColumns(deps, hooks, ctx, mapping, byId, read))\n review = {\n derivations: summarizeTransferDerivations(mappedFields, read),\n ...(lookups.length ? { lookups } : {}),\n matches: transferMatchReview(keys, outcomes, values),\n recordLabels: recordLabelsFor(matched.records, transferMatchedRecordIds(outcomes)),\n }\n }\n\n const now = clock(deps)\n const next = moveJob(job, 'analyzed', now, {\n headers: table.headers,\n rowCount: table.rows.length,\n chunkCount: transferChunkRanges(table.rows.length).length,\n mapping,\n })\n await saveJob(deps, next)\n return {\n job: next,\n headers: table.headers,\n rowCount: table.rows.length,\n samples: samples.map((cells) => cells.map(transferCellText)),\n catalog,\n match,\n mappingProblems: mappingProblems(mapping, catalog.fields),\n matchKeys: offer.keys,\n lockedRules,\n picklists,\n ...review,\n }\n}\n\n/*==========================================\n * LOOKUPS — cells that name another record (AGL-3541)\n *=========================================*/\n\n/** The most suggestions one unresolved value carries. */\nconst LOOKUP_SUGGESTIONS_MAX = 5\n\n/** The most rows one unresolved value lists. */\nconst LOOKUP_ROWS_MAX = 20\n\n/**\n * The names a lookup cell holds, trimmed, blanks dropped: one for a `lookup`\n * field, each item of a `list` field that names a target. `null` for a cell\n * that is neither text nor a list — a value no record could be named by.\n */\nfunction lookupCellNames(raw: unknown): string[] | null {\n if (isBlankTransferValue(raw)) return []\n const items = Array.isArray(raw) ? raw : [raw]\n if (items.some((item) => item !== null && item !== undefined && typeof item === 'object')) return null\n return items.map((item) => String(item ?? '').trim()).filter(Boolean)\n}\n\n/** Who answers a lookup field's target, and the context it is asked in. */\ninterface LookupTarget {\n hooks: TransferLookupTargetHooks\n ctx: TransferResourceContext\n}\n\n/**\n * The target of a lookup field: one the resource answers itself\n * (`lookupTargets`), or the declared resource it names, asked as that\n * resource in the same workspace and site.\n */\nasync function lookupTargetFor(\n deps: TransferEngineDeps,\n hooks: TransferRecordsHooks,\n ctx: TransferResourceContext,\n key: string,\n): Promise<LookupTarget> {\n const own = hooks.lookupTargets?.[key]\n if (own) return { hooks: own, ctx }\n const target = await resolveResource(deps, key)\n const targetCtx = { ...ctx, resource: target.key }\n // Linking rows to another resource's records is part of the import, so\n // it asks that resource's plan as an import does (AGL-3555): a workspace\n // without the feature cannot reach those records through a lookup either.\n if (transferPlanFeature('import', target)) {\n const org = await deps.firestore.collection('orgs').doc(ctx.orgId).get()\n const refusal = await transferPlanRefusal(\n { resource: target.key, orgId: ctx.orgId, hostId: ctx.hostId, org: (org.data() ?? {}) as Record<string, unknown> },\n 'import',\n )\n if (refusal) throw new TransferPlanRefusedError(refusal)\n }\n // The target's keys as they stand for it — read for the context when\n // they depend on it (one dataset's own fields).\n const { keys } = await transferResourceMatchKeys(target, targetCtx)\n return { hooks: { ...transferRecordsHooks(target), matchKeys: keys }, ctx: targetCtx }\n}\n\n/** One distinct value of a lookup column, as the file spelled it, and where. */\ninterface LookupValue {\n value: string\n key: string\n count: number\n rows: number[]\n}\n\n/** What one lookup column's values resolved to. */\ninterface LookupColumn {\n field: TransferField & { lookup: NonNullable<TransferField['lookup']> }\n target: LookupTarget\n /** Value key → the one record it names. */\n resolved: Map<string, string>\n /** Values naming no record, or several, by key. */\n unresolved: Map<string, LookupValue & { candidates: string[] }>\n /** Every record the lookups found, by id. */\n records: Map<string, Readonly<Record<string, unknown>>>\n}\n\n/**\n * A record's name for the person: the first text it holds — the name a\n * resource lists first, as every record label the wizard shows is — else\n * its first `by` value.\n */\nfunction lookupRecordLabel(record: Readonly<Record<string, unknown>> | undefined, by: readonly string[]): string | undefined {\n if (!record) return undefined\n const label = transferRowLabel(record)\n if (label) return label\n for (const fieldId of by) {\n const value = record[fieldId]\n if (value !== null && value !== undefined && String(value).trim()) return String(value).trim()\n }\n return undefined\n}\n\n/**\n * Every mapped lookup column's values resolved against its target: each\n * distinct value asked by id (when it could be one) and then by each `by`\n * field in order; the first key that names exactly one record decides. A\n * value that names several records, or none, is unresolved.\n */\nasync function resolveLookupColumns(\n deps: TransferEngineDeps,\n hooks: TransferRecordsHooks,\n ctx: TransferResourceContext,\n mapping: Record<number, string>,\n byId: ReadonlyMap<string, TransferField>,\n rows: ReadonlyArray<{ index: number; values: Readonly<Record<string, unknown>> }>,\n): Promise<LookupColumn[]> {\n const columns: LookupColumn[] = []\n for (const fieldId of new Set(Object.values(mapping))) {\n const field = byId.get(fieldId)\n if (!isTransferLookupField(field)) continue\n const values = new Map<string, LookupValue>()\n for (const row of rows) {\n // A value is counted once per row, however often a list repeats it.\n const inRow = new Set<string>()\n for (const text of lookupCellNames(row.values[field.id]) ?? []) {\n const key = transferLookupKey(text)\n if (inRow.has(key)) continue\n inRow.add(key)\n const seen = values.get(key)\n if (seen) {\n seen.count += 1\n if (seen.rows.length < LOOKUP_ROWS_MAX) seen.rows.push(row.index)\n } else {\n values.set(key, { value: text, key, count: 1, rows: [row.index] })\n }\n }\n }\n const target = await lookupTargetFor(deps, hooks, ctx, field.lookup.resource)\n const column: LookupColumn = { field, target, resolved: new Map(), unresolved: new Map(), records: new Map() }\n columns.push(column)\n if (!values.size) continue\n\n const keys: MatchKeySpec[] = [\n { fieldId: TRANSFER_ID_FIELD, normalizer: 'aglynId' },\n ...field.lookup.by.map(\n (by): MatchKeySpec =>\n target.hooks.matchKeys?.find((key) => key.fieldId === by) ?? { fieldId: by, normalizer: 'caseless' },\n ),\n ]\n const requests: MatchLookupRequest[] = keys\n .map((key) => {\n const wanted = new Set<string>()\n for (const entry of values.values()) {\n if (key.normalizer === 'aglynId' && !mayBeTransferRecordId(entry.value)) continue\n const normalized = normalizeMatchValue(key.normalizer, entry.value)\n if (normalized) wanted.add(normalized)\n }\n return { ...key, values: [...wanted] }\n })\n .filter((request) => request.values.length)\n const found = await lookupAll(target.hooks, target.ctx, requests)\n for (const [id, record] of found.records) column.records.set(id, record)\n\n for (const entry of values.values()) {\n let candidates: string[] = []\n for (const key of keys) {\n if (key.normalizer === 'aglynId' && !mayBeTransferRecordId(entry.value)) continue\n const normalized = normalizeMatchValue(key.normalizer, entry.value)\n const ids = normalized ? [...new Set(found.lookup.get(matchLookupKey(key.fieldId, normalized)) ?? [])] : []\n if (ids.length === 1) {\n column.resolved.set(entry.key, ids[0] as string)\n candidates = []\n break\n }\n if (ids.length > 1 && !candidates.length) candidates = ids\n }\n if (!column.resolved.has(entry.key)) column.unresolved.set(entry.key, { ...entry, candidates })\n }\n }\n return columns\n}\n\n/** The review the values step shows: every unresolved value, with records it may mean. */\nasync function lookupReviews(columns: readonly LookupColumn[]): Promise<TransferLookupReview[]> {\n const reviews: TransferLookupReview[] = []\n for (const column of columns) {\n const unresolved = [...column.unresolved.values()]\n const asked = unresolved.length && column.target.hooks.suggest\n ? await column.target.hooks.suggest(column.target.ctx, {\n by: column.field.lookup.by,\n values: unresolved.map((entry) => entry.value),\n })\n : {}\n reviews.push({\n fieldId: column.field.id,\n resolved: column.resolved.size,\n unresolved: unresolved.map((entry) => {\n const several: TransferLookupSuggestion[] = entry.candidates.map((recordId) => ({\n recordId,\n label: lookupRecordLabel(column.records.get(recordId), column.field.lookup.by) ?? recordId,\n }))\n const seen = new Set<string>()\n const suggestions = [...several, ...(asked[entry.value] ?? [])]\n .filter((suggestion) => {\n if (!suggestion?.recordId || seen.has(suggestion.recordId)) return false\n seen.add(suggestion.recordId)\n return true\n })\n .slice(0, LOOKUP_SUGGESTIONS_MAX)\n .map((suggestion) => ({ recordId: suggestion.recordId, label: String(suggestion.label || suggestion.recordId) }))\n return { value: entry.value, key: entry.key, count: entry.count, rows: entry.rows, suggestions }\n }),\n })\n }\n return reviews\n}\n\n/**\n * What the person must still decide about the lookup columns, by field: a\n * value with no choice, a \"create\" the target does not allow, and a record\n * chosen that does not exist. The records chosen are looked up by id.\n */\nasync function lookupChoiceProblems(\n columns: readonly LookupColumn[],\n choices: Readonly<Record<string, Readonly<Record<string, TransferLookupChoice>>>> | undefined,\n): Promise<Record<string, string[]>> {\n const problems: Record<string, string[]> = {}\n for (const column of columns) {\n const fieldChoices = choices?.[column.field.id] ?? {}\n const found: string[] = []\n const mapped = new Set<string>()\n for (const entry of column.unresolved.values()) {\n const choice = fieldChoices[entry.key]\n if (!choice) found.push(`Choose what to do with “${entry.value}”.`)\n else if (choice.action === 'create' && !column.field.lookup.creatable) {\n found.push(`“${entry.value}” cannot be created by this import; use a record, leave it blank or refuse the rows.`)\n } else if (choice.action === 'mapTo') {\n if (typeof choice.recordId !== 'string' || !choice.recordId) found.push(`Choose the record “${entry.value}” means.`)\n else if (!column.records.has(choice.recordId)) mapped.add(choice.recordId)\n }\n }\n if (mapped.size) {\n const known = await lookupAll(column.target.hooks, column.target.ctx, [\n { fieldId: TRANSFER_ID_FIELD, normalizer: 'aglynId', values: [...mapped] },\n ])\n for (const id of mapped) {\n if (known.records.has(id)) column.records.set(id, known.records.get(id) as Readonly<Record<string, unknown>>)\n else found.push(`The record chosen for a value no longer exists (${id}); choose again.`)\n }\n }\n if (found.length) problems[column.field.id] = found\n }\n return problems\n}\n\n/**\n * The person's lookup choices applied to the rows: a resolved value becomes\n * its record's id; an unresolved one its choice — the chosen record's id, a\n * record to create, nothing written, or the row refused — each noted on the\n * row as `unresolvedLookup`. A value left blank by choice is not written at\n * all: it must never read as \"clear the field\". In a list, each item is\n * decided on its own and an item left blank is dropped from the list; a\n * list whose every item was left blank is not written.\n */\nfunction applyLookupChoices(\n rows: TransferPlanRow[],\n columns: readonly LookupColumn[],\n choices: Readonly<Record<string, Readonly<Record<string, TransferLookupChoice>>>> | undefined,\n): void {\n for (const row of rows) {\n const values = row.values as Record<string, unknown>\n const notes = [...(row.notes ?? [])]\n for (const column of columns) {\n const raw = values[column.field.id]\n const names = lookupCellNames(raw)\n if (!names?.length) continue\n const ids: string[] = []\n let refused = false\n for (const text of names) {\n const key = transferLookupKey(text)\n const id = column.resolved.get(key)\n if (id) {\n ids.push(id)\n continue\n }\n const choice = choices?.[column.field.id]?.[key]\n const note = { class: 'unresolvedLookup' as const, fieldId: column.field.id, value: text }\n if (choice?.action === 'mapTo') {\n ids.push(choice.recordId)\n const label = lookupRecordLabel(column.records.get(choice.recordId), column.field.lookup.by)\n notes.push({ ...note, detail: label ? `Uses “${label}”` : 'Uses a chosen record' })\n } else if (choice?.action === 'create') {\n ids.push(transferLookupNewValue(text))\n notes.push({ ...note, detail: 'Creates it' })\n } else if (choice?.action === 'refuseRow') {\n refused = true\n notes.push({ ...note, refuse: true, detail: 'Refuses the row' })\n } else {\n notes.push({ ...note, detail: 'Left blank' })\n }\n }\n if (refused || !ids.length) delete values[column.field.id]\n else values[column.field.id] = Array.isArray(raw) ? [...new Set(ids)] : ids[0]\n }\n if (notes.length) row.notes = notes\n }\n}\n\n/*==========================================\n * PLAN — the dry run\n *=========================================*/\n\ninterface PicklistColumn {\n field: TransferField & { picklistId: string }\n resolution: PicklistResolution\n /** Keys the person chose to add. */\n added: Set<string>\n /** Keys that resolve to blank: unmatched and left blank. */\n blank: Set<string>\n}\n\n/** The rows read, picklists resolved: what `buildTransferPlan` takes. */\nfunction readPlanRows(\n table: TransferSourceTable,\n mapping: Record<number, string>,\n byId: ReadonlyMap<string, TransferField>,\n columns: readonly PicklistColumn[],\n choices: TransferPlanChoices,\n): TransferPlanRow[] {\n return table.rows.map((cells, index): TransferPlanRow => {\n const derived = deriveTransferRow(\n byId,\n mapTransferRow(cells, mapping),\n choices.derive ?? {},\n transferDateOrderOptions(choices.dateOrders),\n )\n const notes: TransferRowNote[] = []\n for (const column of columns) {\n const fieldId = column.field.id\n const value = derived.values[fieldId]\n if (value === null || value === undefined) continue\n const noteFor = (raw: unknown): void => {\n const label = normalizePicklistLabel(raw)\n if (!label) return\n const key = picklistLabelKey(label)\n if (column.added.has(key)) notes.push({ class: 'newPicklistValue', fieldId, value: String(raw) })\n else if (column.blank.has(key)) notes.push({ class: 'unmatchedPicklist', fieldId, value: String(raw), detail: 'Left blank' })\n }\n if (column.field.type === 'multiPicklist' && Array.isArray(value)) {\n const outcome = resolveMultiPicklistCell(column.resolution, value)\n if (outcome.kind === 'refuse') {\n notes.push({ class: 'unmatchedPicklist', fieldId, value: value.join(', '), refuse: true, detail: 'Refuses the row' })\n continue\n }\n for (const raw of value) noteFor(raw)\n if (outcome.labels.length) derived.values[fieldId] = outcome.labels\n else delete derived.values[fieldId]\n continue\n }\n const outcome = resolvePicklistCell(column.resolution, value)\n if (outcome.kind === 'refuse') {\n notes.push({ class: 'unmatchedPicklist', fieldId, value: String(value), refuse: true, detail: 'Refuses the row' })\n continue\n }\n noteFor(value)\n // A value left blank by choice is not written at all: a blank here\n // must never read as \"clear the field\".\n if (outcome.kind === 'value') derived.values[fieldId] = outcome.label\n else delete derived.values[fieldId]\n }\n return {\n index,\n values: derived.values,\n derivations: derived.derivations,\n problems: derived.problems,\n ...(notes.length ? { notes } : {}),\n }\n })\n}\n\n/** The match keys the person chose, in their order, from the resource's own. */\nfunction chosenMatchKeys(keys: readonly MatchKeySpec[], chosen: readonly string[]): MatchKeySpec[] {\n return chosen.map((fieldId) => {\n const key = keys.find((entry) => entry.fieldId === fieldId)\n if (!key) throw new TransferEngineError('invalid', 400, `\"${fieldId}\" is not a key records can be matched by.`)\n return key\n })\n}\n\n/** Every lookup request, cut so no single request carries more than {@link MATCH_LOOKUP_SLICE} values. */\nfunction sliceLookupRequests(requests: readonly MatchLookupRequest[]): MatchLookupRequest[][] {\n const slices: MatchLookupRequest[][] = []\n for (const request of requests) {\n for (let at = 0; at < request.values.length; at += MATCH_LOOKUP_SLICE) {\n slices.push([{ ...request, values: request.values.slice(at, at + MATCH_LOOKUP_SLICE) }])\n }\n }\n return slices\n}\n\nasync function lookupAll(\n hooks: Pick<TransferRecordsHooks, 'lookup'>,\n ctx: TransferResourceContext,\n requests: readonly MatchLookupRequest[],\n): Promise<{ lookup: Map<string, string[]>; records: Map<string, Readonly<Record<string, unknown>>> }> {\n const lookup = new Map<string, string[]>()\n const records = new Map<string, Readonly<Record<string, unknown>>>()\n for (const slice of sliceLookupRequests(requests)) {\n const found = await hooks.lookup(ctx, slice)\n for (const [key, ids] of found.lookup) lookup.set(key, [...new Set([...(lookup.get(key) ?? []), ...ids])])\n for (const [id, values] of found.records) records.set(id, values)\n }\n return { lookup, records }\n}\n\n/**\n * The dry run: every row read, its picklist values resolved, matched to the\n * records that exist and planned under the policy — without writing a\n * record. The planned rows are stored chunk by chunk for Apply; the summary,\n * the warnings and the first page answer the wizard.\n */\nexport async function planTransferJob(\n deps: TransferEngineDeps,\n input: { orgId: string; jobId: string; actorUid: string; choices: TransferPlanChoices },\n): Promise<Omit<TransferPlanResponse, 'ok'>> {\n const job = await readJob(deps, input.orgId, input.jobId)\n assertBeforeWrites(job, 'planned')\n if (job.status === 'draft') throw new TransferEngineError('state', 409, 'Analyze the file before planning it.')\n const resource = await resolveResource(deps, job.resource)\n const hooks = transferRecordsHooks(resource)\n const choices = input.choices\n // The plugin steps' answers as sent with this dry run, not the last one's.\n const ctx: TransferResourceContext = { ...contextFor(job, input.actorUid) }\n delete ctx.extras\n if (choices.extras) ctx.extras = choices.extras\n const table = await loadTable(deps, job)\n const catalog = await transferResourceCatalog(resource, ctx)\n const byId = new Map(catalog.fields.map((field) => [field.id, field]))\n\n const mapping = usableMapping(choices.mapping)\n const problems = mappingProblems(mapping, catalog.fields)\n if (!mappingIsUsable(problems)) {\n throw new TransferEngineError('invalid', 422, 'Resolve the mapping before the dry run.', problems)\n }\n const lockedRules = await transferResourceLockedRules(resource, ctx)\n // The person's choices over the resource's starting point (AGL-3548).\n const defaults = await transferResourcePolicyDefaults(resource, ctx, catalog.fields)\n const policy = createTransferPolicy({ ...withTransferPolicyDefaults(defaults, choices.policy ?? {}), locked: lockedRules })\n const policyProblems = transferPolicyProblems(policy, catalog.fields)\n if (policyProblems.length) throw new TransferEngineError('invalid', 422, policyProblems[0] as string, policyProblems)\n const offer = await transferResourceMatchKeys(resource, ctx)\n const keys = chosenMatchKeys(offer.keys, choices.matchKeys ?? offer.defaults)\n\n // Picklists: every unmatched value needs the person's choice.\n const lists = await picklistLists(hooks, ctx, catalog.fields)\n const analyses = analyzePicklistColumns(table, mapping, byId, lists)\n const columns: PicklistColumn[] = []\n const choiceProblems: Record<string, string[]> = {}\n const additions: Record<string, PicklistValue[]> = {}\n for (const analysis of analyses) {\n const fieldChoices: Record<string, PicklistValueChoice> = choices.picklistChoices?.[analysis.fieldId] ?? {}\n const found = picklistChoiceProblems(analysis.spec, analysis.set, analysis.unmatched, fieldChoices)\n if (found.length) {\n choiceProblems[analysis.fieldId] = found\n continue\n }\n const resolution = resolvePicklistChoices(\n analysis.spec,\n analysis.set,\n { matched: analysis.matched, unmatched: analysis.unmatched },\n fieldChoices,\n )\n const added = new Set<string>()\n const blank = new Set<string>()\n for (const value of analysis.unmatched) {\n const choice = fieldChoices[value.key]\n if (choice?.action === 'addValue') added.add(value.key)\n else if (choice?.action !== 'mapTo' && choice?.action !== 'refuseRow') blank.add(value.key)\n }\n const list = (additions[analysis.picklistId] ??= [])\n for (const value of resolution.added) {\n if (!list.some((entry) => entry.id === value.id)) list.push(value)\n }\n columns.push({ field: byId.get(analysis.fieldId) as PicklistColumn['field'], resolution, added, blank })\n }\n for (const [picklistId, values] of Object.entries(additions)) if (!values.length) delete additions[picklistId]\n\n const rows = readPlanRows(table, mapping, byId, columns, choices)\n\n // Lookups: every value that names no record needs the person's choice too.\n const lookupColumns = await resolveLookupColumns(deps, hooks, ctx, mapping, byId, rows)\n const lookupProblems = await lookupChoiceProblems(lookupColumns, choices.lookupChoices)\n for (const [fieldId, found] of Object.entries(lookupProblems)) {\n choiceProblems[fieldId] = [...(choiceProblems[fieldId] ?? []), ...found]\n }\n if (Object.keys(choiceProblems).length) {\n throw new TransferEngineError(\n 'choicesNeeded',\n 422,\n Object.keys(lookupProblems).length\n ? 'Choose what to do with every value the list does not hold and every record the file names that was not found.'\n : 'Choose what to do with every value the list does not hold.',\n choiceProblems,\n )\n }\n applyLookupChoices(rows, lookupColumns, choices.lookupChoices)\n const values = rows.map((row) => row.values)\n const looked = keys.length\n ? await lookupAll(hooks, ctx, matchLookupRequests(values, keys))\n : { lookup: new Map<string, string[]>(), records: new Map<string, Readonly<Record<string, unknown>>>() }\n const { outcomes: matches, records } = await matchTransferResourceRows(resource, ctx, {\n rows: values,\n keys,\n lookup: looked.lookup,\n records: looked.records,\n })\n const found = { lookup: looked.lookup, records }\n const plan = await planTransferResourceRows(resource, ctx, {\n fields: catalog.fields,\n rows,\n matches,\n existing: found.records,\n policy,\n })\n\n const failures: TransferPlanInvariantFailure[] = transferInvariantFailures(hooks.invariants, plan.rows, found.records)\n if (failures.length) {\n const failing = new Set(failures.map((failure) => failure.row))\n plan.rows = plan.rows.map(\n (row): PlannedTransferRow =>\n failing.has(row.index) ? { ...row, verdict: 'fail', reason: 'refusedValue', diff: [] } : row,\n )\n plan.summary = { create: 0, update: 0, unchanged: 0, skip: 0, fail: 0, total: plan.rows.length }\n for (const row of plan.rows) plan.summary[row.verdict] += 1\n }\n\n // The stored dry run, replaced whole.\n const jobRef = transferJobsCollection(deps.firestore, job.orgId).doc(job.id)\n await clearCollection(jobRef.collection('chunks'))\n const ranges = transferChunkRanges(plan.rows.length)\n await eachLimited(ranges, TRANSFER_WRITE_CONCURRENCY, async (range) => {\n await writeJsonDoc(\n jobRef.collection('chunks').doc(String(range.index)),\n { jobId: job.id, index: range.index, start: range.start, end: range.end },\n plan.rows.slice(range.start, range.end),\n )\n })\n\n const now = clock(deps)\n const matchSummary = summarizeMatches(matches)\n const allConflicts = transferPlanConflicts({\n fields: byId,\n rows,\n matches,\n existing: found.records,\n policy,\n ...(hooks.valuesEqual ? { valuesEqual: hooks.valuesEqual } : {}),\n })\n const conflicts = allConflicts.slice(0, TRANSFER_PLAN_CONFLICTS_MAX)\n const ambiguous = transferAmbiguities(matches)\n const sample = transferPlanSample(plan.rows)\n const labelled = new Set<string>()\n for (const row of sample) if (row.recordId) labelled.add(row.recordId)\n for (const conflict of conflicts) labelled.add(conflict.recordId)\n for (const row of ambiguous) for (const id of row.recordIds) labelled.add(id)\n const next = moveJob(job, 'planned', now, {\n mapping,\n matchKeys: keys.map((key) => key.fieldId),\n policy,\n picklistChoices: choices.picklistChoices ?? {},\n lookupChoices: choices.lookupChoices ?? {},\n ...(choices.derive ? { derive: choices.derive } : {}),\n ...(choices.dateOrders ? { dateOrders: choices.dateOrders } : {}),\n ...(choices.extras ? { extras: choices.extras } : {}),\n picklistAdditions: additions,\n summary: plan.summary,\n warnings: plan.warnings,\n acknowledgementsRequired: plan.acknowledgementsRequired,\n acknowledged: [],\n matchSummary,\n invariantFailures: failures.slice(0, 50),\n invariantFailureCount: failures.length,\n rowCount: plan.rows.length,\n chunkCount: ranges.length,\n plannedAt: now,\n })\n await saveJob(deps, next)\n const first = plan.rows.slice(0, 50)\n return {\n job: next,\n summary: plan.summary,\n warnings: plan.warnings,\n acknowledgementsRequired: plan.acknowledgementsRequired,\n matchSummary,\n invariantFailures: failures.slice(0, 50),\n invariantFailureCount: failures.length,\n picklistAdditions: additions,\n rows: { rows: first, offset: 0, next: plan.rows.length > first.length ? first.length : null },\n sample,\n conflicts,\n conflictCount: allConflicts.length,\n ambiguous,\n recordLabels: recordLabelsFor(found.records, labelled),\n }\n}\n\nasync function readChunkRows(\n jobRef: FirebaseFirestore.DocumentReference,\n index: number,\n): Promise<{ range: TransferChunkRange; rows: PlannedTransferRow[] } | null> {\n const ref = jobRef.collection('chunks').doc(String(index))\n const snapshot = await ref.get()\n if (!snapshot.exists) return null\n const data = snapshot.data() as TransferChunkRange\n const rows = (await readJsonDoc<PlannedTransferRow[]>(ref)) ?? []\n return { range: { index: data.index, start: data.start, end: data.end }, rows }\n}\n\n/** One page of the stored dry run, optionally only rows with some verdicts. */\nexport async function readTransferPlanRows(\n deps: TransferEngineDeps,\n input: { orgId: string; jobId: string; offset?: number; limit?: number; verdicts?: readonly TransferRowVerdict[] },\n): Promise<TransferPlanRowsPage> {\n const job = await readJob(deps, input.orgId, input.jobId)\n if (job.plannedAt === undefined) throw new TransferEngineError('state', 409, 'This import has no dry run yet.')\n const offset = Math.max(0, Math.floor(Number(input.offset ?? 0)) || 0)\n const limit = Math.min(TRANSFER_PLAN_PAGE_MAX, Math.max(1, Math.floor(Number(input.limit ?? 50)) || 50))\n const filter = input.verdicts?.length ? new Set(input.verdicts) : null\n const jobRef = transferJobsCollection(deps.firestore, job.orgId).doc(job.id)\n const rows: PlannedTransferRow[] = []\n let seen = 0\n let more = false\n scan: for (let index = 0; index < (job.chunkCount ?? 0); index += 1) {\n const chunk = await readChunkRows(jobRef, index)\n if (!chunk) break\n for (const row of chunk.rows) {\n if (filter && !filter.has(row.verdict)) continue\n if (seen >= offset) {\n if (rows.length >= limit) {\n more = true\n break scan\n }\n rows.push(row)\n }\n seen += 1\n }\n }\n return { rows, offset, next: more ? offset + rows.length : null }\n}\n\n/*==========================================\n * APPLY\n *=========================================*/\n\nexport interface ApplyTransferInput {\n orgId: string\n jobId: string\n /** Whose import it is, for the plugin's own checks and activity lines. */\n actorUid: string\n acknowledged?: readonly TransferWarningClass[]\n /** When this request must stop starting chunks (epoch ms). */\n deadlineMs: number\n /** Who is driving: a request id, or the sweep. */\n driver: string\n}\n\nexport interface ApplyTransferOutcome {\n job: TransferJobRecord\n progress: TransferProgress\n done: boolean\n /** This call moved the job into `applying` (the first call, or a resume after a failure). */\n started: boolean\n /** That move was a resume after a failure. */\n resumed: boolean\n /** The results of the chunks this call wrote. */\n results: TransferRowResult[]\n}\n\n/** A row the plan does not write, as its result. */\nfunction plannedResult(row: PlannedTransferRow): TransferRowResult {\n if (row.verdict === 'unchanged') return { row: row.index, outcome: 'unchanged', ...(row.recordId ? { recordId: row.recordId } : {}) }\n if (row.verdict === 'skip') return { row: row.index, outcome: 'skipped', ...(row.reason ? { reason: row.reason } : {}) }\n return {\n row: row.index,\n outcome: 'failed',\n ...(row.recordId ? { recordId: row.recordId } : {}),\n ...(row.reason ? { reason: row.reason } : {}),\n }\n}\n\nexport function addResults(total: TransferResultSummary, more: TransferResultSummary): TransferResultSummary {\n return {\n created: total.created + more.created,\n updated: total.updated + more.updated,\n unchanged: total.unchanged + more.unchanged,\n skipped: total.skipped + more.skipped,\n failed: total.failed + more.failed,\n total: total.total + more.total,\n }\n}\n\nexport interface LedgerEntry {\n result: TransferRowResult\n undo: TransferUndoEntry | null\n}\n\n/** Takes the job for `driver`, or refuses: another driver holds it, or another import of the resource is running. */\nexport async function takeLease(\n deps: TransferEngineDeps,\n job: TransferJobRecord,\n driver: string,\n expiresAt: number,\n enter: (current: TransferJobRecord, now: number) => TransferJobRecord,\n): Promise<TransferJobRecord> {\n const jobs = transferJobsCollection(deps.firestore, job.orgId)\n return deps.firestore.runTransaction(async (transaction) => {\n const ref = jobs.doc(job.id)\n const snapshot = await transaction.get(ref)\n if (!snapshot.exists) throw new TransferEngineError('notFound', 404, 'No such import.')\n const current = { ...(snapshot.data() as TransferJobRecord), id: job.id }\n const now = clock(deps)\n if (current.lease && current.lease.expiresAt > now && current.lease.owner !== driver) {\n throw new TransferEngineError('busy', 409, 'This import is already running in another window. Its progress shows here.')\n }\n const running = await transaction.get(\n jobs.where('resource', '==', current.resource).where('status', '==', 'applying').limit(5),\n )\n const other = running.docs.find((doc) => doc.id !== job.id)\n if (other) {\n throw new TransferEngineError('busy', 409, 'Another import of the same records is running. Wait for it to finish.', {\n jobId: other.id,\n })\n }\n const next = { ...enter(current, now), lease: { owner: driver, expiresAt } }\n transaction.set(ref, storedJob(next))\n return next\n })\n}\n\n/**\n * Writes chunks until the budget runs out (see the block header). The first\n * call needs every required acknowledgement; later calls — the browser's\n * next, or the sweep's — resume at the cursor. A plugin `apply` that throws\n * fails the job with the chunk named, and calling again resumes it.\n */\nexport async function applyTransferJob(\n deps: TransferEngineDeps,\n input: ApplyTransferInput,\n): Promise<ApplyTransferOutcome> {\n let job = await readJob(deps, input.orgId, input.jobId)\n if (job.status === 'applied') {\n return { job, progress: transferJobProgress(job), done: true, started: false, resumed: false, results: [] }\n }\n if (job.status !== 'planned' && job.status !== 'applying' && job.status !== 'failed') {\n throw new TransferEngineError('state', 409, `This import is ${job.status}; plan it before applying.`)\n }\n if (job.plannedAt === undefined || !job.summary) {\n throw new TransferEngineError('state', 409, 'This import has no dry run yet.')\n }\n const acknowledged = [...(input.acknowledged ?? job.acknowledged ?? [])]\n if (job.applyStartedAt === undefined) {\n const plan = { acknowledgementsRequired: job.acknowledgementsRequired ?? [], summary: job.summary }\n if (!canApplyTransferPlan(plan, acknowledged)) {\n const missing = missingAcknowledgements(plan, acknowledged)\n if (!missing.length) throw new TransferEngineError('state', 409, 'The dry run writes nothing.')\n throw new TransferEngineError('acknowledgementsMissing', 422, 'Acknowledge every warning before applying.', {\n missing,\n })\n }\n }\n const resource = await resolveResource(deps, job.resource)\n const hooks = transferRecordsHooks(resource)\n const ctx = contextFor(job, input.actorUid)\n let started = false\n let resumed = false\n job = await takeLease(deps, job, input.driver, input.deadlineMs + TRANSFER_LEASE_GRACE_MS, (current, now) => {\n if (current.status === 'applying') return current\n started = true\n resumed = current.status === 'failed'\n return moveJob(current, 'applying', now, {\n acknowledged: current.applyStartedAt === undefined ? acknowledged : current.acknowledged,\n cursor: current.cursor ?? { chunk: 0, rowsDone: 0 },\n applyStartedAt: current.applyStartedAt ?? now,\n results: current.results ?? emptyResults(),\n })\n })\n\n const jobRef = transferJobsCollection(deps.firestore, job.orgId).doc(job.id)\n const timeLeft = () => input.deadlineMs - clock(deps)\n const written: TransferRowResult[] = []\n try {\n if (!job.picklistsAdded) {\n for (const [picklistId, values] of Object.entries(job.picklistAdditions ?? {})) {\n if (values.length) await hooks.addPicklistValues?.(ctx, picklistId, values)\n }\n job = { ...job, picklistsAdded: true, updatedAt: clock(deps) }\n await saveJob(deps, job)\n }\n const chunkCount = job.chunkCount ?? 0\n while ((job.cursor?.chunk ?? 0) < chunkCount && timeLeft() > TRANSFER_MIN_CHUNK_BUDGET_MS) {\n const next = await applyChunk(deps, job, jobRef, hooks, ctx, timeLeft)\n if (!next) break\n job = next.job\n written.push(...next.results)\n }\n } catch (error) {\n const chunk = job.cursor?.chunk ?? 0\n const message = error instanceof Error ? error.message : String(error)\n job = moveJob(job, 'failed', clock(deps), {\n error: { code: 'applyFailed', message: `Chunk ${chunk + 1} could not be written: ${message}`, chunk },\n lease: null,\n })\n await saveJob(deps, job)\n return { job, progress: transferJobProgress(job), done: false, started, resumed, results: written }\n }\n\n const done = (job.cursor?.chunk ?? 0) >= (job.chunkCount ?? 0)\n job = done\n ? moveJob(job, 'applied', clock(deps), { lease: null })\n : { ...job, lease: null, updatedAt: clock(deps) }\n await saveJob(deps, job)\n return { job, progress: transferJobProgress(job), done, started, resumed, results: written }\n}\n\n/**\n * One chunk, through the plugin's `apply` and the ledger. Answers the job\n * with the cursor moved past the chunk and the chunk's results, or `null`\n * when the chunk is not complete yet (the budget ran short and the plugin\n * stopped at a row).\n */\nasync function applyChunk(\n deps: TransferEngineDeps,\n job: TransferJobRecord,\n jobRef: FirebaseFirestore.DocumentReference,\n hooks: TransferRecordsHooks,\n ctx: TransferResourceContext,\n timeLeft: () => number,\n): Promise<{ job: TransferJobRecord; results: TransferRowResult[] } | null> {\n const index = job.cursor?.chunk ?? 0\n const chunk = await readChunkRows(jobRef, index)\n if (!chunk) throw new Error(`the dry run has no chunk ${index + 1}`)\n const ledgerCollection = jobRef.collection('ledger')\n const ledger = new Map<number, LedgerEntry>()\n for (const doc of (await ledgerCollection.where('chunk', '==', index).get()).docs) {\n const data = doc.data() as { row: number; result: TransferRowResult; undoJson?: string | null }\n ledger.set(data.row, { result: data.result, undo: data.undoJson ? (JSON.parse(data.undoJson) as TransferUndoEntry) : null })\n }\n\n const writer: TransferApplyWriter = {\n async alreadyApplied(row) {\n return ledger.get(row)?.result ?? null\n },\n async markApplied(result, undo) {\n if (ledger.has(result.row)) return\n try {\n await ledgerCollection.doc(transferLedgerKey(job.id, result.row)).create(\n stored({ row: result.row, chunk: index, result, undoJson: undo ? JSON.stringify(undo) : null, at: clock(deps) }),\n )\n } catch (error) {\n if (!isAlreadyExists(error)) throw error\n }\n ledger.set(result.row, { result, undo: undo ?? null })\n },\n timeLeftMs: timeLeft,\n }\n\n const writes = chunk.rows.filter((row) => row.verdict === 'create' || row.verdict === 'update')\n if (writes.some((row) => !ledger.has(row.index))) {\n const applied = await hooks.apply(ctx, { jobId: job.id, index, start: chunk.range.start, end: chunk.range.end, rows: writes }, writer)\n const planned = new Set(writes.map((row) => row.index))\n for (const result of applied.results) {\n if (!planned.has(result.row) || ledger.has(result.row)) continue\n await writer.markApplied(result, applied.undo.find((entry) => entry.row === result.row))\n }\n }\n if (writes.some((row) => !ledger.has(row.index))) return null\n\n const results = chunk.rows.map((row) =>\n row.verdict === 'create' || row.verdict === 'update' ? (ledger.get(row.index) as LedgerEntry).result : plannedResult(row),\n )\n const undo: TransferUndoEntry[] = writes\n .map((row) => ledger.get(row.index)?.undo ?? null)\n .filter((entry): entry is TransferUndoEntry => entry !== null)\n const now = clock(deps)\n const next: TransferJobRecord = {\n ...job,\n cursor: { chunk: index + 1, rowsDone: chunk.range.end },\n results: addResults(job.results ?? emptyResults(), summarizeTransferResults(results)),\n updatedAt: now,\n }\n const undoJson = JSON.stringify(undo)\n const batch = deps.firestore.batch()\n batch.set(jobRef.collection('results').doc(String(index)), stored({ jobId: job.id, index, results, completedAt: now }))\n if (undoJson.length <= JSON_PIECE_CHARS) {\n batch.set(jobRef.collection('undo').doc(String(index)), { jobId: job.id, chunk: index, json: undoJson })\n }\n batch.set(jobRef, storedJob(next))\n if (undoJson.length > JSON_PIECE_CHARS) {\n // Too large for the batch: the undo snapshot is written whole first, so\n // the cursor never moves past a chunk whose undo is missing.\n await writeJsonDoc(jobRef.collection('undo').doc(String(index)), { jobId: job.id, chunk: index }, undo)\n }\n await batch.commit()\n\n // The ledger has done its work once the results are committed.\n const entries = (await ledgerCollection.where('chunk', '==', index).get()).docs\n await eachLimited(entries, TRANSFER_WRITE_CONCURRENCY, async (doc) => {\n await doc.ref.delete()\n })\n return { job: next, results }\n}\n\n/*==========================================\n * STATUS AND THE RESULT FILE\n *=========================================*/\n\n/** The job, its progress, and whether undo is open. */\nexport async function readTransferJobStatus(\n deps: TransferEngineDeps,\n input: { orgId: string; jobId: string; include?: 'results' },\n): Promise<{\n job: TransferJobRecord\n progress: TransferProgress\n undo: { available: boolean; expiresAt: number | null; state: TransferUndoState | null }\n rows?: TransferRowResult[]\n}> {\n const job = await readJob(deps, input.orgId, input.jobId)\n const rows =\n input.include === 'results'\n ? [...(await readResults(transferJobsCollection(deps.firestore, job.orgId).doc(job.id))).values()].sort(\n (a, b) => a.row - b.row,\n )\n : undefined\n return {\n ...(rows ? { rows } : {}),\n job,\n progress: transferJobProgress(job),\n undo: {\n available: transferUndoAvailable(job, clock(deps)) && job.undo?.status !== 'done',\n expiresAt: transferUndoExpiresAt(job),\n state: job.undo ?? null,\n },\n }\n}\n\nasync function readResults(\n jobRef: FirebaseFirestore.DocumentReference,\n): Promise<Map<number, TransferRowResult>> {\n const results = new Map<number, TransferRowResult>()\n for (const doc of (await jobRef.collection('results').get()).docs) {\n for (const result of ((doc.data() as { results?: TransferRowResult[] }).results ?? [])) results.set(result.row, result)\n }\n return results\n}\n\n\n/**\n * The result file: every row of the file as it was sent, then what happened\n * to it, why, and the record it wrote. A row not written yet says `pending`.\n */\nexport async function transferResultFile(\n deps: TransferEngineDeps,\n input: { orgId: string; jobId: string },\n): Promise<{ csv: string; rows: number; fileName: string }> {\n const job = await readJob(deps, input.orgId, input.jobId)\n if (job.applyStartedAt === undefined) throw new TransferEngineError('state', 409, 'Nothing has been written yet.')\n if (job.kind === 'package') {\n const { transferPackageResultFile } = await import('./transfer-packages')\n return transferPackageResultFile(deps, job)\n }\n if (job.trimmedAt !== undefined) {\n throw new TransferEngineError(\n 'state',\n 409,\n 'The file behind this import was cleared once its undo window closed; its results are still counted.',\n )\n }\n const table = await loadTable(deps, job)\n const results = await readResults(transferJobsCollection(deps.firestore, job.orgId).doc(job.id))\n // Every cell through the one escaper, so a formula the file carried is not\n // armed again in the copy handed back (a number from a JSON file stays one).\n const lines = [[...table.headers, ...TRANSFER_RESULT_COLUMNS].map((cell) => escapeCsvCell(cell)).join(',')]\n table.rows.forEach((cells, row) => {\n const result = results.get(row)\n const tail = result\n ? [result.outcome, result.message ?? (result.reason ? String(result.reason) : ''), result.recordId ?? '']\n : ['pending', '', '']\n lines.push(\n [\n ...table.headers.map((_header, column) =>\n escapeCsvCell(transferCellText(cells[column]), { numeric: typeof cells[column] === 'number' }),\n ),\n ...tail.map((cell) => escapeCsvCell(cell)),\n ].join(','),\n )\n })\n const base = (job.fileName ?? 'import').replace(/\\.[a-z0-9]+$/i, '')\n return { csv: `${lines.join('\\r\\n')}\\r\\n`, rows: table.rows.length, fileName: `${base}-results.csv` }\n}\n\n/*==========================================\n * THE HISTORY — the workspace's imports, for the hub (AGL-3535)\n *=========================================*/\n\n/**\n * The workspace's imports, newest first, a page at a time, as the hub's\n * history lists them. Clients cannot read the jobs' subcollections, and\n * the hub needs more than the job document says — whether undo is still\n * open, whether the result file can still be made — so the route answers\n * this. `labels` names each resource; `emailsOf` says who each member is.\n */\nexport async function listTransferJobs(\n deps: TransferEngineDeps,\n input: {\n orgId: string\n limit?: number\n after?: number | null\n labels?: Readonly<Record<string, string>>\n emailsOf?: (uids: readonly string[]) => Promise<ReadonlyMap<string, string>>\n },\n): Promise<{ jobs: TransferJobSummary[]; next: number | null }> {\n const limit = Math.min(TRANSFER_JOBS_PAGE_MAX, Math.max(1, Math.floor(Number(input.limit ?? 20)) || 20))\n let query = transferJobsCollection(deps.firestore, input.orgId).orderBy('createdAt', 'desc')\n if (typeof input.after === 'number' && Number.isFinite(input.after)) query = query.where('createdAt', '<', input.after)\n const snapshot = await query.limit(limit + 1).get()\n const page = snapshot.docs.slice(0, limit).map((doc) => ({ ...(doc.data() as TransferJobRecord), id: doc.id }))\n const uids = [...new Set(page.map((job) => job.createdBy).filter(Boolean))]\n const emails = input.emailsOf && uids.length ? await input.emailsOf(uids).catch(() => new Map<string, string>()) : new Map<string, string>()\n const now = clock(deps)\n const jobs = page.map((job): TransferJobSummary => ({\n id: job.id,\n resource: job.resource,\n // One instance's job (`data.dataset:<id>`) is named by its resource.\n label:\n input.labels?.[job.resource] ??\n input.labels?.[parseTransferResourceKey(job.resource).key] ??\n (job.kind === 'package' ? 'Package' : job.resource),\n kind: job.kind,\n status: job.status,\n hostId: job.hostId ?? null,\n fileName: job.fileName ?? null,\n createdAt: job.createdAt,\n updatedAt: job.updatedAt,\n createdBy: job.createdBy,\n createdByEmail: emails.get(job.createdBy) ?? null,\n rowCount: job.rowCount ?? 0,\n results: job.results ?? null,\n appliedAt: job.appliedAt ?? null,\n undo: {\n available: transferUndoAvailable(job, now) && job.undo?.status !== 'done',\n expiresAt: transferUndoExpiresAt(job),\n status: job.undo?.status ?? null,\n },\n resultFile: job.applyStartedAt !== undefined && job.trimmedAt === undefined,\n error: job.error?.message ?? null,\n }))\n const last = page[page.length - 1]\n return { jobs, next: snapshot.docs.length > limit && last ? last.createdAt : null }\n}\n\n/*==========================================\n * UNFINISHED IMPORTS (AGL-3549)\n *\n * An import the person left before it wrote anything — a tab closed\n * mid-wizard — is a job whose retention is `expire`: the cleanup deletes it\n * seven days after it was last touched. Until then the surface that started\n * it, and the hub, offer it back (`openImport({ jobId })` reopens the\n * wizard on its step) or throw it away now. Only its own creator's: a\n * colleague's half-made import is theirs to finish, and a statement of\n * permission made in it is theirs alone.\n *=========================================*/\n\nconst UNFINISHED_STATUSES = new Set(['draft', 'analyzed', 'planned', 'failed'])\n\n/**\n * The caller's unfinished imports of records, newest first — a Firestore\n * query on `(createdBy, retention, updatedAt ↓)`, never a page of the\n * history filtered.\n */\nexport async function listUnfinishedTransferJobs(\n deps: TransferEngineDeps,\n input: { orgId: string; actorUid: string; labels?: Readonly<Record<string, string>> },\n): Promise<TransferUnfinishedImportSummary[]> {\n const snapshot = await transferJobsCollection(deps.firestore, input.orgId)\n .where('createdBy', '==', input.actorUid)\n .where('retention', '==', 'expire')\n .orderBy('updatedAt', 'desc')\n .limit(TRANSFER_UNFINISHED_IMPORTS_MAX)\n .get()\n return snapshot.docs\n .map((doc) => ({ ...(doc.data() as TransferJobRecord), id: doc.id }))\n .filter((job) => job.kind !== 'package' && UNFINISHED_STATUSES.has(job.status))\n .map((job) => ({\n jobId: job.id,\n resource: job.resource,\n hostId: job.hostId ?? null,\n fileName: job.fileName ?? null,\n status: job.status as TransferUnfinishedImportSummary['status'],\n updatedAt: job.updatedAt,\n label:\n input.labels?.[job.resource] ?? input.labels?.[parseTransferResourceKey(job.resource).key] ?? job.resource,\n }))\n}\n\n/**\n * Throws one of the caller's unfinished imports away now: its job, its\n * pieces and its file, as the cleanup would a week on. Refused for someone\n * else's import, and for one that has written anything — that is undone.\n */\nexport async function discardTransferJob(\n deps: TransferEngineDeps,\n input: { orgId: string; jobId: string; actorUid: string },\n): Promise<void> {\n const job = await readJob(deps, input.orgId, input.jobId)\n if (job.createdBy !== input.actorUid) {\n throw new TransferEngineError('forbidden', 403, 'Only the person who started an import can discard it.')\n }\n if (transferJobRetention(job)?.retention !== 'expire') {\n throw new TransferEngineError('state', 409, 'This import has written records; undo it instead of discarding it.')\n }\n await expireTransferJob(deps, job)\n}\n\n/*==========================================\n * UNDO\n *=========================================*/\n\nasync function readUndoSnapshots(\n jobRef: FirebaseFirestore.DocumentReference,\n chunkCount: number,\n from = 0,\n): Promise<TransferUndoSnapshot[]> {\n const snapshots: TransferUndoSnapshot[] = []\n for (let index = from; index < chunkCount; index += 1) {\n const entries = await readJsonDoc<TransferUndoEntry[]>(jobRef.collection('undo').doc(String(index)))\n snapshots.push({ jobId: jobRef.id, chunk: index, entries: entries ?? [] })\n }\n return snapshots\n}\n\nfunction assertUndoOpen(job: TransferJobRecord, now: number): void {\n if (job.status !== 'applied') throw new TransferEngineError('state', 409, `This import is ${job.status}; only an applied import can be undone.`)\n if (job.undo?.status === 'done') throw new TransferEngineError('state', 409, 'This import was already undone.')\n if (!job.undo && !transferUndoAvailable(job, now)) {\n throw new TransferEngineError('undoExpired', 410, 'An import can be undone for seven days; this one is older.')\n }\n}\n\n/**\n * What undo would do, writing nothing: every record the import touched,\n * read as it is now, and planned with the core's `planTransferUndo`. A\n * record edited since comes back as a conflict, with what it holds now and\n * what undo would put back, for the person to decide.\n */\nexport async function planTransferJobUndo(\n deps: TransferEngineDeps,\n input: { orgId: string; jobId: string; actorUid: string; offset?: number; limit?: number },\n): Promise<Omit<TransferUndoPlanResponse, 'ok'>> {\n const job = await readJob(deps, input.orgId, input.jobId)\n assertUndoOpen(job, clock(deps))\n const resource = await resolveResource(deps, job.resource)\n const hooks = transferRecordsHooks(resource)\n const ctx = contextFor(job, input.actorUid)\n const jobRef = transferJobsCollection(deps.firestore, job.orgId).doc(job.id)\n const snapshots = await readUndoSnapshots(jobRef, job.chunkCount ?? 0, job.undo?.chunk ?? 0)\n const entries = snapshots.flatMap((snapshot) => snapshot.entries)\n const ids = [...new Set(entries.map((entry) => entry.recordId))]\n const records = new Map<string, Readonly<Record<string, unknown>>>()\n for (let at = 0; at < ids.length; at += UNDO_LOOKUP_SLICE) {\n const found = await hooks.lookup(ctx, [\n { fieldId: TRANSFER_ID_FIELD, normalizer: 'aglynId', values: ids.slice(at, at + UNDO_LOOKUP_SLICE) },\n ])\n for (const [id, values] of found.records) records.set(id, values)\n }\n const counts = emptyUndoCounts()\n const conflicts: TransferUndoConflict[] = []\n for (const entry of entries) {\n const current = records.get(entry.recordId) ?? null\n const step = planTransferUndo(entry, current)\n if (step.action === 'conflict') {\n counts.conflict += 1\n const label = transferRowLabel(current)\n conflicts.push({\n row: entry.row,\n recordId: entry.recordId,\n ...(label ? { label } : {}),\n action: entry.action,\n fields: step.fields,\n current: Object.fromEntries(step.fields.map((fieldId) => [fieldId, current?.[fieldId] ?? null])),\n restore: step.values,\n })\n } else if (step.action === 'restore') counts.restore += 1\n else if (step.action === 'delete') counts.delete += 1\n else counts.nothing += 1\n }\n const offset = Math.max(0, Math.floor(Number(input.offset ?? 0)) || 0)\n const limit = Math.min(TRANSFER_UNDO_PAGE_MAX, Math.max(1, Math.floor(Number(input.limit ?? 50)) || 50))\n const page = conflicts.slice(offset, offset + limit)\n return {\n job,\n counts,\n conflicts: page,\n offset,\n next: offset + page.length < conflicts.length ? offset + page.length : null,\n expiresAt: transferUndoExpiresAt(job),\n }\n}\n\nexport interface ApplyTransferUndoInput {\n orgId: string\n jobId: string\n actorUid: string\n decisions?: Readonly<Record<string, TransferUndoDecision>>\n otherwise: TransferUndoDecision\n deadlineMs: number\n driver: string\n}\n\n/**\n * Carries undo out, chunk by chunk, through the plugin's `revert`, each\n * record with the person's decision (`otherwise` for one the decisions do\n * not name). Called again until `done`; the last chunk moves the job to\n * `undone`. Reverting a chunk twice is harmless: a field already restored\n * plans as nothing.\n */\nexport async function applyTransferJobUndo(\n deps: TransferEngineDeps,\n input: ApplyTransferUndoInput,\n): Promise<{ job: TransferJobRecord; undo: TransferUndoState; done: boolean; started: boolean }> {\n if (input.otherwise !== 'keep' && input.otherwise !== 'revert') {\n throw new TransferEngineError('invalid', 400, 'Say what happens to a record edited since the import.')\n }\n let job = await readJob(deps, input.orgId, input.jobId)\n assertUndoOpen(job, clock(deps))\n const resource = await resolveResource(deps, job.resource)\n const hooks = transferRecordsHooks(resource)\n const ctx = contextFor(job, input.actorUid)\n const decisions: Record<string, TransferUndoDecision> = { ...(input.decisions ?? {}) }\n let started = false\n job = await takeLease(deps, job, input.driver, input.deadlineMs + TRANSFER_LEASE_GRACE_MS, (current, now) => {\n if (current.undo) {\n return {\n ...current,\n undo: { ...current.undo, otherwise: input.otherwise, decisions: { ...current.undo.decisions, ...decisions } },\n updatedAt: now,\n }\n }\n started = true\n return {\n ...current,\n updatedAt: now,\n undo: {\n status: 'running',\n chunk: 0,\n startedAt: now,\n startedBy: input.actorUid,\n otherwise: input.otherwise,\n decisions,\n counts: emptyUndoCounts(),\n },\n }\n })\n const jobRef = transferJobsCollection(deps.firestore, job.orgId).doc(job.id)\n const chunkCount = job.chunkCount ?? 0\n let undo = job.undo as TransferUndoState\n // The person's decisions, this call's and every earlier call's: a resumed undo decides the same way.\n Object.assign(decisions, undo.decisions ?? {}, input.decisions ?? {})\n try {\n while (undo.chunk < chunkCount && input.deadlineMs - clock(deps) > TRANSFER_MIN_CHUNK_BUDGET_MS) {\n const [snapshot] = await readUndoSnapshots(jobRef, undo.chunk + 1, undo.chunk)\n const counts = { ...undo.counts }\n if (snapshot && snapshot.entries.length) {\n const chosen = Object.fromEntries(\n snapshot.entries.map((entry) => [entry.recordId, decisions[entry.recordId] ?? input.otherwise]),\n )\n const reverted = await hooks.revert(ctx, snapshot, chosen)\n for (const step of reverted.done) counts[step.action] += 1\n counts.conflict += reverted.conflicts.length\n }\n undo = { ...undo, chunk: undo.chunk + 1, counts }\n job = { ...job, undo, updatedAt: clock(deps) }\n await saveJob(deps, job)\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n job = { ...job, lease: null, updatedAt: clock(deps), error: { code: 'undoFailed', message, chunk: undo.chunk } }\n await saveJob(deps, job)\n throw new TransferEngineError('failed', 500, `Undo stopped at chunk ${undo.chunk + 1}: ${message}. Try again to continue.`)\n }\n const done = undo.chunk >= chunkCount\n if (done) {\n undo = { ...undo, status: 'done' }\n job = moveJob({ ...job, undo }, 'undone', clock(deps), { lease: null })\n } else {\n job = { ...job, lease: null, updatedAt: clock(deps) }\n }\n await saveJob(deps, job)\n return { job, undo, done, started }\n}\n\n/*==========================================\n * THE SWEEP — what a closed tab left behind, and what has outlived its use\n *\n * - an import left `applying`, or an undo left running, untouched for\n * {@link TRANSFER_STALE_MS}: resumed through the same engine, under the\n * sweep's lease (undo with the person's stored decisions);\n * - a job that never wrote, untouched for seven days\n * (`TRANSFER_DRAFT_RETENTION_MS`): deleted with its subcollections and\n * its file;\n * - a job that wrote, once its seven-day undo window has closed: its dry\n * run, undo snapshots, ledger and file are cleared, and the job and its\n * per-row results kept (`trimmedAt`).\n *\n * The last two are found by the `retention` and `retainUntil` every job\n * write stamps (`transferJobRetention`), so a trimmed job never matches\n * again.\n *=========================================*/\n\n/** The most jobs one sweep expires or trims. */\nconst CLEANUP_LIMIT = 50\n\nexport interface TransferSweepOutcome {\n /** Jobs found applying and untouched past the stale window. */\n found: number\n resumed: Array<{ orgId: string; jobId: string; status: TransferJobRecord['status']; done: boolean }>\n /** Jobs that could not be resumed this time (held by a driver, or failed). */\n skipped: Array<{ orgId: string; jobId: string; reason: string }>\n /** Undos found running and untouched, and what resuming each did. */\n undone: Array<{ orgId: string; jobId: string; done: boolean }>\n /** Jobs that never wrote, deleted with their file. */\n expired: Array<{ orgId: string; jobId: string }>\n /** Jobs past their undo window, cleared to the job and its results. */\n trimmed: Array<{ orgId: string; jobId: string }>\n}\n\n/** Deletes a Storage object, if it is there. */\nasync function deleteObject(deps: TransferEngineDeps, path: string): Promise<void> {\n await deps.bucket.file(path).delete({ ignoreNotFound: true })\n}\n\n/** The job's stored file and any parts still waiting for the rest. */\nasync function deleteSourceFiles(deps: TransferEngineDeps, job: TransferJobRecord): Promise<void> {\n await deleteObject(deps, transferSourcePath(job.orgId, job.id))\n const parts = job.upload?.parts ?? 0\n await eachLimited(\n Array.from({ length: parts > 1 ? parts : 0 }, (_unused, index) => index),\n TRANSFER_WRITE_CONCURRENCY,\n async (index) => deleteObject(deps, transferPartPath(job.orgId, job.id, index)),\n )\n}\n\n/** A job that never wrote, gone: its subcollections, its file, then the job. */\nexport async function expireTransferJob(deps: TransferEngineDeps, job: TransferJobRecord): Promise<void> {\n const jobRef = transferJobsCollection(deps.firestore, job.orgId).doc(job.id)\n for (const name of ['chunks', 'ledger', 'results', 'undo']) await clearCollection(jobRef.collection(name))\n await deleteSourceFiles(deps, job)\n await jobRef.delete()\n}\n\n/** A job past its undo window, kept as the job and its results: the dry run, undo snapshots, ledger and file cleared. */\nexport async function trimTransferJob(deps: TransferEngineDeps, job: TransferJobRecord): Promise<TransferJobRecord> {\n const jobRef = transferJobsCollection(deps.firestore, job.orgId).doc(job.id)\n for (const name of ['chunks', 'ledger', 'undo']) await clearCollection(jobRef.collection(name))\n await deleteSourceFiles(deps, job)\n const trimmed: TransferJobRecord = { ...job, trimmedAt: clock(deps) }\n delete trimmed.sourcePath\n await saveJob(deps, trimmed)\n return trimmed\n}\n\nfunction jobOf(doc: FirebaseFirestore.QueryDocumentSnapshot): { orgId: string; job: TransferJobRecord } {\n const job = { ...(doc.data() as TransferJobRecord), id: doc.id }\n return { orgId: doc.ref.parent.parent?.id ?? job.orgId, job: { ...job, orgId: doc.ref.parent.parent?.id ?? job.orgId } }\n}\n\n/**\n * The sweep (see the block header). Each resume runs under the sweep's\n * lease until the budget is spent; the ledger makes overlapping with a\n * returning browser harmless. `dryRun` lists what it would do and does\n * nothing.\n */\nexport async function sweepAbandonedTransferJobs(\n deps: TransferEngineDeps,\n input: { deadlineMs: number; dryRun?: boolean; limit?: number; staleMs?: number },\n): Promise<TransferSweepOutcome> {\n const now = clock(deps)\n const stale = now - (input.staleMs ?? TRANSFER_STALE_MS)\n const jobs = deps.firestore.collectionGroup(TRANSFER_JOBS_COLLECTION)\n const budgetLeft = () => input.deadlineMs - clock(deps) > TRANSFER_MIN_CHUNK_BUDGET_MS\n const snapshot = await jobs\n .where('status', '==', 'applying')\n .where('updatedAt', '<=', stale)\n .orderBy('updatedAt', 'asc')\n .limit(input.limit ?? 10)\n .get()\n const outcome: TransferSweepOutcome = { found: snapshot.docs.length, resumed: [], skipped: [], undone: [], expired: [], trimmed: [] }\n for (const doc of snapshot.docs) {\n const { orgId, job } = jobOf(doc)\n if (input.dryRun) {\n outcome.skipped.push({ orgId, jobId: doc.id, reason: 'dryRun' })\n continue\n }\n if (!budgetLeft()) {\n outcome.skipped.push({ orgId, jobId: doc.id, reason: 'budget' })\n continue\n }\n try {\n const resume = {\n orgId,\n jobId: doc.id,\n actorUid: job.createdBy,\n deadlineMs: input.deadlineMs,\n driver: `sweep:${doc.id}`,\n }\n // A workspace package is resumed by its own engine, under the same lease and ledger.\n const applied =\n job.kind === 'package'\n ? await (await import('./transfer-packages')).applyTransferPackage(deps, resume)\n : await applyTransferJob(deps, resume)\n outcome.resumed.push({ orgId, jobId: doc.id, status: applied.job.status, done: applied.done })\n } catch (error) {\n outcome.skipped.push({ orgId, jobId: doc.id, reason: error instanceof Error ? error.message : String(error) })\n }\n }\n\n // An undo the browser left part-way, finished with the person's own decisions.\n const undoing = await jobs\n .where('undo.status', '==', 'running')\n .where('updatedAt', '<=', stale)\n .orderBy('updatedAt', 'asc')\n .limit(input.limit ?? 10)\n .get()\n for (const doc of undoing.docs) {\n const { orgId, job } = jobOf(doc)\n if (input.dryRun || !budgetLeft() || !job.undo) {\n outcome.skipped.push({ orgId, jobId: doc.id, reason: input.dryRun ? 'dryRun' : 'budget' })\n continue\n }\n try {\n const finish = {\n orgId,\n jobId: doc.id,\n actorUid: job.undo.startedBy,\n decisions: job.undo.decisions ?? {},\n otherwise: job.undo.otherwise,\n deadlineMs: input.deadlineMs,\n driver: `sweep-undo:${doc.id}`,\n }\n const undone =\n job.kind === 'package'\n ? await (await import('./transfer-packages')).applyTransferPackageUndo(deps, finish)\n : await applyTransferJobUndo(deps, finish)\n outcome.undone.push({ orgId, jobId: doc.id, done: undone.done })\n } catch (error) {\n outcome.skipped.push({ orgId, jobId: doc.id, reason: error instanceof Error ? error.message : String(error) })\n }\n }\n\n // What has outlived its use: drafts that never wrote, and applied jobs past their undo window.\n for (const retention of ['expire', 'trim'] as const) {\n const due = await jobs\n .where('retention', '==', retention)\n .where('retainUntil', '<=', now)\n .orderBy('retainUntil', 'asc')\n .limit(CLEANUP_LIMIT)\n .get()\n for (const doc of due.docs) {\n const { orgId } = jobOf(doc)\n if (input.dryRun || !budgetLeft()) {\n outcome.skipped.push({ orgId, jobId: doc.id, reason: input.dryRun ? 'dryRun' : 'budget' })\n continue\n }\n // Read again: the job may have moved on since the query, and is decided as it is now.\n const current = await readJob(deps, orgId, doc.id).catch(() => null)\n const verdict = current ? transferJobRetention(current) : null\n if (!current || !verdict || verdict.retention !== retention || verdict.retainUntil > clock(deps)) continue\n try {\n if (retention === 'expire') {\n await expireTransferJob(deps, current)\n outcome.expired.push({ orgId, jobId: doc.id })\n } else {\n await trimTransferJob(deps, current)\n outcome.trimmed.push({ orgId, jobId: doc.id })\n }\n } catch (error) {\n outcome.skipped.push({ orgId, jobId: doc.id, reason: error instanceof Error ? error.message : String(error) })\n }\n }\n }\n return outcome\n}\n"],"names":["TRANSFER_DEFAULT_MAX_ROWS","TRANSFER_DRAFT_RETENTION_MS","TRANSFER_ID_FIELD","TRANSFER_PLAN_CONFLICTS_MAX","TRANSFER_PLAN_PAGE_MAX","TRANSFER_RESULT_COLUMNS","TRANSFER_UNDO_PAGE_MAX","TRANSFER_UPLOAD_MAX_BYTES","TRANSFER_UPLOAD_MAX_PARTS","TRANSFER_UPLOAD_PART_MAX_BYTES","TRANSFER_WRITE_CONCURRENCY","canApplyTransferPlan","collectPicklistValues","createTransferPolicy","withTransferPolicyDefaults","deriveTransferCell","deriveTransferRow","mapTransferRow","mappingIsUsable","mappingProblems","matchHeaders","matchLookupRequests","matchPicklistValues","missingAcknowledgements","picklistChoiceProblems","planTransferUndo","proposePicklistChoice","readTransferSource","resolveMultiPicklistCell","resolvePicklistCell","resolvePicklistChoices","sniffTransferFormat","summarizeMatches","summarizeTransferDerivations","summarizeTransferResults","transferAmbiguities","transferCellText","transferChunkRanges","transferContentType","transferDateOrderOptions","transferFormatFromFileName","transferLedgerKey","transferMatchReview","transferMatchedRecordIds","transferPlanConflicts","transferPlanFeature","transferPlanSample","transferPolicyProblems","transferRowLabel","transferUndoAvailable","transferUndoExpiresAt","transitionTransferJob","transferLookupKey","transferResourceImports","transferLookupNewValue","mayBeTransferRecordId","normalizeMatchValue","matchLookupKey","isBlankTransferValue","isTransferLookupField","TRANSFER_UNDO_WINDOW_MS","TRANSFER_UNFINISHED_IMPORTS_MAX","TRANSFER_JOBS_PAGE_MAX","parseTransferResourceKey","normalizePicklistLabel","picklistLabelKey","createResourceUid","escapeCsvCell","inspectUploadBytes","matchTransferResourceRows","planTransferResourceRows","transferResourcePolicyDefaults","resolveTransferResource","transferInvariantFailures","transferRecordsHooks","transferResourceCatalog","transferResourceLockedRules","transferResourceMatchKeys","TransferResourceUnavailableError","transferPlanRefusal","TransferEngineError","Error","code","status","message","details","name","TransferPlanRefusedError","refusal","body","error","TRANSFER_JOBS_COLLECTION","TRANSFER_LEASE_GRACE_MS","TRANSFER_STALE_MS","TRANSFER_MIN_CHUNK_BUDGET_MS","UNDO_LOOKUP_SLICE","MATCH_LOOKUP_SLICE","JSON_PIECE_CHARS","transferJobsCollection","firestore","orgId","collection","doc","transferSourcePath","jobId","transferPartPath","part","clock","deps","now","Date","stored","value","JSON","parse","stringify","emptyResults","created","updated","unchanged","skipped","failed","total","emptyUndoCounts","restore","delete","conflict","nothing","eachLimited","items","limit","fn","next","workers","Array","from","length","Math","min","item","Promise","all","isAlreadyExists","failure","test","String","writeJsonDoc","ref","fields","json","set","pieces","at","push","slice","map","index","piece","readJsonDoc","data","snapshot","get","exists","count","Number","parts","join","clearCollection","docs","readJob","includes","id","transferJobRetention","job","trimmedAt","undefined","undo","wrote","applyStartedAt","retention","retainUntil","updatedAt","appliedAt","storedJob","rest","saveJob","readTransferJob","input","resolveTransferRecordsResource","key","resolveResource","resource","kinds","label","reason","transferHostIdFor","hostId","site","trim","scope","contextFor","actorUid","extras","headers","moveJob","to","patch","transferJobProgress","chunk","cursor","chunkCount","rowsDone","rowCount","results","policyDefaultsEntry","ctx","defaultPolicy","Object","keys","readTransferResourceInfo","hooks","filter","isArray","catalog","offer","matchKeys","singularLabel","formats","limits","description","exportOnly","groups","defaultMatchKeys","defaults","presetHints","matchKeyFieldIds","presets","resourcePresets","preset","fieldIds","fieldId","byId","has","locked","aliases","dictionaries","canCreateCustomField","CSV_DELIMITERS","readOptionsOf","options","delimiter","headerRow","inspectTransferBytes","bytes","format","fileName","contentType","textOf","toString","uploadTransferSource","content","toUpperCase","isInteger","Buffer","maxBytes","jobs","upload","complete","received","newJobId","kind","direction","createdBy","createdAt","read","round","whole","bucket","file","save","resumable","runTransaction","transaction","current","Set","sort","a","b","download","concat","problem","maxRows","table","rows","toLocaleString","sourcePath","_unused","ignoreNotFound","done","loadTable","assertBeforeWrites","what","usableMapping","mapping","out","column","entries","isPicklistField","field","Boolean","type","picklistId","picklistLists","ids","picklists","analyzePicklistColumns","lists","analyses","list","incoming","cells","row","derived","ok","result","spec","matched","unmatched","proposals","fromEntries","recordLabelsFor","records","labels","analyzeTransferJob","samples","match","Map","lockedRules","review","fieldOptions","dateOrders","mapped","mappedFields","values","chosenMatchKeys","found","lookupAll","lookup","outcomes","lookups","lookupReviews","resolveLookupColumns","derivations","matches","recordLabels","LOOKUP_SUGGESTIONS_MAX","LOOKUP_ROWS_MAX","lookupCellNames","raw","some","lookupTargetFor","own","lookupTargets","target","targetCtx","org","lookupRecordLabel","record","by","columns","inRow","text","add","seen","resolved","unresolved","size","normalizer","find","requests","wanted","entry","normalized","request","candidates","reviews","asked","suggest","several","recordId","suggestions","suggestion","lookupChoiceProblems","choices","problems","fieldChoices","choice","action","creatable","known","applyLookupChoices","notes","names","refused","note","class","detail","refuse","readPlanRows","derive","noteFor","added","blank","outcome","resolution","chosen","sliceLookupRequests","slices","planTransferJob","policy","policyProblems","choiceProblems","additions","analysis","picklistChoices","lookupColumns","lookupProblems","lookupChoices","looked","plan","existing","failures","invariants","failing","verdict","diff","summary","create","update","skip","fail","jobRef","ranges","range","start","end","matchSummary","allConflicts","valuesEqual","conflicts","ambiguous","sample","labelled","recordIds","picklistAdditions","warnings","acknowledgementsRequired","acknowledged","invariantFailures","invariantFailureCount","plannedAt","first","offset","conflictCount","readChunkRows","readTransferPlanRows","max","floor","verdicts","more","scan","plannedResult","addResults","takeLease","driver","expiresAt","enter","lease","owner","running","where","other","applyTransferJob","progress","started","resumed","missing","deadlineMs","timeLeft","written","picklistsAdded","addPicklistValues","applyChunk","ledgerCollection","ledger","undoJson","writer","alreadyApplied","markApplied","timeLeftMs","writes","applied","apply","planned","batch","completedAt","commit","readTransferJobStatus","include","readResults","available","state","transferResultFile","transferPackageResultFile","lines","cell","forEach","tail","_header","numeric","base","replace","csv","listTransferJobs","query","orderBy","after","isFinite","page","uids","emails","emailsOf","catch","createdByEmail","resultFile","last","UNFINISHED_STATUSES","listUnfinishedTransferJobs","discardTransferJob","expireTransferJob","readUndoSnapshots","snapshots","assertUndoOpen","planTransferJobUndo","flatMap","counts","step","applyTransferJobUndo","otherwise","decisions","startedAt","startedBy","assign","reverted","revert","CLEANUP_LIMIT","deleteObject","path","deleteSourceFiles","trimTransferJob","trimmed","jobOf","parent","sweepAbandonedTransferJobs","stale","staleMs","collectionGroup","budgetLeft","undone","expired","dryRun","resume","applyTransferPackage","undoing","finish","applyTransferPackageUndo","due"],"mappings":"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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { type PackageItemDecision, type TransferJobRecord, type TransferPackage, type TransferPackageDependencyChoice, type TransferPackagePlan, type TransferPackageResourceList, type TransferPackageRuleView, type TransferPackageUndoConflict, type TransferPackageWarningClass, type TransferRowResult, type TransferUndoCounts, type TransferUndoDecision, type TransferUndoState } from '@aglyn/aglyn/data-transfer';
|
|
18
|
+
import { type TransferEngineDeps } from './transfer-jobs';
|
|
19
|
+
export interface TransferPackageListInput {
|
|
20
|
+
orgId: string;
|
|
21
|
+
actorUid: string;
|
|
22
|
+
/** The package resources the workspace may move (its enabled plugins'). */
|
|
23
|
+
allowed: readonly string[];
|
|
24
|
+
/** Only these; every allowed one when absent. */
|
|
25
|
+
resources?: readonly string[];
|
|
26
|
+
}
|
|
27
|
+
/** Every item of each package resource, with its name and what it names, for the export picker. */
|
|
28
|
+
export declare function listTransferPackageItems(deps: TransferEngineDeps, input: TransferPackageListInput): Promise<TransferPackageResourceList[]>;
|
|
29
|
+
export interface TransferPackageExportInput extends TransferPackageListInput {
|
|
30
|
+
/** Item keys; every item of the resources when absent. */
|
|
31
|
+
items?: readonly string[];
|
|
32
|
+
/** Add what the chosen items name that the workspace holds as package items, transitively. */
|
|
33
|
+
dependencies?: boolean;
|
|
34
|
+
/** Where the file says it came from ("Workspace: Acme"). */
|
|
35
|
+
source?: string;
|
|
36
|
+
}
|
|
37
|
+
/** The package file: the chosen items (and, when asked, what they need), hashed and listed. */
|
|
38
|
+
export declare function exportTransferPackage(deps: TransferEngineDeps, input: TransferPackageExportInput): Promise<TransferPackage>;
|
|
39
|
+
export interface PlanTransferPackageInput {
|
|
40
|
+
orgId: string;
|
|
41
|
+
actorUid: string;
|
|
42
|
+
allowed: readonly string[];
|
|
43
|
+
jobId?: string | null;
|
|
44
|
+
/** The file's parsed JSON, on the first call. */
|
|
45
|
+
package?: unknown;
|
|
46
|
+
fileName?: string | null;
|
|
47
|
+
decisions?: Readonly<Record<string, PackageItemDecision>>;
|
|
48
|
+
dependencyChoices?: Readonly<Record<string, TransferPackageDependencyChoice>>;
|
|
49
|
+
}
|
|
50
|
+
export interface PlanTransferPackageOutcome {
|
|
51
|
+
job: TransferJobRecord;
|
|
52
|
+
plan: TransferPackagePlan;
|
|
53
|
+
resources: Record<string, {
|
|
54
|
+
label: string;
|
|
55
|
+
rules: TransferPackageRuleView[];
|
|
56
|
+
}>;
|
|
57
|
+
/** The first call made the job. */
|
|
58
|
+
created: boolean;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The dry run (see the block header): reads what the workspace holds of
|
|
62
|
+
* every kind the package carries or names, plans with the person's
|
|
63
|
+
* choices, asks each written item's plugin what its own write would
|
|
64
|
+
* refuse, and stores the plan. Writes no item.
|
|
65
|
+
*/
|
|
66
|
+
export declare function planTransferPackageImport(deps: TransferEngineDeps, input: PlanTransferPackageInput): Promise<PlanTransferPackageOutcome>;
|
|
67
|
+
export interface ApplyTransferPackageInput {
|
|
68
|
+
orgId: string;
|
|
69
|
+
jobId: string;
|
|
70
|
+
actorUid: string;
|
|
71
|
+
acknowledged?: readonly TransferPackageWarningClass[];
|
|
72
|
+
deadlineMs: number;
|
|
73
|
+
driver: string;
|
|
74
|
+
}
|
|
75
|
+
export interface ApplyTransferPackageOutcome {
|
|
76
|
+
job: TransferJobRecord;
|
|
77
|
+
done: boolean;
|
|
78
|
+
/** This call moved the job into `applying`. */
|
|
79
|
+
started: boolean;
|
|
80
|
+
resumed: boolean;
|
|
81
|
+
results: TransferRowResult[];
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Writes the planned items (see the block header): the undo snapshot
|
|
85
|
+
* first, then each owning plugin's items in dependency order through the
|
|
86
|
+
* ledger, then the written hashes and the results. Called again until
|
|
87
|
+
* `done`; a plugin that throws fails the job, and calling again resumes it.
|
|
88
|
+
*/
|
|
89
|
+
export declare function applyTransferPackage(deps: TransferEngineDeps, input: ApplyTransferPackageInput): Promise<ApplyTransferPackageOutcome>;
|
|
90
|
+
/** The result file of a package import: each item, what was decided, and what happened. */
|
|
91
|
+
export declare function transferPackageResultFile(deps: TransferEngineDeps, job: TransferJobRecord): Promise<{
|
|
92
|
+
csv: string;
|
|
93
|
+
rows: number;
|
|
94
|
+
fileName: string;
|
|
95
|
+
}>;
|
|
96
|
+
/** What undo would do, writing nothing: counts, and every item edited since the import. */
|
|
97
|
+
export declare function planTransferPackageUndo(deps: TransferEngineDeps, input: {
|
|
98
|
+
orgId: string;
|
|
99
|
+
jobId: string;
|
|
100
|
+
actorUid: string;
|
|
101
|
+
}): Promise<{
|
|
102
|
+
job: TransferJobRecord;
|
|
103
|
+
counts: TransferUndoCounts;
|
|
104
|
+
conflicts: TransferPackageUndoConflict[];
|
|
105
|
+
expiresAt: number | null;
|
|
106
|
+
}>;
|
|
107
|
+
export interface ApplyTransferPackageUndoInput {
|
|
108
|
+
orgId: string;
|
|
109
|
+
jobId: string;
|
|
110
|
+
actorUid: string;
|
|
111
|
+
/** By item id. */
|
|
112
|
+
decisions?: Readonly<Record<string, TransferUndoDecision>>;
|
|
113
|
+
otherwise: TransferUndoDecision;
|
|
114
|
+
deadlineMs: number;
|
|
115
|
+
driver: string;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Carries undo out through each plugin's `revertItems`: every untouched
|
|
119
|
+
* item, and every edited one the person (or `otherwise`) said to revert.
|
|
120
|
+
* A step a plugin's own rules refuse is counted as a conflict and left.
|
|
121
|
+
*/
|
|
122
|
+
export declare function applyTransferPackageUndo(deps: TransferEngineDeps, input: ApplyTransferPackageUndoInput): Promise<{
|
|
123
|
+
job: TransferJobRecord;
|
|
124
|
+
undo: TransferUndoState;
|
|
125
|
+
done: boolean;
|
|
126
|
+
started: boolean;
|
|
127
|
+
}>;
|