Save State

1. Front Matter


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:

  • percentage

  • visited_cards

  • last_visited_at

  • location

Progress Normalization

The backend includes normalization logic for both legacy and current formats:

  • Legacy numeric progress values

  • Old completed_sections arrays

  • Current visited_cards format

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-progress

  • Auth: Required

  • Request Body:

{
"quest_id": "uuid",
"node_id": "node-id",
"location": "optional-location"
}

Logic & Workflow

  1. The learner opens a quest and the hook loads the existing enrollment state.

  2. When the learner visits a node, the hook calls the update-progress endpoint.

  3. The backend verifies the enrollment exists and the quest exists.

  4. The backend validates that the requested node exists in the quest’s canvas metadata.

  5. The backend appends the node to visited_cards if it is new.

  6. The backend recomputes the progress percentage based on visited nodes and completed interactables.

  7. 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.


Was this article helpful?