27 KiB
PRD: Real-time Collaboration & Character/Variable Management
Introduction
Two major features to enhance the Visual Novel Flowchart Editor:
-
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.
-
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_collaboratorstable: id (uuid), project_id (references projects), user_id (references profiles), role ('owner' | 'editor' | 'viewer'), invited_at (timestamptz), accepted_at (timestamptz) - Create
collaboration_sessionstable: id (uuid), project_id, user_id, cursor_position (jsonb), selected_node_id (text nullable), connected_at (timestamptz), last_heartbeat (timestamptz) - Create
audit_trailtable: 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.tsmodule - 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_heartbeatevery 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.tsmodule 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_trailtable - Every edge add/update/delete operation writes a record to
audit_trailtable - Records include
previous_state(null for additions) andnew_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
Charactertype totypes/flowchart.ts: id (string), name (string), color (string, hex), description (string, optional) - Add
Variabletype totypes/flowchart.ts: id (string), name (string), type ('numeric' | 'string' | 'boolean'), initialValue (number | string | boolean), description (string, optional) - Update
FlowchartDatatype to includecharacters: Character[]andvariables: Variable[] - Update
DialogueNodeDatato add optionalcharacterId: stringfield (alongside existingspeakerfor migration) - Update
Conditiontype to add optionalvariableId: stringfield (alongside existingvariableNamefor migration) - Update
VariableNodeDatato add optionalvariableId: stringfield (alongside existingvariableNamefor 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_datacolumn to includecharacters: []andvariables: [] - 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
characterIdon 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
characterIdthat 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
variableIdon 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
variableIdon 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
variableIdon 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
charactersarray is empty but nodes havespeakervalues, 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
variablesarray is empty but nodes/edges havevariableNamevalues, auto-create Variable entries (default type: numeric, initial value: 0) - After auto-creation, update all nodes to set
characterId/variableIdreferences 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/variableIdreferences 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
onAddNewprop 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_dataJSONB 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?