diff --git a/fusion_plating/docs/superpowers/specs/2026-04-25-overnight-progress-summary.md b/fusion_plating/docs/superpowers/specs/2026-04-25-overnight-progress-summary.md new file mode 100644 index 00000000..9bbadbe3 --- /dev/null +++ b/fusion_plating/docs/superpowers/specs/2026-04-25-overnight-progress-summary.md @@ -0,0 +1,371 @@ +# Overnight Progress Summary — Native Job Model Migration + +**Date:** 2026-04-25 (work performed Apr 25 evening through Apr 26 early morning) +**Branch:** `feat/fp-native-job-model` +**Tags:** `phase-1-complete`, `phase-2-complete` +**Test status (last verified on entech):** 50 tests passing (Phase 1+2) +**Test status (Phase 3-7):** untested due to Tailscale SSH lockout mid-session + +--- + +## TL;DR + +You went to bed asking me to "keep coding through all the phases." I did. The +data layer of the native job migration is complete on the branch and pushed +to GitHub. The cutover runbook is written. The full operator UI rewrite is +deferred to post-cutover hardening (it's a 5-day OWL/JS rewrite that genuinely +needs in-browser testing on entech). + +**Bottom line:** the legacy `mrp.production`/`mrp.workorder` flow on entech +is **untouched**. The new `fp.job`/`fp.job.step` flow exists in parallel, +gated behind a settings flag (`x_fc_use_native_jobs`, default False). Nothing +operators do today changes. When you're ready to cutover, follow the runbook +in `docs/superpowers/specs/2026-04-25-fp-native-job-cutover-runbook.md`. + +--- + +## Critical context: Tailscale SSH lockout mid-session + +Around Phase 5 my SSH calls to `pve-worker5` started returning a Tailscale +re-authentication URL. I couldn't access entech for the rest of the night. +This means: + +- **Phase 1 + 2 (Tasks 1.2 through 2.5):** tested live on entech. 50 tests pass. +- **Phase 3 onwards:** **NOT tested on entech.** Code is committed locally and + pushed to GitHub, but never installed/run on entech. +- **Migration script (Phase 7):** **NEVER executed.** Just authored. + +**First thing you should do when you wake up:** +1. Re-authenticate Tailscale (the URL was in the implementer's earlier output + blocks). Or, run `tailscale up` from your Mac. +2. Pull the latest branch on entech. +3. Run the test suite: `odoo --update=base -u fusion_plating_jobs --test-tags fusion_plating,fusion_plating_jobs --stop-after-init` +4. Triage anything that fails. + +--- + +## Commits added overnight + +``` +97861df refactor(jobs): gate fp.job lifecycle hooks on fp_jobs_migration context + feat(jobs): Phase 8/9/10 cutover runbook +f9fab69 feat(jobs): Phase 7 — migration script + legacy id fields +7137622 feat(jobs): Phase 6 lean — scan controller + process-tree JSON endpoint +c528d58 feat(jobs): Phase 5 — fp.job reports (sticker + traveller) +51a5cbb feat(jobs): Phase 4 light refactors — notifications, KPI source tag +b359be3 feat(jobs): Phase 3 light refactors — parallel job/step links on dependent models +dd88afd feat(jobs): add lifecycle hooks — portal/QC/delivery/invoice (Tasks 2.6-2.9) +294cea0 feat(jobs): add x_fc_use_native_jobs flag + SO confirm hook (Task 2.5) +3b7eae9 feat(jobs): add fp.job._generate_steps_from_recipe (Task 2.4) +4c68327 feat(jobs): add fp.job.node.override for per-job opt-in/out decisions +36b9f30 refactor(jobs): drop index=True on part_catalog_id for consistency +6e57b35 feat(jobs): add cross-module fields to fp.job via _inherit (Task 2.2) +4341a03 feat(jobs): add fusion_plating_jobs module skeleton (Phase 2 Task 2.1) +``` + +Plus the cutover runbook commit (no code). + +All pushed to `origin/feat/fp-native-job-model`. + +--- + +## What's complete + +### Phase 1 — Core models (Phase 1 Tasks 1.2–1.9, tagged) +- `fp.work.centre` — replaces `mrp.workcenter` for plating +- `fp.job` — replaces `mrp.production` +- `fp.job.step` — replaces `mrp.workorder` +- `fp.job.step.timelog` — granular timer tracking +- Sequence `WH/JOB/00001+` (`noupdate=1`) +- Manager-only admin views ("Plating Jobs (new)" menu) +- 28 unit tests passing on entech + +### Phase 2 — Native jobs bridge module (Tasks 2.1–2.10, tagged) +- New module `fusion_plating_jobs` alongside `fusion_plating_bridge_mrp` + (parallel coexistence, no destructive renames) +- 5 cross-module fields on `fp.job` via `_inherit` (part_catalog, + coating_config, customer_spec, portal_job, delivery) +- `fp.job.node.override` model for per-job opt-in/out +- Recipe → fp.job.step generator (`_generate_steps_from_recipe`) +- Settings flag `x_fc_use_native_jobs` + SO confirm hook +- Lifecycle hooks: portal job, QC check, delivery, certificates, invoice +- 50 unit tests total passing on entech + +### Phase 3 — Light refactors batch A (untested locally) +- Parallel `x_fc_job_id` / `x_fc_step_id` Many2ones added via `_inherit` on: + - `fusion.plating.batch` + - `fusion.plating.quality.hold` + - `fp.certificate` + - `fp.thickness.reading` + - `fusion.plating.delivery` + - `fp.racking.inspection` +- Racking inspection auto-create on job confirm (best-effort, skips if + legacy production_id required field can't be satisfied) + +### Phase 4 — Light refactors batch B (untested locally) +- Notifications: `job_confirmed` and `job_complete` events added to + `fp.notification.template`. Hooked from `fp.job.action_confirm` and + `button_mark_done`. +- KPI value source tag: `x_fc_source` selection on `fusion.plating.kpi.value` +- Verified `fusion_plating_aerospace`, `_nuclear`, `_cgp`, `_safety` don't + reference `mrp.production`/`mrp.workorder` (no refactor needed) +- Configurator integration was already complete via Task 2.5 + +### Phase 5 — Reports (untested locally) +- New `Job Sticker` paperformat (6×4") + QWeb template + report action, + bound to `fp.job`. QR encodes `/fp/job/`. +- New `Job Traveller` (A4 portrait) report bound to `fp.job`. Lists all + steps with sequence, work centre, kind, expected/actual minutes, state, + sign-off column. +- Both reports coexist with `fusion_plating_reports`' MO/WO bindings. +- Deferred (use existing during migration; rebind at cutover): BoL, packing + slip, invoice (read from SO), WO Margin (cost rollup). + +### Phase 6 lean — controllers (untested locally) +- `/fp/job/` HTTP scan-redirect controller. Manager → form, operator → + also form (process tree action stub). +- `/fp/jobs/process_tree` JSON-RPC endpoint serializing recipe + step state + for an OWL renderer. +- **Deferred to post-cutover:** Plant Overview kanban, Tablet Station UI, + Manager Dashboard, Process Tree OWL component. Documented in + `fusion_plating_jobs/README.md`. + +### Phase 7 — Migration script (untested, never executed) +- `legacy_mrp_production_id` (Integer index) on `fp.job` +- `legacy_mrp_workorder_id` on `fp.job.step` +- Three scripts in `fusion_plating_jobs/scripts/`: + - `audit_pre_migration.py` — pre-cutover row counts and data quality + - `migrate_to_fp_jobs.py` — main migration. Idempotent. Uses context flag + `fp_jobs_migration=True` to skip lifecycle side-effects during + migration (would otherwise create duplicate portal jobs / inspections + / certs). + - `audit_post_migration.py` — post-cutover verification + +### Phase 8/9/10 — Cutover runbook (doc only) +- `docs/superpowers/specs/2026-04-25-fp-native-job-cutover-runbook.md` +- Phase 8 — 5-day E2E test plan on entech-clone +- Phase 9 — Cutover weekend runbook (Friday 6pm → Monday 7am) +- Phase 10 — 2-week burn-in monitoring + rollback + +--- + +## What's NOT complete (deferred or pending verification) + +### Pending entech test (HIGH priority — first thing in the morning) + +After Tailscale re-auth, run on entech: + +```bash +ssh pve-worker5 "pct exec 111 -- bash -c 'systemctl stop odoo && su - odoo -s /bin/bash -c \"/usr/bin/odoo -c /etc/odoo/odoo.conf -d admin --update=base -u fusion_plating_jobs --test-tags fusion_plating,fusion_plating_jobs --stop-after-init\" 2>&1 | tail -30 && systemctl start odoo'" +``` + +Expected: **all tests pass** (28 from Phase 1 + 22 from Phase 2 + ~15 from +Phases 3-7 = ~65 tests). If anything fails, it's likely a model-name +mismatch I couldn't verify without entech access. + +Most likely failure points: +- Field name guesses on `fusion.plating.process.node` (`estimated_duration`, + `opt_in_out`, `requires_signoff`, etc. — verified by greps but not by + runtime instantiation) +- `fusion.plating.work.center.x_fc_fp_work_centre_id` doesn't exist (the + Phase 2 generator falls back to code lookup; should be fine) +- `fp.notification.template.trigger_event` — Selection extension via + `selection_add` should work but I didn't verify +- Migration script: completely untested + +### Operator UI rewrite (deferred to post-cutover) + +The full Phase 6 — Plant Overview kanban, Tablet Station, Manager Dashboard, +Process Tree OWL component — was scoped at 6 days of OWL/JS work. With +Tailscale blocked I couldn't iterate in a browser, so I shipped the +data-layer pieces (controller endpoints, scan-redirect) and deferred the +visible UI. Plan in the cutover runbook §10.5. + +### Phase-end polish (deferred) + +Documented in cutover runbook §10.5. Items include: +- `currency_id required=True` and explicit `ondelete=` policies uniformly + across both Phase 1 core fields and Phase 2 _inherit fields +- `tracking=True` on `fp.job.manager_id`, `facility_id` +- `digits='Product Unit of Measure'` on `qty` +- `_('New')` translation safety in `create()` +- Author/website/maintainer block in `fusion_plating_jobs/__manifest__.py` + (Nexa Systems convention; install warning currently emits) +- i18n wrapping on user-visible strings +- `_compute_state_ready` for fp.job.step pending → ready (TODO from Task 1.5) +- `button_pause` / `button_skip` / `button_cancel` real implementations + (currently raise NotImplementedError) + +--- + +## Architecture decisions made autonomously overnight + +These deviated from or extended the original spec/plan. Document them so you +can roll back if disagreement. + +1. **Phase 2 strategy revised: parallel coexistence vs. rename.** Original + plan said "rename `fusion_plating_bridge_mrp` → `fusion_plating_jobs`." + That's destructive on a live system — every existing record's xmlid + prefix would need to be migrated. Instead I built `fusion_plating_jobs` + as a NEW module alongside `fusion_plating_bridge_mrp`. Both can be + installed simultaneously. The settings flag controls which path SO + confirm takes. Cutover (Phase 9) flips the flag. This is documented in + the plan §6.2. + +2. **Phase 6 scoped down to lean.** Original Phase 6 was the full operator UI + rewrite (6 days). I shipped the data-layer pieces (scan controller, JSON + endpoint) and deferred the visible UI to post-cutover. Documented in + `fusion_plating_jobs/README.md` and the cutover runbook §10.5. + +3. **`qc_check_id` field on fp.job remains deferred.** Spec §5.1 lists it. + The target model `fusion.plating.quality.check` lives in + `fusion_plating_bridge_mrp` and we deliberately don't depend on bridge_mrp + from the new jobs module (avoids tying our future to bridge's lifecycle). + Phase 2 Task 2.7 originally meant to address this; I kept it deferred. + The QC auto-create still works via runtime model detection (best-effort). + +4. **Migration context flag.** I added an `fp_jobs_migration` context check to + `fp.job.action_confirm` and `button_mark_done` so the migration script can + skip lifecycle side-effects. Without this, the script would double-create + portal jobs / racking inspections / certs / notifications. + +5. **`_sql_constraints` → `models.Constraint`.** Discovered during Task 2.3 + that Odoo 19 deprecates `_sql_constraints` in favor of + `_unique_field = models.Constraint(...)`. Used the new form on + `fp.job.node.override` and any other models I added. Phase 1's + `_sql_constraints` on `fp.work.centre` still works but emits a warning; + it's on the polish list. + +6. **Bridge_mrp left untouched as a constraint.** Even when the constraint + was awkward (e.g. when both modules' SO confirm hooks would run with + flag=True). Documented as a Phase 9 cutover task to either gate + bridge_mrp's hook on the inverse flag, or uninstall its action_confirm + override entirely. + +--- + +## Files I touched / didn't touch + +### Created (all in `fusion_plating/fusion_plating_jobs/`): +- `__init__.py`, `__manifest__.py`, `README.md` +- `models/__init__.py`, `models/fp_job.py`, `models/fp_job_node_override.py`, + `models/sale_order.py`, `models/res_config_settings.py`, + `models/account_move.py`, `models/fp_portal_job.py`, `models/fp_batch.py`, + `models/fp_quality_hold.py`, `models/fp_certificate.py`, + `models/fp_thickness_reading.py`, `models/fp_delivery.py`, + `models/fp_racking_inspection.py`, `models/fp_notification_trigger.py`, + `models/fusion_plating_kpi_value.py` +- `views/res_config_settings_views.xml` +- `report/__init__.py`, `report/report_fp_job_sticker.xml`, + `report/report_fp_job_traveller.xml` +- `controllers/__init__.py`, `controllers/job_scan.py`, + `controllers/process_tree.py` +- `scripts/__init__.py`, `scripts/README.md`, + `scripts/audit_pre_migration.py`, `scripts/migrate_to_fp_jobs.py`, + `scripts/audit_post_migration.py` +- `security/ir.model.access.csv` +- `tests/__init__.py`, `tests/test_fp_job_extensions.py` + +### Created in `docs/superpowers/specs/`: +- `2026-04-25-fp-native-job-cutover-runbook.md` +- `2026-04-25-overnight-progress-summary.md` (this file) + +### Modified: +- `docs/superpowers/specs/2026-04-25-fp-native-job-model-design.md` (during + earlier Phase 1 work; locked decisions section) +- `docs/superpowers/plans/2026-04-25-fp-native-job-model.md` (during earlier + Phase 1 + Phase 2 task breakdown; ACL convention fix; spec field deferral + documentation) + +### Did NOT touch (per constraints): +- `fusion_plating/fusion_plating/` (Phase 1 core — locked) +- `fusion_plating/fusion_plating_bridge_mrp/` (legacy MRP bridge — must keep + working for entech operators) +- `fusion_plating/fusion_plating_configurator/`, + `fusion_plating_portal/`, `fusion_plating_logistics/`, + `fusion_plating_quality/`, `fusion_plating_certificates/`, + `fusion_plating_batch/`, `fusion_plating_receiving/`, + `fusion_plating_kpi/`, `fusion_plating_notifications/`, + `fusion_plating_reports/`, `fusion_plating_shopfloor/` — original modules +- Anything else in the monorepo + +--- + +## Recommended morning checklist + +1. **Re-auth Tailscale** (the URL was in earlier subagent output if needed; or `tailscale up`) + +2. **Pull the branch on Mac:** + ```bash + cd /Users/gurpreet/Github/Odoo-Modules + git fetch origin + git status # should show clean tree on feat/fp-native-job-model + ``` + +3. **Sync the branch state to entech:** + ```bash + # The branch is already pushed to GitHub. To get it on entech: + ssh pve-worker5 "pct exec 111 -- bash -c 'cd /mnt/extra-addons/custom && git fetch origin feat/fp-native-job-model && git checkout feat/fp-native-job-model && git pull'" + # If entech doesn't have a git checkout, sync via base64+pct exec for the new files + # in fusion_plating_jobs/ + ``` + +4. **Run the full test suite on entech:** + ```bash + ssh pve-worker5 "pct exec 111 -- bash -c 'systemctl stop odoo && su - odoo -s /bin/bash -c \"/usr/bin/odoo -c /etc/odoo/odoo.conf -d admin --update=base -u fusion_plating_jobs --test-tags fusion_plating,fusion_plating_jobs --stop-after-init\" 2>&1 | tail -40 && systemctl start odoo'" + ``` + Expected: **all tests pass.** If anything fails, paste the error and I'll fix. + +5. **Smoke test the new flow manually** (browser): + - Log in as a manager. + - **Settings → Fusion Plating Jobs → Use Native Plating Jobs** flag — DON'T turn on yet. + - Open **Plating Jobs (new)** menu. + - Create a Work Centre, then a Job, then add Steps. Confirm. Mark a step + started, then finished. + - Print the Job Sticker. Verify QR. + - Print the Job Traveller. + +6. **Read the cutover runbook:** + `docs/superpowers/specs/2026-04-25-fp-native-job-cutover-runbook.md` + +7. **When ready,** schedule a Phase 8 test (entech-clone) with at least 1 + week notice. Then Phase 9 cutover with at least 4 weeks notice. + +--- + +## Honest assessment + +The code is consistent with the architecture decisions in the spec. The +parallel-coexistence strategy means even if I have a bug in the migration +script, **bridge_mrp keeps working** and the production system isn't +affected. + +What I'd worry about most: +- **Migration script field-name accuracy.** I made best-effort guesses about + the `x_fc_*` field names on bridge_mrp's `mrp.production` and + `mrp.workorder`. If those names are different from what I assumed, the + migration silently skips fields. A pre-migration audit run on + entech-clone will surface this. +- **Lifecycle hook coverage during migration.** The `fp_jobs_migration` + context flag I added bypasses portal/QC/cert/inspection creation. If + there's another hook I missed (e.g. a `create()` override), it will fire + during migration and may double-create. The audit_post_migration script + will catch counts that don't match. +- **Phase 3 racking inspection auto-create.** Currently degrades silently + when there's no MO. After cutover with the flag flipped, jobs won't have + MOs, so racking inspection won't auto-create. Need to either modify + `fp.racking.inspection.production_id` to be optional, or add a + `x_fc_job_id`-keyed create path. + +What I'm confident in: +- Phase 1 is rock solid. 28 tests pass. Models are clean. Code reviewed. +- Phase 2 is rock solid. 22 more tests pass. Reviewed. +- Phase 3-5 are likely correct (defensive `_fields` checks throughout) but + unverified on entech. + +--- + +Sleep well. Branch is safe. Production is safe. 14 commits ahead of where +you went to bed, all atomic and reversible if needed. + +— Claude