mirror of
https://github.com/saltbo/zpan.git
synced 2026-09-01 15:49:00 +08:00
7b8c8c915e
Resolve #448 — one upload entry point and an AIP-164 soft delete. Upload: POST /objects now returns size-decided upload instructions { sessionId, partSize, urls }; the server picks single PutObject (<=5 GiB) vs 5 GiB-part multipart (>5 GiB) and rejects >5 TiB. The client PUTs each slice, reads its ETag, then POSTs them to POST /objects/{id}/uploads/{sid}/completions (returns the live object). DELETE /objects/{id}/uploads/{sid} aborts and discards the draft. Trash: matters.status drops 'trashed' (enum is {draft,active}); trash is tracked by the existing trashedAt timestamp. DELETE /objects/{id} now soft-deletes; the recycle bin lives under /trash/objects (list roots, get, restorations, purge). Empty-trash is a frontend loop over roots. BREAKING CHANGE: - removes PUT /objects/{id}/status and POST /objects/{id}/uploads - PUT .../uploads/{sid}/status -> POST .../uploads/{sid}/completions {parts} - DELETE /objects/{id} flips hard-purge -> soft-delete; permanent purge moves to DELETE /trash/objects/{id} - DELETE /trash removed; restore is POST /trash/objects/{id}/restorations - matters.status enum loses 'trashed' (migration backfills to trashedAt) The migration swaps the matters_active_name_uniq partial index to exclude trashed rows (WHERE status='active' AND trashed_at IS NULL). The single-PUT presign is header-free so the uniform slice uploader's raw PUT matches the S3 signature. Go downloader client + agent reworked to the unified flow. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
15 lines
832 B
SQL
15 lines
832 B
SQL
-- Trash is now tracked by `trashed_at`, not the `status` value.
|
|
-- Backfill existing trashed rows to status='active' (their trashed_at is already
|
|
-- set by the old trash() path), so they surface under /trash/objects.
|
|
UPDATE `matters` SET `status` = 'active' WHERE `status` = 'trashed';
|
|
--> statement-breakpoint
|
|
-- Swap the partial unique index: trashed rows are now status='active', so the
|
|
-- "one active name per parent" constraint must also exclude trashed rows
|
|
-- (trashed_at IS NOT NULL) or a restored/recreated name would collide with a
|
|
-- trashed sibling. Replaces migration 0009's `WHERE status = 'active'`.
|
|
DROP INDEX `matters_active_name_uniq`;
|
|
--> statement-breakpoint
|
|
CREATE UNIQUE INDEX `matters_active_name_uniq`
|
|
ON `matters` (`org_id`, `parent`, LOWER(`name`))
|
|
WHERE `status` = 'active' AND `trashed_at` IS NULL;
|