Overview & user management
The admin Overview dashboard (KPIs, activity, weakest topics, noticeboard, escalation queue) and the Users screen for changing roles, suspending, editing and resetting passwords — all audit-logged.
The Programme admin area is your control centre for the whole CLIP Learn platform. This page covers two screens: the Overview dashboard you land on, and the Users screen where you manage every account. Both live under the top admin navigation and are reached at /admin and /admin/users.
Who can open this area
The admin area requires the ADMIN or CORPORATE role. A CORPORATE user (a client's learning-and-development sponsor) sees a different, ROI-focused version of the Overview and cannot open the Users screen at all — the Users, Conversations, Audit and Benchmark tabs are hidden for them. Everything about user management below is ADMIN-only. Anyone else who navigates here is redirected to /app.
The admin navigation
Every admin screen shares a header. The heading reads Programme admin for an ADMIN (subtitle "Learners, escalations and knowledge — self-service") and Team overview for a CORPORATE sponsor (subtitle "Your sponsored candidates at a glance"). The tab row is:
| Tab | Link | Visible to |
|---|---|---|
| Overview | /admin | ADMIN, CORPORATE |
| Learners | /admin/learners | ADMIN, CORPORATE |
| Cohorts | /admin/cohorts | ADMIN, CORPORATE |
| Users | /admin/users | ADMIN only |
| Knowledge | /admin/knowledge | ADMIN, CORPORATE |
| Conversations | /admin/conversations | ADMIN only |
| Audit | /admin/audit | ADMIN only |
| Benchmark | /admin/benchmark | ADMIN only |
The MOEgent copilot panel appears at the bottom of every admin screen for ADMIN users only.
The Overview dashboard (ADMIN)
/admin opens on four KPI tiles, two charts, a noticeboard composer, an escalation queue and a live-activity feed. All figures are computed live on each page load. For an ADMIN the numbers cover the entire platform; for a CORPORATE sponsor they are silently limited to candidates in that sponsor's own organisation (see The Corporate sponsor view).
The four KPI tiles
| Tile | What it counts | Notes |
|---|---|---|
| Active learners | Users whose role is CANDIDATE and who are not suspended (active = true) | Suspended candidates and staff accounts are excluded. |
| Lessons completed | Total LessonProgress rows across all learners | Each row is one learner completing one lesson. |
| Questions answered | Total AnswerEvent rows across all attempts | Counts every answer in practice and mock attempts. |
| Overall accuracy | Correct answers divided by total answers, as a whole percentage | Shows an em-dash (—) when no questions have been answered yet, to avoid dividing by zero. |
Activity — last 14 days
A bar chart of questions answered per day over the trailing 14 calendar days (UTC), including today. Each bar's height is relative to the busiest day in the window; a day with at least one answer always shows a minimum sliver so it is visible. Hovering a bar shows a tooltip of the exact date and count in the form date: count. The caption beneath reads "N questions answered across the platform", where N is the total across all 14 days — this total and the bars count exactly the same events (both are ANSWER_SUBMITTED learning events since the start of the oldest visible day).
Weakest topics (avg mastery)
A ranked list of up to six topics with the lowest average mastery, drawn from learners' MasteryScore records. Only topics with at least one attempt are included.
- Each learner's mastery of a topic is an Elo-style rating that starts at 1000 and moves up or down as they answer questions on that topic. The dashboard shows the average rating across all learners for each topic, rounded to a whole number.
- Topics are sorted lowest rating first (weakest at the top) and the bottom six are shown. The bar length is scaled against a baseline of 1200, so a topic sitting near the starting 1000 shows as a short-to-medium bar.
- Empty state: if no learner has any mastery data yet, the panel reads "No mastery data yet."
Reading the weakest-topics list
This is your teaching signal. A topic near the top of this list is where the cohort as a whole is struggling — a candidate for a fresh explainer lesson, a noticeboard nudge, or a live session.
Post to the noticeboard
A one-line composer that publishes an announcement to every learner's dashboard within the current tenant. ADMIN only — the panel is hidden for CORPORATE sponsors.
| Field | What it does | Limits |
|---|---|---|
| Title | Headline shown on the learner dashboard | Required; trimmed; truncated to 160 characters |
| Message (body) | The announcement text | Required; trimmed; truncated to 2000 characters |
If either field is blank after trimming, nothing is posted. The announcement is attached to your tenant; if the system cannot resolve a tenant, the post is silently skipped. Posting is recorded in the audit log as an ANNOUNCE action (with the title in the log's metadata). New announcements are not pinned by default.
Learner questions for the team (escalation queue)
When MOEgent cannot answer a learner's question from the course materials, it opens an escalation ticket. Those open tickets land here so a human can close the loop. ADMIN only — the panel is hidden for CORPORATE sponsors (though the underlying reply action is open to FACULTY too, via the faculty screen).
The panel header shows a live count badge — "N waiting" — of tickets whose status is still OPEN, sorted newest first. Each ticket shows:
- The learner's question text.
- The learner's name and the time the ticket was created (
YYYY-MM-DD HH:MM). - A reply box.
| Field | What it does | Limits |
|---|---|---|
| Answer | Your reply to the learner | Required; trimmed; truncated to 4000 characters |
When you send an answer, the ticket's status flips from OPEN to ANSWERED, your reply and your name are stored on the ticket, and a resolved-timestamp is set. A TICKET_ANSWERED learning event is recorded, and the action is written to the audit log as ANSWER_TICKET. The ticket then drops out of the "waiting" queue.
Empty state: when nothing is outstanding, the panel reads "Nothing waiting — every learner question has an answer."
Live activity
A rolling feed of the 12 most recent learning events across the platform — "the event spine: every lesson view, answer and chat, captured." Each row shows the actor's name (or System if the event has no user), the event verb in plain lower-case words (for example ANSWER_SUBMITTED renders as "answer submitted"), and the time of day (HH:MM, UTC). For a CORPORATE sponsor this feed widens to fill the row because the escalation queue beside it is hidden. Empty state: "No activity yet — it appears here as learners study."
The Corporate sponsor view
If you sign in with the CORPORATE role, /admin shows a dedicated Team readiness & ROI page instead of the admin dashboard above. It is scoped entirely to your own organisation's candidates — no platform-wide data, no escalations, no noticeboard. It contains:
- Your organisation's name and an Export CSV button (a client-side download — no data leaves the page to a server; spreadsheet-formula injection in names is neutralised).
- Four KPI tiles: Seats used (
used / purchased), Cohort completion (average progress %), Exam-ready (ready of total), and Need support (highlighted when above zero). - A Projected exam-readiness bar splitting your candidates into Exam-ready / On track / Needs support.
- A per-employee table: name, progress, accuracy, best mock score, target sitting, a readiness badge and last-active date.
Each candidate's readiness is derived automatically:
| Readiness | Condition |
|---|---|
| Exam-ready | Average mastery rating >= 1150 and best mock >= 60% and progress >= 60% |
| On track | Average rating >= 1000 and progress >= 25% and active within the last 7 days |
| Needs support | Everyone else |
Empty state: "No sponsored candidates yet."
User management (ADMIN)
/admin/users is the master list of every account on the platform. ADMIN only. From here you filter and search accounts, change roles, suspend or restore access, edit contact details, and reset passwords. Every one of these changes is written to the append-only audit log (see Audit logging).
Filtering and searching
Above the table sits a row of role filter chips and a search box:
- All (N) plus one chip per role — ADMIN, FACULTY, CORPORATE, CANDIDATE — each showing a live count. The active chip is highlighted. Clicking a chip filters the table to that role via
?role=…. - A search box ("Search name / email…") matches on name or email, case-insensitively, on a partial match. It preserves the current role filter. Submit by pressing Enter.
The table shows at most 200 users, newest account first. If more than 200 match, narrow with a role filter or search.
The user table
| Column | What it shows |
|---|---|
| User | Name (bold), email, and phone if one is set |
| Client | The organisation name from the user's first membership, or — if none |
| Courses | Count of the user's course enrolments |
| Role | A dropdown of the four roles plus a Set button |
| Status | A toggle button reading Active (green) or Suspended |
| Manage | An Edit details expander and a Reset password button |
Change a user's role
Lockout guards on role changes
Two safety rules block a change that would lock everyone out of the admin area:
- You cannot demote yourself away from ADMIN.
- You cannot demote the last remaining active ADMIN — if only one active admin exists, the change is refused.
In both cases the request is silently ignored (no error is shown; the role simply does not change). Promoting anyone to ADMIN is always allowed.
The four roles mean:
| Role | What it grants |
|---|---|
| ADMIN | Full platform administration — this whole area, all learners, users, audit, knowledge. |
| FACULTY | Teaching staff; can answer escalated learner questions and preview any course, but not manage users. |
| CORPORATE | An external client sponsor; sees only their own organisation's readiness/ROI view. Never reads lesson bodies or exam answers. |
| CANDIDATE | A learner. The default role for a new account. |
Suspend or restore a user
The Status button is a one-click toggle:
Suspending sets the account's active flag to false and is logged as SUSPEND_USER; restoring sets it back to true and is logged as RESTORE_USER.
What suspension actually does
A suspended user is redirected to a /suspended page on their next page load, and every API route (trainer, practice, mock) rejects them with a 401 — even if their browser still holds a valid login cookie, because the platform re-checks the active flag from the database on every request. Note that suspension does not delete their existing sessions; access is denied on the next request rather than by force-logging-them-out mid-request. To forcibly end all sessions immediately, use Reset password (below), which deletes every session for that user.
Lockout guards on suspension
Mirroring the role guards, you cannot suspend yourself, and you cannot suspend the last remaining active ADMIN. Such requests are silently ignored.
Edit a user's details
| Field | What it does | Limits / defaults |
|---|---|---|
| Name | The user's display name | Required; trimmed; truncated to 120 characters |
| Login email and unique identifier | Required; trimmed; lower-cased; truncated to 160 characters; must be unique | |
| WhatsApp / phone | Mobile number, used to authorise WhatsApp messaging channels | Optional; trimmed; truncated to 40 characters; leave blank to clear it |
If Name or Email is empty after trimming, the save is ignored. If the new email is already in use by another account, the save is silently refused (the email is not changed) — there is no on-screen error, so if an edit appears not to take, check for a duplicate email.
Reset a user's password
The Reset password button generates a fresh temporary password and shows it to you once.
Details and edge cases:
- The temporary password has the form
Clip-followed by a short random string and two digits (for exampleClip-a4f9k57). It is shown only once — it is not stored in readable form and cannot be retrieved again. If you lose it, reset again. - Resetting a password immediately deletes every active session for that user, so any old password (and any logged-in device) stops working at once.
- The reset is recorded as RESET_PASSWORD in the audit log.
- It only works for password (email/credential) accounts. If the user signs in with Google (or any other social provider) and has no password credential, the button shows "Failed — retry" — there is no password to reset. Direct such users to sign in with their provider instead.
Audit logging
Every privileged change described on this page is appended to an immutable audit log, viewable by an ADMIN at /admin/audit. This exists because CLIP Learn is a regulated certificate issuer: roles, suspensions, answers and announcements cannot be changed silently.
Each entry records when, who (the acting admin's email, or a short id if no email), what action, and the target. The most recent 200 entries are shown, newest first. Audit entries reference the target by id rather than a hard link, so they survive even if the user or ticket is later deleted. The actions logged from the screens above are:
| Action code | Shown as | Raised by |
|---|---|---|
| ROLE_CHANGE | Changed role (with → new role) | Setting a user's role |
| SUSPEND_USER | Suspended user | Toggling a user to Suspended |
| RESTORE_USER | Restored user | Toggling a user back to Active |
| EDIT_USER | (raw code shown) | Saving edited user details |
| RESET_PASSWORD | (raw code shown) | Resetting a password |
| ANSWER_TICKET | Answered a learner question | Replying to an escalation |
| ANNOUNCE | Posted an announcement | Posting to the noticeboard |
Audit logging never blocks your action
Writing the audit entry is best-effort: if the log write were ever to fail, the underlying change (the role update, the suspension, and so on) still goes through. In normal operation every action above produces exactly one audit row.