Skip to content
Plinth
All guides

Documentation

Accepted jobs CSV move-in kit

This first move-in kit accepts a documented CSV shape. Its committed examples are synthetic fixtures, not exports verified against a live provider. There is no connector, provider authorization, automatic source download or live-provider compatibility claim.

The exact UTF-8 header is:

external_id,title,client_email,site_address,quote_cents,accepted_on

Each row represents one job. external_id is a stable, unique source identifier (up to 200 characters); title is up to 200 characters; client_email is a valid email up to 254 characters; site_address is optional, up to 500 characters. quote_cents is a whole nonnegative AUD cents amount up to 1,000,000,000,000. accepted_on is a real calendar date in YYYY-MM-DD form. Header order is fixed. RFC 4180 quoted commas, escaped quotes and embedded newlines are supported; UTF-8 BOM, LF and CRLF are accepted. Required fields cannot have surrounding spaces. Duplicate identifiers and invalid rows reject the upload before writes. The limit is 100 data rows and 256 KiB per CSV; the request body is separately bounded to allow JSON escaping. File-name metadata is fixed to accepted-jobs.csv; original CSV bytes remain exact.

Review and adoption

Only a signed-in human owner may preview, commit, resume, reverse or inspect an import. Agent credentials cannot approve an import. The route reuses native sessions; Base also checks the current owner, session expiry, revocation and operator version inside every atomic journal/native mutation.

Preview returns rows, diagnostics, counts and a SHA-256 fingerprint. It writes neither native jobs nor import custody. A person approves that exact fingerprint. Commit parses and plans the submitted CSV again and refuses a changed fingerprint before creating the job. The original bytes, normalized rows, reviewed plan, named human reviewer, source evidence and journal persist through Base's D1 import APIs.

The source's acceptance date and amount are retained as unverified source evidence in each native job. Every job starts at quoting with a draft quote. It must pass the ordinary native acceptance action before active job work. Importing sends no email, invitation, client access grant, financial export, schedule booking or other lifecycle action. Source stamps identify the CSV and its claimed acceptance date; they are not a native acceptance or approval.

Native job IDs derive from the format namespace and stable external_id. Repeating the exact approved upload returns the same durable import. Another export cannot silently overwrite an existing job or change an already claimed source identity. Review changes in the native job instead.

HTTP contract

All paths begin /api/plinth/imports. POST requests require the same Origin header as native mutations. JSON responses are private and no-store.

Method and suffix Input Result
GET / — {jobs}; most recent 100 import journal summaries
POST /preview {csv} {fingerprint,counts,diagnostics,rows,adoption:"draft",limits}
POST /commit {csv,fingerprint} {job}
GET /:id — {job} after retained-plan integrity checks
POST /:id/resume — {job} from the immutable retained plan
POST /:id/undo — {job,report}; completed import only
POST /:id/rollback — {job,report}; partial import reversal
GET /:id/report — {report} with retained/reversed dispositions
GET /:id/originals — {originals} with exact bytes or explicit erasure unavailability
GET /erasure-journal — {entries}; value-free erasure receipts

A request applies at most ten native jobs, one atomic native entity per batch. Call resume until the job state is completed. Interrupted requests leave the last committed checkpoint; resume uses retained custody, without another upload or parser run. Reversal is similarly restartable. Conflicts are explicit; there are no automatic retries or replacement fallbacks.

Undo, erasure and restore

Undo uses Base's durable preserve-conflicts policy. An unchanged imported job is removed; a changed job, accepted quote, added attachment or changed native version is retained and reported. The adapter guards the entire job JSON, version, import revision, attachment bytes and metadata, including same-version edits. Native rows, attribution and checkpoint advance in one D1 batch. Undo retains original CSV and audit custody; it is not privacy erasure.

Native job erasure calls eraseJob for imported and native-created jobs. It commits exact native CAS/auth guards, attachment deletion, native deletion, permanent job tombstone, Base import-custody retirement/redaction, the append-only erasure journal and the real portability redaction checkpoint together. Affected whole CSV originals become unavailable, including peers' raw bytes in the same file; peer normalized jobs remain. Job erasure concerns that job's lineage; it is not a request to erase every other job held by the same client.

If a personal identifier occupies an import header, Base retires that custody and its dependent closure; those jobs can no longer resume or undo. The erasure journal stores counts and receipt IDs, never selected personal values. The portability checkpoint prevents an older archive from resurrecting the deleted custody when checked with a later trusted journal. In-flight portability copies are invalidated. Import ownership is the durable role:owner principal, so a restored installation's newly created owner can resume and reverse retained jobs while their actual current native session is checked afresh.

Migration 0021_import_kit.sql contains the complete ordered Base D1 schema, including preserved undo, custody revisions, original-byte storage, staging, preparation, reversal fences and append-only retirement support. The Worker imports the D1 entry point and requires nodejs_compat. The vendored runtime is copied from the committed Base reference. Local integration checks establish local behavior only; hosted upload, Worker resource and provider acceptance are not claimed.

Read this page on GitHub