Files
ImpTune/.planning/phases/11-ui-enhancements/11-04-SUMMARY.md
T
2026-04-15 17:57:12 +02:00

4.1 KiB


phase: 11-ui-enhancements plan: "04" subsystem: navigation/client-detail tags: [client-nav, routing, templates, tdd] dependency_graph: requires: [11-02, 11-03] provides: [GET /clients/{id}, client_detail.html, client-name-links] affects: [imptune/api/pages.py, printer_list.html, client_list.html] tech_stack: added: [] patterns: [grouped-dict-reuse, client_id-from-FK-field] key_files: created: - imptune/templates/client_detail.html modified: - imptune/api/pages.py - imptune/templates/partials/printer_list.html - imptune/templates/partials/client_list.html decisions:

  • "client_id extracted from printers[0].client_id in Jinja2 template (no grouped structure change)"
  • "Unassigned group renders plain text — condition is False when client_id is None"
  • "client_detail route placed after /clients to avoid FastAPI path conflict ordering" metrics: duration_minutes: 4 completed_date: "2026-04-15" tasks_completed: 2 files_changed: 4

Phase 11 Plan 04: Client Name Navigation Summary

One-liner: Per-client filtered printer page at GET /clients/{id} with clickable client names in printer group headers and client table, using grouped-dict reuse pattern from existing printer_list partial.

What Was Built

  • GET /clients/{client_id} route in imptune/api/pages.py: queries client by id (404 if not found), builds grouped = {client.name: [printers]} dict, passes full context (clients, driver_data) so printer_list partial with Edit/Delete modals works identically to /printers.
  • client_detail.html template: extends base.html, renders client name as <h1>, back-link to /clients, includes partials/printer_list.html.
  • printer_list.html updated: added {% set group_client_id = printers[0].client_id if printers else None %} + conditional <h3> — assigned clients get anchor link, Unassigned group remains plain text.
  • client_list.html updated: client name <td> now wraps name in <a href="/clients/{{ c.id }}">.

Tasks Completed

Task Name Commit Files
1 GET /clients/{id} route + client_detail.html f364479 imptune/api/pages.py, imptune/templates/client_detail.html
2 Client name links in printer_list.html and client_list.html 5bf152b imptune/templates/partials/printer_list.html, imptune/templates/partials/client_list.html

Test Results

All 3 UIE-03 scaffolded tests now GREEN:

  • test_client_detail_returns_200 — PASSED
  • test_client_detail_not_found — PASSED
  • test_client_links_in_printer_list — PASSED

Full non-E2E suite: 122/122 PASSED

E2E suite: 6/7 passed — test_port_autofill[chromium] FAILED (pre-existing failure, present before this plan's changes; deferred to deferred-items.md).

Decisions Made

  1. client_id from printers[0].client_id: Extracted in Jinja2 template rather than changing the grouped data structure. The client_id FK field on Printer returns raw integer when accessed as .client_id, avoiding FK object traversal. No changes to the route's grouped dict construction needed.
  2. Unassigned group is plain text: group_client_id evaluates to None/falsy for unassigned printers; {% if group_client_id %} condition cleanly handles both cases.
  3. Route ordering: /clients/{client_id} placed after /clients in pages.py to respect FastAPI path-specificity ordering — FastAPI matches literal /clients before the parameter route.

Deviations from Plan

None — plan executed exactly as written. All recommended approaches in the plan's interfaces section worked as described without modification.

Out-of-Scope Items Deferred

test_port_autofill[chromium] E2E failure: pre-existing, introduced when Plan 11-01 separated the add-printer form to /printers/new while the test still navigates to /printers expecting input[name='ip_address']. Logged in .planning/phases/11-ui-enhancements/deferred-items.md.

Self-Check: PASSED

  • imptune/api/pages.py — FOUND
  • imptune/templates/client_detail.html — FOUND
  • imptune/templates/partials/printer_list.html — FOUND
  • imptune/templates/partials/client_list.html — FOUND
  • Commit f364479 — FOUND
  • Commit 5bf152b — FOUND