3a. "Tech #N" display fix (HIGH — customer complaint)
The FM dashboard's Technician Workload card built names from Tech #${assigned_to} (user id). It now uses the real assigned_technician_name with an 'Unassigned' fallback, matching the /tickets pattern. Swept the app — no Tech # template usages remain.
3b. Technician performance dashboard (new)
GET /api/tickets/tech-performance — per-technician aggregation by real name: total assigned, completed, in progress, escalated, cancelled, completion rate, and created→closed aging (task counts only where timestamps are absent). Buckets sum to total assigned.
/dashboard/tech-performance page, reachable from FM + CEO nav: per-tech table/cards, completion rate, aging, sorted by completed/workload, with empty states.
No DB schema change (derives from existing columns). Same-origin only; CSP unchanged.
Review-gate corrections: KPI bucket relabeled "Pending / In review" (it covers post-completion review stages as well as unstarted tickets — "Unstarted" was misleading); both-null technician sort now falls through to a name tiebreak; source-grep tests replaced with a behavioral test exercising the real name fields on /api/tickets + /api/tickets/tech-performance.
Relay #748 v3 next-wave (captain-directed; Wahab customer request). no-mistakes validated (110 tests), gate fixes applied.
**3a. "Tech #N" display fix (HIGH — customer complaint)**
The FM dashboard's Technician Workload card built names from `Tech #${assigned_to}` (user id). It now uses the real `assigned_technician_name` with an 'Unassigned' fallback, matching the /tickets pattern. Swept the app — no `Tech #` template usages remain.
**3b. Technician performance dashboard (new)**
- `GET /api/tickets/tech-performance` — per-technician aggregation by real name: total assigned, completed, in progress, escalated, cancelled, completion rate, and created→closed aging (task counts only where timestamps are absent). Buckets sum to total assigned.
- `/dashboard/tech-performance` page, reachable from FM + CEO nav: per-tech table/cards, completion rate, aging, sorted by completed/workload, with empty states.
- No DB schema change (derives from existing columns). Same-origin only; CSP unchanged.
Review-gate corrections: KPI bucket relabeled "Pending / In review" (it covers post-completion review stages as well as unstarted tickets — "Unstarted" was misleading); both-null technician sort now falls through to a name tiebreak; source-grep tests replaced with a behavioral test exercising the real name fields on /api/tickets + /api/tickets/tech-performance.
Wahab customer request (relay #748 v3 next-wave).
3a. Fix 'Tech #N' display:
- FM dashboard's "Technician Workload" card was built from
`Tech #${t.assigned_to}`; it now reads Ticket.assigned_technician_name
(falling back to 'Unassigned', matching /tickets).
- Template sweep confirms no other `Tech #` placeholder exists.
3b. Technician performance dashboard:
- New bearer-gated GET /api/tickets/tech-performance aggregating existing
ticket columns only (no schema change): per-technician total assigned,
completed, in progress, escalated, cancelled, pending, open tasks,
completion rate, and created_at -> closed_at resolution time with explicit
counts for finished tasks lacking a timestamp. Rows key on user id so
same-name technicians stay separate; labels are real names. Fleet totals
and an unassigned-ticket count are included.
- New /dashboard/tech-performance page (FM + CEO nav and links) with sortable
table, completion bars and empty states; same-origin vendored assets only.
- Bucket map, service, schemas and tests in app/services/ticket.py,
app/schemas/ticket.py, tests/test_tech_performance.py.
Tests: 111 passed (101 existing + 10 new).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Relay #748 v3 next-wave (captain-directed; Wahab customer request). no-mistakes validated (110 tests), gate fixes applied.
3a. "Tech #N" display fix (HIGH — customer complaint)
The FM dashboard's Technician Workload card built names from
Tech #${assigned_to}(user id). It now uses the realassigned_technician_namewith an 'Unassigned' fallback, matching the /tickets pattern. Swept the app — noTech #template usages remain.3b. Technician performance dashboard (new)
GET /api/tickets/tech-performance— per-technician aggregation by real name: total assigned, completed, in progress, escalated, cancelled, completion rate, and created→closed aging (task counts only where timestamps are absent). Buckets sum to total assigned./dashboard/tech-performancepage, reachable from FM + CEO nav: per-tech table/cards, completion rate, aging, sorted by completed/workload, with empty states.Review-gate corrections: KPI bucket relabeled "Pending / In review" (it covers post-completion review stages as well as unstarted tickets — "Unstarted" was misleading); both-null technician sort now falls through to a name tiebreak; source-grep tests replaced with a behavioral test exercising the real name fields on /api/tickets + /api/tickets/tech-performance.