The marketing surface (PricingPage, Stripe products) was wired for
"Starter / Pro / Enterprise" while the backend was on "free / pro / team",
leaving plan_billing unseeded and BillingPlan accepting a literal that
violated the FK to plan_limits.
This change:
- Migration 4ce3e594cb87: defensive UPDATE of any subscriptions on
plan='team' to 'enterprise' (dev has zero), renames the plan_limits
row team -> enterprise, inserts a starter row with caps interpolated
between free and pro (max_trees=10, sessions=75, ai=15/mo).
- Renames the plan tier across schemas (invite_code, billing, admin,
subscription comment), is_paid/has_pro_entitlement checks in the
Subscription model, admin/admin_dashboard plan validators, and the
frontend useSubscription isPaidPlan check. Resource visibility uses
the same string 'team' in a separate domain (Tree/StepLibrary
visibility) and is intentionally untouched.
- New backend/scripts/sync_stripe_plan_ids.py: idempotent upsert of
plan_billing rows from Stripe products by exact name match. Picks
the active monthly recurring price for tiers that have one; leaves
annual fields NULL by design. Works against test or live keys.
- Test fixture updates: conftest seeds the new taxonomy, the public
plans helper is a true upsert so tests can override max_users, and
team -> enterprise across test_admin_plan_limits and test_invite_plan.
Verified: 86/86 passing across the subscription/billing/plan/invite/
admin sweep; sync script run against test mode populates plan_billing
correctly for all three tiers.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Migration 030: add email, assigned_plan, trial_duration_days, email_sent_at
to invite_codes with CHECK constraints
- Resend email integration (graceful degradation when API key not set)
- Invite codes now support plan assignment (free/pro/team) and trial duration (1-90 days)
- Registration applies invite code plan/trial to new subscription
- Auto-downgrade expired trials on authenticated access
- Enriched GET /admin/users/{id} with account, subscription, sessions, audit logs
- New endpoints: PUT /admin/users/{id}/subscription/plan and extend-trial
- Frontend: enhanced invite codes page with email, plan, trial fields
- Frontend: new user detail page at /admin/users/:userId
- Fixed API path drift: /invite-codes -> /invites
- 11 new backend tests, 416 total passing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>