What's changed
- The inbox campaign context card is now a narrow GB-only Travio practice-link card: it displays only numeric Travio practice IDs with host-validated links to
https://new.travio.it/pratiche/detail/. - Broad Travio/family/resort/price/reservation snapshots are no longer exposed in the card. The follow-up slice will wire identity resolution into the same ID-only contract.
Privacy & security
- Raw
campaign_recipient_client_contextsrows are no longer directly selectable by authenticated clients; app routes expose only sanitized server DTOs. - Composite workspace-scoped foreign keys prevent malformed imports from attaching one workspace/contact/campaign's context to another.
- Envelope-only inbox refreshes always strip
clientContext, preserving the metadata-only refresh contract and keeping IndexedDB/list cache payloads free of Travio context. - The card is gated server-side to the known GB workspaces via
GB_TRAVIO_CLIENT_CONTEXT_*.
Verification
pnpm --filter @repo/database typecheckpnpm --filter app typecheck- targeted route/adapter/card tests
- adversarial review