Documentation
¶
Overview ¶
Package exporter builds the /api/export zip per PHILOSOPHY § 4 (compose, don't absorb) — it ships JSONL bytes straight from disk into a streaming zip, no transformation. The SQLite store is consulted only to decide *which* JSONL lines to ship (filesystem is truth; SQLite is the derived index, principle 6).
The zip layout matches uiux-research/phase-i-export-contract.md and uiux-research/phase-k-media-contract.md § 9:
data/<YYYY-MM-DD>/<keyhash8>.jsonl (all rows on disk matched) data/<YYYY-MM-DD>/<keyhash8>.partial.jsonl (subset matched) media/<trace_id>/<idx>.<ext> (extracted attachments, if any) agent/CLAUDE.md agent/jq-cheatsheet.md README.md
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func WriteZip ¶
func WriteZip(w io.Writer, store *sqlite.Store, dataDir string, filters sqlite.ListFilters, limit int) error
WriteZip streams a zip archive of every row matched by filters into w.
dataDir is the storage root that JSONL paths in the SQLite rows are relative to (or absolute; we accept either — the row's JSONLPath is the authoritative reader-side path).
limit optionally bounds how many rows we read from SQLite. Pass 0 (or any non-positive value) to export every matching row — there is no fixed upper bound; the export streams so memory is not the bottleneck and SQLite handles 100k+ rows comfortably.
The returned error means either the SQLite read failed (zip not yet started) or a disk read failed mid-stream (zip may be partial). The caller is responsible for setting HTTP headers BEFORE calling — once bytes start flowing to w we can no longer set a status code.
Types ¶
This section is empty.