Skip to content

feat(documents): real upload control, and archive / delete actions - #378

Merged
QSchlegel merged 1 commit into
preprodfrom
claude/documents-detail-actions
Aug 22, 2026
Merged

feat(documents): real upload control, and archive / delete actions#378
QSchlegel merged 1 commit into
preprodfrom
claude/documents-detail-actions

Conversation

@QSchlegel

Copy link
Copy Markdown
Collaborator

Upload control

The new-version control was a bare <input type="file">, so it rendered the browser's own Choose file / No file chosen — unstyleable, out of place against the rest of the UI, and silent about what happens next.

Replaced with a drop zone that accepts drag-and-drop and says the thing worth saying: with storageMode: hashOnly the file is hashed in the browser and only the SHA-256 digest is sent, so the bytes never leave the machine. That is a surprising property, and it belongs on the control rather than in documentation nobody opens.

Archive and delete

archiveDocument already existed server-side and was reachable from nowhere. Both actions are now in a header menu, archive listed first because it is almost always the right one.

Deleting is genuinely destructive here — versions, signatures, signer snapshots, attestations and the document's own event log all cascade, and there is no tombstone. So deleteDocument has two guards:

1. Signed documents require the title to be retyped. The dialog states exactly what is being destroyed and how many signatures go with it. In a product whose entire purpose is proving who approved what, erasing that evidence must not be one stray click. A document nobody has signed is just a draft and deletes without ceremony.

2. An AuditLog row is written, awaited, before the delete. AuditLog holds no foreign key to Document, so unlike DocumentEvent it survives the cascade. The document goes; the record that someone deleted it — with title, version count and signature count — does not.

Verification

The control was rendered in isolation against a real build to confirm the visual result (screenshot below the fold in the linked session). The documents page itself is wallet-gated, so the full flow could not be driven end to end here — worth a look on preprod once merged.

tsc --noEmit clean; 1139 tests pass; next build exit 0.

🤖 Generated with Claude Code

@vercel

vercel Bot commented Aug 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
multisig Ready Ready Preview Aug 22, 2026 8:37pm

Request Review

UPLOAD
The new-version control was a bare <input type="file">, so it rendered the
browser's own "Choose file / No file chosen" — unstyleable, out of place
against the rest of the UI, and silent about what happens next. Replaced
with a drop zone that accepts drag-and-drop and says the thing worth
saying: with storageMode hashOnly the file is hashed in the browser and
only the digest is sent, so the bytes never leave the machine. That is a
surprising property and it belongs on the control, not in documentation.

DELETE
`archiveDocument` already existed server-side and was reachable from
nowhere. Both are now in a header menu, with archive listed first because
it is almost always the right one.

Deleting is genuinely destructive here: versions, signatures, signer
snapshots, attestations and the document's own event log all cascade, and
there is no tombstone. So the mutation has two guards.

A document anyone has signed requires the caller to retype its title. The
dialog says plainly what is being destroyed and how many signatures go
with it — in a product whose purpose is proving who approved what, that
must not be one stray click.

And an AuditLog row is written, awaited, BEFORE the delete. AuditLog holds
no foreign key to Document, so unlike DocumentEvent it survives the
cascade: the document goes, the record that someone deleted it — with the
title, version count and signature count — does not.

Verified the control by rendering it in isolation against a real build;
the documents page itself is wallet-gated so it could not be driven
end to end here.

1139 tests pass; tsc clean; next build exit 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@QSchlegel
QSchlegel force-pushed the claude/documents-detail-actions branch from e8712f4 to 17d61e0 Compare August 22, 2026 20:33
@QSchlegel
QSchlegel merged commit 08f595f into preprod Aug 22, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant