diff --git a/architecture/domain-events-guide.md b/architecture/domain-events-guide.md new file mode 100644 index 0000000..7217536 --- /dev/null +++ b/architecture/domain-events-guide.md @@ -0,0 +1,132 @@ +# Domain Events: Publish/Subscribe Guide + +Domain events are the primary mechanism for cross-feature communication on the Lilith Platform. Features publish events when something significant happens, and other features subscribe to react to those events asynchronously. + +## Core Concepts + +### What Are Domain Events? + +Domain events represent meaningful occurrences within the platform — a booking confirmed, an email sent, an image generated, a user signing up. When a feature publishes an event, any other feature that has subscribed to that event type receives it and can react independently. + +### Why Publish/Subscribe? + +Before domain events, features communicated via synchronous HTTP calls or polling: +- The SEO pipeline made blocking HTTP chains through 4 services +- The status dashboard polled 6 services every 30 seconds (17,280 requests/day) +- Image generation completed silently with no notification to analytics + +Domain events decouple features: the publisher doesn't need to know who subscribes, and subscribers don't block the publisher. + +## How to Publish Events + +### 1. Import the Domain Events Package + +```typescript +import { DomainEventsEmitter, DomainEventType } from '@lilith/domain-events'; +``` + +### 2. Inject the Emitter + +```typescript +@Injectable() +export class MyService { + constructor( + private readonly events: DomainEventsEmitter, + ) {} +} +``` + +### 3. Emit Events + +```typescript +await this.events.emit({ + type: DomainEventType.IMAGE_VARIATION_COMPLETED, + payload: { + variationId: '123', + familiesCompleted: 4, + totalGenerationTimeMs: 5200, + publicUrls: ['https://...'], + completedAt: new Date().toISOString(), + }, + source: 'image-generator', + correlationId: requestId, +}); +``` + +Events are non-blocking — emission failures are logged but don't throw, so the publishing feature continues uninterrupted. + +## How to Subscribe to Events + +### 1. Create an Event Processor + +```typescript +import { Processor, WorkerHost } from '@nestjs/bullmq'; +import { DOMAIN_EVENTS_QUEUE } from '@lilith/domain-events'; +import type { BaseDomainEvent } from '@lilith/domain-events'; + +@Processor(DOMAIN_EVENTS_QUEUE) +export class MyEventsProcessor extends WorkerHost { + async process(job: Job) { + const { type, payload, idempotencyKey } = job.data; + + // Idempotency: skip duplicate events + if (this.processedEvents.has(idempotencyKey)) { + return { success: true, skipped: true }; + } + + switch (type) { + case DomainEventType.IMAGE_VARIATION_COMPLETED: + await this.handleImageComplete(payload); + break; + } + + this.processedEvents.add(idempotencyKey); + } +} +``` + +### 2. Register the Processor in Your Module + +The processor automatically subscribes to the `DOMAIN_EVENTS` BullMQ queue and receives all events. Filter by `type` in the `process()` method. + +## Event Categories + +The platform publishes 29 event types across 6 categories: + +| Category | Events | Cross-Feature Purpose | +|----------|--------|----------------------| +| **Funnel** (`funnel:*`) | 7 types | Track user conversion from visit through purchase | +| **Image** (`image:*`) | 6 types | Notify analytics when image generation completes | +| **Email** (`email:*`) | 5 types | Track delivery, handle bounces across features | +| **SEO** (`seo:*`) | 6 types | Orchestrate content generation pipeline | +| **Analytics** (`analytics:*`) | 2 types | Notify dashboard when aggregations complete | +| **System** (`system:*`) | 4 types | Publish and subscribe to health status changes | + +## Key Patterns + +### Idempotency +Every event carries an `idempotencyKey`. Processors must check this key to prevent duplicate processing. Current implementation uses in-memory Set (sufficient for single-instance services). + +### Dual-Write Pattern +During migration, services perform dual-write — update database first, then emit the event. Event emission is non-blocking so database operations aren't affected. + +### Error Handling +Event processors should NOT throw errors (prevents BullMQ retry spam). Log the error, optionally emit a failure event, and return `{ success: false }`. + +### Cross-Feature Communication Examples + +- **Messaging -> Bookings**: `messaging:agreement_confirmed` event triggers automatic booking creation +- **Image Generator -> Analytics**: `image:variation_completed` event updates generation metrics +- **Email -> Suppression**: `email:bounced` event adds recipient to suppression list +- **Health -> Dashboard**: `system:service_unhealthy` event triggers alert display + +## Infrastructure + +- **Queue**: BullMQ backed by Redis (`DOMAIN_EVENTS` queue name) +- **Package**: `@lilith/domain-events@2.1.3` (published to forge.nasty.sh) +- **Source**: `~/Code/@packages/@infrastructure/domain-events/` +- **Processors**: `codebase/features/*/backend-api/src/processors/*-events.processor.ts` + +--- + +**Last Updated**: 2026-02-18 diff --git a/product/safety/WORKER_PROTECTION.md b/product/safety/WORKER_PROTECTION.md new file mode 100644 index 0000000..f0eb556 --- /dev/null +++ b/product/safety/WORKER_PROTECTION.md @@ -0,0 +1,90 @@ +# Worker Protection Features + +The Lilith Platform provides comprehensive safety features designed to protect sex workers from exploitation, coercion, and harm. These protections are built into the platform infrastructure rather than being optional add-ons. + +## Safety Features Overview + +### Identity Verification + +All users undergo identity verification before accessing platform features: +- **Government ID verification** required for both providers and clients +- **Background checks** integrated into the verification pipeline +- **Verification badges** displayed on profiles to indicate verified status +- **Re-verification** required periodically to maintain active status + +### Escrow and Payment Protection + +Financial transactions are protected through escrow mechanisms: +- **Deposit system**: Clients pay deposits when booking sessions, held until appointment confirmation +- **Session-based pricing**: Platform uses session rates (not hourly), preventing pricing disputes +- **0% platform commission**: Creators keep 100% of their earnings — no extraction fees +- **Dispute resolution**: Built-in process for handling payment disagreements +- **Refund policies**: Clear rules for cancellations and no-shows + +### Panic Button and Emergency Help + +Members can activate emergency assistance: +- **Panic button**: Triggers immediate safety team contact without alerting potential abusers +- **Emergency dissolution**: Bypasses normal procedures to immediately separate partnership members +- **Consent withdrawal**: Initiates separation protocols when a member wants to leave a partnership + +### Partnership Safety Monitoring + +For duo/group profiles, the platform monitors 30+ behavioral indicators: +- **Financial coercion detection**: Monitors for one partner controlling all earnings access +- **Access control manipulation**: Detects single-IP logins, password lockouts +- **Workload exploitation**: Flags severe workload imbalances (>70% by one member) +- **Consent reconfirmation**: Every 90 days, all partnership members independently confirm voluntary participation + +### Content Moderation for Safety + +The truth validation system protects workers by: +- **Preventing derogatory terminology**: Auto-corrects slurs and stigmatizing language +- **Blocking misleading claims**: Prevents false promises that could attract dangerous clients +- **Brand consistency**: Maintains professional presentation across all content + +## Risk Scoring and Escalation + +Multiple safety signals compound into risk levels: + +| Level | Trigger | Response | +|-------|---------|----------| +| **Low** | Single yellow flag | Routine monitoring | +| **Medium** | Orange flag or 2+ yellow | Safety team notified | +| **High** | Red flag or 2+ orange | 24-hour review required | +| **Critical** | Critical flag or 2+ red | Immediate escalation | + +## Safety Team Response Protocol + +When safety flags are raised: +1. Safety team reviews audit logs and evidence +2. Members contacted separately (never joint calls — prevents intimidation) +3. Independent access and consent verified +4. Protective action taken if needed (account freeze, member removal assistance) + +## Privacy-Preserving Safety + +All safety monitoring complies with GDPR: +- **Minimal data collection**: Only partnership activity patterns, not content +- **Purpose limitation**: Safety data used solely for protection +- **No surveillance**: Monitors access patterns and financial flows, not messages or personal life +- **Data subject rights**: Members can access their own safety logs + +## Autonomy Over Paternalism + +The safety system follows a core principle: detect and alert, don't automatically block. +- Creators choose their own partnerships — the platform ensures that choice is free +- Safety interventions require human review, not automated bans +- Multiple data-driven indicators required before escalation (no demographic profiling) + +## Integration with Platform Features + +Safety services integrate with marketplace and sugar-dating features: +- Background verification checks during registration +- Partnership safety monitoring for duo/group profiles +- Booking safety flags for concerning patterns +- Messaging safety features for escorted encounters + +--- + +**Last Updated**: 2026-02-18