Skip to content

Commit 6a1f0ce

Browse files
committed
fix(flags): align rbac enum with governance defaults
1 parent f5c4a07 commit 6a1f0ce

File tree

5 files changed

+35
-1
lines changed

5 files changed

+35
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3131
- Removed `window.confirm` usage in favor of accessible AlertDialog components
3232
- Updated admin dashboard to surface highest-role badges and gate role management via `rbac_hardening_v1` with new authz telemetry.
3333

34+
### Fixed
35+
36+
- Added the missing `rbac_hardening_v1` enum value to feature flag migrations to keep Supabase schema in sync with governance defaults.
37+
3438
### Planned - Library Feature
3539
- **User Library System**: Complete Medium-style library feature for saving and organizing content
3640
- Your Library: Central dashboard for all saved content

docs/assumptions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@
1111
| A-007 | 2025-02-14 | Observability vendor (Grafana Cloud/Honeycomb) budget approved for Phase 1. | Required to meet telemetry commitments. | Open |
1212
| A-008 | 2025-02-14 | Legal/compliance resources available before Phase 3 commerce rollout. | Necessary for payments, KYC, events. | Open |
1313
| A-009 | 2025-10-10 | Feature flag ownership stored as free-text owner label until RBAC revamp in SEC-001. | Allows governance UI to launch without expanded role matrix; revisit once role hierarchy finalized. | Closed (2025-10-17) |
14+
| A-010 | 2025-02-18 | Despite cutover directive, execution continues ticket-by-ticket under feature flags to avoid destabilizing one-shot release until all prerequisites validated. | Aligns with risk register and roadmap gating; supports rehearsed cutover later without skipping validation. | Open |

docs/progress/weekly-2025-10-17.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
- Delivered SEC-001 RBAC hardening: refreshed Supabase `roles`/`profile_roles`, migrated legacy slugs, and rewrote taxonomy/community policies for the new member → admin ladder.
55
- Gated admin role management behind the new `rbac_hardening_v1` flag, surfaced highest-role badges in the console sidebar, and mapped legacy editor/author selections.
66
- Instrumented `authz_denied_count` counter plus console telemetry for admin/community APIs; added Vitest coverage for role slug normalization and metrics emission.
7+
- Patched feature flag enum to include `rbac_hardening_v1` for parity with release plan defaults and backfilled unit coverage to guard regressions.
78

89
## Feature Flags
910
- `rbac_hardening_v1`: OFF (internal testing only).

supabase/migrations/0017_create_feature_flags.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,16 @@ BEGIN
2424
'payouts_v1',
2525
'events_v1',
2626
'messaging_v1',
27+
'rbac_hardening_v1',
2728
'notifications_v1'
2829
);
2930
END IF;
3031
END;
3132
$$;
3233

34+
-- Ensure enum contains rbac_hardening_v1 for existing environments
35+
ALTER TYPE public.feature_flag_key ADD VALUE IF NOT EXISTS 'rbac_hardening_v1';
36+
3337
-- Create feature_flags table
3438
CREATE TABLE IF NOT EXISTS public.feature_flags (
3539
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),

tests/unit/feature-flags-server.test.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { recordHistogram } from '@/lib/observability/metrics'
1616

1717
const createSupabaseClient = (
1818
rows: Array<{
19-
flag_key: 'spaces_v1' | 'content_templates_v1'
19+
flag_key: 'spaces_v1' | 'content_templates_v1' | 'rbac_hardening_v1'
2020
description: string
2121
enabled: boolean
2222
owner: string
@@ -122,4 +122,28 @@ describe('feature flag server helpers', () => {
122122
expect(firstClient.from).toHaveBeenCalledTimes(1)
123123
expect(secondClient.from).toHaveBeenCalledTimes(1)
124124
})
125+
126+
it('falls back to defaults for non-persisted flags', async () => {
127+
const now = new Date().toISOString()
128+
const client = createSupabaseClient([
129+
{
130+
flag_key: 'spaces_v1',
131+
description: 'Spaces rollout',
132+
enabled: true,
133+
owner: 'Product Lead',
134+
metadata: {},
135+
created_at: now,
136+
updated_at: now,
137+
},
138+
])
139+
140+
serviceRoleClientMock.mockReturnValue(client)
141+
142+
const { getFeatureFlagDefinition } = await loadModule()
143+
const definition = await getFeatureFlagDefinition('rbac_hardening_v1')
144+
145+
expect(definition.flagKey).toBe('rbac_hardening_v1')
146+
expect(definition.enabled).toBe(false)
147+
expect(definition.owner).toBe('Security Lead')
148+
})
125149
})

0 commit comments

Comments
 (0)