Files
resolutionflow/docs/archive/2026-02-11-invite-codes-admin-panel.md
chihlasm 350c977eda feat: add procedural flows with intake forms, navigation, and seed templates
Adds a new "procedural" tree type for linear step-by-step project workflows
(domain controller setup, M365 onboarding, VPN config, etc). Includes intake
form builder, two-panel step navigation, variable resolution, procedural
exports, 3 seed templates, and UI rename from "Trees" to "Flows".

Also archives 19 implemented plan docs and creates deferred features backlog.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 04:13:52 -05:00

6.7 KiB

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 <invites@resolutionflow.com>


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.pySubscriptionPlanUpdate, ExtendTrialRequest, SubscriptionResponse New file: backend/app/schemas/user_detail.pyUserDetailResponse, 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