# Admin Panel: Invite Codes + User Management Enhancement ## Context The admin panel has basic invite code CRUD and user listing, but lacks: - **Plan assignment on invite codes** — all registrations get "free" plan - **Email delivery** — admin must manually copy/send codes - **Trial duration** — no time-limited plan access for beta testers - **User detail page** — no way to view/manage a user's subscription, activity, or trial This change enables the admin to create invite codes tied to specific plans (free/pro/team) with optional trial durations, send branded invite emails via Resend, and manage user subscriptions from a detailed user page. --- ## Phase 1: Database Migration (030) **New file:** `backend/alembic/versions/030_enhance_invite_codes.py` Add columns to `invite_codes`: - `email` (String(255), nullable, indexed) - `assigned_plan` (String(50), nullable, default `'free'`, CHECK `free/pro/team`) - `trial_duration_days` (Integer, nullable) - `email_sent_at` (DateTime(timezone=True), nullable) **Update:** `backend/app/models/invite_code.py` — add fields + `has_trial` and `email_sent` properties --- ## Phase 2: Resend Email Integration **New file:** `backend/app/core/email.py` - `EmailService` class with `send_invite_email(to, code, plan, trial_days)` - Graceful degradation: if `RESEND_API_KEY` not set, log warning, skip sending - Email failure doesn't block invite creation (best-effort) **New file:** `backend/app/templates/invite_email.html` - Branded HTML email: monochrome design, ResolutionFlow logo, CTA button - Shows invite code, plan name, trial duration if applicable, signup link **Update:** `backend/app/core/config.py` — add `RESEND_API_KEY`, `FROM_EMAIL`, `email_enabled` property **Update:** `backend/requirements.txt` — add `resend` **Env vars:** `RESEND_API_KEY`, `FROM_EMAIL=ResolutionFlow ` --- ## Phase 3: Backend API Changes ### Invite code enhancements **Update:** `backend/app/schemas/invite_code.py` - `InviteCodeCreate`: add `email`, `assigned_plan`, `trial_duration_days` - `InviteCodeResponse`: add new fields + computed `has_trial`, `email_sent` **Update:** `backend/app/api/endpoints/invite.py` - `create_invite_code`: accept new fields, send email if email provided, set `email_sent_at`, audit log ### Registration plan assignment **Update:** `backend/app/api/endpoints/auth.py` (lines 178-183) - When `invite_code_record` has `assigned_plan`/`trial_duration_days`, apply to new subscription - Set `plan=invite_code_record.assigned_plan`, `status='trialing'` if trial, calculate `current_period_end` ### Subscription management endpoints **Update:** `backend/app/api/endpoints/admin.py` - `PUT /admin/users/{id}/subscription/plan` — change plan - `PUT /admin/users/{id}/subscription/extend-trial` — add days to trial - `GET /admin/users/{id}/detail` — enhanced user detail with account, subscription, sessions, audit logs, invite code used **New file:** `backend/app/schemas/subscription.py` — `SubscriptionPlanUpdate`, `ExtendTrialRequest`, `SubscriptionResponse` **New file:** `backend/app/schemas/user_detail.py` — `UserDetailResponse`, `SessionSummary`, `AuditLogSummary`, `AccountSummary` ### Trial expiry on login (lightweight) **Update:** `backend/app/api/deps.py` — in `get_current_active_user`, check if subscription is trialing and expired → auto-downgrade to free --- ## Phase 4: Frontend Types & API Client **Update:** `frontend/src/types/admin.ts` - Enhanced `InviteCodeResponse` with email/plan/trial fields - New: `UserDetail`, `SubscriptionDetail`, `SessionSummary`, `AuditLogSummary`, `AccountSummary` **Update:** `frontend/src/api/admin.ts` - Enhanced `createInviteCode` with new fields - New: `getUserDetail`, `updateUserSubscriptionPlan`, `extendUserTrial` --- ## Phase 5: Frontend — Enhanced Invite Codes Page **Update:** `frontend/src/pages/admin/InviteCodesPage.tsx` Create form additions: - Email input (optional, validated) - Plan selector dropdown (Free / Pro / Team) - Trial duration input (number of days, shown only if plan != free) Table additions: - "Recipient" column (email or "—") - "Plan" column with badge - "Trial" column (days or "—") - "Email Sent" indicator --- ## Phase 6: Frontend — User Detail Page **New file:** `frontend/src/pages/admin/UserDetailPage.tsx` Sections: 1. **Header** — name, email, role badges, active status 2. **Account & Subscription card** — plan, status, trial end date, account display code 3. **Admin Actions card** — Change Role, Change Plan, Extend Trial, Activate/Deactivate (modal-based) 4. **Recent Sessions tab** — tree name, started, completed, outcome 5. **Audit Logs tab** — action, resource, timestamp, expandable details 6. **Invite Code card** — code used, plan assigned, who created it **Update:** `frontend/src/router.tsx` — add route `admin/users/:userId` **Update:** `frontend/src/pages/admin/UsersPage.tsx` — make user rows clickable → navigate to detail page --- ## Implementation Order 1. Migration 030 (invite code fields) 2. Model update (invite_code.py) 3. Resend integration (email.py, config.py, template, requirements.txt) 4. Backend schemas (invite_code, subscription, user_detail) 5. Backend API (invite.py, auth.py, admin.py, deps.py) 6. Backend tests 7. Frontend types + API client 8. Frontend invite codes page enhancement 9. Frontend user detail page 10. End-to-end testing --- ## Files to Create - `backend/alembic/versions/030_enhance_invite_codes.py` - `backend/app/core/email.py` - `backend/app/templates/invite_email.html` - `backend/app/schemas/subscription.py` - `backend/app/schemas/user_detail.py` - `frontend/src/pages/admin/UserDetailPage.tsx` ## Files to Modify - `backend/app/models/invite_code.py` - `backend/app/schemas/invite_code.py` - `backend/app/api/endpoints/invite.py` - `backend/app/api/endpoints/auth.py` (lines 178-183) - `backend/app/api/endpoints/admin.py` - `backend/app/api/deps.py` - `backend/app/core/config.py` - `backend/requirements.txt` - `frontend/src/types/admin.ts` - `frontend/src/api/admin.ts` - `frontend/src/pages/admin/InviteCodesPage.tsx` - `frontend/src/pages/admin/UsersPage.tsx` - `frontend/src/router.tsx` --- ## Verification 1. **Backend tests:** Create invite with plan+trial → register with code → verify subscription has correct plan/status/period_end 2. **Email test:** Mock Resend, verify template renders, verify email_sent_at set on success 3. **Trial expiry:** Create expired trial → login → verify auto-downgrade to free 4. **Admin UI:** Create invite with email+plan+trial → verify email sent → register → verify in user detail page → change plan → extend trial 5. **Build:** `cd frontend && npm run build` passes 6. **Full test suite:** `cd backend && pytest --override-ini="addopts="` passes