feat: Add folder system for feature flag organization#352
feat: Add folder system for feature flag organization#352promisingcoder wants to merge 2 commits intodatabuddy-analytics:mainfrom
Conversation
…ytics#271) Adds a folder organization system to the feature flags dashboard using Option A (simple string folder field on the flags table). ## Database - Add optional `folder` text column to `flags` table - Add `idx_flags_folder` btree index for query performance - Fully backward compatible — existing flags without folders work unchanged ## API (packages/rpc, packages/shared) - `flags.list`: add optional `folder` filter param + update cache key - `flags.create`: persist `folder` field on new and restored flags - `flags.update`: support `folder` updates (null clears the folder) - `flagFormSchema`: add validated `folder` field (max 100 chars, safe chars only) ## Dashboard UI (apps/dashboard) - **FolderSidebar** (new): collapsible left sidebar showing All Flags, Uncategorized, and named folders with flag counts; create/rename/delete folder actions with confirmation dialogs; batch-updates flags on rename/delete - **FlagsList**: new `groupByFolder` prop renders collapsible folder sections when viewing all flags; uncategorized flags shown at bottom - **FlagSheet**: Folder combobox field in create/edit form — shows existing folders as suggestions, supports typing a new folder name, clear button - **FlagsPage**: flex-row layout with sidebar + content; client-side folder filtering; empty state when selected folder has no flags Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
|
@promisingcoder is attempting to deploy a commit to the Databuddy OSS Team on Vercel. A member of the Team first needs to authorize it. |
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: ASSERTIVE Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR adds a folder/grouping system for feature flags, including a schema column, RPC changes, a new sidebar navigation component, and grouped list rendering. The overall design is solid — the change is purely additive (nullable column, no breaking API changes) and client-side filtering avoids extra round-trips. Key issues found:
Confidence Score: 3/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant User
participant FolderSidebar
participant FlagsPage
participant FlagsList
participant FlagSheet
participant FlagsRPC
User->>FolderSidebar: Select folder / "All" / "Uncategorized"
FolderSidebar->>FlagsPage: onSelectFolder(selection)
FlagsPage->>FlagsPage: filteredFlags = useMemo(filter by selectedFolder)
FlagsPage->>FlagsList: flags=filteredFlags, groupByFolder=shouldGroupByFolder
FlagsList->>FlagsList: Render FolderSection(s) or flat list
User->>FolderSidebar: Rename folder
FolderSidebar->>FlagsRPC: Promise.all(update each flag with newFolder)
Note over FolderSidebar,FlagsRPC: ⚠️ No transaction — partial failure possible
FlagsRPC-->>FolderSidebar: results (may be partial)
FolderSidebar->>FlagsPage: onRenamedAction(old, new)
User->>FlagSheet: Create/Edit flag with folder
FlagSheet->>FlagsRPC: create({ folder: data.folder?.trim() || null })
FlagsRPC->>FlagsRPC: Insert or restore soft-deleted flag
FlagsRPC-->>FlagSheet: created flag
|
- Remove manual onClick on FolderCombobox PopoverTrigger that prevented closing on re-click (Radix handles toggle natively) - Replace Promise.all with Promise.allSettled in folder rename/delete to handle partial failures gracefully with per-outcome toasts - Remove dead isNull branch in listFlags folder filter (z.string().optional() never produces null) - Add .min(1) validation to folder field in updateFlagSchema and flagFormSchema to reject empty string folder names Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
Adds a folder system for organizing feature flags in the dashboard UI, as requested in #271.
Implementation: Option A (Simple String Folder Field)
Database Schema (
packages/db/src/drizzle/schema.ts)foldertext field to flags tableidx_flags_folderindex for query performancenullShared Validation (
packages/shared/src/flags/index.ts)folderfield toflagFormSchema: optional string, max 100 charsAPI Router (
packages/rpc/src/routers/flags.ts)flags.list: Addedfolderfilter parameter + updated cache keyflags.update:folderfield included via schema spreadflags.create: Addedfolderto both new flag insert and soft-deleted flag restoreDashboard UI
folder-sidebar.tsx): Left sidebar showing "All Flags", "Uncategorized", and named folders with counts. Create/rename/delete folder modals.flags-list.tsx):groupByFolderprop with collapsibleFolderSectioncomponentsflag-sheet.tsx):FolderComboboxcomponent in create/edit form with search, suggestions, and "create new" optionpage.tsx): Sidebar layout with folder filtering state and grouped/filtered modesKey Design Decisions
drizzle-kit push(no migration files) — apply withbun run db:pushFiles Changed (8 files, +888/-47)
packages/db/src/drizzle/schema.tsfolderfield + indexpackages/shared/src/flags/index.tsfolderto validation schemapackages/rpc/src/routers/flags.tsapps/.../flags/_components/types.tsfolderto Flag typeapps/.../flags/_components/folder-sidebar.tsxapps/.../flags/_components/flags-list.tsxapps/.../flags/_components/flag-sheet.tsxapps/.../flags/page.tsx/claim #271