Skip to content

feat: add forgettable payloads for GDPR-compliant data deletion#94

Draft
bodymindarts wants to merge 7 commits intomainfrom
feat/forgettable-payloads
Draft

feat: add forgettable payloads for GDPR-compliant data deletion#94
bodymindarts wants to merge 7 commits intomainfrom
feat/forgettable-payloads

Conversation

@bodymindarts
Copy link
Copy Markdown
Member

Implement the Forgettable Payloads pattern for event sourcing, allowing sensitive field values to be stored separately and permanently deleted on request while keeping events intact.

  • Add Forgettable wrapper type with transparent serde serialization
  • Extract forgettable fields into a separate payloads table on persist
  • Inject payloads back during event loading via LEFT JOIN
  • Generate forget() and forget_in_op() methods on repos with forgettable flag
  • Support forgettable across all query paths (find_by, find_all, list_by, etc.)
  • Add integration tests for create, load, forget, and find_all flows

bodymindarts and others added 7 commits February 27, 2026 22:29
Implement the Forgettable Payloads pattern for event sourcing, allowing
sensitive field values to be stored separately and permanently deleted
on request while keeping events intact.

- Add Forgettable<T> wrapper type with transparent serde serialization
- Extract forgettable fields into a separate payloads table on persist
- Inject payloads back during event loading via LEFT JOIN
- Generate forget() and forget_in_op() methods on repos with forgettable flag
- Support forgettable across all query paths (find_by, find_all, list_by, etc.)
- Add integration tests for create, load, forget, and find_all flows

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ssor

Convert Forgettable from a public enum (Set/Forgotten) to an opaque struct
with private internals to prevent accidental extraction and re-serialization
of personal data. The value() method now returns ForgettableRef<T> which
implements Deref<Target=T> but NOT Serialize, so accidental re-serialization
won't compile. Adds value_cloned() convenience method and
__extract_payload_value() for macro-generated code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove into_value() and value_cloned() which circumvented ForgettableRef
  safety by allowing direct extraction of the inner T
- Change inject_forgettable_payload to take payload by move instead of &ref,
  eliminating unnecessary clones
- Merge forgettable test migration into main test_setup file
- Remove inline review comments

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Change forget() to take &mut Entity instead of id, so the caller
  sees forgotten fields immediately without a manual reload
- Generate forget_forgettable_payloads() on event types to clear
  Forgettable<T> fields in-place without a DB round-trip
- Add EntityEvents::forget_and_take() to forget persisted events and
  rebuild the entity via TryFromEvents
- Auto-delete forgettable payloads when delete() is called on repos
  with forgettable enabled, preventing orphaned personal data

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…apter

Rename the `payload` field in `GenericEvent` to `forgettable_payload`
for clarity about its purpose. Update all SQL aliases in generated
queries to match. Add a new "Forgettable Data" chapter to the book
covering the full workflow: field definitions, accessing values,
hydration, repository configuration, and delete integration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rom for Forgettable

es_query! now emits a compile-time error when forgettable_tbl is omitted
on event types with Forgettable<T> fields, preventing silent data loss.
Also adds Default and From<T> impls for ergonomic Forgettable construction,
and documents es_query! usage, compile-time safety, and delete asymmetry
in the book chapter.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
es_query! now emits a compile-time error when tbl_prefix is omitted
on a repo that uses tbl_prefix, unless entity is explicitly specified.
Uses a const in the repo types module (same pattern as the forgettable
check) to avoid the Self-in-const limitation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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