Move Clio contacts into Satchel
Only a signed-in human owner can preview, commit, inspect, resume or undo an import. Agents, lawyers and assistants cannot use this move-in path.
Prepare the CSV
This kit supports a documented-shape subset, not every Clio export format. Use the contact fields from Clio's contacts migration template. For a Clio Manage export, export contacts as CSV, then prepare these columns. Clio exports reflect selected columns and filters; this importer does not guess mappings from arbitrary export headers.
| Column | Treatment |
|---|---|
first_name |
Person's first name; required together with last name for a person |
last_name |
Person's last name |
company |
Party name when both person-name fields are empty |
email_address |
Primary email, or empty; trimmed and lowercased |
id |
Optional Satchel input extension: preserve the original Clio contact ID |
aliases |
Optional Satchel input extension: additional conflict-search names |
The first four headers must exist even when their cells are empty. Names are limited to 300 characters, aliases to 2,000, and IDs to 300. Each file contains 1–1,000 contacts and at most 1 MB of UTF-8 CSV. Quoted commas, quoted newlines, escaped quotes, CRLF/LF and a leading BOM are supported. Invalid rows and duplicate source identities block the entire commit. Structurally invalid CSV returns an error before planning. See the example CSV.
If a person also has a company value, the person becomes one party and the company stays in provenance with a warning. No company relationship is created. Unmapped columns, including phone/address/custom fields, remain in the exact original file and raw row provenance; the preview lists those columns.
If id is supplied, it is the stable source identity. Otherwise identity is a
SHA-256 digest of the normalized contact name and email. Without original IDs,
a changed name/email is a different identity; supply IDs when reconciling exports.
Native parties are keyed by a digest of that identity and marked source='clio'.
The kit does not merge contacts by name or overwrite native/edited parties.
An exact source replay is idempotent; changed content for an already imported
identity fails with a conflict and requires deliberate reconciliation.
Review, commit, and recover
importAction(db, actor, op, body) exposes the following operations to the
authenticated server transport:
op |
body |
Response |
|---|---|---|
preview |
{csv, filename?} |
{fingerprint, mappingVersion, counts, summary, parties, diagnostics} |
commit |
Same CSV/filename plus {fingerprint} from preview |
The review fields plus {job} |
resume |
{id, mappingVersion?} |
{job} |
undo |
{id, mappingVersion?} |
{job} |
status |
{id, mappingVersion?, offset?, limit?} |
{job, originals, undo} |
importState(db, actor) returns {jobs} with each job's ID, mapping version,
fingerprint, state, checkpoint, total and error. mappingVersion, if supplied,
must match clio-contacts-v1.
Preview calls Base's real planD1Import and performs no writes. Review errors,
warnings and the normalized parties before committing. Commit requires the exact
reviewed fingerprint, which covers original bytes, filename, mapping, destination
and owner principal. Changing any of these requires a fresh preview. Commit
creates a durable Base job and applies bounded native batches. When the job is
still applying, use resume until it completes; do not upload a different file
as a substitute. Repeating an identical commit reuses its job. A fully undone
file can be deliberately imported again as a new job.
Status exposes Base's retained originals (including exact CSV bytes as base64),
source locations/hashes and per-party undo dispositions. These are private owner
records. The undo report returns 100 entries by default; use its nextOffset
with status's offset to read subsequent pages (limit accepts 1–1,000).
Jobs, raw provenance, originals and checkpoints live in the ik_*
tables and must travel with the native parties in backup/restore. A stable
role:owner principal permits the restored installation's current owner to use
its jobs; every operation rechecks the active native owner in SQL.
Undo uses Base's preserve-conflicts policy. It deletes only unchanged parties
created by that job. Changed parties, including same-revision field edits, and
parties linked to any matter remain, with reasons in the undo report. The exact
party and incoming matter-link snapshots are rechecked inside the atomic undo
transaction, so a new link or edit cannot slip between observation and deletion.
Undo may require repeated undo calls while its state is undoing; status
shows progress and dispositions. A dependency-retained party is a terminal
retention for that undo, even if its link is removed later.
Imports affect only s_parties. Existing party triggers advance the conflict
revision, invalidating pre-import conflict searches. The importer cannot create
matters, conflict clearance, access grants, time entries, invoices, trust entries
or client credentials. A matter must still pass Satchel's ordinary fresh conflict
search and human opening procedure.
Shared implementation
The unmodified Base import-kit source is copied from
runeditrun/base@fc0e1041efa55771142bbb57c4ab4743147e264d into
src/modules/import-kit; base-import-copies.json
records the exact files and SHA-256 checksums. No Base test suite is copied.
Migration 0023_import.sql is generated from Base's schema exports in
initializeD1ImportStorage order. Satchel supplies only the CSV mapping,
native-party adapter, incoming-matter dependency observations and owner checks.
There is no shadow party store or alternate conflict-opening path.