1. Overview
A nightly CSV export from the ERP (orders_YYYY-MM-DD.csv, dropped to SFTP at 01:30 UTC) is validated, matched on external_order_id and upserted into the CRM as order records associated with the company. Rows that fail validation are quarantined and listed in the exception report; nothing is written partially.
- Owner on your side: the operations lead named in the SOW.
- Runs: daily at 02:00 UTC, plus manual replays.
- Source of truth: the ERP for orders; the CRM for owners and stages.
2. Architecture
ERP ──(CSV over SFTP)──▶ ingest job ──▶ validate ──▶ upsert ──▶ CRM
│ │
└──▶ quarantine table ◀────┘
│
└──▶ exception report + alertThe job runs as a scheduled function in your cloud account. State (last processed file, quarantine rows, run history) lives in a small Postgres database in the same account.
3. Environments and access
| Item | Where it lives | Who has access |
|---|---|---|
| Source code | Your Git repository | Your engineering team |
| CRM private app token | Secret manager in your cloud account | The deploy pipeline only |
| SFTP credentials | Secret manager in your cloud account | The deploy pipeline only |
| Staging environment | Separate project, CRM sandbox | Your engineering team |
4. Deploying a change
- Open a pull request. CI runs the schema tests and a dry run against the sample file.
- Merge to
main. The pipeline deploys to staging and replays yesterday’s file. - Check the staging exception report matches production’s for the same file.
- Promote to production from the pipeline. Rollback is the previous release, one click.
5. Monitoring and alerts
- File missing by 03:00 UTC: alert to the operations channel.
- Run failed (any unhandled error): alert, and the batch is left unapplied.
- Quarantine above threshold (more than 1% of rows): alert with the report attached.
- API rate limit reached: the job backs off and retries; alert after three attempts.
6. Procedures
Reprocess a failed batch
- Fix the cause (bad file, expired credential, CRM outage).
- Run
replay --file orders_YYYY-MM-DD.csvfrom the pipeline. - Upserts are idempotent: replaying a file that partly succeeded cannot duplicate records.
Resolve quarantined rows
- Open the exception report for the run; each row lists its reason.
- Correct the data at the source (the ERP), not in the CRM.
- The next nightly run picks the corrected rows up automatically.
Add a field
- Create the property in the CRM sandbox, then in production.
- Add the column to
mapping.tsand its rule to the schema. - Deploy as above. Backfill with a replay of the files you need.
Rotate credentials
- Create the new token in the CRM or SFTP server.
- Update it in the secret manager; the next run uses it.
- Revoke the old token and note the date in the change log.
7. Change log
| Date | Change |
|---|---|
| YYYY-MM-DD | Initial handover. |
| YYYY-MM-DD | Added the ship_date field and backfilled 90 days. |