Author: James Derick Billate
Reviewer: Krizha Onise Cortez
Creation Date: July 6, 2026
Status: Published
References: https://github.com/wyzlab/WyzQuests/issues/78
INTRODUCTION AND GOALS
Problem Summary: Allows the learner to navigate their progress across quests. For them to know locked and unlocked nodes as they continue to develop their learning path from these contents. Additionally, it bridges gamification to their overall experience in these quest content
Goals and Non-Goals: Learners will have the ability to check what particular number (similar to book page) to where they at right now. They also have the source to check what achievements (badges) they have gathered while progressing in the quest.
HIGH-LEVEL ARCHITECTURE
System Diagram
Technologies Used:
Frontend: Next.js, Tailwind CSS and Shadcn Components
Backend: RESTful APIs, Typscript, ZOD Validation, Clerk and Supabase
DETAILED DESIGN AND IMPLEMENTATION
Schema:
The quests can be navigated via these APIs /api/learner/update-progress and /api/learner/get-enrollment which are connected to Save State and Enrollment module of WyzQuests.
Learner Global Stats: this table stores relevant learner details such as number of completed courses, completed chapters, completed lessons, product purchases, community posts and community interactions. Where it is automatic once learner state of progress updates via hardcode in API specification.
This table also is connected to Global Gamification’s trigger.
create table public.learner_global_stats ( user_id uuid not null, xp_rewards integer null default 0, completed_courses integer null default 0, completed_chapters integer null default 0, completed_lessons integer null default 0, product_purchases integer null default 0, community_posts integer null default 0, community_interactions integer null default 0, created_at timestamp without time zone null default CURRENT_TIMESTAMP, updated_at timestamp without time zone null default CURRENT_TIMESTAMP, current_rank integer null default 0, previous_rank integer null default 0, badge_triggers jsonb null default '[]'::jsonb, constraint learner_global_stats_pkey primary key (user_id), constraint learner_global_stats_user_id_fkey foreign KEY (user_id) references app_users (id) on delete CASCADE, constraint learner_global_stats_completed_chapters_check check ((completed_chapters >= 0)), constraint learner_global_stats_completed_courses_check check ((completed_courses >= 0)), constraint learner_global_stats_completed_lessons_check check ((completed_lessons >= 0)), constraint learner_global_stats_current_rank_check check ((current_rank >= 0)), constraint learner_global_stats_previous_rank_check check ((previous_rank >= 0)), constraint learner_global_stats_product_purchases_check check ((product_purchases >= 0)), constraint learner_global_stats_community_interactions_check check ((community_interactions >= 0)), constraint learner_global_stats_xp_rewards_check check ((xp_rewards >= 0)), constraint learner_global_stats_community_posts_check check ((community_posts >= 0))) TABLESPACE pg_default; create index IF not exists idx_learner_global_current_rank on public.learner_global_stats using btree (current_rank desc) TABLESPACE pg_default; create index IF not exists idx_learner_global_stats_xp on public.learner_global_stats using btree (xp_rewards desc) TABLESPACE pg_default; create index IF not exists idx_learner_global_stats_courses on public.learner_global_stats using btree (completed_courses desc) TABLESPACE pg_default; create trigger trigger_update_learner_global_stats_updated_at BEFOREupdate on learner_global_stats for EACH rowexecute FUNCTION update_global_gamification_updated_at ();
Learner Achievements: this table stores the acquired achievements (badges) which corresponds to specific trigger that is connected to a learner stats. It has the information of locked and unlocked which will be reflected in learner view.
create table public.learner_achievements ( user_id uuid not null, achievement_id uuid not null, progress integer null default 0, unlocked_at timestamp without time zone null, is_quest boolean null default false, created_at timestamp without time zone null default CURRENT_TIMESTAMP, updated_at timestamp without time zone null default CURRENT_TIMESTAMP, constraint learner_achievements_pkey primary key (user_id, achievement_id), constraint learner_achievements_achievement_id_fkey foreign KEY (achievement_id) references global_achievements (id), constraint learner_achievements_user_id_fkey foreign KEY (user_id) references app_users (id) on delete CASCADE, constraint learner_achievements_progress_check check ( ( (progress >= 0) and (progress <= 100) ) )) TABLESPACE pg_default; create index IF not exists idx_learner_achievements_user on public.learner_achievements using btree (user_id) TABLESPACE pg_default; create index IF not exists idx_learner_achievements_achievement on public.learner_achievements using btree (achievement_id) TABLESPACE pg_default; create index IF not exists idx_learner_achievements_unlocked on public.learner_achievements using btree (unlocked_at desc) TABLESPACE pg_defaultwhere (unlocked_at is not null); create index IF not exists idx_learner_achievements_quest on public.learner_achievements using btree (is_quest) TABLESPACE pg_default; create trigger trigger_update_learner_achievements_updated_at BEFOREupdate on learner_achievements for EACH rowexecute FUNCTION update_global_gamification_updated_at ();
API Specification:
POST /api/learner/achievements/progress
Updates learner's achievement progress
| |
|---|---|
Status | Return |
401 | Unauthorized |
400 (Null body) | Missing required fields |
400 (Incorrect input) | Progress must be between 0 and 100 |
404 (Validate User) | User not found |
500 |
|
200 OK | Data: user_id, achievement_id |
GET /api/learner/achievements
Retrieves all achievements for the authenticated user
| |
|---|---|
Status | Return |
401 | Unauthorized |
500 (Fetching Achievements) | Failed to fetch achievements with |
200 OK | Data: all details of |
POST /api/learner/achievements
Creates or updates an achievement progress for the authenticated user
| |
|---|---|
Status | Return |
401 | Unauthorized |
400 (Missing fields) | Missing required fields: achievement_id, progress, is_quest |
400 (Incorrect range) | Progress must be between 0 and 100 |
500 (Update | Failed to update achievement |
500 (Create) | Failed to create achievement |
200 OK (Update) | Achievement updated successfully |
200 OK (Create) | Achievement created successfully |
GET /api/learner/global-stats
Fetches the current user's global statistics
Status | Return |
401 | Unauthorized |
404 (User Validation) | User not found |
200 OK (Stats Does not Exist) | Learner stats into 0 |
500 |
|
200 OK | Data: user_id, xp_rewards, completed_courses, completed_chapters, completed_lessons, product_purchases, community_posts, community_interactions |
PATCH /api/learner/global-stats
Updates specific learner's global statistics
| |
|---|---|
Status | Return |
401 | Unauthorized |
404 (User Validation) | User not found |
404 (No stat record) | Learner stats not found |
500 |
|
200 OK | All columns of |
POST /api/learner/global-stats
Updates specific learner's global statistics
| |
|---|---|
Status | Return |
401 | Unauthorized |
404 (User Validation) | User not found |
404 (No stat record) | Learner stats not found |
500 |
|
200 OK | All columns of |
GET /api/learner/leaderboard
Fetches all global achievements with learner's progress
| |
|---|---|
Status | Return |
401 | Unauthorized |
500 |
|
200 OK | All columns of |
Core Logic and Workflow:
Must be a learner in WyzQuests
This learner must be able to interact within the application to either a quest, community or various products.
Via backend with the APIs listed about, it automatically assigned the progress and achievement.
The process of update continue, but whenever the trigger to an achievement is met to 100% then comparison to that badge halts.
INFRASTRUCTURE AND OPERATIONS
Dependencies: No known major dependencies other than ZOD validation to ensure data inputs and returns are correct and accurate
Monitoring and Alerting:
Check via database its egress to ensure that gamification does not take much of the processed data.
Other than that, alert notification will be sent whenever internal services do not provide accurate returns or have an error.
Deployment Plan:
Ensure that tables
learner_global_statsandlearner_achievementsare migrated to the main database.Ensure that all APIs are configured and is directed only to learners. Logged out users (via share or SCORM) must not bypass these APIs.
TESTING AND QUALITY ASSURANCE
Testing Strategy:
Navigate in learner view all possible actions, from quest, purchases and community
Multiple learners must act in completing quests to test leaderboard for XP comparison
Known Limitations:
Not all badges are implemented yet within the system
Per node XP is not implemented for further XP configuration
MAINTENANCE AND SUPPORT
Ensure that via Admin there are specified triggers and badges configured connected to learner stats to process achievement whenever learners navigate the application.
Document Version
1.0 - Draft, Feature pushed but in need for further development 07/06/2026