Skip to content

Feature Flags Reference

Curaway uses Flagsmith for feature flag management. Flags control which features are active in each environment and allow gradual rollouts without code deploys.

Architecture

  • Backend: The Python backend queries Flagsmith on startup and caches flag values for 60 seconds (configurable via FLAGSMITH_CACHE_TTL). This prevents excessive API calls and avoids the Flagsmith warning flood issue documented in the troubleshooting runbook.
  • Frontend: The React frontend uses the Flagsmith React SDK and evaluates flags client-side based on the current tenant identity.
  • Targeting: Flags can be targeted by tenant ID, environment, or percentage rollout.

Flag Inventory

agent_enhanced_matching

Controls whether the AI agent uses the enhanced multi-signal matching pipeline that combines Qdrant semantic search, Neo4j graph traversal, and LLM re-ranking.

Property Value
Type Boolean
Default false
Targeting Enabled for tenant-apollo-001 in production; enabled for all tenants in staging
Impact When disabled, matching falls back to simple SQL-based filtering by country and procedure
Dependencies Requires Qdrant and Neo4j to be available; falls back gracefully if either is down

agent_explanations_enabled

Controls whether the AI agent generates natural-language explanations for why each provider was recommended.

Property Value
Type Boolean
Default false
Targeting Enabled for tenant-apollo-001
Impact When enabled, each match result includes a match_explanation field with a 2-3 sentence LLM-generated rationale
Dependencies Requires agent_enhanced_matching to also be enabled
Cost note Each explanation costs ~200 tokens (gpt-4o-mini); with 5 providers per match, this adds ~1000 tokens per query

guardrail_input_classifier_enabled

Controls whether inbound user messages are classified by the guardrail system before reaching the LLM.

Property Value
Type Boolean
Default true
Targeting Enabled globally; can be disabled per-tenant for debugging
Impact When disabled, all user messages pass directly to the LLM without safety classification
Risk Disabling in production exposes the agent to prompt injection and off-topic abuse

guardrail_output_validator_enabled

Controls whether LLM responses are scanned against forbidden output patterns before being sent to the user.

Property Value
Type Boolean
Default true
Targeting Enabled globally
Impact When disabled, LLM responses are returned to the user without output validation
Risk Disabling in production may allow the agent to return medical advice, internal URLs, or other prohibited content

guardrail_file_validation_enabled

Controls whether uploaded files are validated against the size, type, and content rules defined in config/guardrails.yaml.

Property Value
Type Boolean
Default true
Targeting Enabled globally
Impact When disabled, files are accepted without pre-upload validation (R2 still enforces its own size limits)
Risk Disabling may allow oversized or unsupported file types to reach the processing pipeline

DOCTORS_IN_MATCHING

Controls whether the matching pipeline considers individual doctors in addition to provider-level matches. When enabled, the system returns both the matched provider and the specific doctor(s) at that provider who are most relevant.

Property Value
Type Boolean
Default false
Targeting Enabled for tenant-apollo-001 in production
Impact When enabled, match results include a matched_doctors array with doctor profiles, specialties, languages, and procedure experience
Dependencies Requires the doctors table to be seeded (see seed data runbook)

PUBLIC_API_ENABLED

Controls the entire /api/v1/public/ router. When disabled, all public storefront endpoints return 503 Service Unavailable.

Property Value
Type Boolean
Default false
Targeting Disabled globally; enable per-environment when storefront is ready
Impact When disabled, all /api/v1/public/* endpoints return 503

STOREFRONT_PAGES_ENABLED

Controls frontend storefront routes. When disabled, storefront URLs redirect to the homepage.

Property Value
Type Boolean
Default false
Targeting Disabled globally; enable when storefront UI is complete
Impact When disabled, frontend storefront routes redirect to homepage
Dependencies Requires PUBLIC_API_ENABLED for data fetching

PUBLIC_SEARCH_ENABLED

Controls the unified search endpoint independently from the rest of the public API.

Property Value
Type Boolean
Default false
Targeting Disabled globally; can be enabled independently of other storefront flags
Impact When disabled, /api/v1/public/search returns 503 even if PUBLIC_API_ENABLED is on

STOREFRONT_CACHE_ENABLED

Controls whether storefront responses are cached. When disabled, all requests hit the database directly (useful for debugging).

Property Value
Type Boolean
Default false
Targeting Disabled globally; enable in production for performance
Impact When disabled, every storefront request queries the database directly

PROVIDER_COMPLETENESS_DISPLAY

Controls whether completeness badges are shown on provider listing cards in the storefront.

Property Value
Type Boolean
Default false
Targeting Disabled globally; enable when completeness scoring is validated
Impact When disabled, provider cards do not display completeness badges
Dependencies Requires PUBLIC_API_ENABLED and STOREFRONT_PAGES_ENABLED

embedding_document_matching

Controls whether uploaded patient documents (medical reports, imaging) are embedded and used as additional signals in provider matching.

Property Value
Type Boolean
Default false
Targeting Disabled globally; experimental feature
Impact When enabled, the system extracts text from uploaded documents via OCR, generates embeddings, and includes document-based similarity scores in the matching pipeline
Dependencies Requires guardrail_file_validation_enabled to be true; requires Qdrant
Cost note Each document embedding costs ~500-2000 tokens depending on document length

Adding New Flags

  1. Create the flag in the Flagsmith dashboard with a descriptive name using snake_case.
  2. Set the default value and any tenant-level overrides.
  3. In the backend, access the flag via the flagsmith_client:
from app.core.flagsmith import flagsmith_client

if flagsmith_client.get_flag_value("my_new_flag", tenant_id=tenant_id):
    # Feature-flagged code path
    ...
  1. In the frontend, use the Flagsmith React hook:
import { useFlags } from 'flagsmith/react';

function MyComponent() {
  const flags = useFlags(['my_new_flag']);

  if (flags.my_new_flag.enabled) {
    return <NewFeature />;
  }

  return <ExistingFeature />;
}
  1. Document the flag in this page following the format above.

Flag Lifecycle

Stage Description
Experimental Flag defaults to false; enabled only for specific test tenants
Beta Flag enabled for a subset of production tenants via targeting
GA (General Availability) Flag defaults to true for all tenants
Cleanup Flag is removed from code; the feature is permanently enabled

Flags should not remain in the "Experimental" stage for more than 90 days. If a feature is not promoted to Beta within that window, it should be removed.