Feature Flags Strategy - Hybrid Approach
Comprehensive strategy for managing feature flags using both custom API and PostHog.
Last Updated: February 2, 2026
Overview
We use a hybrid approach for feature flags:
- Custom API System - For admin-controlled platform features and provider-controlled premium features
- PostHog - For gradual percentage-based rollouts and A/B testing
- Unified Admin UI - Manage all flags from one place
- User Self-Service - Providers control their own premium features
Feature Flag Categories
1. Admin-Controlled Features (Custom API)
System: Custom API (juniro-api/src/config/feature-flags.ts)
Characteristics:
- Admin-controlled (Juniro admins enable/disable platform-wide)
- Can be provider-controlled (premium features)
- Requires database persistence
- Needs admin override capability
- Platform-wide or provider-level settings
Admin-Controlled (Platform-Wide):
REVIEWS_ENABLED- Admin enables/disables reviews feature platform-wideATTENDANCE_ENABLED- Admin enables/disables attendance tracking platform-wideASSIGNMENTS_ENABLED- Admin enables/disables assignments feature platform-wideAI_SEARCH_ENABLED- Admin enables/disables AI search platform-wideBOOKING_FLOW_ENABLED- Admin enables/disables booking flow platform-wide (master switch)PAYMENT_ENABLED- Admin enables/disables payment collection platform-wide (default: ON)STAFF_PORTAL_ENABLED- Admin enables/disables staff portal platform-wide
Provider-Controlled (Premium Features):
PAYMENT_ENABLED- Provider can enable/disable online payments for their account (freemium)MESSAGING_ENABLED- Provider can enable/disable messaging (premium)AI_RECOMMENDATIONS_ENABLED- Provider can enable/disable AI recommendations (premium)- Future:
ADVANCED_ANALYTICS_ENABLED,CUSTOM_BRANDING_ENABLED, etc.
Storage:
- Global flags:
FeatureFlagtable (admin-controlled platform-wide features) - Provider flags:
ProviderAccount.featureFlagsJSON column (provider-controlled premium features) - User flags:
User.featureFlagsJSON column (future)
API Endpoints:
GET /config/feature-flags- Get flags for current user/provider (includes global + provider flags)GET /me/provider/feature-flags- Get my provider's flags (provider-controlled only)PATCH /me/provider/feature-flags- Update my provider's flags (provider-controlled only)GET /config/feature-flags/:providerId- Admin: Get provider flagsPATCH /config/feature-flags/:providerId- Admin: Override provider flagsGET /config/feature-flags/global- Admin: Get all global flags (future)PATCH /config/feature-flags/global/:key- Admin: Update global flag (future)
Naming Convention: UPPER_SNAKE_CASE with _ENABLED suffix (e.g., REVIEWS_ENABLED, PAYMENT_ENABLED)
2. Rollout/A/B Testing Features (PostHog)
System: PostHog Feature Flags
Characteristics:
- Platform-controlled (admin only)
- Gradual rollout (10% → 50% → 100%)
- A/B testing variants
- Analytics and conversion tracking
- Temporary (removed after stable)
- Percentage-based user targeting
Examples:
admin-v2- Gradual rollout of new admin UI (10% → 50% → 100%)parent-headline-variant- A/B test landing page headlinesparent-cta-variant- A/B test CTA buttonsbooking-flow-v2- A/B test new booking flow vs oldcheckout-variant-a- A/B test checkout experience
Note: Platform features like reviews, attendance, assignments, ai-search, booking-flow are controlled via Custom API (admin on/off toggle), not PostHog (gradual rollout).
Storage:
- PostHog dashboard
- Evaluated client-side and server-side via PostHog SDK
API Integration:
- Frontend:
useFeatureFlag('booking-flow')fromposthog-js/react - Backend:
posthog.isFeatureEnabled('booking-flow', userId)
Naming Convention: kebab-case with consistent patterns:
- Feature rollouts:
{feature-name}(e.g.,booking-flow,reviews,staff-portal,attendance,assignments) - A/B tests:
{page}-{element}-variant(e.g.,parent-headline-variant,parent-cta-variant) - Regional:
{feature}-{region}(e.g.,payments-stripe,payments-razorpay) - Versions:
{feature}-v{number}(e.g.,admin-v2)
Standardization Rule:
- ✅ DO: Use descriptive feature names (
reviews,attendance,assignments) - ❌ DON'T: Add
-enabledsuffix (redundant - flags are toggles by nature) - ❌ DON'T: Use underscores (use hyphens for kebab-case consistency)
3. Regional Features (Hybrid)
System: Custom API + PostHog (depending on use case)
Characteristics:
- Region-specific features
- Can be user-controlled or platform-controlled
Examples:
payments-stripe- US payment provider (PostHog - platform-controlled)payments-razorpay- India payment provider (PostHog - platform-controlled)whatsapp-notifications- India messaging (Custom API - provider-controlled)
Decision Rule:
- If user can enable/disable → Custom API
- If platform controls rollout → PostHog
Booking & Payment Flag Hierarchy
The booking and payment features use a three-tier hierarchy:
Hierarchy Diagram
User clicks "Book Now"
│
▼
┌────────────────────────────────────┐
│ Check BOOKING_FLOW_ENABLED (Global)│ Admin controlled
│ Default: ON (core feature) │
└────────────────────────────────────┘
│
│ OFF → Show "Booking coming soon" (rare, maintenance mode)
│
▼ ON
┌────────────────────────────────────┐
│ Proceed to Booking Flow │
│ (Select session, child, etc.) │
└────────────────────────────────────┘
│
▼
┌────────────────────────────────────┐
│ Check PAYMENT_ENABLED (Global) │ Admin controlled
│ Default: ON │
└────────────────────────────────────┘
│
│ OFF → Skip payment for ALL bookings
│ Providers don't see payment option in settings
│ Show "Payment will be collected offline"
│ Complete booking as "pending_payment"
│
▼ ON
┌────────────────────────────────────┐
│ Check PAYMENT_ENABLED (Provider) │ Provider controlled (opt-in)
│ Default: OFF (freemium feature) │ Only visible if Global=ON
└────────────────────────────────────┘
│
│ OFF → Skip payment for this provider
│ Show "Payment will be collected offline"
│ Complete booking as "pending_payment"
│
▼ ON
┌────────────────────────────────────┐
│ Show Payment Form │
│ (Stripe US / Razorpay India) │
└────────────────────────────────────┘
│
▼
┌────────────────────── ──────────────┐
│ Complete Booking │
│ Status: "confirmed" │
└────────────────────────────────────┘
Use Cases
| BOOKING_FLOW (G) | PAYMENT (G) | PAYMENT (P) | Result | Provider Settings |
|---|---|---|---|---|
| ❌ OFF | N/A | N/A | "Booking coming soon" | N/A |
| ✅ ON | ❌ OFF | N/A | Book without payment (all) | Payment option hidden |
| ✅ ON | ✅ ON | ❌ OFF | Book without payment (this provider) | Payment option visible, provider opted out |
| ✅ ON | ✅ ON | ✅ ON | Full booking with payment | Payment option visible, provider opted in |
Key Points
BOOKING_FLOW_ENABLED(Global, Default: ON) = Core feature, always available unless maintenancePAYMENT_ENABLED(Global, Default: ON) = Master switch for payment feature- If ON: Providers can see and control their payment settings
- If OFF: Payment option hidden from all providers, all bookings are offline
PAYMENT_ENABLED(Provider, Default: OFF) = Provider opt-in for online payment (freemium)- Only relevant when Global is ON
They work hierarchically: Global flags are checked first, then provider flags.
Flag Classification Matrix
| Flag Name | System | Controlled By | Scope | Default | Naming |
|---|---|---|---|---|---|
| Admin-Controlled (Platform-Wide) | |||||
BOOKING_FLOW_ENABLED | Custom API | Admin | Global | ON | UPPER_SNAKE_CASE |
PAYMENT_ENABLED | Custom API | Admin | Global | ON | UPPER_SNAKE_CASE |
REVIEWS_ENABLED | Custom API | Admin | Global | OFF | UPPER_SNAKE_CASE |
ATTENDANCE_ENABLED | Custom API | Admin | Global | OFF | UPPER_SNAKE_CASE |
ASSIGNMENTS_ENABLED | Custom API | Admin | Global | OFF | UPPER_SNAKE_CASE |
AI_SEARCH_ENABLED | Custom API | Admin | Global | OFF | UPPER_SNAKE_CASE |
STAFF_PORTAL_ENABLED | Custom API | Admin | Global | OFF | UPPER_SNAKE_CASE |
| Provider-Controlled (Premium) | |||||
PAYMENT_ENABLED | Custom API | Provider | Provider | OFF | UPPER_SNAKE_CASE |
MESSAGING_ENABLED | Custom API | Provider | Premium | UPPER_SNAKE_CASE | |
AI_RECOMMENDATIONS_ENABLED | Custom API | Provider | Premium | UPPER_SNAKE_CASE | |
| PostHog (Gradual Rollout/A/B Testing) | |||||
admin-v2 | PostHog | Admin | Rollout | kebab-case | |
payments-stripe | PostHog | Admin | Regional | kebab-case | |
payments-razorpay | PostHog | Admin | Regional | kebab-case | |
parent-headline-variant | PostHog | Admin | A/B Test | kebab-case | |
parent-cta-variant | PostHog | Admin | A/B Test | kebab-case | |
booking-flow-v2 | PostHog | Admin | A/B Test | kebab-case |
Admin Feature Flags UI
Requirements
Location: Admin Portal → System → Feature Flags
Sections:
-
Business Features (Custom API)
- List all provider-level flags
- Show provider count per flag (how many have it enabled)
- Allow admin to:
- View all providers and their flag status
- Override provider flags (with confirmation)
- Set default values for new providers
- View flag usage analytics
-
Rollout Features (PostHog)
- List all PostHog flags
- Show current rollout percentage
- Allow admin to:
- View PostHog dashboard (link)
- See flag status (enabled/disabled)
- See rollout percentage
- See A/B test variants and distribution
- View conversion analytics
-
Unified View
- Combined list of all flags (both systems)
- Filter by system (Custom API / PostHog)
- Filter by type (Premium / Rollout / A/B Test / Regional)
- Search by flag name
- Export flag configuration
Implementation:
- Wire existing
FeatureFlagsManagementcomponent - Integrate PostHog API for PostHog flags
- Integrate Custom API for business flags
- Show unified dashboard
Provider Feature Flags UI
Requirements
Location: Provider Portal → Settings → Features
Sections:
-
Premium Features
- List all provider-controllable flags
- Show current status (enabled/disabled)
- Show feature description and benefits
- Allow provider to:
- Enable/disable features
- See pricing (if applicable)
- View feature documentation
- Show admin override indicator (if admin has overridden)
-
Platform Features (Read-Only)
- Show platform-controlled flags (PostHog)
- Show status (enabled/disabled for their account)
- Show rollout percentage (if applicable)
- Informational only (no controls)
Implementation:
- Create
SettingsFeaturescomponent - Wire to
GET /me/provider/feature-flags - Wire to
PATCH /me/provider/feature-flags - Show PostHog flags (read-only) via PostHog SDK
Parent Feature Flags UI (Future)
Requirements
Location: Parent Portal → Settings → Features
Sections:
-
Premium Features (Future)
- List parent-controllable flags
- Similar to provider UI
- Examples:
ADVANCED_CALENDAR_ENABLED,FAMILY_SHARING_ENABLED
-
Platform Features (Read-Only)
- Show platform-controlled flags (PostHog)
- Informational only
Implementation:
- Future: Add
User.featureFlagscolumn - Future: Add
GET /me/feature-flagsendpoint - Future: Create parent settings UI
Implementation Plan
Phase 1: Custom API System (✅ COMPLETED)
- Custom feature flags API
- Provider self-service endpoints
- Admin override endpoints
- Global flag endpoints (GET/PATCH /config/feature-flags/global)
- Database schema (FeatureFlag table for global flags)
Phase 2: PostHog Integration (TODO)
- Install PostHog SDK in all frontend apps
- Install PostHog Node SDK in API
- Create PostHog config module
- Add PostHog flags to booking flow
- Add PostHog flags to reviews
- Add PostHog flags to staff portal
- Document PostHog flag creation process
Phase 3: Admin UI (TODO)
- Wire
FeatureFlagsManagementcomponent - Integrate Custom API for business flags
- Integrate PostHog API for rollout flags
- Create unified dashboard
- Add provider search/filter
- Add analytics views
Phase 4: Provider UI (TODO)
- Create
SettingsFeaturescomponent - Wire to Custom API endpoints
- Show PostHog flags (read-only)
- Add feature descriptions
- Add confirmation dialogs
Phase 5: Documentation (TODO)
- Update roadmap matrix with hybrid approach
- Document flag classification process
- Create admin guide for managing flags
- Create provider guide for premium features
Decision Framework
When to use Custom API:
- ✅ Admin needs to enable/disable platform-wide (on/off toggle)
- ✅ User (provider/parent) can control it (premium features)
- ✅ Needs database persistence
- ✅ Provider-level or platform-level setting
- ✅ Needs admin override capability
- ✅ Examples: Reviews, Attendance, Assignments, AI Search, Booking Flow, Staff Portal
When to use PostHog:
- ✅ Gradual percentage-based rollout (10% → 50% → 100%)
- ✅ A/B testing with variants
- ✅ Temporary flag (will be removed after stable)
- ✅ Needs analytics and conversion tracking
- ✅ User targeting by percentage
- ✅ Examples: Admin v2 rollout, A/B test variants, regional payment providers
When to use both:
- ✅ Regional features (PostHog for platform control, Custom API if user-controlled)
- ✅ Complex features with multiple aspects
Flag Lifecycle
Custom API Flags (Business Features)
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Create │ ──► │ Available │ ──► │ Deprecated│
│ Flag │ │ (Active) │ │ (Keep) │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
▼ ▼ ▼
Add to DB Users enable/ Keep for backward
Add to API disable compatibility
Lifecycle: Flags persist indefinitely (premium features don't expire)
PostHog Flags (Rollout Features)
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Create │ ──► │ Rollout │ ──► │ 100% │ ──► │ Remove │
│ Flag │ │ Gradual │ │ Stable │ │ Flag │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
│ │ │ │
▼ ▼ ▼ ▼
Feature in 10% → 50% Monitor for Delete flag
development → 100% 2 weeks from code
Lifecycle: Flags removed after 2 weeks at 100% with no issues
Migration Notes
Existing Custom API Flags
- ✅
MESSAGING_ENABLED(Provider) - Keep in Custom API (provider-controlled premium) - ✅
PAYMENT_ENABLED(Provider) - Keep in Custom API (provider-controlled freemium) - ✅
AI_RECOMMENDATIONS_ENABLED(Provider) - Keep in Custom API (provider-controlled premium)
New Flags to Add (Custom API - Admin-Controlled)
- ✅
REVIEWS_ENABLED(Global) - Admin enables/disables reviews platform-wide - ✅
ATTENDANCE_ENABLED(Global) - Admin enables/disables attendance platform-wide - ✅
ASSIGNMENTS_ENABLED(Global) - Admin enables/disables assignments platform-wide - ✅
AI_SEARCH_ENABLED(Global) - Admin enables/disables AI search platform-wide - ✅
BOOKING_FLOW_ENABLED(Global) - Admin enables/disables booking flow platform-wide - ✅
PAYMENT_ENABLED(Global) - Admin enables/disables payment collection platform-wide (default: ON) - ✅
STAFF_PORTAL_ENABLED(Global) - Admin enables/disables staff portal platform-wide
PostHog Flags (Gradual Rollout/A/B Testing)
admin-v2- Gradual rollout of new admin UIparent-headline-variant- A/B test landing pageparent-cta-variant- A/B test CTA buttonspayments-stripe- Regional payment provider (US)payments-razorpay- Regional payment provider (India)
Related Documentation
- Product Roadmap Matrix - Feature flags mapping
- Product Development Roadmap - Implementation tasks
- Feature Flags API Documentation - API endpoints
Last Updated: February 2, 2026