# PRD: Real-time Collaboration & Character/Variable Management ## Introduction Two major features to enhance the Visual Novel Flowchart Editor: 1. **Real-time Collaboration** - Enable multiple users to work on the same flowchart simultaneously with presence indicators, live cursors, CRDT-based conflict-free synchronization, and a full audit trail with revert capability. 2. **Character & Variable Management** - Replace free-text fields for speaker names and variable names with a centralized management system. Users define characters and variables once per project, then select from dropdowns throughout the flowchart, preventing typos and ensuring consistency. ## Goals - Enable simultaneous multi-user editing of flowcharts with zero data loss - Provide real-time awareness of collaborators (presence, cursors, editing state) - Maintain a full audit trail of all changes with the ability to revert - Centralize character and variable definitions per project - Replace free-text inputs with searchable dropdowns for characters/variables - Auto-migrate existing projects with free-text values to the new system - Allow importing characters/variables from other projects --- ## User Stories --- ### FEATURE 1: Real-time Collaboration --- ### US-043: Database schema for collaboration sessions and audit trail **Description:** As a developer, I need database tables to track active collaboration sessions and store the full change history for projects. **Acceptance Criteria:** - [ ] Create migration adding `project_collaborators` table: id (uuid), project_id (references projects), user_id (references profiles), role ('owner' | 'editor' | 'viewer'), invited_at (timestamptz), accepted_at (timestamptz) - [ ] Create `collaboration_sessions` table: id (uuid), project_id, user_id, cursor_position (jsonb), selected_node_id (text nullable), connected_at (timestamptz), last_heartbeat (timestamptz) - [ ] Create `audit_trail` table: id (uuid), project_id, user_id, action_type (text: 'node_add' | 'node_update' | 'node_delete' | 'edge_add' | 'edge_update' | 'edge_delete'), entity_id (text), previous_state (jsonb), new_state (jsonb), created_at (timestamptz) - [ ] Add RLS policies: collaborators can access sessions/audit for projects they belong to - [ ] Add index on audit_trail(project_id, created_at) for efficient history queries - [ ] Typecheck passes **Complexity:** L --- ### US-044: Project sharing and collaborator management **Description:** As a project owner, I want to invite other users to collaborate on my project so that we can work together. **Acceptance Criteria:** - [ ] Add "Share" button in the editor toolbar - [ ] Share modal displays current collaborators with roles (owner/editor/viewer) - [ ] Owner can invite users by email with a selected role - [ ] Owner can change collaborator roles or remove collaborators - [ ] Invited users see shared projects on their dashboard with a "Shared with me" indicator - [ ] RLS policies updated so collaborators can read/write projects based on their role - [ ] Typecheck passes - [ ] Verify in browser using dev-browser skill **Dependencies:** US-043 **Complexity:** M --- ### US-045: Supabase Realtime channel and connection management **Description:** As a developer, I need a WebSocket connection layer using Supabase Realtime so that clients can exchange presence and change events in real time. **Acceptance Criteria:** - [ ] Create `lib/collaboration/realtime.ts` module - [ ] On editor mount, join a Supabase Realtime channel scoped to the project ID - [ ] Track connection state (connecting, connected, disconnected, reconnecting) - [ ] Implement heartbeat mechanism (update `last_heartbeat` every 30 seconds) - [ ] Auto-reconnect on network interruption with exponential backoff - [ ] Clean up session record on disconnect/unmount - [ ] Show connection status indicator in editor toolbar (green=connected, yellow=reconnecting, red=disconnected) - [ ] Typecheck passes - [ ] Verify in browser using dev-browser skill **Dependencies:** US-043 **Complexity:** M --- ### US-046: Presence indicators for active collaborators **Description:** As a user, I want to see who else is currently viewing or editing the project so that I am aware of my collaborators. **Acceptance Criteria:** - [ ] Display a row of avatar circles in the editor toolbar showing connected users - [ ] Each avatar shows the user's display_name on hover (tooltip) - [ ] Each user is assigned a consistent color (derived from user ID hash) - [ ] Avatars appear when users join and disappear when they leave - [ ] Maximum 5 avatars shown with "+N" overflow indicator - [ ] Own avatar not shown in the list - [ ] Typecheck passes - [ ] Verify in browser using dev-browser skill **Dependencies:** US-045 **Complexity:** S --- ### US-047: Live cursor positions on canvas **Description:** As a user, I want to see other collaborators' cursor positions on the canvas so that I can understand where they are working. **Acceptance Criteria:** - [ ] Broadcast local cursor position to the Realtime channel (throttled to 50ms) - [ ] Render remote cursors as colored arrows/pointers on the canvas with user name labels - [ ] Cursor color matches the user's assigned presence color - [ ] Remote cursors smoothly interpolate between position updates (no jumping) - [ ] Remote cursors fade out after 5 seconds of inactivity - [ ] Cursors are rendered in screen coordinates and properly transform with canvas zoom/pan - [ ] Typecheck passes - [ ] Verify in browser using dev-browser skill **Dependencies:** US-045, US-046 **Complexity:** M --- ### US-048: Integrate Yjs CRDT for conflict-free node/edge synchronization **Description:** As a developer, I need to integrate a CRDT library so that concurrent edits from multiple users merge automatically without data loss. **Acceptance Criteria:** - [ ] Install and configure Yjs with a Supabase-compatible provider (or WebSocket provider) - [ ] Create `lib/collaboration/crdt.ts` module wrapping Yjs document setup - [ ] Model flowchart nodes as a Y.Map keyed by node ID - [ ] Model flowchart edges as a Y.Map keyed by edge ID - [ ] Local React Flow state changes are synced to the Yjs document - [ ] Remote Yjs document changes update local React Flow state - [ ] Initial load populates Yjs document from database state - [ ] Periodic persistence of Yjs document state to Supabase (debounced 2 seconds) - [ ] Typecheck passes **Dependencies:** US-045 **Complexity:** L --- ### US-049: Node editing lock indicators **Description:** As a user, I want to see when another collaborator is actively editing a specific node so that I can avoid conflicts and wait for them to finish. **Acceptance Criteria:** - [ ] When a user focuses/opens a node for editing, broadcast the node ID to the channel - [ ] Nodes being edited by others show a colored border matching the editor's presence color - [ ] A small label with the editor's name appears on the locked node - [ ] Other users can still view but see a "Being edited by [name]" indicator if they try to edit - [ ] Lock is released when the user clicks away, closes the node, or disconnects - [ ] Lock auto-expires after 60 seconds of inactivity as a safety measure - [ ] Typecheck passes - [ ] Verify in browser using dev-browser skill **Dependencies:** US-045, US-048 **Complexity:** M --- ### US-050: Join/leave notifications **Description:** As a user, I want to be notified when collaborators join or leave the editing session so that I stay aware of the team's activity. **Acceptance Criteria:** - [ ] Show a toast notification when a collaborator joins: "[Name] joined" - [ ] Show a toast notification when a collaborator leaves: "[Name] left" - [ ] Notifications use the collaborator's assigned color as an accent - [ ] Notifications auto-dismiss after 3 seconds (matches existing Toast behavior) - [ ] No notification shown for own join/leave events - [ ] Typecheck passes - [ ] Verify in browser using dev-browser skill **Dependencies:** US-045, US-046 **Complexity:** S --- ### US-051: Audit trail recording **Description:** As a developer, I need all node and edge changes to be recorded in the audit trail so that users can review history and revert changes. **Acceptance Criteria:** - [ ] Every node add/update/delete operation writes a record to `audit_trail` table - [ ] Every edge add/update/delete operation writes a record to `audit_trail` table - [ ] Records include `previous_state` (null for additions) and `new_state` (null for deletions) - [ ] Records include the acting user's ID and timestamp - [ ] Writes are batched/debounced to avoid excessive DB calls (max 1 write per second per entity) - [ ] Audit writes do not block the user's editing flow (fire-and-forget with error logging) - [ ] Typecheck passes **Dependencies:** US-043, US-048 **Complexity:** M --- ### US-052: Activity history sidebar **Description:** As a user, I want to view a history of all changes made to the project so that I can see what collaborators have done and when. **Acceptance Criteria:** - [ ] Add "History" button to editor toolbar that opens a right sidebar panel - [ ] Sidebar displays a chronological list of changes with: user name, action type, entity description, timestamp - [ ] Entries are grouped by time period (Today, Yesterday, Earlier) - [ ] Each entry shows the user's presence color as an accent - [ ] Clicking an entry highlights/selects the affected node or edge on the canvas - [ ] Paginated loading (20 entries per page) with "Load more" button - [ ] Typecheck passes - [ ] Verify in browser using dev-browser skill **Dependencies:** US-051 **Complexity:** M --- ### US-053: Revert changes from audit trail **Description:** As a user, I want to revert a specific change from the history so that I can undo mistakes made by myself or collaborators. **Acceptance Criteria:** - [ ] Each entry in the activity history sidebar has a "Revert" button - [ ] Clicking "Revert" shows a confirmation dialog with before/after preview - [ ] Reverting a node addition deletes the node - [ ] Reverting a node update restores the previous state - [ ] Reverting a node deletion re-creates the node with its previous state - [ ] Reverting an edge change follows the same add/update/delete logic - [ ] The revert itself is recorded as a new audit trail entry - [ ] Reverted state is synced to all connected clients via CRDT - [ ] Typecheck passes - [ ] Verify in browser using dev-browser skill **Dependencies:** US-052, US-048 **Complexity:** L --- --- ### FEATURE 2: Character & Variable Management --- ### US-054: Character and Variable TypeScript types **Description:** As a developer, I need TypeScript types for Character and Variable models so that the rest of the feature can be built with type safety. **Acceptance Criteria:** - [ ] Add `Character` type to `types/flowchart.ts`: id (string), name (string), color (string, hex), description (string, optional) - [ ] Add `Variable` type to `types/flowchart.ts`: id (string), name (string), type ('numeric' | 'string' | 'boolean'), initialValue (number | string | boolean), description (string, optional) - [ ] Update `FlowchartData` type to include `characters: Character[]` and `variables: Variable[]` - [ ] Update `DialogueNodeData` to add optional `characterId: string` field (alongside existing `speaker` for migration) - [ ] Update `Condition` type to add optional `variableId: string` field (alongside existing `variableName` for migration) - [ ] Update `VariableNodeData` to add optional `variableId: string` field (alongside existing `variableName` for migration) - [ ] Typecheck passes **Complexity:** S --- ### US-055: Database schema update for characters and variables **Description:** As a developer, I need the database schema to store characters and variables as part of the project's flowchart data. **Acceptance Criteria:** - [ ] Create migration that documents the new JSONB structure (characters/variables arrays stored within `flowchart_data`) - [ ] Update the default value for `flowchart_data` column to include `characters: []` and `variables: []` - [ ] Existing projects with no characters/variables arrays continue to load (handled as empty arrays in app code) - [ ] Typecheck passes **Dependencies:** US-054 **Complexity:** S --- ### US-056: Character management UI in project settings **Description:** As a user, I want a dedicated page to manage my project's characters so that I can define them once and reuse them throughout the flowchart. **Acceptance Criteria:** - [ ] Add "Project Settings" button to editor toolbar - [ ] Project settings opens as a modal with "Characters" and "Variables" tabs - [ ] Characters tab shows a list of defined characters with name, color swatch, and description - [ ] "Add Character" button opens inline form with: name (required), color picker (required, defaults to random), description (optional) - [ ] Each character row has Edit and Delete buttons - [ ] Deleting a character that is referenced by nodes shows a warning: "This character is used in N nodes. Removing it will leave those nodes without a speaker." - [ ] Character names must be unique within the project (show validation error if duplicate) - [ ] Changes are saved to the flowchart data (same save mechanism as nodes/edges) - [ ] Typecheck passes - [ ] Verify in browser using dev-browser skill **Dependencies:** US-054, US-055 **Complexity:** M --- ### US-057: Variable management UI in project settings **Description:** As a user, I want a dedicated page to manage my project's variables so that I can define them with types and initial values for use throughout the flowchart. **Acceptance Criteria:** - [ ] Variables tab in project settings modal shows a list of defined variables - [ ] Each variable displays: name, type badge (numeric/string/boolean), initial value, description - [ ] "Add Variable" button opens inline form with: name (required), type dropdown (required), initial value (required, input type matches selected type), description (optional) - [ ] Each variable row has Edit and Delete buttons - [ ] Deleting a variable that is referenced by nodes/edges shows a warning with usage count - [ ] Variable names must be unique within the project - [ ] Changes are saved to the flowchart data - [ ] Typecheck passes - [ ] Verify in browser using dev-browser skill **Dependencies:** US-054, US-055 **Complexity:** M --- ### US-058: Dialogue node speaker dropdown **Description:** As a user, I want to select a character from a dropdown in the dialogue node instead of typing a name so that I avoid typos and maintain consistency. **Acceptance Criteria:** - [ ] Replace the speaker text input in DialogueNode with a searchable dropdown (combobox) - [ ] Dropdown lists all characters defined in the project, showing color swatch + name - [ ] Selecting a character sets `characterId` on the node data - [ ] Dropdown includes an "Add new character..." option at the bottom - [ ] Clicking "Add new character..." opens a mini form inline (name + color) that creates the character and selects it - [ ] If node has a `characterId` that doesn't match any defined character, show orange warning border on the dropdown - [ ] Empty/unset speaker shows placeholder "Select speaker..." - [ ] Typecheck passes - [ ] Verify in browser using dev-browser skill **Dependencies:** US-056 **Complexity:** M --- ### US-059: Variable node variable dropdown **Description:** As a user, I want to select a variable from a dropdown in the variable node instead of typing a name so that I avoid typos and maintain consistency. **Acceptance Criteria:** - [ ] Replace the variableName text input in VariableNode with a searchable dropdown - [ ] Dropdown lists all variables defined in the project, showing type badge + name - [ ] Selecting a variable sets `variableId` on the node data - [ ] Dropdown includes "Add new variable..." option that opens inline creation form - [ ] If node references a variableId that doesn't match any defined variable, show orange warning border - [ ] Operation options (set/add/subtract) are filtered based on selected variable's type (add/subtract only for numeric) - [ ] Typecheck passes - [ ] Verify in browser using dev-browser skill **Dependencies:** US-057 **Complexity:** M --- ### US-060: Edge condition variable dropdown **Description:** As a user, I want to select a variable from a dropdown when setting edge conditions so that I reference valid variables consistently. **Acceptance Criteria:** - [ ] Replace the variableName text input in ConditionEditor with a searchable dropdown - [ ] Dropdown lists all variables defined in the project, showing type badge + name - [ ] Selecting a variable sets `variableId` on the condition object - [ ] Dropdown includes "Add new variable..." option - [ ] If condition references an undefined variableId, show orange warning indicator - [ ] Operator options are filtered based on variable type (comparison operators for numeric, == and != for string/boolean) - [ ] Value input adapts to variable type (number input for numeric, text for string, checkbox for boolean) - [ ] Typecheck passes - [ ] Verify in browser using dev-browser skill **Dependencies:** US-057 **Complexity:** M --- ### US-061: Choice option condition variable dropdown **Description:** As a user, I want to select a variable from a dropdown when setting choice option conditions so that I reference valid variables consistently. **Acceptance Criteria:** - [ ] Replace the variableName text input in OptionConditionEditor with a searchable dropdown - [ ] Dropdown lists all variables defined in the project, showing type badge + name - [ ] Selecting a variable sets `variableId` on the option's condition object - [ ] Dropdown includes "Add new variable..." option - [ ] If condition references an undefined variableId, show orange warning indicator - [ ] Operator and value inputs adapt to variable type (same behavior as US-060) - [ ] Typecheck passes - [ ] Verify in browser using dev-browser skill **Dependencies:** US-057 **Complexity:** S --- ### US-062: Auto-migration of existing free-text values **Description:** As a user, I want my existing projects to automatically create character and variable definitions from free-text values so that I don't have to manually re-enter them. **Acceptance Criteria:** - [ ] On project load, if `characters` array is empty but nodes have `speaker` values, auto-create Character entries from unique speaker names - [ ] Auto-created characters get randomly assigned colors and the speaker text as name - [ ] On project load, if `variables` array is empty but nodes/edges have `variableName` values, auto-create Variable entries (default type: numeric, initial value: 0) - [ ] After auto-creation, update all nodes to set `characterId`/`variableId` references pointing to the new entries - [ ] Show a toast notification: "Auto-imported N characters and M variables from existing data" - [ ] Migration only runs once (presence of characters/variables arrays, even if empty, means migration already happened) - [ ] Typecheck passes **Dependencies:** US-054, US-058, US-059 **Complexity:** M --- ### US-063: Import characters/variables from another project **Description:** As a user, I want to import character and variable definitions from another project so that I can reuse them without redefining everything. **Acceptance Criteria:** - [ ] Add "Import from project" button in both Characters and Variables tabs of project settings - [ ] Button opens a modal listing the user's other projects - [ ] Selecting a project shows its characters (or variables) with checkboxes for selection - [ ] User can select which entries to import (select all / none / individual) - [ ] Imported entries are added to the current project (duplicates by name are skipped with a warning) - [ ] Imported characters keep their colors; imported variables keep their types and initial values - [ ] Typecheck passes - [ ] Verify in browser using dev-browser skill **Dependencies:** US-056, US-057 **Complexity:** M --- ### US-064: Export validation for undefined references **Description:** As a user, I want to be warned before exporting if any nodes reference undefined characters or variables so that I can fix issues before generating output. **Acceptance Criteria:** - [ ] Before export, scan all nodes and edges for `characterId`/`variableId` references that don't match defined entries - [ ] If issues found, show a warning modal listing: node type, node content snippet, and the undefined reference - [ ] Modal offers "Export anyway" and "Cancel" options - [ ] Nodes with undefined references are highlighted on the canvas with orange warning borders when modal is shown - [ ] If no issues found, export proceeds normally - [ ] Typecheck passes - [ ] Verify in browser using dev-browser skill **Dependencies:** US-058, US-059, US-060, US-061 **Complexity:** M --- ### US-065: Searchable combobox component **Description:** As a developer, I need a reusable searchable combobox component so that all character/variable dropdowns share consistent behavior and styling. **Acceptance Criteria:** - [ ] Create `components/editor/Combobox.tsx` - a reusable searchable dropdown component - [ ] Props: items (id, label, color?, badge?), value, onChange, placeholder, onAddNew (optional callback) - [ ] Typing in the input filters the list by name (case-insensitive) - [ ] Keyboard navigation: arrow keys to move, Enter to select, Escape to close - [ ] Shows color swatch and/or badge next to item labels when provided - [ ] "Add new..." option rendered at bottom when `onAddNew` prop is provided - [ ] Dropdown positions itself above or below input based on available space - [ ] Matches existing editor styling (TailwindCSS, dark mode support) - [ ] Typecheck passes - [ ] Verify in browser using dev-browser skill **Complexity:** M --- ## Functional Requirements ### Real-time Collaboration - FR-1: The system must establish a WebSocket connection via Supabase Realtime when a user opens a project in the editor - FR-2: The system must broadcast user presence (cursor position, selected node, connected status) to all collaborators on the same project - FR-3: The system must display up to 5 collaborator avatars in the toolbar with overflow count - FR-4: The system must render remote cursors on the canvas with color-coded labels - FR-5: The system must use Yjs CRDT documents to synchronize node and edge state across clients without data loss - FR-6: The system must show a colored border and name label on nodes being actively edited by another user - FR-7: The system must display toast notifications when collaborators join or leave the session - FR-8: The system must record all node/edge mutations to an audit_trail table with previous and new state - FR-9: The system must provide a history sidebar showing chronological change entries grouped by date - FR-10: The system must allow reverting any individual change from the history, restoring the previous state - FR-11: The system must handle network disconnection gracefully with automatic reconnection and state re-sync - FR-12: The system must allow project owners to invite collaborators by email with a specific role (editor/viewer) ### Character & Variable Management - FR-13: The system must store Character definitions (id, name, color, description) in the project's flowchart_data - FR-14: The system must store Variable definitions (id, name, type, initialValue, description) in the project's flowchart_data - FR-15: The system must provide a project settings modal with tabs for managing characters and variables - FR-16: The system must replace all speaker text inputs with searchable combobox dropdowns populated from the characters list - FR-17: The system must replace all variableName text inputs with searchable combobox dropdowns populated from the variables list - FR-18: The system must allow inline creation of new characters/variables from within dropdowns - FR-19: The system must show orange warning indicators on nodes/edges referencing undefined characters or variables - FR-20: The system must validate references before export and warn the user of any undefined references - FR-21: The system must auto-migrate existing free-text speaker/variableName values to Character/Variable definitions on first load - FR-22: The system must allow importing characters/variables from other projects owned by the user - FR-23: The system must filter operator options and value inputs based on the selected variable's type ## Non-Goals (Out of Scope) - No voice/video chat between collaborators - No commenting/annotation system on nodes - No permission system beyond owner/editor/viewer roles - No offline-first editing (requires active connection for collaboration) - No version branching or forking (linear history only) - No global character/variable library shared across all users - No AI-assisted character or variable suggestions - No real-time text editing within a single node's text field (CRDT operates at node level) - No variable dependencies or computed values ## Design Considerations - Presence avatars should follow existing toolbar button styling (compact, consistent height) - Remote cursors should be semi-transparent to avoid visual clutter - Node lock indicators should use the existing node border styling with color override - Project settings modal should match existing modal patterns (ProjectCard rename/delete modals) - Combobox dropdown should match existing input styling with dark mode support - Character colors should be distinguishable in both light and dark modes - History sidebar width should not exceed 320px to preserve canvas space ## Technical Considerations - **Supabase Realtime** for presence and broadcast channels (already available in the stack) - **Yjs** CRDT library for conflict-free document synchronization - **y-supabase** or custom provider to bridge Yjs with Supabase Realtime - Cursor position broadcasts should be throttled (50ms) to avoid overwhelming the channel - Audit trail writes should be debounced and batched to minimize database load - Auto-migration logic must be idempotent (safe to run multiple times) - Combobox component should use React portal for dropdown to avoid z-index/overflow issues - Character/variable ID references enable renaming without breaking node associations - The `flowchart_data` JSONB column grows with characters/variables arrays; monitor size for large projects ## Success Metrics - Multiple users can simultaneously edit a flowchart with all changes reflected within 500ms - No data loss during concurrent edits (CRDT guarantees) - Collaborators can see each other's presence and activity within 1 second of connection - Any historical change can be reverted without side effects on other nodes - Zero typo-related issues in character names and variable references after migration to dropdowns - New characters/variables can be created inline without leaving the canvas (under 3 clicks) - Existing projects auto-migrate to the new system seamlessly on first load ## Open Questions - Should the Yjs document be persisted separately from the Supabase JSONB column (dedicated storage)? - What is the maximum number of concurrent collaborators to support per project? - Should viewer-role users see other viewers' cursors, or only editors'? - How long should audit trail entries be retained (indefinitely, or time-based cleanup)? - Should the combobox support creating characters/variables with full details inline, or just name + essentials? - Should variable type changes be allowed after creation if the variable is already in use?