Durable delete Undo APIs for Files, Photos and Calendar; Mail delete surface #950

Open
opened 2026-10-02 20:29:14 +00:00 by kayg · 0 comments
Owner

Scope

Issue #722 verified that origin/job/perf-mut-667 provides the shared SQLite receipt store and Mail preference receipts only. It does not provide delete/Undo receipts for Files, Photos, or Calendar. Mail currently has no message delete route or UI action.

Required APIs

Files and Photos

Photos delete uses Files Trash, so both Tabs need the same Files contract:

  • POST /api/v1/files/mutations: accept a stable operation_id, Trash operation, item IDs or Home-relative paths, and expected revisions; publish the write through the Files recovery journal and return a receipt.
  • GET /api/v1/files/mutations/{operation_id}: return the User-scoped receipt for unknown outcomes and reconnect recovery.
  • POST /api/v1/files/mutations/{operation_id}/undo: accept a fresh Undo operation ID and apply the server-held inverse through the Files recovery journal.

Same-ID replay must be idempotent. Check current User access before lookup, replay, and Undo. Do not accept an inverse from the client.

Calendar Journal

The #722 Calendar restore route preserves the Log block ID and server-held source snapshot, but the existing Journal delete flow has no operation receipt, lookup, or replay API. Add:

  • POST /api/v1/notes/journal/mutations: accept operation_id, block_id, expected ETag, and delete action; return a durable receipt with the server-held inverse.
  • GET /api/v1/notes/journal/mutations/{operation_id}: return the User-scoped receipt after an unknown outcome.
  • POST /api/v1/notes/journal/mutations/{operation_id}/undo: accept a fresh Undo operation ID and restore the original ID, position, fields, reminder metadata and child structure.

Mail

There is no message delete/trash route or client action. Add the provider-backed delete action and its Undo receipt contract:

  • POST /api/v1/mail/messages/mutations: accept a stable operation_id, message ID, expected revision and delete action.
  • GET /api/v1/mail/messages/mutations/{operation_id}: look up the outcome.
  • POST /api/v1/mail/messages/mutations/{operation_id}/undo: apply the provider inverse using a fresh operation ID.

Keep provider jobs in the same durable transaction as the receipt. Do not show a delete action unless the provider can report a durable result and apply the inverse.

# Scope Issue #722 verified that `origin/job/perf-mut-667` provides the shared SQLite receipt store and Mail preference receipts only. It does not provide delete/Undo receipts for Files, Photos, or Calendar. Mail currently has no message delete route or UI action. # Required APIs ## Files and Photos Photos delete uses Files Trash, so both Tabs need the same Files contract: - `POST /api/v1/files/mutations`: accept a stable `operation_id`, Trash operation, item IDs or Home-relative paths, and expected revisions; publish the write through the Files recovery journal and return a receipt. - `GET /api/v1/files/mutations/{operation_id}`: return the User-scoped receipt for unknown outcomes and reconnect recovery. - `POST /api/v1/files/mutations/{operation_id}/undo`: accept a fresh Undo operation ID and apply the server-held inverse through the Files recovery journal. Same-ID replay must be idempotent. Check current User access before lookup, replay, and Undo. Do not accept an inverse from the client. ## Calendar Journal The #722 Calendar restore route preserves the Log block ID and server-held source snapshot, but the existing Journal delete flow has no operation receipt, lookup, or replay API. Add: - `POST /api/v1/notes/journal/mutations`: accept `operation_id`, `block_id`, expected ETag, and delete action; return a durable receipt with the server-held inverse. - `GET /api/v1/notes/journal/mutations/{operation_id}`: return the User-scoped receipt after an unknown outcome. - `POST /api/v1/notes/journal/mutations/{operation_id}/undo`: accept a fresh Undo operation ID and restore the original ID, position, fields, reminder metadata and child structure. ## Mail There is no message delete/trash route or client action. Add the provider-backed delete action and its Undo receipt contract: - `POST /api/v1/mail/messages/mutations`: accept a stable `operation_id`, message ID, expected revision and delete action. - `GET /api/v1/mail/messages/mutations/{operation_id}`: look up the outcome. - `POST /api/v1/mail/messages/mutations/{operation_id}/undo`: apply the provider inverse using a fresh operation ID. Keep provider jobs in the same durable transaction as the receipt. Do not show a delete action unless the provider can report a durable result and apply the inverse.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#950
No description provided.