lilith-platform.live/codebase/@features/user-data/README.md

48 lines
2.5 KiB
Markdown
Raw Normal View History

# user-data
Parent feature: cross-domain, cross-corp visitor flow on the lilith-platform.live mesh.
This feature absorbs what used to be `@features/analytics/` and adds the missing layers
needed to stitch a visitor journey across `adulttherapytour.com →
maisonsansonnet.com → transquinnftw.com → atlilith.com`. The deployed surface remains
[`quinn.data`](../../../deployments/@domains/quinn.data/) (data.transquinnftw.com).
## Shape
| Path | Package | Role |
|---|---|---|
| `shared/` | `@lilith/analytics-client` | Browser client core — batch queue, attribution, device collector. No React dep. |
| `frontend-client/` | `@lilith/analytics-client-react` | React provider + hooks (`useAnalytics`, `useFunnelEvents`, `usePageViewTracking`). |
| `website-backend-users/` | `@lilith/analytics-website-backend` | BFF proxy → @analytics collector (`:4001`) + query API (`:4003`). Stamps every event with `visitor_id_daily`, `corp_id`, `domain_id`. |
| `website-frontend-users/` | `@lilith/analytics-website-users` | Dashboard SPA. Includes the **Cross-Corp Flow** tab. |
| `identity/` | `@lilith/user-data-identity` | Server-side visitor identity. `visitorIdDaily(ip, ua, lang, now) = sha256(daily_salt ‖ ip ‖ ua ‖ lang)`. Salt rotates at 00:00 UTC. Cookie-free, GDPR-clean. |
| `beacon/` | `@lilith/user-data-beacon` | ~2 KB IIFE for static-HTML sites that can't host the React provider. Served from `https://quinn.data/beacon.js`. |
| `flow/` | `@lilith/user-data-flow` | SQL building blocks + dashboard tab for corp → corp flow analysis. |
## Visitor identity model
- **No cookies.** No localStorage. No fingerprint canvas.
- `visitor_id_daily = sha256(salt_today ‖ X-Real-IP ‖ User-Agent ‖ Accept-Language)`.
- Same visitor → same id across **all** our domains within a UTC day.
- Salt rotates at 00:00 UTC and is purged from `visitor_salts` after 7 days, making
historical re-identification mathematically impossible.
- Tab-scoped `sessionId` (client-side, in-memory) is preserved for per-tab funnels.
## Corp / domain taxonomy
Every event row carries `corp_id` and `domain_id`. Seed corps:
| slug | legal_name |
|---|---|
| `lilith-apps-ehf` | Lilith Apps ehf |
| `att` | Adult Therapy Tour |
| `sansonnet` | Maison Sansonnet |
| `transquinnftw` | transquinnftw |
Domains map to corps (`adulttherapytour.com``att`, `maisonsansonnet.com``sansonnet`, etc.).
See migration `<TBD>` in `website-backend-users/migrations/`.
## Privacy
See [`PRIVACY.md`](./PRIVACY.md).