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

531 lines
27 KiB
Markdown

# 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?