# Architect — F-028 Security hardening

## Feature
F-028 introduces rate limiting, audit log, and admin MFA enrollment gate.

## Design

### Module boundaries
Create `project/src/modules/security/` with domain/application/infrastructure/api/tests. The module owns an in-memory rate limiter and audit log table.

### Data model
Add migration `021_security.js`:
- `security_audit_log`: id, actor_id uuid nullable, action text, target text, metadata jsonb, created_at.

### Behavior
- `RateLimiter` per-key sliding window (in-memory for v1).
- `AuditLogger.log(actor, action, target, metadata)` writes row.
- Admin login gate: existing `login` route checks `security_admin_mfa` flag; MFA enrollment required for admin login.

### API
- `GET /admin/mfa/status` returns whether current admin has MFA enrolled.
- `POST /admin/mfa/enroll` admin-only flips the flag.

## Acceptance trace
- Rate limit above threshold -> HTTP 429.
- Admin login without MFA -> blocked.
- Admin mutation -> audit log row.
