diff --git a/docs/adr/0005-allow-private-table-file-byte-transports.md b/docs/adr/0005-allow-private-table-file-byte-transports.md new file mode 100644 index 0000000..db0ee81 --- /dev/null +++ b/docs/adr/0005-allow-private-table-file-byte-transports.md @@ -0,0 +1,27 @@ +# Allow private table-file byte transports + +CMS WO-TF-009 adds administrator file management through generated ConnectRPC +hooks. Binary upload, content download and bounded preview streams use the +private HTTP serving boundary because unary metadata hooks cannot express +resumable chunks, download bodies or preview derivatives. + +Allow exactly three literal fetch targets in `lib/table-file-transport.ts`: +`/api/table-file-uploads/${sessionId}`, +`/api/table-files/${attachmentId}/content?version=${versionId}` and +`/api/table-files/${attachmentId}/preview?version=${versionId}`. Preserve ADR 0002's +file-and-target matching. Admission, status, cancellation, finalization and +lifecycle controls remain generated RPC calls. + +An entire-file exception or route-prefix allowance was rejected because either +would permit unrelated future controls to bypass generated hooks. Ordinary +media routes were rejected because table files have separate authority. + +Consequences: + +- `frontend.go` documents each exact target's binary transport reason. +- Moving the bridge or changing a target requires another reviewed allowance. +- Existing narrow-allowance tests cover sibling routes and other callers; the + complete checker test suite passes. +- These allowances change no runtime authority or admission gate. + +Keywords: WO-TF-009, table files, allowedNonProtoFetches, frontend.go, frontend_test.go, lib/table-file-transport.ts, /api/table-file-uploads, /api/table-files, content, preview, versionId, ConnectRPC, resumable chunks diff --git a/frontend.go b/frontend.go index 403a5f1..0834d08 100644 --- a/frontend.go +++ b/frontend.go @@ -82,6 +82,9 @@ type nonProtoFetchAllowance struct { // generated-hook rule. Add an entry only after confirming that no generated // ConnectRPC hook can carry the endpoint's transport contract. var allowedNonProtoFetches = []nonProtoFetchAllowance{ + {file: "lib/table-file-transport.ts", target: "/api/table-file-uploads/${sessionId}", reason: "bounded resumable binary chunks with durable offsets; controls use generated RPC hooks"}, + {file: "lib/table-file-transport.ts", target: "/api/table-files/${attachmentId}/content?version=${versionId}", reason: "authenticated exact-version binary download; access is rechecked at open"}, + {file: "lib/table-file-transport.ts", target: "/api/table-files/${attachmentId}/preview?version=${versionId}", reason: "bounded safe binary/text preview; no raw document embedding"}, { file: "components/admin/backups/restore-new-instance-dialog.tsx", target: "/api/push/upload?account_id=${encodeURIComponent(accountId)}",