# 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
