1. Front Matter
Title: Creator Quest Card Background Audio
Author: Joshua Uriel Tribiana
Handover To: Patrick Babala
Created: July 2026
Status: Handover
References:
Feature: [1.7.2] (Creator) Add audio feature in each Quest Card
Core implementation files:
2. Introduction & Goals
Problem Summary
Creators need per-card audio support for narration, ambience, and guided content. The feature adds a reusable audio upload UI across quest card editors and persists audio URL in each card’s content payload.
Goals
Allow creators to upload background audio per quest content card.
Persist card-level
audio_urlin card content JSON.Provide immediate in-editor preview and remove action.
Ensure learner renderers can consume
audio_urlfor playback.
Non-Goals
Global quest-level audio replacement (already a separate media feature).
Audio editing/mixing/transcoding pipeline.
Server-managed streaming/DRM features.
Glossary
Card Audio: Background audio file tied to an individual quest content card.
audio_url: Content JSON field storing the public URL for card audio.
Primary Upload Field: Existing upload path for
link-based media uploads.Audio Upload Field: Upload mode that writes
audio_urlinstead oflink.
3. High-Level Architecture
System Diagram
+----------------------+| Creator Form Editor |+----------------------+ | v+----------------------+| CardAudioUpload |+----------------------+ | v+----------------------+| useQuestFileUpload |+----------------------+ | v+------------------------------------------------------+| POST /api/creator/quest-content-cards/upload-media |+------------------------------------------------------+ | +----+----+ | | | | v v+-------------------------------+ +--------------------------------------+| Supabase Storage | | quest_content_cards.content.audio_url || public-assets | +--------------------------------------++-------------------------------+ | v +-------------------------------+ | Immediate local state update | +-------------------------------+ | v +------------------------------------------------------+ | PUT /api/creator/quest-content-cards/update | +------------------------------------------------------+ | v +--------------------------------------+ | Learner renderers consume audio_url | +--------------------------------------+
Technologies Used
Next.js App Router (client + API routes)
Supabase Storage for file upload
Supabase Postgres JSON content persistence (
quest_content_cards.content)React hooks for upload state and immediate UI feedback
4. Detailed Design & Implementation
Data Model / Schema
QuestContentCard.content includes optional audio field:
audio_url?: string
Defined in types/quest-content-cards.d.ts.
Creator UI Integration
The shared CardAudioUpload component is wired into multiple card editors inside app/quest-editor/[questID]/(sections)/content/form-editor/page.tsx, including:
Discussion card
Text card
Image card
Video card
File card
Link card
Codeblock card
Behavior in CardAudioUpload:
Accepts
audio/*files.Enforces 10MB client-side file size limit.
Uploads using
uploadField = "audio_url".On success, applies
onUpdate({ audio_url: result.link }).Supports remove action via
onUpdate({ audio_url: undefined }).Displays audio preview player when
audio_urlexists.
Upload Hook
useQuestFileUpload in form editor:
Builds
FormDatawithfile,quest_id,card_type,card_id,upload_field.Calls
POST /api/creator/quest-content-cards/upload-media.Returns normalized URL from
linkorfile_url.
Backend Upload Route
In app/api/creator/quest-content-cards/upload-media/route.ts:
Validates required fields.
Validates
card_typeagainst allowed set.Verifies quest ownership and agency scope.
Uploads file to storage path:
quests/{quest_id}/content-cards/{card_id}/content.{ext}
If
upload_field === "audio_url", updates card content with:audio_url: publicUrl
Returns
success,file_url,file_path,link,card.
Save/Persist Behavior in Editor
In form editor, handleUpdateCardContent updates local editing state and card list state immediately. When updates include audio_url, it triggers immediate persistence via updateContentCard(...) so audio changes are saved without waiting for full modal save.
Learner Consumption
Learner card renderers consume card.content.audio_url and auto-play looped audio where supported (for example activity and content-card renderers), confirming end-to-end path from creator upload to learner playback.
5. Infrastructure & Operations
Dependencies
quest_content_cardstable with JSON content payload.Supabase Storage bucket
public-assets.Agency ownership auth helpers for creator authorization.
Monitoring & Alerting
Current behavior is log + toast driven:
Upload and API failures are logged via
console.error.Creator UI shows toast success/error feedback.
No dedicated metric stream exists yet for audio upload success/failure rate.
Deployment Plan
Verify storage bucket access and public URL generation.
Verify agency/ownership checks in creator routes.
Validate upload + immediate save on each supported card type.
Validate learner playback for cards with
audio_url.
6. Testing & Quality Assurance
Test Strategy
Unit/integration tests:
Upload route success/failure paths.
Ownership rejection cases.
upload_field = audio_urlbranch behavior.
UI tests:
Audio tab visible on supported card editors.
10MB validation error handling.
Remove audio action clears preview and persists.
End-to-end tests:
Upload in creator form editor.
Reload content cards and confirm persisted
audio_url.Open learner view and confirm playback.
Known Limitations
10MB audio limit is currently client-side; no explicit server-side size guard in upload route.
Upload route cleanup logic targets
content.linkcleanup and does not explicitly clean replacedaudio_urlobjects.File path naming (
content.{ext}) may overwrite previous uploads per card, which is acceptable for replacement but should be documented.
7. Maintenance & Support
Troubleshooting
Upload fails immediately: Check missing form fields or invalid card type payload.
Upload succeeds but no playback: Verify
audio_urlsaved in card content and reachable public URL.Audio removed in UI but returns after refresh: Confirm immediate
updateContentCardsucceeded and route returned 200.Permission errors: Verify creator ownership and agency membership context.
Handover Tasks for Patrick Babala
Add explicit server-side validation for audio MIME and max file size.
Add cleanup strategy for replaced
audio_urlfiles to avoid orphaned storage objects.Add automated coverage for immediate
audio_urlpersistence branch.Verify all intended quest card editors include
CardAudioUploadin Week acceptance criteria.Add structured telemetry for upload failure categories.
Changelog
1.0 - Approved, Technical guide created for creator per-card audio feature.