docs: design class scoped training tasks
parent
ee65303f38
commit
eef1473481
@ -0,0 +1,205 @@
|
|||||||
|
# Training Task Class Scope Design
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Limit teacher-edited training tasks to the students in teaching classes created by that teacher, while allowing platform administrators to maintain a system default version.
|
||||||
|
|
||||||
|
Students should see the training task configuration for their own teaching class. If their teaching class has no custom configuration, they should see the administrator-maintained default task.
|
||||||
|
|
||||||
|
## Current Behavior
|
||||||
|
|
||||||
|
Training task configuration is currently global:
|
||||||
|
|
||||||
|
- The teacher page reads `/api/training-tasks`.
|
||||||
|
- Student task pages read `/api/training-tasks/key/{taskKey}`.
|
||||||
|
- The `training_task` table is keyed by `task_key`.
|
||||||
|
- The student side does not pass or resolve a teaching class when loading the task background, goals, requirements, or material.
|
||||||
|
|
||||||
|
The student menu is currently mostly route-driven in the frontend. Training task records override titles and provide content/materials, but they are not the only source of menu existence.
|
||||||
|
|
||||||
|
## Target Roles
|
||||||
|
|
||||||
|
Administrator:
|
||||||
|
|
||||||
|
- Maintains system default training tasks.
|
||||||
|
- These defaults are used when a teaching class has no custom task configuration.
|
||||||
|
- The system should initialize with default task skeletons so the menu/task catalog has stable keys, names, sort order, and enabled state.
|
||||||
|
|
||||||
|
Teacher:
|
||||||
|
|
||||||
|
- Can edit training task configurations only for teaching classes created by that teacher.
|
||||||
|
- Must choose a teaching class before editing training tasks.
|
||||||
|
- Saved configurations affect only that teaching class.
|
||||||
|
|
||||||
|
Student:
|
||||||
|
|
||||||
|
- Loads task configuration according to the student's teaching class.
|
||||||
|
- Cannot choose or spoof another teaching class id through the frontend API.
|
||||||
|
- Sees class-specific configuration first, then administrator default configuration as fallback.
|
||||||
|
|
||||||
|
## Data Model
|
||||||
|
|
||||||
|
Keep `training_task` as the administrator default task table.
|
||||||
|
|
||||||
|
Add a class-level override table, suggested name: `training_task_class_config`.
|
||||||
|
|
||||||
|
Suggested fields:
|
||||||
|
|
||||||
|
- `id`
|
||||||
|
- `teaching_class_id`
|
||||||
|
- `task_key`
|
||||||
|
- `project_name`
|
||||||
|
- `task_name`
|
||||||
|
- `background`
|
||||||
|
- `objectives`
|
||||||
|
- `requirements`
|
||||||
|
- `steps`
|
||||||
|
- `material_name`
|
||||||
|
- `material_url`
|
||||||
|
- `sort`
|
||||||
|
- `enabled`
|
||||||
|
- `created_by`
|
||||||
|
- `create_time`
|
||||||
|
- `update_time`
|
||||||
|
|
||||||
|
Unique rules:
|
||||||
|
|
||||||
|
- `training_task.task_key` remains unique for default tasks.
|
||||||
|
- `training_task_class_config` uses unique key `(teaching_class_id, task_key)`.
|
||||||
|
|
||||||
|
Indexes:
|
||||||
|
|
||||||
|
- `(teaching_class_id, task_key)`
|
||||||
|
- `(teaching_class_id, enabled, sort)`
|
||||||
|
- `created_by` if teacher-owned filtering needs fast lookup.
|
||||||
|
|
||||||
|
## Default Task Initialization
|
||||||
|
|
||||||
|
The system should initialize built-in task skeletons in `training_task`.
|
||||||
|
|
||||||
|
The skeleton must include:
|
||||||
|
|
||||||
|
- `task_key`
|
||||||
|
- `project_name`
|
||||||
|
- `task_name`
|
||||||
|
- `sort`
|
||||||
|
- `enabled`
|
||||||
|
|
||||||
|
The content fields can be empty if needed:
|
||||||
|
|
||||||
|
- `background`
|
||||||
|
- `objectives`
|
||||||
|
- `requirements`
|
||||||
|
- `material_name`
|
||||||
|
- `material_url`
|
||||||
|
|
||||||
|
This ensures administrators and teachers always have a stable task catalog to edit, and students always have a fallback source.
|
||||||
|
|
||||||
|
## Backend API Design
|
||||||
|
|
||||||
|
Administrator APIs:
|
||||||
|
|
||||||
|
- Existing `/api/training-tasks` can remain the default task management API.
|
||||||
|
- Only administrator-level users should be allowed to create or edit default tasks after this change.
|
||||||
|
- These APIs operate on `training_task`.
|
||||||
|
|
||||||
|
Teacher APIs:
|
||||||
|
|
||||||
|
- Add class-scoped endpoints, for example:
|
||||||
|
- `GET /api/training-tasks/classes/{teachingClassId}`
|
||||||
|
- `GET /api/training-tasks/classes/{teachingClassId}/key/{taskKey}`
|
||||||
|
- `PUT /api/training-tasks/classes/{teachingClassId}/{taskKey}`
|
||||||
|
- Backend must verify the teaching class was created by the current teacher.
|
||||||
|
- Teacher saves write to `training_task_class_config`.
|
||||||
|
- If a class row does not exist yet, save should create it from the default task plus the submitted changes.
|
||||||
|
|
||||||
|
Student APIs:
|
||||||
|
|
||||||
|
- Keep student-facing loading simple, for example:
|
||||||
|
- `GET /api/training-tasks/key/{taskKey}`
|
||||||
|
- Backend resolves the logged-in student and determines the student's teaching class.
|
||||||
|
- Backend returns class override if present and enabled.
|
||||||
|
- If no class override exists, backend returns administrator default.
|
||||||
|
- The frontend should not pass `teachingClassId` for student reads.
|
||||||
|
|
||||||
|
## Student Class Resolution
|
||||||
|
|
||||||
|
The first implementation should assume one effective teaching class for a student.
|
||||||
|
|
||||||
|
Resolution order:
|
||||||
|
|
||||||
|
1. Find the student's teaching class membership.
|
||||||
|
2. If multiple teaching classes exist, choose the most deterministic current behavior available in existing data.
|
||||||
|
3. If there is no teaching class membership, fall back to administrator default task.
|
||||||
|
|
||||||
|
If the product later needs multiple active teaching classes per student, add an explicit student-side teaching class switcher instead of guessing.
|
||||||
|
|
||||||
|
## Frontend Changes
|
||||||
|
|
||||||
|
Administrator side:
|
||||||
|
|
||||||
|
- Add a training task management menu.
|
||||||
|
- Reuse the current task editing UI where practical.
|
||||||
|
- The page edits default tasks, not class overrides.
|
||||||
|
|
||||||
|
Teacher side:
|
||||||
|
|
||||||
|
- Training task management page starts with a teaching class selector.
|
||||||
|
- Selector lists only teaching classes created by the logged-in teacher.
|
||||||
|
- After selecting a class, the page loads class-specific task configuration with default fallback values.
|
||||||
|
- Save writes only to the selected teaching class.
|
||||||
|
|
||||||
|
Student side:
|
||||||
|
|
||||||
|
- Continue loading each route by `taskKey`.
|
||||||
|
- Display returned background, goals, requirements, and material.
|
||||||
|
- No student-side teaching class id should be sent.
|
||||||
|
|
||||||
|
## Fallback Rules
|
||||||
|
|
||||||
|
For a student task page:
|
||||||
|
|
||||||
|
1. Use enabled class-specific task config for the student's teaching class.
|
||||||
|
2. If missing, use enabled administrator default task.
|
||||||
|
3. If default is missing, keep the route/menu stable but render empty content or a "not configured" state.
|
||||||
|
|
||||||
|
For teacher edit pages:
|
||||||
|
|
||||||
|
1. Show class override if it exists.
|
||||||
|
2. Otherwise show administrator default values as editable initial values.
|
||||||
|
3. Saving creates the class override.
|
||||||
|
|
||||||
|
## Migration
|
||||||
|
|
||||||
|
Existing rows in `training_task` remain administrator default tasks.
|
||||||
|
|
||||||
|
Add the new class override table without deleting or rewriting existing default tasks.
|
||||||
|
|
||||||
|
No class override rows need to be generated immediately. They can be created lazily when a teacher saves a class configuration.
|
||||||
|
|
||||||
|
## Risks And Decisions
|
||||||
|
|
||||||
|
Multiple teaching classes per student:
|
||||||
|
|
||||||
|
- Initial behavior should use one effective class or fallback to default.
|
||||||
|
- A later switcher can support explicit multi-class selection.
|
||||||
|
|
||||||
|
Permission leakage:
|
||||||
|
|
||||||
|
- Student reads must resolve class server-side.
|
||||||
|
- Teacher edits must verify class ownership server-side.
|
||||||
|
|
||||||
|
Menu consistency:
|
||||||
|
|
||||||
|
- Current student menus are route-driven.
|
||||||
|
- Default task skeletons are still required to make task names, enabled state, sort order, and fallback content manageable from the admin side.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- Administrators can edit default training task configuration from an admin menu.
|
||||||
|
- Teachers can edit training task configuration only after selecting one of their own teaching classes.
|
||||||
|
- A teacher cannot edit another teacher's teaching class task configuration.
|
||||||
|
- Students see their teaching class configuration when it exists.
|
||||||
|
- Students fall back to administrator default configuration when their class has no configuration.
|
||||||
|
- Case material follows the same class-specific then default fallback rule.
|
||||||
|
- The system initializes default task skeletons for all built-in task keys.
|
||||||
Loading…
Reference in New Issue