analytics/CLAUDE.md
Natalie 8fde986eb3 chore(registry): cut @lilith npm/swift registry from dead black to ct-forge (134.199.243.61)
black homelan is gone; point install+publish+auth at the live cocotte ct-forge
verdaccio (:4873) / forgejo (:3000). Config-only; resolution verified.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 18:37:48 -04:00

121 lines
3.6 KiB
Markdown

# @analytics - Generic Analytics Platform
**Purpose**: Self-hosted, privacy-first analytics platform. This is a reusable, open-sourceable product - NOT Lilith-specific code.
---
## Architecture
```
@analytics/
├── packages/ # Shared libraries
│ ├── analytics-types/ # Event schemas, TypeScript types
│ ├── analytics-widgets/ # React UI components
│ └── analytics-nestjs/ # NestJS integration module
├── services/ # Backend microservices
│ ├── collector/ # POST /track - Event ingestion
│ ├── processor/ # BullMQ workers - Aggregation
│ ├── api/ # Query API - Trends, funnels, cohorts
│ └── realtime/ # WebSocket gateway - Live metrics
└── infrastructure/ # Docker deployment configs
```
---
## Core Principles
### 1. Privacy First
- No third-party pixels or tracking
- IP addresses hashed, never stored raw
- Session-based tracking (no persistent identifiers)
- DoNotTrack signal respected
- GDPR compliance built-in (deletion, export)
### 2. Self-Hostable
- Docker Compose deployment
- TimescaleDB + Redis dependencies
- No external service requirements
### 3. Generic (Not Platform-Specific)
- NO business-specific entities (gifts, subscriptions, marketplace)
- NO platform branding or customization
- Generic event types: view, click, conversion, funnel_step
- Platform-specific code belongs in consumer projects
---
## Package Conventions
| Package | Scope | Published As |
|---------|-------|--------------|
| analytics-types | Types/schemas | `@analytics/types` |
| analytics-widgets | React components | `@analytics/widgets` |
| analytics-nestjs | NestJS module | `@analytics/nestjs` |
---
## Service Ports (Development)
| Service | Port | Purpose |
|---------|------|---------|
| collector | 4001 | Event ingestion |
| processor | 4002 | Background workers |
| api | 4003 | Query API |
| realtime | 4004 | WebSocket |
---
## Key Technologies
- **Database**: TimescaleDB (hypertables for time-series)
- **Queue**: BullMQ + Redis
- **API**: NestJS
- **Widgets**: React + Recharts
- **SDK**: TypeScript (browser + Node.js)
---
## Operational Invariants
- **Prod runs `synchronize: false` with no migration runner.** A new `@Column` does NOT
reach a long-lived prod database on its own — every INSERT referencing it then throws
`column "…" does not exist`, and if the write path swallows errors (e.g. session
fingerprinting) the failure is silent: `raw_events` keeps filling while the derived
table (`session_fingerprints`) freezes and its dashboard pages (Traffic/Audience/
Network) silently show `0`. **When you add a column prod must have, add it to the
processor's `SchemaGuardService` too** (idempotent `ALTER TABLE … ADD COLUMN IF NOT
EXISTS`). See [Schema Management & Drift](./docs/deployment.md#schema-management--drift).
- **Deploys build `linux/amd64` images off the VPS** (vps-0 has 4 GB RAM and OOMs on
build). `BUILD_HOST=black` (default, native) / `local` (emulated) / `quinn-vps` (last
resort). See [scripts/README.md](./scripts/README.md).
---
## Development
```bash
# Install dependencies
pnpm install
# Build all packages
pnpm build:packages
# Start services (requires Docker infra)
pnpm dev:collector
pnpm dev:api
pnpm dev:realtime
```
---
## What Does NOT Belong Here
- Creator profiles, listings, marketplace entities
- Gift tracking, subscription tiers
- Platform-specific enums (POST, GALLERY, PRODUCT)
- Government IP detection
- Any business logic specific to Lilith
These belong in `features/platform-analytics/` in the consumer project.