fix(shopfloor): sudo cross-module reads in Plant Kanban _render_card

Post-migration, Technicians (now group_fp_technician) have read on
fp.job but NOT on sale.order / fp.part.catalog / fusion.plating.customer.spec.
The kanban render path tries to access job.sale_order_id.x_fc_po_number
and AccessErrors silently — kanban returns empty, user sees blank
'Shop Floor' page.

Fix: `job = job.sudo()` at the top of _render_card. The output is
denormalized display data, no security concerns; ACL gating is still
enforced by the caller's access to fp.job (which Technician does have).

CLAUDE.md rule 13m documents the broader pattern: any dashboard /
tablet / kanban controller surfacing cross-module data to low-priv
roles needs this sudo at the helper top.

Module version: 19.0.32.0.8 -> 19.0.32.0.9

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-24 10:19:39 -04:00
parent e99cf20887
commit 31740b3949
3 changed files with 16 additions and 2 deletions

View File

@@ -172,13 +172,19 @@ def _resolve_card_area(job):
def _render_card(job, paired):
"""Build the full card payload for one fp.job."""
# Sudo the job recordset so cross-module field reads (sale.order,
# fp.part.catalog, fusion.plating.customer.spec) don't AccessError
# for low-privilege roles like Technician. The output is denormalized
# display data; the underlying record visibility is controlled by the
# caller's fp.job ACL (Technician can read all jobs).
job = job.sudo()
step = job.active_step_id
try:
timeline = json.loads(job.mini_timeline_json or '[]')
except (TypeError, ValueError):
timeline = []
# Cross-module field probes
# Cross-module field probes (sudo'd via job.sudo() above)
part = job.part_catalog_id if 'part_catalog_id' in job._fields else None
spec = job.customer_spec_id if 'customer_spec_id' in job._fields else None
so = job.sale_order_id