WebVNWrite/prd.json

764 lines
37 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": false,
"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": false,
"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": false,
"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": false,
"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,
<<<<<<< HEAD
"passes": false,
"notes": "Dependencies: US-052, US-048"
=======
"passes": true,
"notes": ""
},
{
"id": "US-024",
"title": "Add/remove choice options",
"description": "As a user, I want to add or remove choice options (2-6 options supported).",
"acceptanceCriteria": [
"ChoiceNode has '+' button to add new option",
"Maximum 6 options (button disabled or hidden at max)",
"Each option has 'x' button to remove it",
"Minimum 2 options (remove button disabled or hidden at min)",
"Adding option creates new output Handle dynamically",
"Removing option removes its Handle",
"Node data updates in React Flow state",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 24,
"passes": true,
"notes": ""
},
{
"id": "US-025",
"title": "Create custom variable node component",
"description": "As a user, I want variable nodes to set or modify story variables.",
"acceptanceCriteria": [
"Create components/editor/nodes/VariableNode.tsx",
"Node styled with orange background/border",
"Displays editable input for variable name (placeholder: 'variableName')",
"Displays dropdown/select for operation: set, add, subtract",
"Displays editable number input for value (default: 0)",
"Has one Handle at top (type='target', id='input')",
"Has one Handle at bottom (type='source', id='output')",
"Register as custom node type in React Flow",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 25,
"passes": true,
"notes": ""
},
{
"id": "US-026",
"title": "Add variable node from toolbar",
"description": "As a user, I want to add variable nodes by clicking the toolbar button.",
"acceptanceCriteria": [
"Clicking 'Add Variable' in toolbar creates new VariableNode",
"Node appears at center of current viewport",
"Node has unique ID",
"Node initialized with empty variableName, operation='set', value=0",
"Node added to React Flow nodes state",
"Node can be dragged to reposition",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 26,
"passes": true,
"notes": ""
},
{
"id": "US-027",
"title": "Connect nodes with edges",
"description": "As a user, I want to connect nodes with arrows to define story flow.",
"acceptanceCriteria": [
"Dragging from source Handle to target Handle creates edge (React Flow default)",
"Edges render as smooth bezier curves (default edge type or smoothstep)",
"Edges show arrow marker indicating direction (markerEnd)",
"Edges update position when nodes are moved",
"Cannot connect source-to-source or target-to-target (React Flow handles this)",
"New edges added to React Flow edges state",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 27,
"passes": true,
"notes": ""
},
{
"id": "US-028",
"title": "Select and delete nodes",
"description": "As a user, I want to delete nodes to revise my flowchart.",
"acceptanceCriteria": [
"Clicking a node selects it (visual highlight via React Flow)",
"Pressing Delete or Backspace key removes selected node(s)",
"Deleting node also removes all connected edges",
"Use onNodesDelete callback to handle deletion",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 28,
"passes": true,
"notes": ""
},
{
"id": "US-029",
"title": "Select and delete edges",
"description": "As a user, I want to delete connections between nodes.",
"acceptanceCriteria": [
"Clicking an edge selects it (visual highlight via React Flow)",
"Pressing Delete or Backspace key removes selected edge(s)",
"Use onEdgesDelete callback to handle deletion",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 29,
"passes": true,
"notes": ""
},
{
"id": "US-030",
"title": "Right-click context menu",
"description": "As a user, I want a context menu for quick actions.",
"acceptanceCriteria": [
"Create components/editor/ContextMenu.tsx",
"Right-click on canvas shows menu: Add Dialogue, Add Choice, Add Variable",
"New node created at click position",
"Right-click on node shows menu: Delete",
"Right-click on edge shows menu: Delete, Add Condition",
"Clicking elsewhere or pressing Escape closes menu",
"Menu styled with TailwindCSS",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 30,
"passes": true,
"notes": ""
},
{
"id": "US-031",
"title": "Condition editor modal",
"description": "As a user, I want to add conditions to edges so branches depend on variables.",
"acceptanceCriteria": [
"Create components/editor/ConditionEditor.tsx modal/popover",
"Opens on double-click edge or via context menu 'Add Condition'",
"Form fields: variable name input, operator dropdown (>, <, ==, >=, <=, !=), value number input",
"Pre-fill fields if edge already has condition",
"Save button applies condition to edge data",
"Clear/Remove button removes condition from edge",
"Cancel button closes without saving",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 31,
"passes": true,
"notes": ""
},
{
"id": "US-032",
"title": "Display conditions on edges",
"description": "As a user, I want to see conditions displayed on edges.",
"acceptanceCriteria": [
"Create custom edge component or use edge labels",
"Edges with conditions render as dashed lines (strokeDasharray)",
"Condition label displayed on edge (e.g., 'score > 5')",
"Unconditional edges remain solid lines",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 32,
"passes": true,
"notes": ""
},
{
"id": "US-033",
"title": "Auto-save to LocalStorage",
"description": "As a user, I want my work auto-saved locally so I don't lose progress if the browser crashes.",
"acceptanceCriteria": [
"Save flowchart state (nodes + edges) to LocalStorage on every change",
"Debounce saves (e.g., 1 second delay after last change)",
"LocalStorage key format: 'vnwrite-draft-{projectId}'",
"On editor load, check LocalStorage for saved draft",
"If local draft exists and differs from database, show prompt to restore or discard",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 33,
"passes": true,
"notes": ""
},
{
"id": "US-034",
"title": "Save project to database",
"description": "As a user, I want to save my project to the database manually.",
"acceptanceCriteria": [
"Clicking 'Save' in toolbar saves current nodes/edges to Supabase",
"Update project's flowchart_data and updated_at fields",
"Show saving indicator/spinner while in progress",
"Show success toast on completion",
"Clear LocalStorage draft after successful save",
"Show error toast if save fails",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 34,
"passes": true,
"notes": ""
},
{
"id": "US-035",
"title": "Export project as .vnflow file",
"description": "As a user, I want to export my project as a JSON file for backup or sharing.",
"acceptanceCriteria": [
"Clicking 'Export' in toolbar triggers file download",
"File named '[project-name].vnflow'",
"File contains JSON with nodes and edges arrays",
"JSON is pretty-printed (2-space indent) for readability",
"Uses browser download API (create blob, trigger download)",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 35,
"passes": true,
"notes": ""
},
{
"id": "US-036",
"title": "Import project from .vnflow file",
"description": "As a user, I want to import a .vnflow file to restore or share projects.",
"acceptanceCriteria": [
"Clicking 'Import' in toolbar opens file picker",
"Accept .vnflow and .json file extensions",
"If current project has unsaved changes, show confirmation dialog",
"Validate imported file has nodes and edges arrays",
"Show error toast if file is invalid",
"Load valid data into React Flow state (replaces current flowchart)",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 36,
"passes": true,
"notes": ""
},
{
"id": "US-037",
"title": "Export to Ren'Py JSON format",
"description": "As a user, I want to export my flowchart to Ren'Py-compatible JSON for use in my game.",
"acceptanceCriteria": [
"Add 'Export to Ren'Py' option (button or dropdown item)",
"File named '[project-name]-renpy.json'",
"Dialogue nodes export as: { type: 'dialogue', speaker: '...', text: '...' }",
"Choice nodes export as: { type: 'menu', prompt: '...', choices: [{ label: '...', next: '...' }] }",
"Variable nodes export as: { type: 'variable', name: '...', operation: '...', value: ... }",
"Edges with conditions include condition object on the choice/jump",
"Organize nodes into labeled sections based on flow (traverse from first node)",
"Include metadata: projectName, exportedAt timestamp",
"Output JSON is valid (test with JSON.parse)",
"Typecheck passes"
],
"priority": 37,
"passes": true,
"notes": ""
},
{
"id": "US-038",
"title": "Unsaved changes warning",
"description": "As a user, I want a warning before losing unsaved work.",
"acceptanceCriteria": [
"Track dirty state: true when flowchart modified after last save",
"Set dirty=true on node/edge add, delete, or modify",
"Set dirty=false after successful save",
"Browser beforeunload event shows warning if dirty",
"Navigating to dashboard shows confirmation modal if dirty",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 38,
"passes": true,
"notes": ""
},
{
"id": "US-039",
"title": "Loading and error states",
"description": "As a user, I want clear feedback when things are loading or when errors occur.",
"acceptanceCriteria": [
"Loading spinner component for async operations",
"Editor shows loading spinner while fetching project",
"Error message displayed if project fails to load (with back to dashboard link)",
"Toast notification system for success/error messages",
"Save error shows toast with retry option",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 39,
"passes": true,
"notes": ""
},
{
"id": "US-040",
"title": "Conditionals on choice options",
"description": "As a user, I want individual choice options to have variable conditions so that options are only visible when certain conditions are met (e.g., affection > 10).",
"acceptanceCriteria": [
"Each ChoiceOption can have optional condition (variableName, operator, value)",
"Update ChoiceNode UI to show 'Add condition' button per option",
"Condition editor modal for each option",
"Visual indicator (icon/badge) on options with conditions",
"Update TypeScript types: ChoiceOption gets optional condition field",
"Export includes per-option conditions in Ren'Py JSON",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 40,
"passes": true,
"notes": "Dependencies: US-018, US-019, US-025. Complexity: M"
},
{
"id": "US-041",
"title": "Change password for logged-in user",
"description": "As a user, I want to change my own password from a settings/profile page so that I can keep my account secure.",
"acceptanceCriteria": [
"Settings/profile page accessible from dashboard header",
"Form with: current password, new password, confirm new password fields",
"Calls Supabase updateUser with new password",
"Requires current password verification (re-authenticate)",
"Shows success/error messages",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 41,
"passes": true,
"notes": "Dependencies: US-004. Complexity: S"
},
{
"id": "US-042",
"title": "Password reset modal on token arrival",
"description": "As a user, I want a modal to automatically appear when a password reset token is detected so that I can set my new password seamlessly.",
"acceptanceCriteria": [
"Detect password reset token in URL (from Supabase email link)",
"Show modal/dialog automatically when token present",
"Modal has: new password, confirm password fields",
"Calls Supabase updateUser with token to complete reset",
"On success, close modal and redirect to login",
"On error, show error message",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 42,
"passes": true,
"notes": "Dependencies: US-006. Complexity: S"
>>>>>>> a6a966ce8f445a7ff2c20d92afd65214567eb411
}
]
}