{% extends "base.html" %} {% block title %}{{ learner.display_name }} — Instructor Console{% endblock %} {% block extra_css %} {% include "forge_academy/partials/_chrome_clearance.html" %} {% endblock %} {% block content %}
← INSTRUCTOR CONSOLE

{{ learner.display_name }}

{{ learner.username }} — {{ roles.get(learner.role, {}).get('label', learner.role) }} · rank {{ learner.level }}

{{ summary.completed }}/{{ summary.total_missions }}Missions
{{ summary.steps_completed }}Steps done
{{ learner.xp }}Total XP
{{ learner.streak_days }}Day streak
{{ assignments | length }}Assignments
{{ reviews | length }}Reviews
Assigned Work
{% if assignments %} {% for a in assignments %} {% set mine = a.targets | selectattr('user_id', 'equalto', learner.id) | list | first %} {% endfor %}
WorkDueProgressStatusAssigned by
{{ a.label }}{% if a.note %}
{{ a.note }}
{% endif %}
{{ (a.due_at or '—')[:10] }} {{ mine.completed if mine else 0 }}/{{ mine.total if mine else 0 }} {% if a.status == 'cancelled' %}CANCELLED {% elif mine and mine.complete %}COMPLETE {% elif a.overdue %}OVERDUE {% else %}OPEN{% endif %} {{ a.assigned_by }}
{% else %}
Nothing assigned to this learner.
{% endif %}
Submissions ({{ submissions | length }})
{% if submissions %} {% for s in submissions %} {% endfor %}
MissionStepTypeStatusScoreHintsWork
{{ s.mission_title }}
T{{ s.tier }}
{{ s.step_num }}. {{ s.step_title }} {{ s.step_type }} {% if not s.assessed %}
NOT GRADED
{% endif %}
{% if s.status == 'completed' %}COMPLETED {% elif s.status == 'attempted' %}ATTEMPTED {% else %}{{ s.status | upper }}{% endif %} {{ s.score }} {{ s.hints_used }} {% if s.has_submission %}
{{ s.submission }}
{% else %} no text submitted {% endif %}
{% else %}
This learner has not started any step yet.
{% endif %}
Only coding and reflect steps are machine-graded. The rest are acknowledgements — completable, but not evidence of a demonstrated skill.
Verified Evidence ({{ evidence | length }})
{% if evidence %} {% for e in evidence %} {% endfor %}
WhenKindWhatValue
{{ (e.created_at or e.issued_at or '')[:19] }} {% if e.kind == 'certificate' %}CERTIFICATE {% elif e.is_attendance %}ATTENDANCE {% else %}EARNED XP{% endif %} {% if e.kind == 'certificate' %}{{ e.cert_tier }} {% else %}{{ e.reason }}{% if e.source_type %} ({{ e.source_type }} {{ e.source_id }}){% endif %}{% endif %} {% if e.kind == 'certificate' %}—{% else %}{{ e.xp_delta }} XP{% endif %}
{% else %}
No ledger entries or certificates recorded for this learner.
{% endif %}
Read straight from the append-only XP ledger — the record of what each point was paid for. Attendance is shown separately because it does not count toward rank.
Record a Review
A score override rewrites the recorded mission score and keeps the value it replaced, attributed to you in the append-only audit log. It deliberately does not move XP: every point in the ledger names the work that earned it, and an instructor-mintable XP path would make a rank purchasable again. A mission the learner has never opened cannot be overridden — there is no score there to change.
Review History
{% if reviews %} {% for r in reviews %} {% endfor %}
WhenVerdictMissionScoreCommentReviewer
{{ (r.created_at or '')[:19] }} {% if r.verdict == 'approved' %}APPROVED {% elif r.verdict == 'rejected' %}REJECTED {% else %}NEEDS REWORK{% endif %} {{ r.mission_title or '—' }} {% if r.override_score is not none %} {{ r.prior_score if r.prior_score is not none else '—' }} → {{ r.override_score }} {% else %}—{% endif %} {{ r.comment or '' }} {{ r.reviewer }}
{% else %}
No reviews recorded for this learner yet.
{% endif %}
{% endblock %}