Implement destructive CalDAV move saga
This commit is contained in:
@@ -159,12 +159,28 @@ Collection deletion accepts two explicit, non-destructive external actions for
|
||||
rolling back or hiding the local move.
|
||||
|
||||
Local-to-local moves retain their existing behavior and do not accept an
|
||||
`external_action`. Implicit or mismatched actions, inbound-only destinations,
|
||||
and synchronized-to-synchronized moves are rejected. `remote_move` is a known
|
||||
but deliberately unsupported action: implementing it requires a separately
|
||||
approved saga for destination reconciliation, conditional source deletion,
|
||||
collision handling, and concurrent-edit policy. The WebUI does not offer that
|
||||
destructive mode.
|
||||
`external_action`. Implicit or mismatched actions and inbound-only destinations
|
||||
are rejected. `remote_move` applies only between active, enabled, two-way
|
||||
CalDAV sources. It is an administrator-authorized durable migration saga:
|
||||
|
||||
- the request requires the exact `MOVE REMOTE EVENTS` confirmation and a
|
||||
retained authorization-evidence note;
|
||||
- all destination resources must complete or reconcile their conditional PUTs
|
||||
before any source DELETE can be leased;
|
||||
- every source DELETE uses the ETag captured when the batch started, so a
|
||||
concurrent remote edit becomes an explicit conflict rather than data loss;
|
||||
- UIDs are preserved and target UID collisions stop the batch before mutation;
|
||||
- both calendars, their sources, and moved events reject ordinary edits and
|
||||
synchronization while the batch is active;
|
||||
- progress, resource states, conflicts, authorization evidence, and actor
|
||||
provenance remain queryable; and
|
||||
- cancellation is available only before the first source DELETE attempt. It
|
||||
finishes safe destination copies, retains the source resources, and restores
|
||||
source synchronization. Once deletion starts, the batch must be reconciled.
|
||||
|
||||
The source collection is retired only after every source resource is confirmed
|
||||
absent. A crash after a destination write is reconciled by semantic ICS content
|
||||
before retry, preserving the outbox's no-blind-repeat guarantee.
|
||||
|
||||
Resolved terminal rows (`succeeded`, `superseded`, and `cancelled`) are removed
|
||||
in bounded batches after `CALENDAR_OUTBOX_TERMINAL_RETENTION_DAYS` (90 days by
|
||||
|
||||
Reference in New Issue
Block a user