Captures the owner's requirements and decisions from the planning conversation, current branch/worktree state, open tasks 17-19, pending owner decisions and the controller's rulings so a new agent can resume. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2.3 KiB
2.3 KiB
Task 15 report
Built packages/core/src/export.ts (exportUserBundle, exportUserCsv, importUserBundle) and backup.ts (runBackup, backupHandler), tests in packages/core/test/{export,backup}.test.ts, DECISIONS.md entry (top).
TDD: tests and code were written together, then RED shown by removing src files: Cannot find module '../src/export.ts', 0 pass 2 fail. GREEN: sqlite 8 pass; with TEST_POSTGRES_URL 16 pass 0 fail. bun run typecheck clean.
Decisions/concerns:
- Attachments are restored after the main transaction (storeAttachment uses its own tx; sqlite deadlock otherwise), so a failure there leaves rows without attachments. Attachment createdAt/visibility restored by update after store; extra links inserted directly.
- Attachments whose file is missing on disk are skipped at export.
- Merged-away works are exported as raw tombstone rows (mergedIntoId dropped); with no external IDs they restore as private works.
- Listens inserted with onConflict doNothing (unique user/source/source_key); account-empty check is entries only.
- runBackup
keepoptional (default 14); backupHandler returns() => Promise<void>. - Unknown/invalid zip => ImportError("unsupported_format"); inconsistent refs => ImportError("corrupt_bundle").
- Work hierarchy sibling position uniqueness could collide on reuse edge cases (not handled).
Fix round 1
- I1: mergedIntoId + work_aliases.jsonl exported/restored (tombstone + alias; test with moveEntryToWork then upsertEntry).
- I2: attachments pre-validated (mime, size, sha) -> ImportError("invalid_attachment"); files written before the tx, rows inserted in the tx; files re-written after commit. attachments.ts gained exported
writeAttachmentFile,sha256Hex,normalizeMime,mimeAllowed,MAX_ATTACHMENT_BYTES. - I3: export reads in one transaction (repeatable read on Postgres).
- I4: tests extended (copies, custom fields, listens, grouping list, overrides/visibility, caption on two links, history UUID remap, alias/tombstone, second user isolation, credential-key check, invalid attachment, corrupt rating).
- I5: ARCHITECTURE, TODO, DECISIONS updated.
- M3 validation + 2 GB cap (bundle_too_large); M5 0700/0600 + tmp-then-rename + 500-chunked IN; M1 unique violation -> ImportError("conflict").
- Results: bun test packages/core 113 pass (sqlite), 218 pass (postgres); typecheck clean.