Author: James Derick Billate
Reviewer:
Creation Date: April 7, 2026
Status: Draft
References:
INTRODUCTION & GOALS
Problem Summary: This feature primarily focuses on the export (Deliver) functionality of WyzQuests. It allows the Creators to share their created quests to various Learners without the need for creating or signing-in to the application. Specifically making the quest publicly interactive. Particularly for embed, It allows the Creators to insert their quest on their respective LMS or websites. This is by delivering a pre-generated customizable by size <iframe/> to make the quest running from various browsers.
Goals & Non-Goals: The public share provided gives access to all quest details, but saving it requires logging in to the application. Additionally, there will be pre-generated hashed identification, encapsulating the quest details to a combination of strings. For embed, it can run concurrently with other websites by attachment of the code to the website itself.
On the Creator side, they will be able to revoke (pause), apply and extend expiration, and delete the generated link. It will also offer limited and simple analytics, including viewer and completer count, completer average, and device information of viewers. However, the Creator does not have the ability to customize the hash, the link itself, and know the quest activities of Learners from this generated link.
HIGH-LEVEL ARCHITECTURE
System Diagram:
Public Share Link

Public Share Embed
Technologies Used: Clerk Authentication, Typescript, Next.js, Postgres (Supabase) and Tailwind CSS
DETAILED DESIGN & IMPLEMENTATION
Schema:
Public Share
create table public.public_share ( quest_id uuid not null, hash text not null, created_at timestamp with time zone not null default now(), expires_at timestamp with time zone null, is_live boolean not null default true, revoked_at timestamp with time zone null, type text not null default 'link'::text, constraint share_links_pkey primary key (hash), constraint share_links_quest_id_fkey foreign KEY (quest_id) references quests (id) on delete CASCADE) TABLESPACE pg_default; create index IF not exists idx_share_links_quest_id on public.public_share using btree (quest_id) TABLESPACE pg_default;
Analytics
create table public.public_share_analytics ( hash text not null, view_count integer not null default 0, completer_count integer not null default 0, devices jsonb null, constraint share_link_analytics_pkey primary key (hash), constraint public_share_analytics_hash_fkey foreign KEY (hash) references public_share (hash) on delete CASCADE) TABLESPACE pg_default;
API Specification:
POST /api/creator/public-share/generate/Creating the public share with pre-generated hash
GET /api/creator/public-share/get/GET /api/creator/public-share/view/Fetching both the public share and the quest connected to the hashed id
GET /api/creator/public-share/analytics/updateRetrieving public share analytics
DELETE /api/creator/public-share/delete/Destroying current public share
PATCH /api/creator/public-share/live/PATCH /api/creator/public-share/update/Changing the values e.g. live, expiration
Share Player
/share/[hash]
Core Logic & Workflow:
Selecting specific quest
Initiate “Share” option, choosing “Link” or “Embed” type
Setting day, sending request for creation (for link type)
Generation of Hash
Assignment of Hash to the Quest
Fetching share details
Display share details
const generateRandomHash = (length = 15) => { const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; const array = new Uint8Array(length); crypto.getRandomValues(array); // secure random bytes return Array.from(array, (byte) => chars[byte % chars.length]).join(""); };
const { data: shareData, error: linkError } = await supabase .from("public_share") .insert({ quest_id: quest_id!, hash: generateRandomHash(), created_at: new Date().toISOString(), expires_at: expiration_date, type: type, }) .select() .single();
const { data, error } = await supabase .from("public_share") .select( `hash, created_at, expires_at, is_live, revoked_at, public_share_analytics (view_count, completer_count, devices)`, ) .eq("quest_id", quest_id) .eq("type", type) .single(); if (error || !data) { return ApiResponseHelper.notFound("No share links found"); }
INFRASTRUCTURE & OPERATIONS
Dependencies: [1.1] Project Creation
Monitoring & Alerting: To be indicated after further testing. No prior documentation regarding this matter
Deployment Plan:
Ensure that all variables have their specific ZOD validation configuration and Typescript initialization.
Ensure that the staging or production domain is using SSL Certificate to ensure HTTPS connection for the usage of copy-to-clipboard and embed to HTTPS hosted sites.
TESTING & QUALITY ASSURANCE
Testing Strategy:
Ensure that both public share and its analytics is present in the database.
Check all queries from the indicated APIs, ensuring that the columns exists.
If a link wasn’t able to be retrieved, check first if duplication exists.
For expiration date, manually indicate date via database for testing only.
Validating if the correct quest was displayed through the link, nonetheless, check if the quest is existing, expired/deleted/archived, and or does not have share link access due to revocation or expiration.
Known Limitations:
For “Link”, Limitation of 100 users, concurrently on accessing the public share link.
Saving progress of Learners by logging in feature.
MAINTENANCE & SUPPORT
Troubleshooting:
For in case, in fetching quests. Check first there are ZOD validation, regex expression errors. Nonetheless, check the quest if its existing on the database.
Changelog: No prior historical record were documented, neither in Github or via workspace. If such evidence arise during the testing process, necessary additions to this document must be indicated.
Document version:
1.0 - Draft, Feature already exists on dev server, 04/07/2026
1.1 - Draft, Combined technical documentation for both link and embed type, 04/10/2026