Code Review Checklist
Use when reviewing code changes via git diff, doing quality audits, or
performing final review passes before committing.
Rules
- ALWAYS check for MVC separation violations (business logic in UI pages).
- ALWAYS verify new domain state is exposed via
.healthy/.errorsproperties. - NEVER approve raw exit codes, return codes, or internal IDs shown to users.
- NEVER approve broad
except Exception— require specific exception types. - ALWAYS verify new UI strings are in
data.pyconstants, not hardcoded. - ALWAYS check that new data helpers have tests in
test_webui_data.py. - NEVER approve hardcoded hex colors in page files — use theme constants.
- NEVER read raw
RegisteredNodein page modules — useFleet/Hostfrombuild_fleet(). The only exception iscompute_alerts()which still takesRegisteredNodelist (pending migration). - ALWAYS verify
Hosttelemetry properties return graceful defaults whentelemetry is None(e.g.,disk_pct → 0.0,guests → [],online → False).
MVC / OOP Architecture Review
The web UI follows a strict three-layer separation. Every review MUST check:
Layer 1: Domain model (data.py)
- Does the change add state computation? It MUST be in a domain class, not a page module.
- Does a domain class expose
.healthyand.errors? These are the standard interface for health/status. - Are aggregate classes (e.g.,
Fleet) delegating to children?fleet.healthy = all(h.healthy for h in self.hosts)— not reimplementing. - Are factory functions (
build_fleet()) the only place raw data sources (JSON, env vars) are wired to domain objects? - Does the change use
RegisteredNodedirectly? It should useHostwith attachedHostTelemetryinstead.build_fleet()merges both. - Does a new
Hostproperty handletelemetry is Nonegracefully?
# RED FLAG: health logic in a page module
def _deploy_card(state_dir):
history = data.load_deploy_history(state_dir)
if history[-1].exit_code == 0: # ← business logic in UI
ui.badge("success")
# CORRECT: page reads domain object
def _deploy_card(fleet):
if fleet.healthy: # ← domain object owns the logic
ui.badge("success")
Layer 2: Data helpers (data.py)
- Exit code mapping, status computation, error descriptions — all in
data.py. - Lookup tables (e.g.,
ANSIBLE_EXIT_CODES) live indata.py, not page modules. - Functions that format data for display (e.g.,
exit_code_label()) are indata.py— the UI calls them, not reimplements them.
Layer 3: UI pages (pages/*.py)
- Page functions receive domain objects, not raw data.
- ZERO
if exit_code == 0or status-computing conditionals. - Color decisions reference theme constants, never hardcoded values.
- Exception handling uses specific types (
httpx.HTTPError,OSError).
Review question checklist
Ask these for every diff that touches scripts/webui/:
- "Is there business logic in a page module?" — if/else on exit codes,
status strings, deploy history → move to domain class in
data.py. - "Could I test this logic without NiceGUI?" — if no, the logic is in the wrong layer. Domain logic must be testable with plain pytest.
- "Does the UI show raw internal values?" — exit codes, return codes, enum values, timestamps without formatting → map to human-readable text.
- "Is state derived from a
.healthy/.errorsproperty?" — if the page manually iterates/filters/computes, it should be a domain object method. - "Are new strings in
data.pyconstants?" — button labels, page titles, route paths →Labels,PageTitles,Routesclasses. - "Are colors semantic?" — red=error only, orange=warning/limitation, grey=inactive/unknown, green=healthy/success.
Ansible Code Review
Safety checks
modprobe -rNEVER in broad-scope plays (hosts: proxmox).- No
shutdown/poweroffin cleanup or molecule files. - No
authorized_keysorpveumremoval in cleanup. set -o pipefailon allansible.builtin.shelltasks with|.executable: /bin/bashon pipefail tasks.- FQCN on all modules (
ansible.builtin.command, notcommand). changed_when/failed_whenon command/shell tasks.delegate_to: localhostinstead of deprecatedlocal_action.
Architecture checks
- Configure roles have ZERO package installs.
- Configure roles use
ansible.builtin.uri→ NM API (not SSH/pct exec). Onlykiosk_configure(bootstrap) andopenwrt_configure(no HTTP API) are exceptions. - Verify assertions use fleet API (
/api/fleet/ready,/api/container/{id}/ready) over VPN. No SSH fallback paths. - Hard-failure messages include INVESTIGATE prompts with diagnostic commands.
- Image paths use
role_path, not bare relative paths. - New VMIDs added to both cleanup files.
- Deploy stamp included in provision plays.
- Container IPs don't collide with existing allocations.
Test Review
- New domain classes have pure-Python tests (no NiceGUI required).
- UI tests import constants from
data.py, never hardcode strings. - Tests verify actual behavior, not just string presence in YAML.
- No mocking of things that can be tested for real (infrastructure probes).
- Recovery scenarios tested: failure → success →
.healthy is True. - Telemetry properties tested with AND without
attach_telemetry()to verify graceful defaults (0.0, [], False, "--", "unknown"). - Fleet aggregates tested:
.online_count,.total_guests,.avg_disk_pct,.health_score,.worst_disk,.worst_memory. build_fleet()integration tested: nodes.json wiring, unmatched nodes, missing nodes.json.
Previous bugs caught by review
- Exit code
2displayed as "rc=2" — users thought it meant "release candidate 2". Fix:exit_code_label()indata.py. - Health computation in
dashboard.py— couldn't test without NiceGUI. Fix:Host/Fleetdomain classes with.healthy/.errors. except Exceptionin 6 page modules — masked real errors. Fix:except (httpx.HTTPError, OSError).- Red badge for "No WoL" — users thought it was an error. Fix: orange (warning/limitation, not failure).
- 200+ magic strings across test files — label change broke 26 tests.
Fix:
Routes,PageTitles,Labelsconstants indata.py. RegisteredNode(heartbeat data) andHost(env config) were separate parallel objects. Dashboard read rawnodes.jsonalongsideFleet. Fix: merged viaHostTelemetrydataclass wired bybuild_fleet(). Pages now useFleetexclusively for all host data.- Nodes page had no clickable detail view — users had to scan summary cards.
Fix: added
/nodes/{hostname}detail page with resources, guests table, network info, deploy history, extensions, and sparklines.