1. Front Matter
Title: Save State
Author: Joshua Uriel Tribiana
Reviewers: JD Billate
Created: July 2026
Status: Completed and merged in the codebase
References:
Feature ticket: [9.2] Save State
Related implementation files:
2. Introduction & Goals
Problem Summary
Learners need their quest progress to persist across sessions so that they can pause and resume without losing their place. The save-state feature ensures the system remembers the learner’s visited nodes, last location, and current progress percentage.
Goals
Persist learner progress for each quest enrollment.
Rehydrate progress on subsequent sessions.
Compute a progress percentage from current quest structure and learner interactions.
Support both legacy and current progress payload formats.
Non-Goals
Implementing full offline sync.
Creating a global analytics event stream for every interaction.
Persisting non-progress data outside of the enrollment record.
Glossary
Enrollment: The learner-to-quest relationship that carries progress state.
Visited Cards: The list of node identifiers the learner has encountered.
Location: The current context or node position used for resume behavior.
Canvas Metadata: The quest’s node/edge structure used to validate and calculate progress.
3. High-Level Architecture
System Diagram
+------------------------+| Learner UI |+------------------------+ | v+------------------------+| useQuestProgress Hook |+------------------------+ | | | | v v+------------------------+ +------------------------+| POST | | GET || /api/learner/ | | /api/learner/ || update-progress | | get-enrollment |+------------------------+ +------------------------+ | | | | +-------------+---------------+ | v +--------------------------+ | Supabase | | quest_enrollments | +--------------------------+ | | | | v v +----------------------+ +----------------------+ | Update Progress | | Normalized Progress | | Payload | | Response | +----------------------+ +----------------------+
Technologies Used
Next.js / React / TypeScript
Supabase
Zod-style validation through ApiResponseHelper
Existing learner auth middleware
4. Detailed Design & Implementation
Data Model / Schema
The feature uses the existing quest_enrollments table and updates the progress JSON payload.
Current persisted fields include:
percentagevisited_cardslast_visited_atlocation
Progress Normalization
The backend includes normalization logic for both legacy and current formats:
Legacy numeric progress values
Old
completed_sectionsarraysCurrent
visited_cardsformat
This makes the save-state flow tolerant of older enrollment records.
API Specification
Get Enrollment Progress
Endpoint:
GET /api/learner/get-enrollment?quest_id={questId}Auth: Required
Behavior: Returns the learner’s enrollment ID, current progress payload, and status
Update Progress
Endpoint:
POST /api/learner/update-progressAuth: Required
Request Body:
{ "quest_id": "uuid", "node_id": "node-id", "location": "optional-location"}
Logic & Workflow
The learner opens a quest and the hook loads the existing enrollment state.
When the learner visits a node, the hook calls the update-progress endpoint.
The backend verifies the enrollment exists and the quest exists.
The backend validates that the requested node exists in the quest’s canvas metadata.
The backend appends the node to
visited_cardsif it is new.The backend recomputes the progress percentage based on visited nodes and completed interactables.
The updated progress payload is written back to the enrollment row.
Progress Calculation
The calculation uses:
the total number of active nodes plus the details page
visited nodes count
completed interactable nodes such as quizzes, reflections, questions, and code nodes
The implementation applies a weighted formula:
60% based on visited nodes
40% based on completed interactables
5. Infrastructure & Operations
Dependencies
Supabase for persistence
Learner authentication middleware
Quest canvas metadata from the quest record
Monitoring & Alerting
Errors are logged in the API route and surfaced through the client as error responses.
No dedicated monitoring or alerting pipeline is currently implemented specifically for save-state.
Deployment Plan
No database migration is required for the current implementation.
Deploy the learner API routes and the progress hook together.
Validate resume behavior on a test learner account and ensure the persisted state updates correctly.
6. Testing & Quality Assurance
Test Strategy
Manual verification that progress updates after visiting nodes
Manual verification that progress is restored on reload or return
Validation that legacy progress structures still normalize correctly
Known Limitations
Save-state is tied to activity events and not to background or offline behavior.
The feature is currently scoped to the learner progress payload and does not cover richer analytics or event replay.
7. Maintenance & Support
Troubleshooting
No progress appears saved: Confirm the learner has an enrollment record and the update endpoint is returning success.
Progress percentage seems incorrect: Review the quest’s canvas metadata and the interactable node types.
Node is rejected as invalid: Check whether the node ID exists in the quest canvas and is not archived.
Changelog
1.0 - Under Review: Initial save-state implementation for learner progress persistence, July 2026.