Skip to content

feat(voice): add deleted_at to VoiceCallRecord - #46

Merged
wavekat-eason merged 1 commit into
mainfrom
feat/voice-call-deleted-at
Jul 31, 2026
Merged

feat(voice): add deleted_at to VoiceCallRecord#46
wavekat-eason merged 1 commit into
mainfrom
feat/voice-call-deleted-at

Conversation

@wavekat-eason

Copy link
Copy Markdown
Contributor

Step 2 of the call-delete train. The release is the deliverable — wavekat-voice can't build against this from git, so this needs a 0.0.23 cut before that PR can land.

Adds deleted_at to VoiceCallRecord and include_deleted to VoiceCallsQuery.

Calls are otherwise immutable one-way pushes; the tombstone is the one exception, because a hard DELETE can't sync under a push-the-row model — once the row is gone there's nothing left to push. So a delete rides as an ordinary upsert with deletedAt set, exactly as VoiceAccountRecord already does.

Two things documented on the field because a consumer will get them wrong otherwise:

  • The platform treats this tombstone as sticky, not last-write-wins. A call has no updated_at to resolve on — delete is its only mutation — so the platform resolves the column COALESCE(existing, incoming). Re-syncing the row with None can never undelete it. (This is why re-shipping is safe, not merely idempotent.)
  • Deleting isn't just a flag. The platform destroys the recording bytes, the transcript, and any live share link, then retains the row as its own tombstone so a late-syncing device still learns about the delete.

include_deleted is the delta-pull flag a device sets to reap local copies. Unlike the accounts equivalent there's no "restore a fresh device" use for it — a tombstoned call has had its content destroyed, so the only thing left to learn is that it's gone.

Platform side (accepts the field already): wavekat/wavekat-platform#186 + #187, design in that repo's docs/22.

4 new tests: tombstone serializes, a live call omits the key entirely rather than sending null, a live call parses with the field absent and with null, and the query flag round-trips.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EEyoayhGVRqCCY9BWJTKDD

Carries the call-delete tombstone. Calls are otherwise immutable
one-way pushes; this is the one exception, because a hard DELETE can't
sync under a push-the-row model — so a delete rides as an ordinary
upsert with deletedAt set, same as the account tombstone already does.

Two things a consumer needs to know, documented on the field: the
platform treats this tombstone as *sticky* (COALESCE, not
last-write-wins — a call has no updatedAt to resolve on), so re-syncing
with None can never undelete; and deleting also destroys the recording
bytes, the transcript, and any live share link, not just the flag.

VoiceCallsQuery gains includeDeleted so a device can pull tombstones
and reap its local copies.

Step 2 of the three-repo train — wavekat-platform accepts the field
already; wavekat-voice needs a release of this before it can build.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EEyoayhGVRqCCY9BWJTKDD
@wavekat-eason
wavekat-eason marked this pull request as ready for review July 31, 2026 09:25
@wavekat-eason
wavekat-eason merged commit efeb7ca into main Jul 31, 2026
1 check passed
@wavekat-eason
wavekat-eason deleted the feat/voice-call-deleted-at branch July 31, 2026 09:26
@github-actions github-actions Bot mentioned this pull request Jul 31, 2026
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