Conversation
Signed-off-by: wangzifei <wangzifei@cit.group.hk>
|
Read it end to end. CI approved — fork PRs need that here after every push. This is careful work, and the parts I went looking for trouble in are the parts you got right. Authentication. A new route that serves raw bytes is where I expected to find the hole. Instead there are two independent checks: Ingest tokens are rejected structurally rather than by a check that could be forgotten: A scoped token gets the same The transaction commits before the response is built.
Two things. 1. 2. One sentence missing from the Limits section, which is otherwise the right section. You say the route "buffers within the existing upload cap", and Neither blocks. Once CI reports, and with the index rows added, this looks good to me. |
What
Adds a versioned read contract for retained originals:
GET /api/v1/documents/{id}/contentserves the current or requested?version=Nbytes from the document ledger.GET /api/v1/documents/{id}/versionslistsversion,sha256,size_bytes, andingested_at.410 Gone; soft-deleted retained documents remain readable until purge.Content-Disposition.utp_pat_personal access tokens scoped to the knowledge base; source ingest tokens are rejected.The content transaction takes
SELECT ... FOR NO KEY UPDATEand holds it through the blob read, so replacement or purge cannot move or remove the selected blob after the ledger check. Commit happens after the blob read is complete. A ledger entry whose blob is unavailable returns500as an invariant failure rather than masking it as a normal client error.ADR 0052 records the API/lifecycle boundary and why the ledger is the source of truth.
Why
The document API currently exposes metadata while versions and original bytes stay internal. This makes auditable retention observable to clients, lets callers retrieve the exact recorded original, and closes #859.
Closes #859
Testing
Against Postgres 17 with
UTOPIA_TEST_REQUIRE_DB=1andUTOPIA_DATABASE_URLset:Results:
cargo fmtcompleted without changes.cargo clippypassed with warnings denied.