Document data layer contracts and flag key registry
epic-organization-feature-flags-foundation-task-009 — Produce developer documentation covering the organization_configs table schema and RLS policy rationale, the full list of canonical flag keys from 695-feature-flag-constants with descriptions of each flag's purpose and rollout conditions, the cache TTL configuration guide, and the RolloutEvaluator algorithm including the version-comparison and date-threshold logic. Include usage examples for downstream consumers such as FeatureFlagProvider and FeatureGate.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 5 - 253 tasks
Can start after Tier 4 completes
Implementation Notes
Keep the flag key registry as a Markdown table with sortable columns — this makes it easy to scan by phase or rollout type. For the RolloutEvaluator algorithm, use a numbered list rather than pseudocode to keep it accessible to non-Dart readers (coordinators or QA). Co-locate the doc file at `lib/features/feature_flags/FEATURE_FLAGS.md` so it appears in IDE file trees next to the source. When documenting cache TTL, distinguish between the in-memory cache (process-scoped, cleared on app restart) and any persistent cache (survives restarts) — clarify which layer is in use.
Include a 'When to add a new flag' checklist to guide future contributors and reduce ad-hoc flag proliferation.
Testing Requirements
No automated tests for documentation itself. However, all code snippets must be manually verified to compile and run against the actual implementation before the documentation is considered complete.
A peer reviewer must confirm that a developer unfamiliar with the feature flag system can implement a new FeatureGate using only this documentation without consulting the source code.
Supabase RLS policies for organization_configs may have gaps that allow cross-organization reads if the JWT claim for organization_id is absent or malformed, leading to data leakage between tenants.
Mitigation & Contingency
Mitigation: Implement RLS policies using auth.uid() joined against a memberships table to derive organization_id rather than trusting a client-supplied claim. Write integration tests that simulate a cross-org read attempt and assert it returns zero rows.
Contingency: If a gap is discovered post-launch, immediately disable the affected RLS policy, roll back the migration, and re-implement with a parameterized policy tested against all organization fixture data.
Dart does not have a built-in semantic version comparison library; a naive string comparison (e.g., '2.10.0' < '2.9.0' lexicographically) would cause rollout evaluator to produce incorrect eligibility results for organizations on different app versions.
Mitigation & Contingency
Mitigation: Use the pub.dev `pub_semver` package or implement a proper three-segment integer comparison. Add parameterized unit tests covering 20+ version pairs including double-digit minor/patch segments.
Contingency: If incorrect comparison is discovered in production, push a hotfix with corrected comparison logic and temporarily disable phase-gated flags until all affected organizations have updated to the corrected version.
Persistent local cache written to shared_preferences or Hive could become corrupted or deserialized incorrectly after an app update changes the FeatureFlag schema, causing startup crashes or all flags defaulting to disabled.
Mitigation & Contingency
Mitigation: Wrap all cache reads in try/catch with explicit fallback to the all-disabled default map. Version the cache key (e.g., `feature_flags_v2_{orgId}`) so schema changes automatically invalidate old entries.
Contingency: If cache corruption is detected in a release, publish an app update that clears the versioned cache key on first launch and re-fetches from Supabase.