mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-09-24 19:32:10 +00:00
60dd3e1a37
Implements PLAN-2357 DR-11 / DR-11a. PlanAttachmentCopy takes the copied content plus the FINAL destination fields and returns the old->new attachment UUID map, the rows to create (originals followed by their variants, parent_id remapped), the byte total, and the unresolvable-ref list. It writes nothing, takes no *sql.Tx, and is shared by the copy orchestration and the dry-run endpoint so their numbers cannot drift. DR-11a: every resolution is scoped to workspace_id = A AND deleted_at IS NULL, and the parent/variant traversal carries the identical scope. The reference set comes from user-controlled content, so an unscoped lookup would let a user clone another workspace's blob into a workspace they control, bypassing the download handler's workspace check. Refs that resolve to nothing under that scope -- dangling, soft-deleted, or foreign -- are never cloned and never fatal: they get no map entry, so the rewrite preserves the literal text and the copy renders exactly as broken as the source did. A cross-backend row emits an empty storage_key with the source key in SourceStorageKey, so the plan never contains a key the target backend cannot resolve. CreateAttachment now rejects an empty storage_key, which turns that contract into an enforced invariant: an orchestration that skips the Get/Put byte transfer fails at insert rather than creating a live attachment that 404s on download. Claude-Session: https://claude.ai/code/session_01E2fRi12n8rARczvdEa2LYT