1. Front Matter
Title: Canvas Schema & Supabase Prep
Author: scorevi (Sean Patrick Caintic)
Reviewers: Mich-Tapawan
Created: January 2026
Status: Approved
References:
Issue: [W1.5] Quest Canvas Schema #114
Milestone: [W1] Backend Infrastructure
2. Introduction & Goals
Problem Summary: The Visual Canvas (React Flow) needs to persist node positions, connections, and conditional branching logic. Before W1.5, canvas state was only in-memory, meaning all canvas work was lost on page refresh or navigation. This feature establishes the data model and persistence layer for the canvas, enabling creators to save their visual quest designs.
Goals:
Define TypeScript interfaces for canvas persistence
Add JSONB column to
queststableCreate Zod schemas for runtime validation
Support conditional edge logic with sourceHandle branching
Non-Goals:
Canvas rendering logic (frontend concern)
Real-time collaboration
Version history for canvas
Glossary:
CanvasMetadata: Root object containing nodes and edges arrays
CanvasNode: Individual element on the canvas with position and type
CanvasEdge: Connection between two nodes with optional logic
sourceHandle: Per-choice branching identifier for conditional flows
3. High-Level Architecture
System Diagram:

Technologies Used:
React Flow - Canvas UI library for visual node editing
Supabase JSONB - Schema-less storage for flexible canvas data
Zod - Runtime validation of canvas structure
TypeScript - Type definitions and compile-time safety
4. Detailed Design & Implementation
Data Model / Schema:
questsTable Addition:Column
Type
Default
canvas_metadataJSONB
'{"nodes":[],"edges":[]}'CanvasMetadata Structure:
Field
Type
Description
nodesCanvasNode[]All canvas nodes
edgesCanvasEdge[]Connections between nodes
CanvasNode:
Field
Type
Required
Description
idstring
Yes
Unique identifier
xnumber
Yes
X coordinate
ynumber
Yes
Y coordinate
typestring
Yes
Node type (Scenario, Question, etc.)
dataobject
No
Node-specific metadata
CanvasEdge:
Field
Type
Required
Description
sourcestring
Yes
Source node ID
targetstring
Yes
Target node ID
labelstring
No
Edge label text
logicstring
No
Conditional expression
sourceHandlestring
No
Per-choice branching identifier
API Specification:
GET /api/creator/update-quest-canvas- Fetch canvas state for a questPUT /api/creator/update-quest-canvas- Save canvas state to database
Logic & Workflows:
Supported Node Types:
Scenario- Content module (lesson, chapter) with optional childrenQuestion- Decision/assessment node (multiple-choice, etc.)Text- Text content blockImage- Image contentVideo- Video embedCodeblock- Code snippetFile- File attachmentLink- External linkMusic- Audio contentEssay- Long-form text responseQuiz- Assessment module
Conditional Branching Flow:
┌─────────────┐│ Question │─── sourceHandle: "choice-a" ──▶ Node A│ │─── sourceHandle: "choice-b" ──▶ Node B└─────────────┘Key Files:
types/adventure.ts- TypeScript interfaces for CanvasMetadata, CanvasNode, CanvasEdgeshared/schemas/questSchema.ts- Zod validation schemaslib/supabase/migrations/- Database migration for JSONB column
5. Infrastructure & Operations
Dependencies:
Supabase - PostgreSQL JSONB storage
React Flow - Canvas rendering and interaction
Monitoring & Alerting: No specific monitoring required. Canvas save is user-initiated and follows standard API error handling patterns.
Deployment Plan:
Run migration to add
canvas_metadatacolumn toqueststableDeploy API routes for canvas read/write
No frontend changes required (uses existing React Flow integration)
6. Testing & Quality Assurance
Test Strategy:
Manual: Save/load canvas state, verify node positions persist
Unit: Zod schema validation for CanvasMetadata structure
Known Limitations:
No version history (canvas state is overwritten on each save)
No collaborative editing support
JSONB size limit (~1GB, unlikely to be reached)
7. Maintenance & Support
Troubleshooting:
Canvas not loading → Verify
canvas_metadatais valid JSON in databaseNode positions lost → Check save API response for errors
Invalid edge connections → Validate that source/target node IDs exist
Changelog:
1.0 (Feb 2026): Initial implementation
Document Version
1.0 - Approved, Infrastructure deployed to production, 02/16/2026