generated from john/python-template
Completes the table consolidation deferred within Phase 5. Section 4 of the review lists table construction as a duplication pattern; three call sites had been left bypassing the canonical builder. - table/common.py: build_table gains a row_key parameter so callers with a non-"id" primary key can use it. - linked_people.py: replaces its hand-rolled ui.table with build_table (row_key="person_id", selection="multiple", rows_per_page=0, no search). - print_preview_page.py: _render_metadata_table and _render_job_table now share a local _render_print_table helper. Print tables deliberately do not use build_table - they must never paginate or render a search box, and they carry print-only styling. The helper docstring records that rationale. - tests/test_ui_boundaries.py: new AST guard asserting ui.table() is called from exactly two modules - components/table/common.py and pages/print_preview_page.py. Also closes the intermittent tests/ui/test_jobs_page.py failure observed once after Phase 5 as environmental. Unreproduced across ~54 sequential full-suite runs (including a 25-run soak) and 5 concurrent-process runs. No code change. Verification: ruff check src tests clean; 275 passed, 4 skipped. Co-authored-by: Copilot App <[email protected]>