WebVNWrite/progress.txt

70 lines
6.2 KiB
Plaintext

## Codebase Patterns
- Project uses Next.js 16 with App Router, TypeScript, and TailwindCSS 4
- Source files are in `src/` directory (app, components, lib, types)
- Supabase is configured with @supabase/supabase-js and @supabase/ssr packages
- Environment variables follow NEXT_PUBLIC_* convention for client-side access
- Use `npm run typecheck` to run TypeScript type checking (tsc --noEmit)
- Flowchart types exported from `src/types/flowchart.ts`
- Supabase migrations go in `supabase/migrations/` with timestamp prefix (YYYYMMDDHHMMSS_*.sql)
- Database has profiles table (linked to auth.users) and projects table (with flowchart_data JSONB)
- RLS policies enforce user_id = auth.uid() for project access
- Supabase client utilities in `src/lib/supabase/`: client.ts (browser), server.ts (App Router), middleware.ts (route protection)
- Next.js middleware.ts at project root handles route protection using updateSession helper
- Public auth routes: /login, /signup, /forgot-password, /reset-password
- Protected routes: /dashboard, /editor/* (redirect to /login if unauthenticated)
- Auth pages use 'use client' with useState, createClient() from lib/supabase/client.ts, and useRouter for redirects
- For lists with client-side updates (delete/add), use wrapper client component that receives initialData from server component
- Toast component in `src/components/Toast.tsx` for success/error notifications (auto-dismiss after 3s)
- Admin operations use SUPABASE_SERVICE_ROLE_KEY (server-side only via server actions)
- Admin users have is_admin=true in profiles table; check via .select('is_admin').eq('id', user.id).single()
- React Flow editor is in `src/app/editor/[projectId]/` with page.tsx (server) and FlowchartEditor.tsx (client)
- React Flow requires 'use client' and importing 'reactflow/dist/style.css'
- Use toReactFlowNodes/toReactFlowEdges helpers to convert app types to React Flow types
- Custom node components go in `src/components/editor/nodes/` with NodeProps<T> typing and useReactFlow() for updates
- Register custom node types in nodeTypes object (memoized with useMemo) and pass to ReactFlow component
- FlowchartEditor uses ReactFlowProvider wrapper + inner component pattern for useReactFlow() hook access
- Use nanoid for generating unique node IDs (import from 'nanoid')
- Reusable LoadingSpinner component in `src/components/LoadingSpinner.tsx` with size ('sm'|'md'|'lg') and optional message
- Toast component supports an optional `action` prop: `{ label: string; onClick: () => void }` for retry/undo buttons
- Settings page at `/dashboard/settings` reuses dashboard layout; re-auth via signInWithPassword before updateUser
- Character/Variable types (`Character`, `Variable`) and extracted node data types (`DialogueNodeData`, `VariableNodeData`) are in `src/types/flowchart.ts`
- New JSONB fields (characters, variables) must be defaulted to `[]` when reading from DB in page.tsx to handle pre-existing data
- Reusable `Combobox` component at `src/components/editor/Combobox.tsx` - use for all character/variable dropdowns. Props: items (ComboboxItem[]), value, onChange, placeholder, onAddNew
---
## 2026-01-23 - US-054
- What was implemented: Character and Variable TypeScript types added to `src/types/flowchart.ts`
- Files changed:
- `src/types/flowchart.ts` - Added `Character`, `Variable`, `DialogueNodeData`, `VariableNodeData` types; updated `FlowchartData`, `DialogueNode`, `VariableNode`, `Condition` types
- `src/app/editor/[projectId]/page.tsx` - Updated FlowchartData initialization to include `characters: []` and `variables: []` defaults
- **Learnings for future iterations:**
- The node components (`DialogueNode.tsx`, `VariableNode.tsx`, `ChoiceNode.tsx`) define their own local data types that mirror the global types. When adding fields, both the global type and local component type may need updating in later stories.
- `flowchart_data` is a JSONB column in Supabase, so it comes as `any` type. Always provide defaults for new fields when reading from DB to handle existing data without those fields.
- The new `characterId` and `variableId` fields are optional alongside existing `speaker`/`variableName` fields to support migration from free-text to referenced-entity pattern.
---
## 2026-01-23 - US-055
- What was implemented: Database migration to update flowchart_data JSONB default to include `characters: []` and `variables: []`
- Files changed:
- `supabase/migrations/20260123000000_add_characters_variables_to_flowchart_data.sql` - New migration that alters the default value for the flowchart_data column and documents the expected JSONB structure
- **Learnings for future iterations:**
- Since characters and variables are stored within the existing flowchart_data JSONB column (not as separate tables), schema changes are minimal - just updating the column default. The real data integrity is handled at the application layer.
- The app-side defaults in page.tsx (from US-054) already handle existing projects gracefully, so no data migration of existing rows is needed.
- For JSONB-embedded arrays, the pattern is: update the DB default for new rows + handle missing fields in app code for old rows.
---
## 2026-01-23 - US-065
- What was implemented: Reusable searchable combobox component at `src/components/editor/Combobox.tsx`
- Files changed:
- `src/components/editor/Combobox.tsx` - New component with searchable dropdown, keyboard navigation, color swatches, badges, "Add new..." option, and auto-positioning
- **Learnings for future iterations:**
- The Combobox exports both the default component and the `ComboboxItem` type for consumers to use
- Props: `items` (ComboboxItem[]), `value` (string | undefined), `onChange` (id: string) => void, `placeholder` (string), `onAddNew` (() => void, optional)
- ComboboxItem shape: `{ id: string, label: string, color?: string, badge?: string }`
- The component uses neutral zinc colors for borders/backgrounds (not blue/green/orange) so it can be reused across different node types
- Dropdown auto-positions above or below based on available viewport space (200px threshold)
- Keyboard: ArrowDown/Up navigate, Enter selects, Escape closes
- The component is designed to be a drop-in replacement for text inputs in node components (same `w-full` and `text-sm` sizing)
---