Feature Owner: Joshua Uriel Tribiana
Module: Learner Progress Persistence
Priority: P1
Status: Completed and merged in the codebase (JD Billate)
Date: 07-01-2026
EXECUTIVE SUMMARY
What is this feature?
Save State is the learner progress persistence layer that records which quest nodes a learner has visited and how far they have progressed through the quest. It allows a learner to resume later without restarting the experience.
Why does it matter?
Without reliable save-state behavior, learners can lose continuity, and the app cannot accurately reflect progress or support resume flows. This feature is central to the learner experience and quest completion tracking.
What’s in scope today?
Saving visited nodes and location during learner interaction
Returning normalized progress data for a learner’s enrollment
Computing a progress percentage based on both visited nodes and completed interactable nodes
Supporting resume behavior through the learner progress hook
1. USER PAIN POINT & SOLUTION
Current State (Without Feature)
Learners who leave and come back to a quest would not have a reliable mechanism to preserve where they left off, which creates friction and weakens continuity.
Pain Point
Emotional: Frustration when progress appears lost or inconsistent
Functional: No reliable persistence of ongoing quest progress
Business Impact: Lower completion rates and weaker learner trust in the platform
Future State (With Feature)
Learners can resume a quest and the system will preserve their visited nodes, current location, and progress percentage.
Product Angle
“Keep every learner’s journey intact so they can pause and continue without losing momentum.”
2. CODEBASE ASSESSMENT
Current Implementation Status
The save-state feature is implemented through a learner API and a hook that updates progress during interaction.
Primary Files
hooks/quest/useQuestProgress.ts
Learner-side hook that initializes progress state and reports visited nodes to the backend
app/api/learner/update-progress/route.ts
Server-side endpoint that validates the request, confirms enrollment, and writes updated progress data
app/api/learner/get-enrollment/route.ts
Reads the learner’s current progress state for a quest and normalizes it into a consistent shape
Current Behavior Summary
The hook loads the learner’s existing enrollment from the backend
When a node is visited, the app sends progress updates to the server
Progress is stored in the
quest_enrollments.progressJSON payloadThe system tracks:
percentagevisited_cardslast_visited_atlocation
Strengths Already Present
Progress updates are tied to actual learner activity
The API normalizes both old and new progress formats
The learner hook centralizes state hydration and updates
Gaps / Hardening Opportunities
The feature currently relies on the learner interacting with nodes to update progress
There is no explicit background sync or offline queue mechanism
Progress computation is based on the current quest canvas metadata and interactable types
3. 4D FRAMEWORK MAPPING
Diagnose
Learners need a reliable way to resume their path through a quest without losing progress.
Design
Persist progress as part of the learner’s enrollment record and update it as the learner interacts with nodes.
Develop
The frontend hook sends progress updates when a node is visited; the backend writes the new state to the database.
Deliver
Learners can pause and continue with their progress preserved.
4. USER FLOWS
Entry Point
A learner opens a quest and begins progressing through nodes.
Success Criteria
The learner’s progress state is persisted
Returning to the quest shows the learner’s prior location and progress
The progress values reflect recent learner activity
Happy Path
Learner opens a quest
The app loads the learner’s current enrollment progress
The learner visits a node
The client sends a progress update
The backend writes the updated progress to the enrollment record
The learner can resume later and see their last saved state
Edge Cases
New learner with no existing progress → default zeroed state
Legacy progress format → normalized into current structure
Enrollment not found → error returned
Decision Points
If the learner has visited a node before → the state is updated without duplicating the visited node
If the node is not in the canvas metadata → the request is rejected with a not-found response
5. INFORMATION ARCHITECTURE
Primary Information
Quest ID
Enrollment ID
Visited node IDs
Last visited timestamp
Current location
Progress percentage
Actions
Primary CTA:
Continue quest
Secondary System Actions:
Save visited node
Rehydrate saved state
State Changes
Visited nodes are appended if new
Percentage is recalculated using the current quest canvas structure
Last visited timestamp is updated
6. WIREFRAMES
The save-state experience is invisible to the learner but critical in the background. The visible experience is the resumed quest state and progress percentage.
Key Surface:
Learner’s resumed quest flow and progress display
Annotations:
Resume behavior uses previously saved progress rather than resetting the learner
7. WIREFLOWS
Learner visits node → progress update triggers → backend saves state → learner resumes with same progress context
8. PROTOTYPE
Figma Prototype Link: Not currently available
How to test:
Open a quest as a learner
Visit one or more nodes
Refresh or return later
Confirm the quest resumes with the saved progress state
9. DATA MODEL
Core Table
The feature writes to the quest_enrollments table.
Progress Payload Shape
The primary save-state payload contains:
percentagevisited_cardslast_visited_atlocation
Relationship
The save-state record is linked to the learner enrollment row for the selected quest.
10. API CONTRACTS
Read Enrollment Progress
Endpoint: GET /api/learner/get-enrollment?quest_id={questId}
Behavior:
Authenticates the learner
Retrieves the current enrollment and its progress payload
Normalizes the response into a standard structure
Save / Update Progress
Endpoint: POST /api/learner/update-progress
Request:
{ "quest_id": "uuid", "node_id": "node-id", "location": "optional-location"}
Behavior:
Validates the request
Verifies the learner is enrolled in that quest
Validates the node against the quest canvas metadata
Updates the visited-node list and percentage
Saves the new progress payload
11. DATA REQUIREMENTS
Frontend Needs
The current quest ID
The learner’s enrollment ID
The learner’s saved progress state to resume correctly
Backend Needs
A valid enrollment for the learner and quest
Canvas metadata for the quest to validate visited nodes and compute progress
Who can access this feature?
Learner: ✓
Creator: ✗
Reviewer: ✗
The learner must be authenticated and must already be enrolled in the quest before progress can be updated or retrieved.
13. ERROR HANDLING
Common Errors
Missing quest ID or node ID
Enrollment not found
Quest not found
Node not found in canvas metadata
Database update failure
Handling Guidance
Return clean validation errors for the client
Avoid exposing internal database failures to the learner where not necessary
14. TESTING CHECKLIST
Happy Path
Learner progress is saved after visiting a node
Progress can be reloaded on a later session
Percentage updates based on the quest’s current canvas state
Edge Cases
New learner with no prior progress gets a default state
Legacy progress data is normalized correctly
Invalid node IDs are rejected
15. OPEN QUESTIONS
For Product
Should save-state also capture more granular interaction events beyond visited nodes?
Should there be a visible “resume from last step” prompt?
For Engineering
Should long-lived offline or background sync be introduced later?
Should progress calculation be made more deterministic with explicit quest metadata?
16. OUT OF SCOPE
Not currently implemented:
Offline progress sync
Multi-device conflict resolution
Full audit logging of all progress events
17. SUCCESS METRICS
How will we know this feature is working well?
Learners reliably resume quests from the latest saved state
Progress displayed in the app reflects the learner’s actual activity
Fewer support issues arise from progress loss or inconsistency
18. DEPENDENCIES
This feature depends on:
Learner authentication
Enrollment records in
quest_enrollmentsQuest canvas metadata from the quest record
This feature supports:
Resume flows
Progress visualization
Quest completion tracking
19. TIMELINE & OWNERSHIP
Implementation Ownership
owner: Joshua Uriel Tribiana
QA: JD Billate