Some checks failed
CI / build-and-test (pull_request) Failing after 1m19s
CI (.gitea/workflows/ci.yaml): lint → typecheck → vitest w/ coverage → OpenNext build → preview smoke → bundle-size budgets; Node 20; npm ci; artifacts; safe env; D1 dry-run scaffold. Budgets: add scripts/budgets.mjs; TOTAL_STATIC_MAX_BYTES and MAX_ASSET_BYTES thresholds; report top offenders; fail on breach; README CI section. Flags: add lib/flags.ts with typed booleans and safe defaults (ADMIN_ENABLED, ARTISTS_MODULE_ENABLED, UPLOADS_ADMIN_ENABLED, BOOKING_ENABLED, PUBLIC_APPOINTMENT_REQUESTS_ENABLED, REFERENCE_UPLOADS_PUBLIC_ENABLED, DEPOSITS_ENABLED, PUBLIC_DB_ARTISTS_ENABLED, ADVANCED_NAV_SCROLL_ANIMATIONS_ENABLED, STRICT_CI_GATES_ENABLED, ISR_CACHE_R2_ENABLED); robust parsing; client provider; unit tests. Wiring: gate Admin shell and admin write APIs (503 JSON on uploads and artists writes); disable booking submit and short-circuit booking mutations when off; render static Hero/Artists when advanced animations off; tests for UI and API guards. Ops: expand docs/prd/rollback-strategy.md with “Feature Flags Operations,” Cloudflare Dashboard and wrangler.toml steps, preview simulation, incident playbook, and post-toggle smoke checklist. Release: add docs/releases/2025-09-19-feature-flags-rollout.md with last-good commit, preview/production flag matrices, rollback notes, and smoke results; link from rollback doc. Chore: fix TS issues (gift-cards boolean handling, Lenis options, tailwind darkMode), remove next-on-pages peer conflict, update package.json scripts, configure Gitea act_runner label, open draft PR to trigger CI. Refs: CI-1, FF-1, FF-2, FF-3, OPS-1 Impact: defaults preserve current behavior; no runtime changes unless flags flipped
167 lines
7.9 KiB
Markdown
167 lines
7.9 KiB
Markdown
# Feature Flags Library & Configuration — Brownfield Addition (FF-1)
|
|
|
|
Story ID: FF-1
|
|
Epic: Feature Flags Framework for Controlled Rollbacks — Brownfield Enhancement
|
|
Date: 2025-09-18
|
|
Owner: Product Manager (John)
|
|
Related Docs:
|
|
- docs/prd/epic-feature-flags-controlled-rollbacks.md
|
|
- docs/prd/rollback-strategy.md
|
|
- docs/brownfield-architecture-tech.md
|
|
|
|
---
|
|
|
|
Story Title
|
|
Feature Flags Library & Configuration — Brownfield Addition
|
|
|
|
User Story
|
|
As an operator of the United Tattoo site,
|
|
I want to control critical features via environment-driven flags,
|
|
So that I can safely disable problematic areas without redeploying the application.
|
|
|
|
Story Context
|
|
|
|
Existing System Integration
|
|
- Integrates with: Next.js 14 App Router (server/client), route handlers under app/api, Cloudflare Pages/Workers runtime via OpenNext.
|
|
- Technology: TypeScript, environment variables via wrangler.toml ([env.preview.vars] / [env.production.vars]), Cloudflare bindings.
|
|
- Follows pattern: Centralized lib utilities (e.g., lib/utils.ts), environment validation in lib/env.ts, defensive configuration.
|
|
- Touch points:
|
|
- New module lib/flags.ts (exporting typed, environment-driven booleans).
|
|
- Documentation updates for wrangler env vars and operational usage.
|
|
- Optional: non-breaking additions to lib/env.ts for boolean parsing.
|
|
|
|
Acceptance Criteria
|
|
|
|
Functional Requirements
|
|
1. A new module lib/flags.ts exports a typed Flags object (or individual exports) for the following keys with safe defaults that preserve current behavior:
|
|
- ADMIN_ENABLED
|
|
- ARTISTS_MODULE_ENABLED
|
|
- UPLOADS_ADMIN_ENABLED
|
|
- BOOKING_ENABLED
|
|
- PUBLIC_APPOINTMENT_REQUESTS_ENABLED
|
|
- REFERENCE_UPLOADS_PUBLIC_ENABLED
|
|
- DEPOSITS_ENABLED
|
|
- PUBLIC_DB_ARTISTS_ENABLED
|
|
- ADVANCED_NAV_SCROLL_ANIMATIONS_ENABLED
|
|
- STRICT_CI_GATES_ENABLED
|
|
- ISR_CACHE_R2_ENABLED
|
|
2. Flags are derived from environment variables (string "true"/"false", case-insensitive) with robust parsing; missing or malformed values do not throw and fall back to defaults.
|
|
3. Server-side usage (route handlers, server components) and client-side usage (components) can import the same typed flags safely (tree-shakeable, no runtime errors).
|
|
|
|
Integration Requirements
|
|
4. Existing functionality remains unchanged by default when no flag variables are defined (defaults reflect current behavior).
|
|
5. The new module follows existing lib/* coding standards (TypeScript types, export conventions).
|
|
6. Documentation added to an operations note (append to docs/prd/rollback-strategy.md or new doc referenced by it) including:
|
|
- List of flags, default behavior, and how to toggle via wrangler dashboard/vars.
|
|
- Example wrangler.toml snippets for preview/production vars (non-secret).
|
|
- Post-toggle smoke checklist.
|
|
|
|
Quality Requirements
|
|
7. Unit tests cover boolean parsing and default behavior for at least three representative flags (true/false/undefined cases).
|
|
8. Typecheck, lint, and unit tests pass (no suppression added).
|
|
9. No regressions in existing functionality (smoke run of dev and preview builds).
|
|
|
|
Technical Notes
|
|
|
|
- Integration Approach:
|
|
- Implement a pure-TS helper to parse env booleans: parseBool(str | undefined, defaultValue).
|
|
- Export a const Flags object freezing evaluated booleans at module init time (OK for Workers model).
|
|
- Client-side consumption: Ensure flags do not leak secrets (they are booleans only) and remain serializable if needed.
|
|
- Existing Pattern Reference:
|
|
- Align with lib/utils.ts coding style and export patterns.
|
|
- Reference docs/prd/rollback-strategy.md “Feature Flags Operations” for operator guidance.
|
|
- Key Constraints:
|
|
- Do not introduce breaking changes or throw errors on missing envs.
|
|
- Do not gate any routes/components in this story (wiring will be handled in a separate story).
|
|
- Keep the module minimal; do not add runtime network calls or storage dependencies.
|
|
|
|
Definition of Done
|
|
- [x] lib/flags.ts created with typed exports and safe defaults.
|
|
- [x] Tests added (Vitest) verifying parsing and defaults.
|
|
- [x] Documentation updated (rollback strategy ops section extended with flags list, toggling, smoke steps).
|
|
- [ ] Lint, typecheck, and unit tests pass locally (npm run test).
|
|
- [ ] Preview build succeeds (npm run pages:build && npm run preview).
|
|
- [ ] No functional changes observed when flags are absent (baseline preserved).
|
|
|
|
Risk and Compatibility Check
|
|
|
|
Minimal Risk Assessment
|
|
- Primary Risk: Misinterpretation of default behavior leading to unintended disablement.
|
|
- Mitigation: Defaults preserve current behavior; explicit console.warn on server when critical flags are undefined (non-fatal).
|
|
- Rollback: Delete or bypass imports of lib/flags.ts; defaults ensure no breakage when env flags are absent.
|
|
|
|
Compatibility Verification
|
|
- [x] No breaking changes to existing APIs.
|
|
- [x] No database changes.
|
|
- [x] UI unchanged in this story (no gating yet).
|
|
- [x] Negligible performance impact (constant boolean checks).
|
|
|
|
Validation Checklist
|
|
|
|
Scope Validation
|
|
- [x] Single-session implementable (library + tests + docs).
|
|
- [x] Straightforward integration (new lib module).
|
|
- [x] Follows existing patterns exactly (lib/* utilities, env-based config).
|
|
- [x] No design/architecture work required.
|
|
|
|
Clarity Check
|
|
- [x] Requirements are unambiguous (module + keys + defaults + tests + docs).
|
|
- [x] Integration points specified (lib, docs, env).
|
|
- [x] Success criteria testable (unit tests, build/preview).
|
|
- [x] Rollback approach simple (remove usage; defaults benign).
|
|
|
|
References
|
|
- Epic: docs/prd/epic-feature-flags-controlled-rollbacks.md
|
|
- Ops: docs/prd/rollback-strategy.md (Feature Flags Operations section to be updated in this story)
|
|
|
|
QA Results
|
|
- Gate Decision: PASS — Runtime-aware flag library, hydration, and ops guidance now satisfy FF-1.
|
|
- Coverage Notes:
|
|
- AC1 satisfied via full FLAG_DEFAULTS export and proxy wiring for all 11 toggles (`lib/flags.ts:7`).
|
|
- Server/client usage now share the same snapshot through `getFlags({refresh:true})` and the `FeatureFlagsProvider` runtime registration (`app/layout.tsx:36`, `components/feature-flags-provider.tsx:14`, `lib/flags.ts:98`).
|
|
- Boolean parsing, env overrides, and runtime registration covered by dedicated Vitest suite (`__tests__/lib/flags.test.ts:41`).
|
|
- Ops playbook documents defaults, wrangler preview/production snippets, and the post-toggle smoke checklist (`docs/prd/rollback-strategy.md:64`).
|
|
- Acceptance Criteria Coverage:
|
|
- AC1 — PASS
|
|
- AC2 — PASS
|
|
- AC3 — PASS
|
|
- AC4 — PASS (defaults preserve current behaviour)
|
|
- AC5 — PASS
|
|
- AC6 — PASS
|
|
- AC7 — PASS
|
|
- AC8 — Not assessed (automation run outside QA scope)
|
|
- AC9 — Not assessed (smoke validation requires environment access)
|
|
- NFR & Risk Notes:
|
|
- Server warns once when env vars missing; client gating honours runtime snapshot. For fast flips, ensure at least one page request occurs post-change so API routes warm the fresh cache.
|
|
- Recommended Status: Ready for Done.
|
|
|
|
|
|
---
|
|
|
|
Status: Ready for Review
|
|
|
|
## Dev Agent Record
|
|
- Agent Model Used: GPT-5 (Codex)
|
|
- Debug Log References:
|
|
- `npm run lint` (fails: ESLint package not detected in sandbox)
|
|
- `npx vitest run` (fails: runner exits early without summary in sandbox)
|
|
- Completion Notes:
|
|
- Added runtime-aware `lib/flags.ts` proxy with full key coverage, defaults, and missing-env warnings.
|
|
- Introduced client `FeatureFlagsProvider` and updated affected components to consume context-driven flags.
|
|
- Added focused flag parsing tests and refreshed rollback strategy docs with defaults, wrangler snippets, and smoke checklist.
|
|
|
|
## File List
|
|
- lib/flags.ts
|
|
- components/feature-flags-provider.tsx
|
|
- app/ClientLayout.tsx
|
|
- app/layout.tsx
|
|
- components/hero-section.tsx
|
|
- components/artists-section.tsx
|
|
- components/booking-form.tsx
|
|
- docs/prd/rollback-strategy.md
|
|
- __tests__/lib/flags.test.ts
|
|
- __tests__/flags/booking-form.disabled.test.ts
|
|
|
|
## Change Log
|
|
- 2025-09-20: Restored feature flag coverage, added client provider + tests, and expanded ops documentation to satisfy QA findings.
|