- TrainingRecord model with completion_mode (online/offline/blended) and CompletionStatus state machine
- TrainerSignoff model with decision, notes, trainer FK, and audit timestamp
- SignoffEvidence model for uploaded proof files
- services.py state transitions:
- mark_in_progress: not_started → in_progress
- mark_online_passed: online → completed; blended → pending_signoff
- submit_trainer_signoff: offline/blended approved → completed; rejected → in_progress
- InvalidTransitionError on illegal state moves
- IsTrainer permission class based on training:signoff capability
- API: record detail, start, mark-online-passed, trainer-signoff, pending-signoff list
- 20 unit + integration tests covering all mode paths, invalid transitions, and access control
- Blended completion requires both online pass AND trainer approval
Co-Authored-By: Paperclip <noreply@paperclip.ing>