## Purpose

Admin authentication via Google sign-in, session management, role-based authorization for the three admin roles, and the audit trail of admin actions. v1 deviates from PRD FR-4.1 by owner decision: Google OAuth only — no passwords, no TOTP.

## ADDED Requirements

### Requirement: Google OAuth sign-in with email allowlist (FR-4.1 adapted, P0)
The system SHALL provide admin sign-in at `/admin` exclusively via Google OAuth. Sign-in succeeds only when the Google account's verified email matches an active `admin_user` record (the allowlist); any other Google account is rejected with a generic "not authorized" message and no account is auto-created. No passwords are stored anywhere. Sessions use httpOnly, secure, sameSite cookies with 12-hour expiry; `last_login_at` is recorded.

#### Scenario: Allowlisted admin signs in
- **WHEN** an active admin completes Google sign-in with their allowlisted email
- **THEN** a 12-hour httpOnly session is established and `last_login_at` is recorded

#### Scenario: Unknown Google account
- **WHEN** a Google sign-in completes with an email not on the allowlist
- **THEN** access is rejected with a generic message, no admin account is created, and the attempt is recorded

#### Scenario: Deactivated admin
- **WHEN** an admin whose `is_active` is false attempts sign-in
- **THEN** access is rejected even though the email is on the allowlist

#### Scenario: Unauthenticated access
- **WHEN** a request hits any `/admin` page or admin API without a valid session
- **THEN** it is redirected to sign-in / rejected with 401

#### Scenario: Session expiry
- **WHEN** 12 hours pass after sign-in
- **THEN** the session is invalid and the admin must sign in again

### Requirement: Admin user management (P0)
Super Admin SHALL manage the allowlist: add an admin by Google email, assign a role (Super Admin / Co-host / Viewer), deactivate, and change roles. Changes take effect on the target's next request or sign-in, and every change writes an audit entry. The system MUST prevent removing or demoting the last active Super Admin.

#### Scenario: Add a co-host
- **WHEN** a Super Admin adds `brother@gmail.com` with role Co-host
- **THEN** that Google account can sign in with Co-host permissions

#### Scenario: Last Super Admin protected
- **WHEN** a Super Admin tries to deactivate the only active Super Admin account
- **THEN** the operation is rejected

### Requirement: Role-based permissions (§2.2, P0)
The system SHALL enforce three roles with this capability matrix — Super Admin: everything; Co-host: view dashboard/counts, add/edit/import guests, send invitations & broadcasts, export CSV, edit invitation content — but NOT delete guests, configure gateways/API keys, manage admin users, or view the audit log; Viewer: view dashboard and export CSV only.

#### Scenario: Co-host attempts guest deletion
- **WHEN** a Co-host calls the delete-guest action
- **THEN** the action is rejected with a forbidden error

#### Scenario: Viewer attempts to send
- **WHEN** a Viewer opens the send screen or calls the send API
- **THEN** access is denied

#### Scenario: Enforcement is server-side
- **WHEN** a role-restricted API is called directly (bypassing the UI)
- **THEN** the same authorization rules apply

### Requirement: Audit log (P0)
The system SHALL record an append-only audit log of admin actions — actor, action, entity type/id, before/after values, IP, timestamp — covering at minimum: guest create/edit/delete, imports, sends, exports (FR-5.7), settings changes, admin-user/allowlist changes, rejected sign-in attempts, and manual RSVP overrides. Only Super Admin can view the log.

#### Scenario: Guest edited
- **WHEN** an admin edits a guest's phone number
- **THEN** an audit entry stores who, when, and the before/after values

#### Scenario: Co-host requests audit log
- **WHEN** a Co-host requests the audit log
- **THEN** access is denied
