WebVNWrite/tasks/prd-collaboration-and-chara...

27 KiB

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?