# Phase 9: Computer-Based Testing

## Completed work

- Tenant-scoped question banks with topic, difficulty, type, marks, negative marks,
  approval status, protected explanations, and encrypted non-option answer keys.
- Single/multiple choice, true/false, yes/no, fill-blank, short-answer, essay,
  matching, ordering, numerical, passage, image, audio, and case-study records.
- Examination configuration for type, schedule, duration, attempts, randomization,
  navigation, result release, late entry, access codes, IP allowlists, and device lock.
- Explicit candidate eligibility and accommodation time.
- High-entropy hashed attempt tokens with authenticated token rotation on recovery.
- One active attempt, maximum-attempt enforcement, server deadlines, question and
  option randomization, and persisted randomized attempt manifests.
- Versioned autosave, network/focus activity events, resumption after interruption,
  explicit submission, and scheduled server-side timeout submission.
- Objective marking, negative marking, manual marking, feedback, moderation, and
  controlled result release.
- Incident reporting and automatic flags after repeated focus/fullscreen-loss events.
- Candidate interface with countdown, navigation, save state, interruption logging,
  and sanitized question rendering.
- One seeded five-question examination with ten eligible demo candidates.

## Database changes

Migration `2026_07_30_160000_create_cbt_tables.php` adds:

- `question_banks`
- `questions`
- `question_options`
- `examinations`
- `examination_questions`
- `examination_candidates`
- `examination_attempts`
- `attempt_questions`
- `examination_answers`
- `examination_events`
- `examination_incidents`
- `examination_moderations`

Unique constraints protect option order, exam membership, eligibility, attempt
numbers, randomized manifests, and one current answer per attempt question.

## Security controls

- Candidate DTOs are allowlists and never contain correct flags, answer keys, marker
  explanations, or internal model serialization.
- Candidate question and option text is escaped before browser rendering.
- Numerical/non-option answers are encrypted at rest; model serialization hides
  protected answer fields and session hashes.
- Attempt tokens are random, stored only as SHA-256 hashes, bound to the authenticated
  student, and rotated during recovery.
- Optional device fingerprint locking, exact-IP allowlists, access-code hashing,
  one-active-session rules, and IP/user-agent evidence are enforced server-side.
- Timing uses the persisted server deadline; the browser timer is display-only.
- A scheduled `cbt:submit-expired` command closes abandoned attempts every minute.
- Autosave accepts only the active attempt's question IDs and candidate answer fields.
- Correctness and scoring are calculated only on the server.

## Operations

Production must run Laravel's scheduler:

```bash
php artisan schedule:run
```

from cron every minute, or use `php artisan schedule:work` under a supervised worker.

## Manual testing

1. Sign in as `admin@ecstu.test`, open **CBT Admin**, create/approve questions, create
   an examination, attach questions, publish, and add candidates.
2. Sign in as `student1@ecstu.test`, open **Examinations**, start the seeded CBT,
   answer questions, refresh/resume, disconnect/reconnect, and submit.
3. Sign in as the administrator, open **CBT Marking**, mark the essay, record
   feedback, moderate if authorized, and inspect incident/event evidence.
4. Run `php artisan cbt:submit-expired` to test the server timeout sweep.

## Honest limitations

- Webcam/audio proctoring and biometric identity checks are not claimed or simulated.
- Device fingerprints are advisory hashes supplied by the browser; high-assurance
  lockdown requires a managed secure-browser/proctoring integration.
- IP restrictions currently support exact addresses rather than CIDR parsing.
- Image/audio question records are supported, but a dedicated private media uploader
  is deferred to further CBT hardening.
- Horizontal scale should run the scheduler once per cluster and use Redis-backed
  locks/sessions in production.

## Phase boundary

Phase 10 will build configurable grading, result entry/import, approval, publication,
GPA/CGPA, broadsheets, and academic standing. It has not been started.
