feat(messages): ephemeral / self-destruct messages (LC-547) #516
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/LC-547-ephemeral-messages"
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?
What
Ephemeral / self-destruct messages (LC-547), the second Round-4 build. A sender can attach a self-destruct timer to a message; once it passes, the message is hard-deleted (content gone at rest, not tombstoned) and removed from every connected client.
How
messages.expires_at(chat/0085, partial index over the small live-ephemeral set).models::message::ephemeral_expires_at()maps a closed token set (5m / 1h / 1d / 7d) to an absolute"%Y-%m-%d %H:%M:%S"UTC stamp and returnsNonefor anything else, so a forged token cannot request an arbitrary lifetime.db::chat::set_message_expiry()stamps the row.retention::sweep::sweep_expired_ephemeral()hard-deletes rows whoseexpires_at <= now, reusinghard_delete_messagesand the sameBEGIN IMMEDIATEtransaction shape as the retention sweep. Deliberately NOT gated byLETS_CHAT_RETENTION_SWEEP_ENABLED: a per-message timer is user intent, not operator policy, so it always runs.spawn_ephemeral_sweeperruns it unconditionally every 60s (bounding how long an expired message lingers) and broadcastsMessagePurgedafter commit so clients drop the node.<select>(No timer / 5m / 1h / 1d / 7d) rides the existingaxum::Formsend asttl;post_messagestamps the expiry when the token is in the allowlist. en/es strings added (i18n parity).Scope / follow-ups
expires_atthroughMessageView+ theMessagebroadcast struct (~9 construction sites) and everyRawMessageSELECT; deferred to keep this slice focused and avoid the column-drift trap. The sender picks the timer in the composer; the message vanishes on expiry.post_message); thread replies / DMs can follow.Tests
ephemeral_expires_attoken mapping + rejection of blank/forged tokens.ephemeral_messages): sweep deletes only past-expiry rows (sparing future-dated and permanent), sweep no-ops when nothing expired, andpost_messagestamps a future expiry for an allowlisted token / stays permanent for empty / refuses a forged token.Green locally on
just check, fulljust test, andjust test-saas.🤖 Generated with Claude Code
https://claude.ai/code/session_016e15V7qtQgNFaK3VNYpwkw