feat(calendar): support conditional CalDAV delete for tasks and events #121
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/117-caldav-delete"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #117.
What changed
Verified
Deviations
none
VERDICT: request-changes
src/api/delete.rs:L303: P1: Crash recovery requires a representation field, but delete intents omit it; every prepared or uncertain deletion remains unreconcilable after restart. Teach recovery to classify delete intents from the recorded target and live absence.
src/history/journal.rs:L735: P1: A concurrent sync can read the resource before deletion and upsert its stale projection after this transaction, resurrecting the deleted item. Fence sync commits against the deletion fact or serialize the operations.
src/calendar/client.rs:L299: P1: The shared CalDAV client follows same-origin redirects while carrying Basic credentials; DELETE can follow a redirect with credentials. Refuse redirects for conditional DELETE rather than sending a second credentialed request.
src/api/delete.rs:L379: P2: Any 2xx is treated as completed deletion, but 202 only accepts work for later and 207 can contain a failed member; these responses wrongly record applied and remove projections. Accept completed DELETE statuses only, and retain an unconfirmed state otherwise.
Addressed review round 1 findings:
Added regression tests covering all four fixes in tests/delete_tests.rs; all 18 integration tests pass.
VERDICT: request-changes
P2 src/history/journal.rs:345 — Preserve subsecond ordering in the deletion fence. SQLite datetime() truncates fractional seconds, so a resource deleted and then recreated or synced with the same UID in the same second compares as though its later observation preceded the deletion. upsert_projection silently drops the live projection, and later reads of the projection stay empty. Compare timestamps at their actual precision so a deletion only fences earlier observations.
P2 src/history/journal.rs:351 — Fence stale sync observations along with their projections. The sync transactions append external baseline or change facts before calling upsert_projection. If a deletion commits between the live fetch and that sync transaction, this guard skips the stale projection but leaves a stale presence fact appended after task_deleted or event_deleted. The items absence lookup scans facts by insertion order and then reports the latest fact as not a known removal, so a deleted item loses its confirmed-removal history. Skip both the stale observation fact and projection together.
The other round-one fixes are present: recovery reads deletion intents without a representation, DELETE redirects are blocked, and HTTP 202 is unconfirmed. Focused delete tests passed (18/18), skill package tests passed (7/7), formatter and Clippy passed per the integration run. Both branch commit messages and this comment contain zero backticks.
Addressed review round 2 findings:
VERDICT: approve
Round 3: both round-2 findings are resolved. The deletion fence compares parsed RFC3339 timestamps at subsecond precision, and the sync observation append skips stale presence facts in the same transaction that suppresses stale projections. Focused regression cases cover both paths. Commit messages and this review contain zero backticks. No blocking findings.