Skip to content

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

  1. The admin creates a challenge with a name, semester, start and end dates, and picks a theme from the Themes library.
  2. 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.
  3. The admin attaches assessment items to a task, each tagged to a learning outcome: MCQs with an answer key, or a reflection prompt.
  4. The admin previews the challenge exactly as a student would see it, writing no student data.
  5. 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

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/.