# Terms Agreement Feature Stores legal audit trail for Terms & Conditions acceptance at user signup. ## Purpose Provides comprehensive legal compliance by capturing: - **User consent**: Proof that user agreed to T&C before account creation - **Audit fields**: IP address, user agent, timestamp, terms version, content hash ## Data Flow 1. User checks T&C checkbox on signup form 2. Frontend sends `termsAccepted: true` with signup request 3. Controller extracts IP (from X-Forwarded-For header), User-Agent 4. Service creates user profile and terms agreement atomically in transaction 5. Terms agreement record stores audit fields for legal compliance ## Database Schema | Column | Type | Description | |--------|------|-------------| | id | UUID | Primary key | | user_id | VARCHAR | Auth0 user ID | | agreed_at | TIMESTAMPTZ | UTC timestamp of agreement | | ip_address | VARCHAR(45) | Client IP (supports IPv6) | | user_agent | TEXT | Browser/client user agent | | terms_version | VARCHAR | Version string (e.g., v2026-01-03) | | terms_url | VARCHAR | URL path to PDF | | terms_content_hash | VARCHAR(64) | SHA-256 hash of PDF content | ## Files | Path | Purpose | |------|---------| | `migrations/001_create_terms_agreements.sql` | Database table creation | | `data/terms-agreement.repository.ts` | Data access layer | | `domain/terms-agreement.types.ts` | TypeScript interfaces | | `domain/terms-config.ts` | Static terms version and hash | | `index.ts` | Feature exports | ## Invariants - Every user in `user_profiles` has exactly one record in `terms_agreements` - `agreed_at` is always stored in UTC - `terms_content_hash` matches SHA-256 of PDF at signup time