Skip to content

feat(packages/export): add @klicker-uzh/export package for assessment course data export#5043

Draft
rschlaefli wants to merge 7 commits intov3from
export-assessment-course
Draft

feat(packages/export): add @klicker-uzh/export package for assessment course data export#5043
rschlaefli wants to merge 7 commits intov3from
export-assessment-course

Conversation

@rschlaefli
Copy link
Copy Markdown
Member

@rschlaefli rschlaefli commented Mar 22, 2026

Summary

  • New packages/export/ package for exporting assessment course data to CSV + XLSX
  • Exports LiveQuiz responses, participants, invitations, and applied point corrections for a given course
  • CLI script supports multiple --courseId flags for batch export with combined XLSX workbook
  • Zero-dep RFC 4180 CSV writer + exceljs for XLSX workbooks with named sheets
  • Read-only Prisma client guard (ReadonlyPrismaClient) with both compile-time type narrowing and runtime $extends write blocking

Output structure

<outputDir>/
  <courseName>_<courseId>/
    export.xlsx              # single workbook with 4 sheets (RESPONSES, PARTICIPANTS, INVITATIONS, CORRECTIONS)
    responses.csv
    participants.csv
    invitations.csv
    corrections.csv
  combined-export.xlsx       # only when multiple courses are exported

Exported sheets

Sheet Key columns Join key
RESPONSES participantId, email, elementInstanceId, elementType, elementName, liveQuizName, correctness, points, ... participantId → PARTICIPANTS
PARTICIPANTS participantId, email, participationIsActive, ssoType, ssoId, ssoEmail, ... participantId (primary)
INVITATIONS email, matriculationNumber, status, invitedAt, acceptedAt, participantId participantId → PARTICIPANTS
CORRECTIONS correctionId, participantId, email, liveQuizName, elementName, type, reason, awarded/deducted points, ... participantId → PARTICIPANTS, elementInstanceId → RESPONSES

Usage

# Single course
pnpm --filter @klicker-uzh/export export -- --courseId <uuid>

# Multiple courses with combined workbook
pnpm --filter @klicker-uzh/export export -- --courseId <uuid1> --courseId <uuid2> [--outputDir <path>]

# With Infisical for production
./util/_run_with_infisical.sh --env prd bash -c 'pnpm --filter @klicker-uzh/export export -- --courseId <uuid>'

Safety

  • ReadonlyPrismaClient type excludes all write methods at compile time
  • Runtime $extends guard via $allOperations interceptor blocks any non-read operation
  • All queries are strictly read-only (findMany, findUniqueOrThrow)
  • Export output directory is gitignored (contains PII)

Test plan

  • pnpm --filter @klicker-uzh/export check passes
  • Pre-commit hooks pass (typecheck, prettier, syncpack across full monorepo)
  • Run against production DB for 7 SSP medical faculty assessment courses
  • CSV structural validation (0 bad rows across all courses, verified with Python csv module)
  • Combined XLSX workbook generated with 28 sheets (4 per course × 7 courses)

… course data export

New package for exporting assessment course data (LiveQuiz responses,
participants, invitations) to CSV and XLSX formats. Includes a CLI
script for manual execution and a barrel export for future backend
integration.
- Move @klicker-uzh/types to devDependencies (type-only imports)
- Add \r handling to CSV escaping per RFC 4180
- Add truncation indicator (...) for elementContent column
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 22, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 125b30d4-a9bd-4a9c-b3f6-33b429193e4b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

…ections sheet, and column refinements

- Add ReadonlyPrismaClient type + runtime $extends guard to block all write operations
- Support multiple --courseId flags for batch export with combined XLSX workbook
- Add CORRECTIONS sheet (AppliedPointCorrection data with point correction details)
- Remove unnecessary columns: username, blockId, blockOrder, timeSpent, createdAt (responses),
  username/isActive/isSSOAccount/participationId (participants), participantUsername (invitations)
- Rename sheets to uppercase (RESPONSES, PARTICIPANTS, INVITATIONS, CORRECTIONS)
- Sanitize Excel sheet names to avoid illegal characters (e.g. /)
- Add .gitignore for export-output directory (contains PII)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant