422 lines
23 KiB
JSON
422 lines
23 KiB
JSON
{
|
|
"project": "WebVNWrite",
|
|
"branchName": "ralph/collaboration-and-character-variables",
|
|
"description": "Real-time Collaboration & Character/Variable Management - Enable multi-user editing with CRDT sync, presence indicators, audit trail, plus centralized character/variable definitions with dropdown selectors",
|
|
"userStories": [
|
|
{
|
|
"id": "US-054",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"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"
|
|
],
|
|
"priority": 1,
|
|
"passes": true,
|
|
"notes": ""
|
|
},
|
|
{
|
|
"id": "US-055",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"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"
|
|
],
|
|
"priority": 2,
|
|
"passes": true,
|
|
"notes": "Dependencies: US-054"
|
|
},
|
|
{
|
|
"id": "US-065",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"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"
|
|
],
|
|
"priority": 3,
|
|
"passes": true,
|
|
"notes": ""
|
|
},
|
|
{
|
|
"id": "US-056",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"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 referenced by nodes shows warning with usage count",
|
|
"Character names must be unique within the project (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"
|
|
],
|
|
"priority": 4,
|
|
"passes": true,
|
|
"notes": "Dependencies: US-054, US-055"
|
|
},
|
|
{
|
|
"id": "US-057",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"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 adapts to type), description (optional)",
|
|
"Each variable row has Edit and Delete buttons",
|
|
"Deleting a variable referenced by nodes/edges shows 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"
|
|
],
|
|
"priority": 5,
|
|
"passes": true,
|
|
"notes": "Dependencies: US-054, US-055"
|
|
},
|
|
{
|
|
"id": "US-058",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"Replace the speaker text input in DialogueNode with the Combobox component",
|
|
"Dropdown lists all characters defined in the project, showing color swatch + name",
|
|
"Selecting a character sets characterId on the node data",
|
|
"Dropdown includes '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"
|
|
],
|
|
"priority": 6,
|
|
"passes": true,
|
|
"notes": "Dependencies: US-056, US-065"
|
|
},
|
|
{
|
|
"id": "US-059",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"Replace the variableName text input in VariableNode with the Combobox component",
|
|
"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"
|
|
],
|
|
"priority": 7,
|
|
"passes": true,
|
|
"notes": "Dependencies: US-057, US-065"
|
|
},
|
|
{
|
|
"id": "US-060",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"Replace the variableName text input in ConditionEditor with the Combobox component",
|
|
"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"
|
|
],
|
|
"priority": 8,
|
|
"passes": true,
|
|
"notes": "Dependencies: US-057, US-065"
|
|
},
|
|
{
|
|
"id": "US-061",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"Replace the variableName text input in OptionConditionEditor with the Combobox component",
|
|
"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"
|
|
],
|
|
"priority": 9,
|
|
"passes": true,
|
|
"notes": "Dependencies: US-057, US-065"
|
|
},
|
|
{
|
|
"id": "US-062",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"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"
|
|
],
|
|
"priority": 10,
|
|
"passes": true,
|
|
"notes": "Dependencies: US-054, US-058, US-059"
|
|
},
|
|
{
|
|
"id": "US-063",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"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"
|
|
],
|
|
"priority": 11,
|
|
"passes": true,
|
|
"notes": "Dependencies: US-056, US-057"
|
|
},
|
|
{
|
|
"id": "US-064",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"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"
|
|
],
|
|
"priority": 12,
|
|
"passes": true,
|
|
"notes": "Dependencies: US-058, US-059, US-060, US-061"
|
|
},
|
|
{
|
|
"id": "US-043",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"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"
|
|
],
|
|
"priority": 13,
|
|
"passes": true,
|
|
"notes": ""
|
|
},
|
|
{
|
|
"id": "US-045",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"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"
|
|
],
|
|
"priority": 14,
|
|
"passes": true,
|
|
"notes": "Dependencies: US-043"
|
|
},
|
|
{
|
|
"id": "US-044",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"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"
|
|
],
|
|
"priority": 15,
|
|
"passes": true,
|
|
"notes": "Dependencies: US-043"
|
|
},
|
|
{
|
|
"id": "US-046",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"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"
|
|
],
|
|
"priority": 16,
|
|
"passes": false,
|
|
"notes": "Dependencies: US-045"
|
|
},
|
|
{
|
|
"id": "US-048",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"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"
|
|
],
|
|
"priority": 17,
|
|
"passes": false,
|
|
"notes": "Dependencies: US-045"
|
|
},
|
|
{
|
|
"id": "US-047",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"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"
|
|
],
|
|
"priority": 18,
|
|
"passes": false,
|
|
"notes": "Dependencies: US-045, US-046"
|
|
},
|
|
{
|
|
"id": "US-050",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"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"
|
|
],
|
|
"priority": 19,
|
|
"passes": false,
|
|
"notes": "Dependencies: US-045, US-046"
|
|
},
|
|
{
|
|
"id": "US-049",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"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"
|
|
],
|
|
"priority": 20,
|
|
"passes": false,
|
|
"notes": "Dependencies: US-045, US-048"
|
|
},
|
|
{
|
|
"id": "US-051",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"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"
|
|
],
|
|
"priority": 21,
|
|
"passes": false,
|
|
"notes": "Dependencies: US-043, US-048"
|
|
},
|
|
{
|
|
"id": "US-052",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"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"
|
|
],
|
|
"priority": 22,
|
|
"passes": false,
|
|
"notes": "Dependencies: US-051"
|
|
},
|
|
{
|
|
"id": "US-053",
|
|
"title": "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.",
|
|
"acceptanceCriteria": [
|
|
"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"
|
|
],
|
|
"priority": 23,
|
|
"passes": false,
|
|
"notes": "Dependencies: US-052, US-048"
|
|
}
|
|
]
|
|
}
|