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>
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', CHECKfree/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
EmailServiceclass withsend_invite_email(to, code, plan, trial_days)- Graceful degradation: if
RESEND_API_KEYnot 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: addemail,assigned_plan,trial_duration_daysInviteCodeResponse: add new fields + computedhas_trial,email_sent
Update: backend/app/api/endpoints/invite.py
create_invite_code: accept new fields, send email if email provided, setemail_sent_at, audit log
Registration plan assignment
Update: backend/app/api/endpoints/auth.py (lines 178-183)
- When
invite_code_recordhasassigned_plan/trial_duration_days, apply to new subscription - Set
plan=invite_code_record.assigned_plan,status='trialing'if trial, calculatecurrent_period_end
Subscription management endpoints
Update: backend/app/api/endpoints/admin.py
PUT /admin/users/{id}/subscription/plan— change planPUT /admin/users/{id}/subscription/extend-trial— add days to trialGET /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
InviteCodeResponsewith email/plan/trial fields - New:
UserDetail,SubscriptionDetail,SessionSummary,AuditLogSummary,AccountSummary
Update: frontend/src/api/admin.ts
- Enhanced
createInviteCodewith 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:
- Header — name, email, role badges, active status
- Account & Subscription card — plan, status, trial end date, account display code
- Admin Actions card — Change Role, Change Plan, Extend Trial, Activate/Deactivate (modal-based)
- Recent Sessions tab — tree name, started, completed, outcome
- Audit Logs tab — action, resource, timestamp, expandable details
- 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
- Migration 030 (invite code fields)
- Model update (invite_code.py)
- Resend integration (email.py, config.py, template, requirements.txt)
- Backend schemas (invite_code, subscription, user_detail)
- Backend API (invite.py, auth.py, admin.py, deps.py)
- Backend tests
- Frontend types + API client
- Frontend invite codes page enhancement
- Frontend user detail page
- End-to-end testing
Files to Create
backend/alembic/versions/030_enhance_invite_codes.pybackend/app/core/email.pybackend/app/templates/invite_email.htmlbackend/app/schemas/subscription.pybackend/app/schemas/user_detail.pyfrontend/src/pages/admin/UserDetailPage.tsx
Files to Modify
backend/app/models/invite_code.pybackend/app/schemas/invite_code.pybackend/app/api/endpoints/invite.pybackend/app/api/endpoints/auth.py(lines 178-183)backend/app/api/endpoints/admin.pybackend/app/api/deps.pybackend/app/core/config.pybackend/requirements.txtfrontend/src/types/admin.tsfrontend/src/api/admin.tsfrontend/src/pages/admin/InviteCodesPage.tsxfrontend/src/pages/admin/UsersPage.tsxfrontend/src/router.tsx
Verification
- Backend tests: Create invite with plan+trial → register with code → verify subscription has correct plan/status/period_end
- Email test: Mock Resend, verify template renders, verify email_sent_at set on success
- Trial expiry: Create expired trial → login → verify auto-downgrade to free
- Admin UI: Create invite with email+plan+trial → verify email sent → register → verify in user detail page → change plan → extend trial
- Build:
cd frontend && npm run buildpasses - Full test suite:
cd backend && pytest --override-ini="addopts="passes