UC-5 Admin builds and edits a challenge
| Primary actor | SHS Staff (Admin) |
| Priority | Must |
| Satisfies | FR-B1, FR-B2, FR-B3, FR-B4, FR-B6, FR-B8, FR-B9, FR-B10, FR-D8, NFR-6 |
| Precondition | The admin is signed in with the admin role. |
| Trigger | The admin opens the Challenge Builder. |
Main success scenario
- The admin creates a challenge with a name, semester, start and end dates, and picks a theme from the Themes library.
- The admin adds ordered weekly tasks: title, caption, activity type, location, date window and optional event times, check-in method (a printed poster, the default for a new week, or a rotating code for a staffed table; ADR 0006), prize, required flag, optional task group.
- The admin attaches assessment items to a task, each tagged to a learning outcome: MCQs with an answer key, or a reflection prompt.
- The admin previews the challenge exactly as a student would see it, writing no student data.
- The admin publishes. Enrolment and check-ins open.
Extensions
- 1a. Duplicate a prior challenge as the starting point.
- 2a. A window or challenge whose end precedes its start is refused on create and on edit.
- 2b. A poster week with no window end is refused on create and on edit (422; the message names the rotating code as the alternative), because the poster is valid until the window ends. The editor holds Save until an end is set. Switching a printed week to the rotating code asks first: every printed sheet stops working on save. Weeks from before the field kept the rotating code; the poster default applies only to a new week.
- 5a. Publishing would displace the challenge students currently see. 409 until the admin acknowledges that challenge by id.
- Retire. A published challenge is archived, reversibly, with every row retained. A draft that never published and holds no data may be deleted. A live week with student data is archived, not deleted; an untouched draft week can be deleted with a short undo.
- Re-skin. Themes carry the full palette and copy; a semester re-skin is a configuration change (NFR-6). The theme editor derives a palette from one source colour and shows a live preview.
Acceptance criteria (Gherkin)
| Feature file | Test module |
|---|---|
challenge_date_window_validation.feature |
test_challenge_date_window_validation_bdd.py |
challenge_preview.feature and frontend/challenge_preview.feature |
test_challenge_preview_bdd.py |
challenge_retirement.feature |
test_challenge_retirement_bdd.py |
duplicate_challenge.feature |
test_duplicate_challenge_bdd.py |
live_challenge_visibility.feature |
test_live_challenge_visibility_bdd.py |
publish_displaces_live_challenge.feature |
test_publish_displaces_live_challenge_bdd.py |
week_event_start_and_end_times.feature |
test_week_event_start_and_end_times_bdd.py |
week_reorder_controls.feature and frontend/week_reorder_controls.feature |
test_week_reorder_controls_bdd.py |
week_retirement.feature |
test_week_retirement_bdd.py |
admin_themes_library.feature and frontend/admin_themes_library.feature |
test_admin_themes_library_bdd.py |
Plain pytest for the check-in method (PASS-741): test_task_checkin_method.py (the create default, the 422, migration 0027's backfill, the generation bump and its ledger row, duplicate). Frontend: ChallengeBuilder.checkinMethod.test.tsx.
| theme_source_colour_derivation.feature and frontend/theme_source_colour_derivation.feature | test_theme_source_colour_derivation_bdd.py |
| theme_live_preview.feature and frontend/theme_live_preview.feature | test_theme_live_preview_bdd.py |
| frontend/theme_role_vocabulary.feature | Vitest (see the scenario's Proven by lines) |
| theme_hero_link.feature and frontend/theme_hero_link.feature | test_theme_hero_link_bdd.py |
| admin_navigation_rail.feature and frontend/admin_navigation_rail.feature | test_admin_navigation_rail_bdd.py |
Plain pytest: test_challenges.py, test_challenge_retirement.py, test_week_retirement.py, test_week_undo_delete.py, test_week_visibility.py, test_themes.py, test_session_theme.py. Frontend: ChallengeBuilder*.test.tsx, ThemeEditor.test.tsx, Themes.test.tsx.
Views
- Process: UC-5 Challenge lifecycle and week states
- Logical:
Challenge,Task,AssessmentItem,Themein the domain model
Code: backend/app/routers/challenges.py, backend/app/services/challenges.py, backend/app/services/themes.py, frontend/src/components/admin/ChallengeBuilder/, frontend/src/components/admin/ThemeEditor/.
The design of record for the screens is under docs/design/.