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>
3.6 KiB
3.6 KiB
@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: falsewith no migration runner. A new@Columndoes NOT reach a long-lived prod database on its own — every INSERT referencing it then throwscolumn "…" does not exist, and if the write path swallows errors (e.g. session fingerprinting) the failure is silent:raw_eventskeeps filling while the derived table (session_fingerprints) freezes and its dashboard pages (Traffic/Audience/ Network) silently show0. When you add a column prod must have, add it to the processor'sSchemaGuardServicetoo (idempotentALTER TABLE … ADD COLUMN IF NOT EXISTS). See Schema Management & Drift. - Deploys build
linux/amd64images 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.
Development
# 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.