Export Data

Author: James Derick Billate
Reviewer: Jethro Lagmay and Sean Patrick Caintic
Creation Date: June 29, 2026
Status: Published
References: https://github.com/wyzlab/WyzQuests/issues/49

INTRODUCTION AND GOALS

Problem Summary: Agency Admins need to export agency team and learner dashboard data for reporting. The current feature supports CSV generation from the Agency Team and Agency Learners pages using already-loaded dashboard data.

Goals and Non-Goals: The goal is to allow Agency Owners/Admins to view and export member and learner progress data in CSV format. The feature should support reporting for creators, reviewers, learners, and learner quest progress. The feature does not provide PDF export, scheduled reports, cross-agency reports, login history, or deeper business intelligence dashboards.


HIGH-LEVEL ARCHITECTURE

System Diagram:

Technologies Used:

Frontend: Next.js App Router, React client components, Tailwind CSS, Shadcn UI components, Sonner toast, Lucide icons, PapaParse.

Backend: RESTful API routes, TypeScript, Clerk authentication, agency authorization helpers, Supabase queries, standardized API responses.

Storage/Database: Supabase Postgres tables for agencies, agency_members, app_users, quests, public_share, and quest_enrollments.

External Services: Clerk for authentication and user identity.


DETAILED DESIGN AND IMPLEMENTATION

Schema:

Export Data does not create a dedicated export table. It reads from existing agency, user, quest, and enrollment data. CSV files are generated from in-memory frontend data.

Relevant data sources:

agencies: Stores agency ID, name, plan, owner Clerk ID, and monthly token budget.

agency_members: Stores agency member role, status, invited email, user Clerk ID, and token limit.

app_users: Provides display name, email, platform role, app user ID, and Clerk ID.

quests: Provides creator-owned quest data for agency creator analytics.

public_share: Used to identify shared quests for creator analytics.

quest_enrollments: Provides learner enrollment and progress data.

API Specification:

GET /api/agency/status
Checks the authenticated user's agency membership, ownership, effective role, and agency info.

Body: NONE

Status

Return

401

Unauthorized

500

Failed to check membership or fetch agency info

200 OK

Data: isMember, isOwner, platformRole, platformRoles, effectiveRole, isViewingAsOther, agency, membership

GET /api/agency/team/list
Fetches agency details, agency members, enriched display names/platform roles, creator quest analytics, and current user Clerk ID.

Body: NONE

Status

Return

401

Unauthorized

403

Forbidden when user is not an Agency Owner/Admin

404

Agency not found

500

Failed to fetch members

200 OK

Data: agency, members, quests, currentUserClerkId

GET /api/agency/learners
Fetches learners connected to agency-created quests and includes their enrolled quest progress.

Body: NONE

Status

Return

401

Unauthorized

403

Forbidden when user is not an Agency Owner/Admin

404

Agency not found

500

Failed to fetch members, quests, enrollments, or learners

200 OK

Data: agency, learners, currentUserClerkId

POST /api/agency/team/claim
Best-effort endpoint called before loading agency pages to claim pending invites for the current user.

Body: NONE

Status

Return

401

Unauthorized

200 OK

Invite claim result or no-op response

Client CSV Generation:

Team export uses Papa.unparse on agency member data after removing internal fields such as agency_id, created_at, user_clerk_id, platform_role, and isCurrentUser.

Learner export uses Papa.unparse on a flattened learner quest dataset:

  • learner_id

  • learner_name

  • quest_title

  • percentage

  • last_visited_at

Core Logic and Workflow:

  • Agency page calls /api/agency/status to determine whether the user can manage agency data.

  • Team page calls /api/agency/team/list and stores agency, members, and quest analytics data.

  • Learners page calls /api/agency/learners and stores agency and learner quest progress data.

  • Admin clicks Export Team Data or Export Learner Data.

  • Frontend maps the loaded dataset into an export-safe shape.

  • PapaParse converts the mapped data into CSV.

  • Browser creates a Blob object URL and downloads the CSV using an agency-name filename.

  • Success or failure is shown through toast feedback.


INFRASTRUCTURE AND OPERATIONS

Dependencies: Clerk Authentication, Supabase Database, agency authorization helpers, PapaParse, Agency Team dashboard, Agency Learners dashboard, standardized API response helper.

Monitoring and Alerting:

  • Monitor API errors from /api/agency/team/list and /api/agency/learners.

  • Monitor Supabase query failures for agency members, app users, quests, and enrollments.

  • Check browser/client errors for CSV generation and file download failures.

Deployment Plan:

  • Ensure agency membership and agency ownership authorization is configured.

  • Ensure agency team and learner APIs return only scoped agency data.

  • Ensure PapaParse is installed and bundled with the frontend.

  • Validate CSV export behavior in common browsers.


TESTING AND QUALITY ASSURANCE

Testing Strategy:

  • Sign in as Agency Owner and export Team CSV.

  • Sign in as Agency Owner and export Learner CSV.

  • Verify non-owner/non-admin agency member cannot access export pages.

  • Verify CSV filename sanitizes agency name spaces and special characters.

  • Verify exported team CSV excludes internal fields.

  • Verify exported learner CSV flattens multiple quests per learner into separate rows.

  • Verify no-agency, no-member, and no-learner states do not crash export pages.

Known Limitations:

  • CSV generation is currently client-side and depends on already-loaded dashboard data.

  • There is no dedicated backend route such as /api/agency/admin/export-csv.

  • Large agencies may generate heavy client-side CSV files.

  • Export does not currently support date range filters.

  • Export does not currently support PDF or scheduled delivery.


MAINTENANCE AND SUPPORT

  • Maintain CSV field mapping whenever agency member, learner, quest, or enrollment response shapes change.

  • Review exported fields before adding sensitive data such as private IDs, emails, or internal role metadata.

  • If export volume grows, move CSV generation to a backend route with streaming or paginated export.

  • Ensure future analytics changes remain scoped by agency authorization rules.


Document Version

1.0 - Draft, feature enhanced from current hand-off documentation 07/07/2026

1.1 - Draft, enhancement of documentation 07/09/2026

1.2 - Draft, minor enhancements 07/14/2026




Was this article helpful?