Files
Odoo-Modules/fusion_plating/docs/superpowers/specs/2026-05-22-shopfloor-tablet-redesign-design.md
gsinghpal fb5da1e3cd docs(fusion_plating_shopfloor): brainstorm spec for tablet redesign
Multi-section design covering:

- 3 OWL client actions: fp_shopfloor_landing (replaces fp_shopfloor_tablet
  + folds in fp_plant_overview), fp_job_workspace (NEW full-screen WO
  surface), fp_manager_dashboard (refactored — 4 sibling tabs incl.
  Workflow Funnel, Approval Inbox, At-Risk).

- 5 shared OWL services: WorkflowChip, GateViz, SignaturePad,
  HoldComposer, KanbanCard — reused across all three client actions to
  enforce one-widget-one-place and prevent terminology drift.

- Backend additions: 8 new RPC endpoints, blocker_kind/reason computes
  on fp.job.step, display_wo_name + late_risk_ratio + active_step_id on
  fp.job, bottleneck_score on fp.work.centre, auto-pause cron (fixes
  411h ghost timer), ACL lift for operator group per "techs wear
  multiple hats" rule.

- Terminology pass: WO # 00001 (display only, sequence rename deferred),
  Shop Floor / Up Next / Embrittlement Bakes / etc.

- 5-phase deploy sequence, each phase independently shippable.

- Out of scope (deferred to v2): cost roll-up, cycle time, per-tech
  throughput, system-wide sequence rename.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 21:31:15 -04:00

28 KiB
Raw Blame History

Shop Floor Tablet Redesign — Design Spec

Date: 2026-05-22 Status: Brainstorm complete, awaiting user review Authors: Garry Singh + Claude Module owners: fusion_plating_shopfloor, fusion_plating_jobs Target client: EN Technologies (Fusion Plating)


1. Context

The current Shop Floor tablet view (client action fp_shopfloor_tablet, OWL component ShopfloorTablet) was built during the initial Fusion Plating implementation. Since then the underlying models — fp.job, fp.job.step, fp.job.workflow.state, fp.certificate, fp.thickness.reading, fp.job.consumption, fp.job.node.override, fp.racking.inspection and friends — have grown substantially. Many of those new fields, actions, and workflows are not surfaced on the tablet.

Symptoms observed on a live development instance:

  • Step name shows "Active: Blasting" with no WO/customer context
  • Qty rendered as "Qty 17/1" — ambiguous direction
  • Step position shown as "step 1.1/11" (sequence divided by 10)
  • Active timer reading 411:52:16 — a stale start that never finished and was never auto-paused
  • "SIGN-OFF REQUIRED" chip is informational only; no actual sign-off control
  • Customer spec, drawings, recipe overrides, milestone progress, holds, and most lifecycle actions are invisible

Three roles operate the system: Owner, Manager, Technician. Technicians wear multiple hats (receiving, plating, QC, shipping) — the client explicitly wants minimal gating between roles.

2. Goals

  • A technician can manage a WO end-to-end from a single full-screen workspace, without typing into search bars or jumping to the back-office.
  • A manager can see at a glance: where every WO is in the workflow, what needs their decision right now, what's trending late, and where the bottlenecks are.
  • All recent additions to fp.job / fp.job.step (workflow milestones, blocker reasons, recipe overrides, customer spec, etc.) are surfaced on the tablet and manager dashboard.
  • Terminology matches how techs talk on the shop floor — "WO # 00001" not "WH/JOB/00001".
  • The system never displays a 411-hour ghost timer.

3. Non-goals (v1)

  • Multi-tablet pairing per technician
  • Offline-first / PWA mode
  • Voice input
  • Performance optimization beyond ~500 active jobs (current scale: ~50)
  • Webhooks to external dashboards
  • Cost roll-up per job, cycle time per recipe, per-tech throughput (P2 — deferred to v2)
  • System-wide rename of fp.job sequence (WH/JOB/...WO ...) — display-only on tablet for now; back-office/reports/emails keep current sequence until a separate decision is made

4. Terminology decisions

All approved in brainstorm:

Element Was Is now
Page title "Tablet Station" Shop Floor (with station chip e.g. "@ EN Plating Tank")
Document number WH/JOB/00001 WO # 00001 (display only)
Active step header "Active: Blasting" "WO # 00001 — Blasting" (Step 1 of 11)
Qty "Qty 17/1" "1 / 17 done" + scrap subtext + mini progress bar
Step position "step 1.1/11" "Step 1 of 11"
Sign-off chip "SIGN-OFF REQUIRED" "Finish & Sign Off" action button (replaces plain Finish)
Queue heading "My Queue" "Up Next" (at this station)
Bath state "OPERATIONAL / LOG: OUT_OF_SPEC" "Operating" / "Last log out of spec"
Bake panel "Bake Windows" "Embrittlement Bakes"
Gate panel "First-Piece Gates" "First-Piece Inspections"
Tile set 6 mixed tiles 4 tech-relevant tiles: Ready · Running · Bakes Due · Holds (others move to manager dashboard)
Stale timer "411:52:16" Auto-pause at 8h (configurable) with chatter audit; display switches to "Started Nd ago" past 24h

5. Architecture — option B (specialized components + shared services)

Three OWL client actions, five shared OWL services, a small set of backend additions. Each client action is independently deployable.

┌────────────────────────────────┐  ┌────────────────────────────────┐  ┌────────────────────────────────┐
│  fp_shopfloor_landing          │  │  fp_job_workspace              │  │  fp_manager_dashboard          │
│  (replaces fp_shopfloor_tablet │  │  NEW — full-screen WO surface  │  │  refactored — 4 tabs           │
│   + folds in fp_plant_overview)│  │                                │  │                                │
│  • station-scoped kanban       │  │  • sticky header + WO chips    │  │  • Workflow Funnel (default)   │
│  • All-Plant toggle            │  │  • workflow milestone bar      │  │  • Approval Inbox              │
│  • QR scan, station picker     │  │  • step list + side panel      │  │  • Plant Board (existing)      │
│  • tap card → JobWorkspace     │  │  • sticky action rail          │  │  • At-Risk                     │
└────────────────────────────────┘  └────────────────────────────────┘  └────────────────────────────────┘
                  │                                  │                                  │
                  └──────────────────────────────────┴──────────────────────────────────┘
                                                     │
                                        ┌────────────┴────────────┐
                                        │   Shared OWL services   │
                                        │  WorkflowChip · GateViz │
                                        │  SignaturePad · KanbanCard │
                                        │  HoldComposer           │
                                        └─────────────────────────┘

5.1 Shared OWL services

Service Used by Props Depends on
WorkflowChip Landing card · Workspace header · Manager funnel { state: {id, name, color}, nextActionLabel? } fp.job.workflow.state records (already shipped). Reads color field.
GateViz Workspace step rows · Manager "Needs Worker" cards { canStart, blockerKind, blockerReason, jumpTarget? } New fp.job.step.blocker_kind + blocker_reason computes
SignaturePad Workspace (Finish & Sign Off) · Cert issue { title, contextLabel, onSubmit(dataUri), onCancel } Odoo dialog service; HTML canvas + pointer events
HoldComposer Workspace (Hold button) · Manager Approval Inbox { jobId, stepId?, defaultQty, partRef, onCreated(hold) } New endpoint /fp/workspace/hold (with photo attachment)
KanbanCard Landing (station + all-plant) · Manager (Plant Board + Workflow Funnel) { data, density: 'compact'|'normal', showWorkflowChip, showWorkcenter, showAssignedTo, onTap } Embeds WorkflowChip + GateViz badge

Each service is its own file under fusion_plating_shopfloor/static/src/js/components/. Roughly 80200 lines OWL + 3080 lines SCSS per service.

5.2 Landing component (fp_shopfloor_landing)

Replaces today's fp_shopfloor_tablet, folds in fp_plant_overview. Single entry surface for technicians.

Layout regions (top-to-bottom):

  1. Header strip — "Shop Floor" title, station chip, station picker, mode toggle (StationAll Plant), QR scan controls (Code + Camera), refresh indicator.
  2. KPI tile row (4 tiles) — Ready · Running · Bakes Due · Holds. Holds turns red when > 0.
  3. Kanban board — columns = work centres; cards = KanbanCard (one per WO at that work centre); urgency-sorted within column (existing logic in plant_overview.py carries over). Drag-and-drop between columns keeps current behaviour.
  4. Optional left filter rail (collapsed by default) — search box, priority, customer, due-by, blocker filter. Promote the existing plant_overview search bar.
  5. Footer — auto-refresh indicator + "Last sync HH:MM:SS".

Mode behaviour:

Mode Columns shown Default when
Station Paired work centre + Unassigned + next 12 work centres in the recipe flow A station is paired (via QR scan or picker)
All Plant Every active work centre, recipe-flow order No station paired, OR user toggles

Toggle persists in localStorage per tablet (same pattern as fp_tablet_station_id).

Card tap behaviour:

action.doAction({
  type: 'ir.actions.client',
  tag: 'fp_job_workspace',
  params: { job_id: card.job_id, focus_step_id: card.current_step_id }
});

Browser back returns to Landing with kanban scroll/mode preserved.

QR scan dispatch (existing /fp/shopfloor/scan endpoint, unchanged):

Scanned Behaviour
FP-STATION:<code> Pair tablet, switch to Station mode
FP-JOB:<name> Open JobWorkspace for that WO
FP-STEP:<id> Open JobWorkspace, focus that step
FP-TANK:<code> / FP-BATH:<name> Chemistry quick-log dialog (existing endpoint)
FP-OVEN:<code> Jump to next bake awaiting that oven

Auto-refresh — every 15s.

Files:

fusion_plating_shopfloor/
  controllers/landing_controller.py         ← NEW (~250 lines)
  static/src/js/shopfloor_landing.js        ← OWL (~600 lines)
  static/src/xml/shopfloor_landing.xml
  static/src/scss/shopfloor_landing.scss

5.3 Job Workspace component (fp_job_workspace)

The heart of the redesign. Full-screen surface a tech opens by tapping a kanban card.

Layout regions (sticky top → scrollable middle → sticky bottom):

Region Sticky Data Behaviour
Back top doAction back to Landing, preserves kanban scroll/mode
WO header top display_wo_name, partner_id, part_catalog_id + rev, qty/qty_done/qty_scrapped, date_deadline, workflow_state_id, quality_hold_count, customer_spec_id +1 Done / 1 Done / +1 Scrap quick bumps inline. Holds count → opens Holds drawer.
Workflow milestone bar top All fp.job.workflow.state records ordered by sequence; current = workflow_state_id; next_milestone_action + next_milestone_label Dots: passed (●), current (filled), pending (○). "Next" button on right fires /fp/workspace/advance_milestone. Disabled until preconditions met.
Step list (left/center, scrolls) scrolls fp.job.step_ids sorted by sequence Each row uses step-row template (see below). Active step auto-scrolled and auto-expanded if focus_step_id param set.
Side panel (collapsible right) scrolls customer_spec_id (PDF), attachments, chatter Three sub-cards: Spec (inline via fusion_pdf_preview), Drawings, Notes (chatter — read + quick-add). Collapses to icon strip on narrow screens.
Action rail bottom Always: Create Hold (HoldComposer), Add Note, Photo. Conditional: Issue Cert (when _fp_has_draft_required_certs()), Mark Done / Schedule Delivery / Mark Shipped (per next_milestone_action).

Step row anatomy:

  • Collapsed (default for done/pending/paused): one line — icon + Step N · Name + assigned tech + duration + state badge
  • Expanded active (auto for state == 'in_progress'): recipe chips + instructions + primary + secondary actions
  • Expanded by tap (any step): same shape, action buttons gated by can_start

Per-step actions:

Button Visible when Calls
Start state in ('ready','paused') AND can_start /fp/shopfloor/start_wo
Finish (or Finish & Sign Off) state == 'in_progress' /fp/shopfloor/stop_wo (finish=true) OR /fp/workspace/sign_off if requires_signoff
Pause state == 'in_progress' step.button_pause()
Skip state in ('ready','paused') AND user is supervisor+ step.button_skip()
Move Parts always FpMovePartsDialog (existing)
Move Rack when kind == 'rack' FpMoveRackDialog (existing)
Quick QC when quick_look_prompt_ids non-empty step.action_open_quick_look()
Operator Inputs when step has unrecorded inputs step.action_open_input_wizard() (existing wizard)
Photo always inline camera → attach to step
Stop Timer (correction) when duration looks wrong FpStopTimerDialog (existing)
Open in backend always (small icon) doAction to fp.job.step form (escape hatch)

When step is blocked (can_start == False), action button row is replaced by GateViz block.

When step is opted out (override_ids says excluded), row shows ✕ icon + "Skipped per recipe override" + supervisor-only "Re-include" button.

Auto-pause integration — if _cron_autopause_stale_steps flips a step to paused, the row's chatter reflects "Auto-paused after Nh idle". Tech can tap Resume.

Auto-refresh — every 15s.

Files:

fusion_plating_shopfloor/
  controllers/workspace_controller.py        ← NEW (~400 lines)
  static/src/js/job_workspace.js             ← OWL (~800 lines)
  static/src/xml/job_workspace.xml
  static/src/scss/job_workspace.scss
  static/src/js/components/{workflow_chip,gate_viz,signature_pad,hold_composer,kanban_card}.js

5.4 Manager Dashboard refactor (fp_manager_dashboard)

Same client action, four sibling tabs under a shared header + KPI strip.

KPI strip (extended): keep existing 4 always-on (Unassigned Steps · In Progress · Ready to Ship · Awaiting Assignment) + existing conditional reds (Missed Bakes · Open Holds · Stale Steps · Predecessor Locked) + 2 new: Pending Cert · At-Risk.

Tabs:

Tab Default? Content
Workflow Funnel yes Vertical stack of fp.job.workflow.state records. Each row shows stage chip + count badge + first ~5 KanbanCards + "+ N more" drawer. Bar chart bar behind the row scaled to count. Tap card → JobWorkspace.
Approval Inbox no 4 grouped strips: Holds to Release (state in ('on_hold','under_review')), Certs to Issue (all_steps_terminal + draft required cert), Scrap to Review (recent qty_scrapped bumps with operator reason), Override Requests (deferred — placeholder). Per-row inline action buttons + bulk-action ("Release all").
Plant Board no Today's existing 3-column "Needs Worker / In Progress / Team" view — unchanged behaviour. Becomes one tab among four.
At-Risk no 3 sub-panels: Trending Late (sorted by late_risk_ratio desc, top 20), Hold Reasons (open holds grouped by hold_reason), Bottleneck Heatmap (work centres ranked by bottleneck_score).

Cross-tab features: live 8s refresh (existing cadence), QR scan in header, "Take Over Tablet" supervisor handover.

Permissions: dashboard already gated to group_fusion_plating_supervisor+. That stays. Owner + Manager hit this; Technicians don't.

Files:

fusion_plating_shopfloor/
  controllers/manager_controller.py         ← add 3 endpoints (funnel, approval_inbox, at_risk)
  static/src/js/manager_dashboard.js        ← refactor: extract Plant Board, add 3 sibling tabs
  static/src/xml/manager_dashboard.xml
  static/src/scss/manager_dashboard.scss

6. Backend support

6.1 HTTP endpoints

All type='jsonrpc', auth='user'.

NEW — added by this work:

Endpoint Lives in Purpose
POST /fp/landing/kanban landing_controller.py Station OR all-plant kanban data
POST /fp/workspace/load workspace_controller.py Full Job Workspace payload
POST /fp/workspace/hold workspace_controller.py HoldComposer create (with photo)
POST /fp/workspace/sign_off workspace_controller.py Signature + finish step atomically
POST /fp/workspace/advance_milestone workspace_controller.py Fire next_milestone_action
POST /fp/manager/funnel manager_controller.py (add) Workflow funnel data
POST /fp/manager/approval_inbox manager_controller.py (add) Holds + draft certs + scrap to review
POST /fp/manager/at_risk manager_controller.py (add) Late-risk + hold reasons + bottlenecks

KEPT — unchanged, used by new components via wrappers: /fp/shopfloor/scan, start_wo, stop_wo, start_bake, end_bake, log_chemistry, log_thickness_reading, bump_qty_done, bump_qty_scrapped, mark_gate, pair_station.

DEPRECATED — kept as stubs for 1 release, then removed:

  • /fp/shopfloor/tablet_overview → calls /fp/landing/kanban internally
  • /fp/shopfloor/plant_overview → calls /fp/landing/kanban?mode=all_plant
  • /fp/shopfloor/queue → removed (no replacement)

6.2 Model fields / computes

On fp.job (fusion_plating_jobs/models/fp_job.py):

Field Type Purpose
display_wo_name computed Char "WO # 00001" formatter from name
late_risk_ratio computed Float, stored remaining_planned_minutes / minutes_to_deadline
active_step_id computed Many2one→fp.job.step Current in_progress step (Workspace landing focus)

On fp.job.step (fusion_plating_jobs/models/fp_job_step.py):

Field Type Purpose
blocker_kind computed Selection predecessor · contract_review · parts_not_received · racking_required · manager_input · none
blocker_reason computed Char Human reason (e.g. "Waiting on Step 3: Activation")
blocker_jump_target_model computed Char Optional tap-to-jump target model
blocker_jump_target_id computed Integer Optional tap-to-jump target id

On fp.work.centre (fusion_plating/models/fp_work_centre.py):

Field Type Purpose
bottleneck_score computed Float, non-stored active_step_count × avg_wait_minutes
avg_wait_minutes computed Float, non-stored Rolling 7-day avg ready→start wait

On fusion.plating.process.node (recipe node):

Field Type Purpose
long_running Boolean Opt out of auto-pause (24h bakes etc.)

6.3 Auto-pause cron

<!-- fusion_plating_jobs/data/fp_cron_data.xml -->
<record id="ir_cron_autopause_stale_steps" model="ir.cron">
    <field name="name">FP Jobs: auto-pause stale in-progress steps</field>
    <field name="model_id" ref="model_fp_job_step"/>
    <field name="state">code</field>
    <field name="code">model._cron_autopause_stale_steps()</field>
    <field name="interval_number">30</field>
    <field name="interval_type">minutes</field>
    <field name="active" eval="True"/>
</record>

Method (fp_job_step.py):

@api.model
def _cron_autopause_stale_steps(self):
    threshold = float(self.env['ir.config_parameter'].sudo()
        .get_param('fp.shopfloor.autopause_threshold_hours', 8))
    deadline = fields.Datetime.now() - timedelta(hours=threshold)
    stale = self.search([
        ('state', '=', 'in_progress'),
        ('date_started', '<', deadline),
        ('recipe_node_id.long_running', '=', False),
    ])
    for step in stale:
        step.button_pause()
        step.message_post(body=Markup(
            "<b>Auto-paused</b> after %.1fh idle. "
            "Resume from the tablet when work continues."
        ) % threshold)
        _logger.info("Auto-paused step %s after %.1fh idle", step.id, threshold)

ir.config_parameter key: fp.shopfloor.autopause_threshold_hours (default 8).

6.4 ACL changes (operator group)

Per "techs wear multiple hats" rule — minimal new gates.

Model Read Write Create Unlink Notes
fp.certificate ✓ existing NEW ✓ Flip draft → issued from tablet "Issue Cert"
fp.thickness.reading NEW ✓ NEW ✓ NEW ✓ Capture Fischerscope readings from tablet
fp.job.node.override NEW ✓ Read-only — tech sees opt-out badge

Supervisor-only operations enforced in workspace_controller.py (not via ACL):

  • Step Skip (button_skip)
  • Hold Release (state transition on_holdreleased)
  • Override Re-include

6.5 Terminology — display_wo_name

fp.job.display_wo_name is a computed Char that formats name as WO # 00001. All new tablet/dashboard payloads use this field. The underlying fp.job.name (WH/JOB/00001) stays unchanged — reports, emails, back-office forms continue using name.

System-wide sequence rename is out of scope for this work. If pursued separately, it requires: (a) updating ir.sequence prefix to WO , (b) backfill script for existing records, (c) coordination with any external integrations that grep on the old prefix.

7. Build & deploy sequence

Each phase is independently deployable. Rollback is per-phase, not all-or-nothing.

Phase Ships Independently deployable?
1 Shared OWL services + JobWorkspace + workspace_controller + fp.job.step blocker_* computes + display_wo_name. Opens from existing fp.job form smart button. Yes — works before Landing refactor
2 Auto-pause cron + ACL lift + late_risk_ratio + active_step_id computes Yes — silent infra
3 landing_controller + fp_shopfloor_landing component. Old fp_shopfloor_tablet menu redirected. PlantOverview menu hidden. Yes — Workspace already works via smart button
4 3 new manager endpoints + manager dashboard refactor (4 tabs) + bottleneck_score compute Yes
5 Cleanup: remove deprecated endpoint stubs, retire fp_plant_overview module dir Last

8. Testing strategy

8.1 Python tests (fusion_plating_shopfloor/tests/)

Test Verifies
test_display_wo_name Formatter handles various name shapes
test_late_risk_ratio Correct ratio with deadline / no deadline / overdue / not started
test_active_step_id Sole in_progress step; empty when none; first-by-sequence when multiple
test_blocker_kind_and_reason Each kind returns correct enum + human string + jump target
test_autopause_cron Stale flips; chatter posted; respects long_running; idempotent
test_workspace_load_payload Full payload shape — keys, types, opted-out marked
test_workspace_sign_off Signature captured, step finished, empty-sig rejected
test_workspace_advance_milestone Fires only when preconditions met; friendly error otherwise
test_hold_composer_create Hold + photo + qty split; rollback on validation error
test_acl_operator_permissions Operator can issue cert, cannot skip step (controller gate)
test_funnel_and_inbox Funnel grouping correct; inbox returns all 4 buckets

8.2 OWL tests (light)

  • WorkflowChip renders correct color per state
  • GateViz renders correct copy per blocker_kind
  • SignaturePad returns non-empty data URI after stroke
  • HoldComposer validates qty ≤ remaining before submit
  • KanbanCard collapses chips at compact density

8.3 Manual QA checklist

Lives at docs/qa/shopfloor-redesign-qa.md. 10-step walkthrough covering: pairing → Landing modes → tap card → Workspace → Finish & Sign Off → Create Hold → Manager Funnel → Approval Inbox release → auto-pause test → dark mode.

9. Observability

  • _logger.INFO on milestone advance, hold create from tablet, sign-off, auto-pause
  • _logger.WARNING on workspace_load with bad job_id, sign_off with empty data URI
  • _logger.EXCEPTION on controller failures (existing pattern)
  • Chatter audit on auto-pause, hold create, milestone advance, sign-off

Future metrics (flagged, no infra now): tablet refresh frequency, time-to-Start from Workspace open, auto-pause rate, hold creation rate.

10. Edge cases

Case Handling
Job has zero steps "Recipe not generated" placeholder + back-office link
Job has 50+ steps Standard scroll, no virtualization in v1
All steps in_progress (defensive) active_step_id picks first by sequence; logs warning
No workflow states defined Bar hides; Next button disabled
Step state changed during 15s gap Refresh corrects; no error toast
Two techs tap Start simultaneously button_start idempotent; second call returns state
Wrong station scanned Header "Unpair" link; localStorage cleared
Network drop mid-action Toast "Saving failed — tap to retry"; UI state preserved
24h-bake step recipe_node.long_running=True skips auto-pause
Customer spec PDF missing Side panel: "No customer spec attached"
Funnel with 200+ jobs in stage Top 5 cards + "View all (N)" drawer
Operator with no facility Landing prompts pick-or-scan station
HoldComposer fails after photo upload Photo cleaned in except block — no orphans
Manual step (no recipe_node_id) Chips/instructions empty — OK
Sign-off step finished from back-office Workspace re-renders without re-prompting
Tech opens Workspace for unassigned job Allowed — read+write per "many hats" rule

11. Performance

Surface Load shape Mitigation
Landing kanban (All Plant, ~400 cards) Existing plant_overview.py batch prefetch carries over None new
Workspace load (1 job × ~11 steps) Trivial None
Manager funnel (~50 jobs × 9 stages) Trivial None
Manager At-Risk (7-day step state scan) Potentially heavy on large plants Cache 60s per facility
Auto-pause cron Filtered query, no N+1 None
late_risk_ratio (stored) Recomputed on step state change @api.depends triggers

12. Rollback strategy

Phase Rollback
1 (Workspace) Hide smart-button entry in fp.job form. Workspace becomes orphan, harmless.
2 (Cron + ACL) Disable cron via UI. ACL changes are CSV-line edits.
3 (Landing) Re-enable old fp_shopfloor_tablet menu. Old endpoint stub still active.
4 (Manager) Revert manager_dashboard.xml to single Plant Board tab.
5 (Cleanup) Defer if issues — leave stubs longer.

Only stored field added is late_risk_ratio Float — additive ALTER TABLE, safe to drop.

13. Backwards compatibility

  • All existing QR codes keep working — /fp/shopfloor/scan unchanged
  • Existing fp.job form smart buttons → Workspace opens via doAction
  • Existing fp.job.step form view stays as "Open in backend" escape hatch
  • Old reports/emails keep showing WH/JOB/00001 (sequence rename deferred)

14. Decisions log

Decision Rationale
Hybrid mental model (queue → workspace), not pure queue or pure job-first Queue is the natural entry; full workspace solves "manage the whole job" goal
One tablet, no role-segmentation per persona Client said techs wear multiple hats; minimal gating
Architecture B (specialized components + shared services) over mega-component Each surface has its own lifecycle; shared services enforce consistency
Station-scoped kanban as default landing, All Plant as toggle Matches physical reality (tablet at station) + provides escape hatch
Approval Inbox + Workflow Funnel as new manager tabs, Plant Board stays Tactical (assignment) and strategic (where is everything) views coexist
Auto-pause stale timers at 8h default Solves the 411-hour ghost timer permanently; protects cost/cycle-time math
WO # display only; sequence rename deferred Lower risk; user can choose system-wide rename separately
ACL lift for operator group on cert / thickness reading / override read Per "techs wear many hats" rule; supervisor-only ops enforced in controller, not ACL

15. Out of scope for v1

  • Multi-tablet pairing per tech
  • Offline-first / PWA mode
  • Voice input
  • Performance optimisation beyond ~500 active jobs
  • Webhooks to external dashboards
  • Cost roll-up per job (P2)
  • Cycle time per recipe (P2)
  • Notification audit feed (P2)
  • Per-tech throughput (P2)
  • System-wide fp.job sequence rename to WO prefix

Next step: user reviews this spec; once approved, transition to superpowers:writing-plans skill to produce the phased implementation plan.