File Deposit Monitoring
Summary
The admin deposit dashboard exposes a paginated view of all FileDeposit records, filterable by partner and status. Each deposit tracks the full lifecycle of an SFTP XML file from detection through ingestion. When a deposit fails, admins can retry it (reset + re-enqueue through the normal pipeline). Successfully ingested deposits can be re-ingested to reapply updated mappings — this creates a new FileDeposit record pointing to the archived file.
State Diagram
stateDiagram-v2 state "Fichier détecté" as Detected state "Ingestion en cours" as Ingesting state "Ingéré avec succès" as Ingested state "Erreur d'ingestion" as Error state "Doublon ignoré" as Duplicate [*] --> Detected: chokidar detects file Detected --> Ingesting: enqueueIngestion() called Ingesting --> Ingested: ingestXmlFeed() succeeds Ingesting --> Error: ingestXmlFeed() throws Detected --> Duplicate: same checksum already ingested Error --> Detected: admin retries deposit Detected --> Ingesting: re-enqueued Ingested --> Detected: admin re-ingests deposit (new record)
Steps
1. List All Deposits (Actor: admin)
GET /admin/deposits — cursor-based pagination using compound (createdAt, id) cursor. Query parameters:
partnerId: filter by partner UUIDstatus: filter by status (detected,ingesting,ingested,error,duplicate)cursor: base64url-encoded cursor from previous responselimit: page size, default 20, max 100
Returns { deposits: [...], nextCursor: string | null }. Each deposit includes partner name for display.
Outcome: Paginated list of deposits ordered newest-first
2. List Partner-Scoped Deposits (Actor: admin)
GET /admin/partners/:id/deposits — same cursor pagination but automatically scoped to one partner. Registered as a sub-route under /admin/partners/:id/deposits.
Outcome: Deposits for a specific partner
3. Retry Failed Deposit (Actor: admin)
POST /admin/deposits/:id/retry:
Pre-conditions:
- Deposit must exist → 404 if not.
deposit.statusmust be"error"→ 400 if not.deposit.partner.statusmust not be"paused"→ 400 if paused.
Steps:
- Reconstruct file path:
/home/{sftpUsername}/feeds/{filename}. - Reset
fileDeposit.status → "detected",errorMessage → null. - Call
enqueueIngestion(depositId, filePath, partnerId, partnerName, filename, log)— uses the per-partner mutex fromlib/file-watcher.ts.
Outcome: Deposit reset and re-enqueued, returns { success: true, message: "Retry launched" }
4. Re-ingest Completed Deposit (Actor: admin)
POST /admin/deposits/:id/reingest:
Pre-conditions:
- Deposit must be
"ingested"→ 400 if not. - Partner must not be paused → 400 if paused.
Steps:
- List archive directory
/home/{sftpUsername}/feeds/archive/. - Find files matching
{baseName}.*sorted descending (newest first). - Create a new
FileDepositrecord (with checksum suffixed-reingestto bypass deduplication). - Enqueue ingestion of the archive path.
Use case: admin corrected mappings and wants to reapply them to already-ingested data without waiting for the partner to resend the file.
Outcome: New deposit record created, archive file re-ingested
Error States
- Deposit not found → 404
NOT_FOUND - Retry on non-error status → 400
BAD_REQUEST - Retry while partner is paused → 400
BAD_REQUEST - Reingest on non-ingested status → 400
BAD_REQUEST - No archived file found for reingest → 404
NOT_FOUND - Archive directory missing → 404
NOT_FOUND
Related Processes
- partner-onboarding — creates the partner whose deposits appear here
- sftp-xml-ingestion — the ingestion pipeline that creates and transitions deposit records
- partner-mapping-activation — deposit retry is common after mapping corrections