chore(architecture): 🔧 update domain event patterns documentation with clearer event handling workflows and refined worker protection safety checks for production

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Quinn Ftw 2026-02-18 10:12:51 -08:00
parent efe5eddfdb
commit b539c0096f
2 changed files with 222 additions and 0 deletions

View file

@ -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<BaseDomainEvent>) {
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

View file

@ -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