154 lines
16 KiB
Plaintext
154 lines
16 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`
|
|
- `EditorContext` at `src/components/editor/EditorContext.tsx` provides shared state (characters, onAddCharacter) to all custom node components via React context
|
|
- Use `useEditorContext()` in node components to access project-level characters and variables without prop drilling through React Flow node data
|
|
- 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
|
|
- `ProjectSettingsModal` at `src/components/editor/ProjectSettingsModal.tsx` manages characters/variables. Receives state + callbacks from FlowchartEditor
|
|
- Characters and variables state is managed in `FlowchartEditorInner` with `useState` hooks, passed down to the modal
|
|
- For settings-style modals, use `max-w-2xl h-[80vh]` with overflow-y-auto content area and fixed header/tabs
|
|
- `EditorContext` provides both characters (onAddCharacter) and variables (onAddVariable) to node components. Use `useEditorContext()` to access them.
|
|
- In FlowchartEditor, `handleAddVariable` adds a variable *node* to the canvas; `handleAddVariableDefinition` creates a variable *definition* in project data. Avoid naming collisions between "add node" and "add definition" callbacks.
|
|
- Edge interactions use `onEdgeClick` on ReactFlow component. ConditionEditor opens as a modal overlay since React Flow edges don't support inline panels.
|
|
- `Condition.value` supports `number | string | boolean` — always check variable type before rendering value inputs for edge conditions.
|
|
- `OptionConditionEditor` at `src/components/editor/OptionConditionEditor.tsx` handles choice option conditions. Same pattern as `ConditionEditor` but with simpler props (no edgeId).
|
|
- `ChoiceOption` type includes optional `condition?: Condition`. When counting variable usage, check variable nodes + edge conditions + choice option conditions.
|
|
|
|
---
|
|
|
|
## 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)
|
|
---
|
|
|
|
## 2026-01-23 - US-056
|
|
- What was implemented: Character management UI in the project settings modal
|
|
- Files changed:
|
|
- `src/components/editor/ProjectSettingsModal.tsx` - New modal component with Characters and Variables tabs; Characters tab has full CRUD (add, edit, delete with usage warnings), name uniqueness validation, color picker, inline forms
|
|
- `src/components/editor/Toolbar.tsx` - Added `onProjectSettings` prop and "Project Settings" button to the right side of the toolbar
|
|
- `src/app/editor/[projectId]/FlowchartEditor.tsx` - Added `characters` and `variables` state management, `showSettings` modal state, usage count helpers (`getCharacterUsageCount`, `getVariableUsageCount`), and ProjectSettingsModal rendering
|
|
- **Learnings for future iterations:**
|
|
- The ProjectSettingsModal receives `onCharactersChange` and `onVariablesChange` callbacks that directly set state in FlowchartEditor. When save is implemented, it should read from this state.
|
|
- The Variables tab is a read-only placeholder in US-056; US-057 will implement the full CRUD for variables using the same patterns (inline forms, validation, delete warnings).
|
|
- Modal pattern: fixed inset-0 z-50 with backdrop click to close, max-w-2xl for settings modals (larger than max-w-md used for simple dialogs).
|
|
- Character usage count checks dialogue nodes for `data.characterId`; variable usage count checks both variable nodes and edge conditions.
|
|
- The `randomHexColor()` utility picks from a curated list of 12 vibrant colors for character defaults.
|
|
- No browser testing tools are available; manual verification is needed.
|
|
---
|
|
|
|
## 2026-01-23 - US-057
|
|
- What was implemented: Variable management UI with full CRUD in the project settings modal Variables tab
|
|
- Files changed:
|
|
- `src/components/editor/ProjectSettingsModal.tsx` - Replaced placeholder VariablesTab with full implementation: add/edit/delete with inline forms, type dropdown (numeric/string/boolean), type-adaptive initial value input (number input for numeric, text for string, select for boolean), name uniqueness validation, delete warnings with usage count, colored type badges
|
|
- **Learnings for future iterations:**
|
|
- The VariableForm uses a `handleTypeChange` helper that resets the initial value to the type's default when the type changes, preventing invalid state (e.g., "hello" as a numeric value)
|
|
- Initial values are stored as strings in form state and parsed to the correct type (number/string/boolean) on save via `parseInitialValue()`
|
|
- Type badges use distinct colors: blue for numeric, green for string, purple for boolean - making variable types instantly recognizable in the list
|
|
- The same form patterns from CharactersTab apply: inline form within the list for editing, appended form below the list for adding
|
|
- No browser testing tools are available; manual verification is needed.
|
|
---
|
|
|
|
## 2026-01-23 - US-059
|
|
- What was implemented: Variable node variable dropdown using Combobox component, replacing the free-text input
|
|
- Files changed:
|
|
- `src/components/editor/nodes/VariableNode.tsx` - Replaced text input with Combobox for variable selection, added inline "Add new variable" form with name + type, added orange warning border for invalid references, filtered operation options (add/subtract only for numeric type)
|
|
- `src/components/editor/EditorContext.tsx` - Extended context to include `variables: Variable[]` and `onAddVariable` callback
|
|
- `src/app/editor/[projectId]/FlowchartEditor.tsx` - Added `handleAddVariableDefinition` callback and passed variables + onAddVariable through EditorContext
|
|
- **Learnings for future iterations:**
|
|
- The existing `handleAddVariable` in FlowchartEditor adds a variable *node* to the canvas (toolbar action). The new `handleAddVariableDefinition` creates a variable *definition* in the project's data. Name carefully to avoid collisions.
|
|
- EditorContext is the shared context for node components to access project-level characters and variables. Extend it when new entity types need to be accessible from custom node components.
|
|
- The VariableNode follows the same pattern as DialogueNode for Combobox integration: items derived via useMemo, handleSelect sets both variableId and variableName, inline add form for quick creation, hasInvalidReference for warning state.
|
|
- Operations filtering uses `isNumeric` flag: if no variable is selected (undefined) or type is 'numeric', all operations are shown; otherwise only 'set' is available. When selecting a non-numeric variable, operation is auto-reset to 'set' if it was 'add' or 'subtract'.
|
|
- No browser testing tools are available; manual verification is needed.
|
|
---
|
|
|
|
## 2026-01-23 - US-060
|
|
- What was implemented: Edge condition variable dropdown using Combobox component, replacing free-text input with a type-aware condition editor modal
|
|
- Files changed:
|
|
- `src/types/flowchart.ts` - Updated `Condition.value` type from `number` to `number | string | boolean` to support all variable types
|
|
- `src/components/editor/ConditionEditor.tsx` - New component: modal-based condition editor with Combobox for variable selection, type-aware operator filtering, type-adaptive value inputs, inline "Add new variable" form, orange warning for invalid references, and "Remove condition" action
|
|
- `src/app/editor/[projectId]/FlowchartEditor.tsx` - Added `onEdgeClick` handler to open ConditionEditor, `handleConditionChange` to update edge condition data, `selectedEdgeId` state, and ConditionEditor rendering
|
|
- **Learnings for future iterations:**
|
|
- Edge interactions in React Flow use `onEdgeClick` prop on the ReactFlow component (not on individual edges). The handler receives `(event: React.MouseEvent, edge: Edge)`.
|
|
- The ConditionEditor is rendered as a modal overlay (fixed z-50), not as part of the edge itself — since edges don't have built-in panel/popover support in React Flow.
|
|
- `Condition.value` was originally typed as just `number` but needed broadening to `number | string | boolean` to support string/boolean variables in conditions. This change didn't break existing code since the VariableNode's `value` field is a separate type.
|
|
- Operator filtering for non-numeric types: only `==` and `!=` are available for string/boolean variables. When switching from a numeric variable to a string/boolean, the operator auto-resets to `==` if it was a comparison operator.
|
|
- Value input adapts to type: number input for numeric, text input for string, boolean dropdown for boolean.
|
|
- The `selectedEdge` is derived via `useMemo` from `edges` state and `selectedEdgeId`, so it always reflects the latest condition data.
|
|
- No browser testing tools are available; manual verification is needed.
|
|
---
|
|
|
|
## 2026-01-23 - US-061
|
|
- What was implemented: Choice option condition variable dropdown using OptionConditionEditor component with Combobox
|
|
- Files changed:
|
|
- `src/types/flowchart.ts` - Added `condition?: Condition` to `ChoiceOption` type; moved `Condition` type definition before `ChoiceOption` for correct reference order
|
|
- `src/components/editor/OptionConditionEditor.tsx` - New component: modal-based condition editor for choice options with Combobox variable selection, type-aware operators, type-adaptive value inputs, inline "Add new variable" form, orange warning for invalid references
|
|
- `src/components/editor/nodes/ChoiceNode.tsx` - Added condition button per option (clipboard icon), condition summary text below options, OptionConditionEditor integration, EditorContext usage for variables, invalid reference detection with orange warning styling
|
|
- `src/app/editor/[projectId]/FlowchartEditor.tsx` - Extended `getVariableUsageCount` to also count variable references in choice option conditions
|
|
- **Learnings for future iterations:**
|
|
- The `OptionConditionEditor` follows the same pattern as `ConditionEditor` but with a simpler API: it doesn't need an edgeId since it works with a single option's condition via `onChange(condition | undefined)` callback
|
|
- The `ChoiceOption` type in `flowchart.ts` now references `Condition`, which required reordering type definitions (Condition must be defined before ChoiceOption)
|
|
- Each choice option shows a small clipboard icon button that turns blue when a condition is set, or orange when the referenced variable is invalid/deleted
|
|
- A condition summary line (e.g., "if score > 10") appears below each option label when a condition is active
|
|
- The `getVariableUsageCount` in FlowchartEditor now counts three sources: variable nodes, edge conditions, and choice option conditions
|
|
- No browser testing tools are available; manual verification is needed.
|
|
---
|