# Assessment and category question groups

Implemented locally on 19 October 2026. Production deployment and target Moodle acceptance are separate release checks.

## Authoring

New projects use assessment-group grading. Existing projects keep their course-wide legacy grading until the author chooses **Questions → Assessment settings → Scoring and completion → Enable assessment-group grading** and confirms the explanation. Enabling the mode does not automatically convert groups into assessments.

Use **Add group** or **Edit group settings** to choose:

- **Category (practice):** organizes questions without contributing to the grade.
- **Assessment:** independent submission, passing percentage, and one, limited (1–10), or unlimited attempts. Initial values come from course settings; later changes are independent.

The displayed assessment total sums effective question points, including group inheritance and individual overrides. All active included questions count, including optional questions. Skipping an optional question earns zero. Required questions must be answered before submission. Zero-point questions are allowed, but an assessment must have questions and a positive maximum grade to publish. Assessments on excluded slides and removed groups are inactive.

In the new mode, ungrouped questions are practice too. Answer-change and feedback settings for practice retain their existing behavior. Assessment answers can be edited until group submission; feedback becomes available after submission, respecting correct-answer and explanation visibility settings.

## Learner results and LMS reporting

Each assessment has a review/submission step after its questions. Learners see their latest grade, highest grade, percentage, pass/fail, attempt number, and retry availability. Retrying clears only that assessment's current answers. Other assessment results and slide/media/H5P progress remain intact.

The course grade combines highest earned points and total maximum points. All assessments must be submitted, and every assessment must pass its own threshold for the course to pass. A high combined percentage does not override a failed assessment. Existing slide/media/H5P completion gates still apply. Practice-only courses report completion without a numeric assessment grade.

SCORM 1.2 remains a single SCO:

- `cmi.core.score.raw/min/max`: combined highest earned points, zero, combined maximum.
- `cmi.objectives.n.id`: stable `assessment_g_<group tracking key>` identifier. Objective score and status are updated after submissions.
- Question interactions include the objective identifier and assessment attempt number; revisiting results or resuming does not resubmit an attempt.
- Independent attempt state and best points use compact `v5` resume data, compatible with the existing H5P wrapper. Earlier resume versions remain readable. The existing 4,096-character limit is enforced explicitly; submissions that exceed it are rejected before grade/interaction reporting.

Moodle's Objectives report can display objective scores/statuses; the normal gradebook remains one course grade. See [Moodle SCORM reports](https://docs.moodle.org/402/en/mod/scorm/report). Display and persistence in the target LMS must be verified before production acceptance. No full attempt-answer history is stored in suspend data; latest answers and highest grade are retained, with submitted question attempts sent as SCORM interactions.

## Deployment

Preserve `.env`, `APP_KEY`, the database, and private storage using the established deployment procedure. Publish matching backend, frontend, and player code. Before exposing the new code, apply this additive migration from the backend folder:

```bash
php artisan migrate --path=database/migrations/2026_10_19_120000_add_assessment_question_groups.php --force
```

It adds `conversions.question_grading_mode` (existing rows default to `legacy`), plus question-group `group_type` and `assessment_settings`. Application-created new projects default to `assessment_groups`. Omitted fields in older API requests preserve stored mode/type/settings. Group/slide duplication copies assessment settings and allocates new tracking identities.

Build the frontend, refresh the deployment's configuration cache as usual, and restart existing queue workers (`php artisan queue:restart`, plus the existing Supervisor process procedure where applicable). No dedicated assessment worker is needed. Rebuild SCORM packages that should adopt the new feature; existing ZIPs remain unchanged. Do not roll back the migration to disable the UI, because its down migration removes the added settings columns.

The migration was applied only to the verified local MySQL database `documents_generator_tools` at `127.0.0.1`. No production database was changed.

## Validation and release acceptance

Automated coverage includes legacy activation confirmation, stale revisions, omitted-field preservation, invalid settings, duplicate/remove/restore, positive-grade publishing, effective points, optional/skipped questions, independent retries, best grades, practice exclusion, stable objective reporting, compact resume/overflow, preview progression, and exported-player completion/resume without duplicated interactions.

A two-assessment ZIP is generated by `AssessmentQuestionGroupTest`. Setting `ASSESSMENT_QA_OUTPUT` to a temporary directory copies the test artifact there. Local acceptance artifacts are under `out/assessment-acceptance/` (not tracked).

Browser checks use disposable local fixtures built from the real components and generated package, without modifying production course data. Target Moodle acceptance remains required: import a regenerated two-assessment ZIP; check separate objective results and combined grade; fail one assessment despite a high combined score; retry one assessment; close/reopen the activity; verify resume, completion, interactions, and Arabic/RTL playback.

Local verification completed: production TypeScript/Vite build, 188 frontend tests, focused ESLint, PHP/JavaScript syntax, and diff checks passed. The full guarded in-memory SQLite backend suite passed 173 tests / 2,524 assertions with one renderer-dependent skip; the final focused quiz/assessment run passed 13 tests / 96 assertions. Local MySQL checks confirmed the new columns and all 19 pre-existing projects still in legacy mode. English desktop learner-result feedback and Arabic mobile group settings were visually inspected, with the mobile form reporting no horizontal overflow. Exported-runtime tests exercised two independent submissions, a failed course result, a single-assessment retry, a passed result, and resume without duplicated interactions.
