2.1 KiB
2.1 KiB
Phase 13: Feature Flags + Service Suspension Logic
Status: Not started Depends on: Phase 3 (License Validation), Phase 8 (Billing / Overdue Suspension)
Goal
Hub controls which features each school's on-prem can use via tier-based + per-school feature flag overrides. Suspension from billing (Phase 8) propagates to on-prem via the sync poll. Super admin can enable beta features per school.
Planned Scope
Backend
feature_overrides column on School (new)
feature_overrides: dict | None— JSON column for per-school flag overrides- Example:
{"webhooks": true, "beta_reports": true}to enable premium features on a basic tier
/api/sync/poll config response — already returns feature_flags (Phase 5)
- Enhance: merge tier-based flags with
school.feature_overrides - Add
suspension_reason: str | Noneto config (e.g. "overdue_invoice")
New endpoint: PUT /api/schools/{id}/feature-overrides
- Super admin sets per-school feature flag overrides
- Validates keys against allowed feature set
License validate response — also returns merged feature flags (already does, enhance)
Frontend
SchoolDetailPage.vue — Feature Flags panel (super admin only)
- Shows current effective flags (tier base + overrides)
- Toggle switches for each overrideable feature:
api_keys,webhooks,bulk_enrollment,beta_reports,multi_terminal
- Save button → calls PUT /api/schools/{id}/feature-overrides
- Clear overrides button
On-prem side (documented for reference)
sync/pollresponse:suspended: true+suspension_reason- On-prem shows banner: "Account suspended — {reason}. SMS disabled."
- Feature flags stored in Redis with 5-min TTL for fast checks
Key Files to Create/Modify
backend/app/models/school.py— addfeature_overridesJSON columnbackend/app/routers/schools.py— add PUT /{id}/feature-overrides endpointbackend/app/routers/sync.py— merge feature_overrides into poll configbackend/migrations/versions/005_feature_overrides.py(new)frontend/src/pages/SchoolDetailPage.vue— feature flags panelfrontend/src/lib/api.ts— updateFeatureOverrides(id, data)