At a glance
| Hand-written code | 126,230 lines in 639 files (115,042 non-blank) |
| Web pages | 78 HTML pages in 12 menu groups (77 live, 1 built and not yet deployed) |
| HTTP API | 57 controllers · 240 controller actions (145 GET, 57 POST, 30 PUT, 8 DELETE) + 8 minimal-API routes |
| Live updates | 1 SignalR hub, 7 change events (production, PC&L, design timeline, timeline links, toolroom timeline, firm dates, cancelled jobs) |
| Background jobs | 11 hosted services (Plex refreshers, people cache, notification and email engines, EASE import, publish cleanup, file-drop import) |
| C# types | 1,055 classes, records, structs, interfaces and enums in the API and contracts |
| Plex ERP reads | ~120 distinct ODBC views and tables · 17 REST routes (master data, HCM time clock, production history, purchasing, scheduling) |
| Own storage | 11 SQLite databases + a JSON project store |
| Access model | 16 roles (13 derived from Plex HR data, 3 hand-assigned) · 12 named capabilities |
| Automated tests | 441 xUnit tests (49 files) · 86 Node tests (8 files) · 15 Python · 6 Kotlin · 5 AutoCAD-core |
| Deployments | 51 scripted deploy packages · 149 deployment backups (July → October 2026) |
| Timeline | First source files March 2026 · active through October 2026 |
Lines of code by language
Excluded: vendored libraries (MSAL, three.js, OCCT STEP importer, d3/topojson map data), minified JS, Python virtual environments, the Gradle cache, the bundled Java runtime, bin/obj and other build output, backups and deployment backups, staged deploy packages, generated JSON (timeline indexes, status files, geo data), exported Plex document-link chunks, logs and screenshots. Where a frontend file exists in both the source tree and the live folder, it is counted once (source copy); files that exist only in the live folder are added.
| Language | Lines | Files |
|---|---|---|
| C# | 50,502 | 280 |
| JavaScript | 34,505 | 116 |
| PowerShell | 12,445 | 75 |
| HTML | 10,434 | 79 |
| CSS | 9,787 | 33 |
| Python | 6,101 | 23 |
| Kotlin | 2,009 | 21 |
| C++ (Arduino) | 334 | 1 |
| XML (Android resources) | 83 | 8 |
| Batch | 30 | 3 |
| Total | 126,230 | 639 |
Not counted above: 12,151 lines of Markdown documentation (79 files): design notes, data-viability studies, deploy write-ups and add-in specs.
Lines of code by module
| Module | Lines | Files | What it is |
|---|---|---|---|
| WarRoom.Frontend | 53,339 | 217 | 78 pages; 33,516 JS · 10,036 HTML · 9,787 CSS |
| WarRoom.Api | 38,132 | 211 | ASP.NET Core service: controllers, Plex sources, analytics, stores, background jobs |
| Ops scripts | 14,385 | 72 | Deploy/validate/rollback packages, certificate and hostname setup, local proxies |
| WarRoom.Api.Tests | 8,700 | 49 | xUnit suites |
| Office integrations | 3,391 | 13 | EASE action-plan monitor, Plex document and project-file indexers |
| Android tablet app | 2,092 | 29 | Kotlin/Compose scanner app for the toolroom floor |
| Tools | 1,753 | 16 | MPP timeline indexer, MSPDI converter, Windows service host, migration tools |
| AutoCAD publisher | 1,563 | 17 | AutoCAD 2025 add-in + installer that publishes 2D drawing sets |
| WarRoom.Contracts | 1,317 | 2 | Shared versioned DTOs (publish contract, project management) |
| Frontend tests | 895 | 8 | Node tests for the pure scheduling, CPM and estimate engines |
| ESP32 telemetry | 334 | 1 | Current-clamp + environment sensor firmware |
| Plex document-control prototype | 329 | 4 | Checkout/check-in and drawing download helpers |
The problem
Mursix builds progressive stamping dies and runs them in its own press shop. Plex is the ERP, but its screens answer one transaction at a time, its fast reporting views lag the floor by hours, and a lot of the work that matters (design schedules, gate checklists, who is in, which die keeps failing first piece) lived in spreadsheets, Microsoft Project files, a separate quality tool (EASE) and people's heads.
War Room started in spring 2026 as a toolroom dashboard fed by the SOLIDWORKS add-in. It grew into a plant-wide site: every department has a menu, every page is read live from Plex or from War Room's own stores, and access follows each person's job in Plex.
SOLIDWORKS add-in AutoCAD publisher ESP32 sensors Android tablets CAD time tracker
│ │ │ │ │
└────────────────────┴─────────┬─────────┴────────────────┴──────────────────┘
▼
War Room API (ASP.NET Core · SignalR · SQLite · runs as a Windows service)
▲ Plex ODBC (read) ▲ Plex REST (read; job create) ▲ Entra ID sign-in
▲ EASE monitor ▲ McMaster-Carr API ▲ MS Project files (MPXJ)
▼
Plant · Project Mgmt · Sales · Engineering · Toolroom · Production · Quality ·
Maintenance · PC&L · Inventory · People · Supply · Admin (78 pages)Pages, by menu
Every page shares one navigation bar, one sign-in, a dark design system and a cache-first service worker. Gated links stay hidden until the server confirms the capability, and the API enforces the same rule. Unless noted, a page needs only a signed-in user.
Plant
- Plant Scorecard. One SQDCP screen: delivery, quality, production, maintenance and supply tiles from the endpoints below. The cost-and-cash and people tiles appear only for users who hold those capabilities.
- Finance. Invoiced sales, receivables aging, tooling receivables, gross margin, and spend against budget from Plex accounting views. Gated by
finance.view, which only a hand-assigned Finance Viewer role (and admins) holds. No Plex job title grants it, by design: titles such as "Director" matched too broadly.
Project Management
A full project/gate system that is replacing the action plans in EASE as the system of record.
- Weekly Exceptions / Project Workspace. Portfolio of projects with commitment risk, decisions, ownership and how much to trust each source. The workspace has tasks, evidence, approvals, a responsible-parties tab and a read-only preview of the emails each rule would send.
- Master Schedule. Two tabs. Project timelines shows a Kickoff → PPAP bar per job that expands into the full Microsoft Project schedule; moving a design phase cascades downstream live through the MPP's real predecessor links (FS/SS/FF/SF plus lag), keeps slack, pins started tasks, and shows the impact in a dialog and a toast. Work items is the original task Gantt. First-parts and PPAP dates are firm: a cascade can never move them, and pushing past them raises a warning that needs a reason and a second confirmation. A project manager can cancel a job: it stays visible greyed out, its gates, reminders and queued emails are suspended, and reinstating restores each project's previous status.
- My Work / Approvals. Assigned, due, blocked and returned tasks; submitted work waiting for the project lead.
- Notifications. A bell with unread badge in the header and a full page: assignments, due dates, late items, escalations, job-awarded alerts and schedule-move alerts. These are in-app copies of the gate-rule emails.
- Create Project / Job. Link a Plex shop order or start a standalone project.
- Project Planner. A browser replacement for Microsoft Project for account managers: task grid, critical-path engine, Gantt and views. It imports
.mpp/.mpt/.mpxthrough MPXJ and.xmlnatively, and exports Project XML (MSPDI) that Project opens and saves as.mpp. Writing.mppdirectly needs a commercial library, so the export path was chosen. Gated byproject.plans.edit. - Template Editor. Versioned project templates. Published templates are immutable; cloning allocates the next family version in a transaction, and existing projects keep their original snapshot.
- EASE Migration / EASE Owners (admin). Moves EASE "responsibility matrix" action plans (four gates per job) into native projects through an explicit, reviewed title-mapping table, never fuzzy matching. Preview, apply and revert per job. A dry run on a production copy mapped 2,184 of 2,184 tasks across 41 jobs and queued zero emails.
Sales (gated: sales.view)
The capability goes to Sales, Account Manager, Sales Engineer, Senior Management, Accounting, Finance Viewer and every salaried employee. Pay type isn't in the Plex REST API, so it comes from an ODBC join on the work email (0.3 s, every API email matched).
- Customers / Customer. A d3 map of every customer site, plus account owners (planner, quality engineer, account manager), quotes and jobs per customer. Sites come from per-customer address calls fetched 8 in parallel (~5 s for ~900 sites) and geocoded locally from ZIP and city tables. Free-text note fields are never returned.
- Sales Quote Intelligence. RFQ demand by month, open quotes by owner, status and outcomes, read from the Plex-managed quote log workbook. A background job refreshes it, keeps a refresh history and records which fields changed. About three quarters of free-text customer names link to Plex records by exact or whole-word-prefix match; the rest are prospects.
- Program Timeline. "Where is this job, really?" One shop order's story from quote to production, with files, late steps, source freshness, and matched meeting minutes from a meeting-notes agent. A note is served only if its hash matches the agent's processing receipt.
- EASE Gate Dashboard. Awarded jobs, current gate and audit evidence. War Room's own die checklists take precedence over EASE audits for the same gate.
- Design Lead-Time Simulator. Tests a sales commitment against current designer capacity and shows the resulting designer timeline.
- Estimate vs Outcome. Tool quote against actual internal and supplier cost, and completion performance per tooling job, with cost-mix breakdowns. Pure estimate/distribution engines have their own Node tests.
Engineering
- Design Timeline (Design Management). The design queue: awarded quotes merged with Plex tooling jobs and indexed project files, team workload, assignments, a design timeline built from each job's Microsoft Project file, and draggable, resizable design tiles. Reschedules are stored in War Room as an overlay keyed to the MPP task and the dates they were made against, so a re-saved MPP is flagged instead of silently overwritten; stale edits get HTTP 409. The MPP in Plex is never written. Also includes Early design work (time spent on un-awarded quotes and new part numbers rolls into the job once it's awarded) and an AutoCAD vs SOLIDWORKS hours view.
- Designer Analytics (gated
design.analytics.view). Available hours against tracked hours by designer, job, activity (die design, strip layout, flattening, detailing, meetings) and software. File extension decides the software, because older add-ins labelled everything one way. - Part Master. Any Plex part: revisions, routing with approved workcenters, BOM per operation, where-used, stock and customer POs. Search ranks an exact match first, then prefix, then contains, active parts first.
- Die Checklists (built, not deployed). Die design and error-proofing as seven ordered sub-tasks answered from the Design Assistant add-in at the right design moment. A Fail blocks the next sub-task until it passes. The project manager sets the die type and approves the wording.
Toolroom
- Project Overview / Part / Work Center. The original War Room: die projects published from SOLIDWORKS with every part, its routing through toolroom workcenters, queue breakdowns, operator badge scans, part logs and workflow updates. A workcenter view shows load across all dies.
- Model Viewer / STEP Viewer. A three.js GLB die viewer with assembly hierarchy, selection and completion coloring on a red→amber→green ramp, and an in-browser STEP preview.
- Toolroom Overview. Design overview, machine queues, team clock status, and a Job Timeline tab. Toolroom managers drag build bars that come from the MPP "Tooling Build" phase after design overrides, and the moves cascade onto the Master Schedule (gated
toolroom.timeline.edit; the supervisor role is derived automatically from Plex's supervisor link). - Floor View. A live map of the shop with machine pins placed on the toolroom layout.
- Machine Telemetry. Run/idle/high-load windows, standby-energy waste, current and environment flags, cost assigned to active work, and stale-sensor detection from the ESP32 units. Runtime and energy integrate only intervals bounded by two readings at most five minutes apart, so gaps show as unknown instead of as running time. An earlier version filled empty data with sample readings; that path was removed after an internal review.
Production (live Plex)
Fourteen pages that replaced manual workcenter-log exports. They share slicers (period, department, press group, workcenter, shift, part) that are remembered between pages and linkable by URL.
- Production Overview. Pieces, availability, derived OEE (availability × min(1, performance) × quality), downtime cost, scrap, first-piece failures, setup delay, a needs-attention feed, and best and worst parts.
- Floor Status. Live run state, current job, queue, today's pieces, pieces/hour and rate against standard for every working press. Status and pieces come from the Plex REST production-history endpoints (cached 20 s). ODBC fills in job details only when the job numbers agree, and the page says when a number comes from the lagging source.
- Who's In (gated
production.attendance.view). Hourly attendance now and over time by department, from the Plex time clock. It has trends, turnover and 90-day retention, a per-person drill-down to Plex labor entries, and lateness measured from each person's usual start (calibrated over a fixed 90 days) so a mis-set Plex shift doesn't make someone look late every day. - Shift Report. The previous shift on one page: active time, pieces-per-hour goals met, downtime reasons, scrap, and call-ins against the median of the previous eight same-weekday shifts. Call-ins are returned only to attendance viewers. Runs shorter than 0.5 h are shown but not judged.
- Workcenter Schedule. Operations due or starting in a window, using operation-level dates.
- Downtime & Status. Pareto by status and reason; by day, press, shift and part; a heatmap; an event log with operator notes.
- Part & Press Risk. Balanced risk ranking (30 % downtime/event, 25 % setup-to-production, 25 % first-piece failure rate, 20 % tool-maintenance/event, each scaled 0–100).
- Setup & First Piece. Setup-to-production delay (unstaffed weekend hours excluded), first-piece pass/fail, and a what-if that brings the slowest setups to the best.
- Die Startups & Tear-outs. Every die setup traced to its first good piece. Outcomes: passed first time, passed after a failed first piece, passed after tool maintenance, torn down, changed over, switched, still starting. Dies are ranked by a trouble score (3 × pulled + 2 × after-TM + 1 × after-failed-first-piece) and priced at the press's Plex cost per hour.
- First-Piece Checksheets. SPC checksheet failures by part, die, press and inspector, with the control-plan checklist.
- Workcenter History. One press's status/reason/job timeline over up to 400 days, with day strips, status runs and the die startups on that press.
- Scrap & Quality, Rates & Crew, Cost Opportunity. Scrap cost by reason; actual vs standard rate, crew factor and labor efficiency; rate loss + downtime + setup variance priced per press with Critical/High/Medium bands.
A refresh worker keeps 90 days in memory and pushes production-changed over SignalR when new attention items appear: repeated first-piece failures, tool maintenance far above its four-week norm, scrap spikes, presses down 3+ hours with jobs queued, and similar rules.
Quality
- Customer Complaints. Open complaints, 8D actions and owners from Plex quality problems.
- Gages & Control Plans. Calibration due, gages out of service, and part revisions whose control plan wasn't updated afterwards.
- Process Capability. Cp, Cpk, Pp and Ppk per characteristic from SPC checksheet measurements, computed on demand per part.
- Also linked here: First-Piece Checksheets and Scrap & Quality.
Maintenance
- Die Life & PM. Hits since last service against each die's hit interval, and dies to service before their next scheduled run. Hits are summed from production logs since the last completed service and shown as "≥" where no completed service exists.
- Equipment PM. PM compliance, on-time rate, open work requests and backlog age.
PC&L (production control & logistics)
- PC&L Overview, Demand Changes, Unexpected Demand, Customer Evidence. Plex overwrites customer releases in place, so War Room writes a daily snapshot of open demand. Those snapshots are the only record of what each customer asked for and when. Pages show what changed since yesterday or last week, spikes and drops against each customer's normal rhythm, and how much notice each customer gave. Older days were back-filled from earlier daily snapshots.
- Jobs / Create Jobs. Demand with no job, jobs created late, and jobs not needed. Create Jobs turns the daily alert's proposals into Plex jobs through the Plex scheduling API. This is War Room's only write to Plex. It is behind a feature flag and a capability; while the flag is off, a create returns the exact request it would send and changes nothing. Every attempt is logged with who made it.
- Material, Inventory. What to order, what arrives late, what is no longer needed; stock against 24 weeks of need.
- Delivery Performance. On-time delivery against the customer's due date and against the ship date, past due, a ship board, and EDI/ASN health.
- Shipping & Receiving. Today's loads and receipts, inbound due, staging and print-to-ship, and a freight-lane map of inbound suppliers and outbound customer sites with loads currently on the road.
Inventory
- Container Trace. Any serial back through WIP to the coil, its heat number and the PO receipt, and forward to every shipment. Plex has no key from coil to receipt, so they are matched on part, quantity and receiving time within ±2 minutes.
- Inventory by Location. Active containers by status and location, holds, and the oldest stock (aged by add date, because cycle counts touch the update date).
- Adjustments & Cycle Counts. Manual corrections by reason, person and part, and cycle-count accuracy.
People
- Employee Directory, Contacts. Staff directory, and every customer and supplier contact in Plex (one master-data call returns all ~3,700). Personal address-book and emergency-contact types are filtered out.
- Toolroom Team, Time & Activity. Clock status and weekly hours for the toolroom, and a per-employee calendar with part activity from Plex labor data, served through a small caching Python proxy.
Supply
- Purchasing Board. The BOM buy list from published die models, McMaster part mapping, and live McMaster-Carr pricing. An automation-first redesign is built in source and not yet deployed: consolidate across dies by vendor and part number, then copy an order list, email an RFQ or mark ordered with a PO.
- Inventory Rules. Toolroom hardware stock and reorder points.
- Supplier Performance. Plant-wide supplier on-time delivery, past-due PO lines and spend (spend only for finance viewers), filterable by PO type: raw material, subcontract or MRO. The on-time view has no PO key, so receipts are matched back to POs on supplier and exact receive date (14,814 of 14,816 matched, ~3 s).
- Requisitions. Request → PO → receipt cycle times and requests still waiting. Plex leaves a requisition at "New" after its PO is raised, so the link is read from the PO line instead.
- Vendor Analytics. Die-set spend and lead-time trends.
Admin
- System Controls. Program countdown targets, die-design removal, the part-mapping library, route templates and runtime info.
- People and Roles. Each person's roles from Plex, plus manual grants and blocks, what each capability allows, and "not found in Plex" flags (gated
access.manage).
Backend architecture
- One ASP.NET Core (net9.0) service serves both the API and the static frontend. 57 controllers; long-running reads sit behind per-domain services with in-memory caches and last-good-copy fallbacks, so a Plex blip never blanks a page.
- Plex behind adapters. Each domain (production, delivery, quality, maintenance, finance, supply, stock, trace, PC&L, dock) has a
*PlexSourcethat is the only code that talks to Plex, a pure analytics layer, and a service. Pages bind to War Room's own domain models, not to Plex column names, so the backend can later be swapped for Mursix's own ERP. Analytics are pure functions and unit-tested with fake sources. - Background jobs (11 hosted services): production refresh (90 days warm; today and yesterday every 4 minutes, last week hourly, older history every 12 h), PC&L refresh and daily demand history, sales quote log refresh, Plex people cache (every 30 minutes, keeps the last good copy, never blocks a request), employee directory, in-app notification and schedule-alert engine, the email outbox, nightly EASE import, schema initialization, file-drop import, and 2D publish session cleanup. A failing job can't stop the host: the host is set to ignore background exceptions, and catch filters key on the stopping token, not on exception type, because HTTP timeouts are themselves cancellation exceptions.
- Storage. 11 SQLite databases (project management with an additive migration ledger, access, design time, design overrides, timeline links, early work, checklists, firm dates, toolroom timeline, project plans, machine telemetry) and a JSON file store for published die projects with snapshots and assets. Editors check row versions, and schedule applies also validate a preview token.
- Live updates. A SignalR hub pushes change events; pages also poll as a backstop.
- Sign-in and roles. Microsoft Entra ID (MSAL in the browser, JWT bearer on the API) is required sitewide. Entra only proves identity: roles come from Plex. The people cache matches the sign-in email to the Plex employee record and applies rules on department, position, position keywords and pay type (for example, the engineering department → Engineering; titles containing Director or Plant Manager → Senior Management). Admins layer manual grants and blocks on top, stored by email and bound to the Entra object ID on first sign-in. Pages and endpoints declare
cap:<capability>policies. Adding a gated page is one capability entry, with no new Entra group. Plain-HTTP browsers are sent to HTTPS, and headless shop-floor devices have their own narrowly scoped policy. - AI-agent reads. Read-only "operations" projections (capabilities, overview, one job across systems) keep the source data next to each conclusion, so an agent can explain its answer. Missing dates produce an unknown schedule state, never a false on-time.
Windows service and hosting
- A small .NET Framework service host starts at boot and supervises the API, two Python helper proxies and the hourly MS Project timeline worker. It relaunches a component only when its port is free, with a 30 s grace period, so a deploy script can swap processes without racing it.
- HTTPS uses a Let's Encrypt certificate issued by DNS-01 challenge with automatic renewal and a post-renewal service restart. The site stays internal to the company network. This replaced a self-signed certificate that other PCs didn't trust, which had surfaced as "sign-in could not be completed."
Deployment approach
The source tree and the live folder are separate, and several sessions sometimes build in the same source tree, so every deploy is a sealed package:
- Publish a Release build and stage only the changed binaries and pages, with a SHA-256 manifest.
- Pin the expected hashes of the live files. If anything was deployed in between, the package refuses to run and is rebuilt.
- Prove the build with an IL diff against the live DLL: only the intended types may change.
- Patch live pages in place (asset version tags, nav entries, service-worker cache name) instead of copying source pages over them, because the live folder is sometimes ahead of source.
- Every script has a
-ValidateOnlydry run. The real run backs up files and SQLite, stops and starts the Windows service, verifies routes (treating 401/403 as "route exists" under sitewide auth), and always restarts the service on rollback.
These rules came from incidents: an early rollback hit a DLL file lock and left the API down for two minutes, and a deploy rolled back because a post-check opened the running service's log with an exclusive lock. Since then, non-essential steps run outside the rollback-protected block.
Integrations
- Plex ERP, ODBC. Read-only access to about 120 views and tables for production logs, scrap, quality, maintenance, shipping, receiving, containers, finance and HR pay type. Every call runs through a watchdog wrapper (below).
- Plex ERP, REST. Master data (employees, user accounts, customers and addresses, suppliers, contacts), the HCM time clock, production history (workcenter status entries, production entries, labor entries), purchasing, AP invoices, and scheduling jobs (the only write).
- Microsoft sign-in, plus a ticket broker for other internal apps. A separate internal quoting app gets single sign-on without any new Entra registration. A War Room page issues a short-lived one-time ticket, the app's callback redeems it server-to-server with a shared secret, and the existing War Room sign-in is reused.
- CAD time tracker (SOLIDWORKS/AutoCAD add-in). Designers' add-ins post time intervals per job, quote or new part number, with an activity type. Signed-in add-ins send an Entra token; the server maps it to the Plex user, fills in the designer, and returns 409 on a mismatch. Retries are idempotent, so older add-ins keep matching their stored intervals.
- SOLIDWORKS Design Assistant add-in. Publishes die projects (parts, routings, previews, GLB models) to the toolroom pages, and will answer the die checklists.
- AutoCAD publisher. A separate AutoCAD 2025 .NET add-in (net8.0-windows) with a self-contained installer. It finds title-block frames in model space, reads the BOM table, has the designer review the sheet-to-part mapping, and blocks publishing on any unresolved frame, Xref or plot. It then produces the master DWG, a DWG/PDF/PNG per sheet and a combined PDF, hashes every file, and uploads them in one server session that commits atomically. The server never opens or plots a DWG.
- Android tablet app. Kotlin + Jetpack Compose (Material 3), Retrofit/Moshi, CameraX + ML Kit. It scans a part's QR code, shows the part and its routing, updates workflow status, logs notes, and opens the part's CAD file in eDrawings through a FileProvider. Landscape, sideloaded, with unit-tested QR parsing and server-URL policy.
- ESP32 machine telemetry. A non-invasive current-transformer clamp (RMS computed on the ESP32 after removing the DC bias) plus a BME280 temperature/humidity/pressure sensor. A hosted config page handles calibration and Wi-Fi setup, and the unit posts readings to the API.
- Microsoft Project. An MPXJ-based Python worker indexes every job's
.mppfrom Plex document folders into a timeline index with predecessor links (721 of 998 task rows carried links in the first 65 files). It files each schedule by job number, so a timeline survives the design queue re-keying a row. A refresh-request file triggers a re-scan within a minute. - EASE. A read-only browser monitor (Playwright, dedicated profile) catalogs EASE action plans and task status every five minutes. War Room can't write to EASE.
- McMaster-Carr Product Information API. Client-certificate TLS with a cached bearer token refreshed on 401. Calls are serialized and spaced, prices are cached per selling unit with pack sizes parsed ("Pack of 100" = 100), and parts over a per-request limit are deferred to a later call.
- Email and notifications. Per-item gate rules: on assignment, N days before due, daily when late, the Plex supervisor when more than N days late, and a weekly follow-up. Each person gets at most one digest per day. Email runs through a claimed outbox with backoff. It ships in Preview mode: rules write in-app notifications and email previews, and no email is sent until it is switched to live.
Hard problems and measured results
- Plex ODBC speed rules. Single-table queries on base tables return about 1 s per week of history. The "accelerated" reporting views took 75+ s per day and timed out on ranges, and a 6-table join took 94 s for one day. Everything was rebuilt as single-table queries, with names resolved in memory through key-list
IN (...)lookups (0.2 s). The driver also rejects bound date parameters, so typed values are inlined as validated literals. Result: 90 days of production history loads within a minute, and pages answer in under 1 s from the warm cache. - ODBC lags the floor; the REST API doesn't. ODBC trailed the floor by up to ~4 hours: on one Sunday evening it still showed every press shut down and had no logs since Friday afternoon, while the API showed six presses running. Floor status moved to the API's status entries (0.4 s per call). A 1-minute window returns exactly one current entry per workcenter, and durations come from consecutive log times because open entries report an arbitrary horizon. Piece counts from the API matched ODBC within 1.6 % per press over a full shift, so pieces moved to the API too.
- Driver hangs. The ODBC driver ignored connection timeouts, command timeouts and cancellation, so one stuck query held the production cache lock for 13+ minutes. ODBC work now runs on a dedicated thread with progress heartbeats and is abandoned after 4 minutes with no progress. Waiting for the cache lock is capped at 45 s, after which the page gets a 503 instead of hanging.
- Two employee-ID systems. Plex master-data employee IDs don't match the time-clock IDs, but user-account IDs do. Filtering by pay date (night shift = the day the shift ends) is exact and fast: ~4 s per 45 days, and a full year cold-loads in ~15 s in 3 parallel chunks.
- Re-logged setups. Operators re-log "Full Setup" after breaks and shift ends (226 times in 90 days for the same part). Tracking startups per press rather than per job, and treating repeats as one cycle, stopped trouble from being lost between them.
- Design queue flipping after restarts. The queue was built from an empty Plex tooling cache until the first refresh, so jobs fell back to "project pending" and closed jobs reappeared. Persisting a snapshot to disk and serving it until the first refresh lands fixed it: the next timeline scan linked 62 queue records instead of 26.
- Cascade on real schedules. With design moved +7 days, PPAP moved exactly 7 days in 18 of 26 real timelines. Finished projects stayed put, and jobs with float absorbed the move and raised overlap warnings from +14 days.
- Verification against the old manual reports. The 90-day production numbers matched the scale of the workbook they replaced: 1,325 h / 1,312 tool-maintenance events against 1,217 / 1,232, and 437 / 170 first-piece pass/fail against 418 / 141. The remaining differences come from duplicate rows in the old export.
- "No data source, no build." Before the plant KPI pages, every gap-analysis item was profiled against live Plex. Ten were rejected with reasons: safety tables last used in 2015–2019, PPAP statuses stuck at "In-Process", corrective work orders too sparse for MTBF, purchase price variance not credible from standard costs, and others.
Testing and engineering process
- 441 xUnit tests across 49 files cover the pure analytics (production, die startups, shift report, attendance, live floor, PC&L, dock, plant KPIs, stock trace), access rules, design timelines and overrides, early work, checklists, project management and the email rules. The main test project has a long-standing compile break in one stale file, so suites run through a scratch project that links the relevant test files. Recent runs: 599 passing on the design build, 259 on the ERP pages build.
- 86 Node tests cover the browser engines that both pages share: the schedule-shift cascade, the design schedule, critical-path scheduling for the Project Planner, estimate distributions and project management. Python tests cover the MPP indexer (12), Kotlin tests the QR parser and URL policy, and the AutoCAD core has contract and failure-path tests that run without AutoCAD.
- Smoke hosts. Isolated hosts run selected controllers against real read-only Plex with synthetic identities and scratch storage, and are checked in a browser pane. Synthetic tests never touch production storage and never send real email.
- Independent checks. Project Planner schedules were cross-checked against MPXJ's Microsoft Project scheduler. An internal review in September 2026 found out-of-order project selection, telemetry sample data presented as real readings, and job identities resolved differently between views; all were fixed and deployed.
- AI-assisted development. Built with Claude Code across many parallel sessions, with shared notes per feature, deploy packages that the owner runs from an elevated shell, and a rule that a successful build is never reported as a successful deployment.
Honest status
- Live: the Production section (14 pages, with live floor status and pieces from the Plex API), Who's In with lateness calibration, Shift Report, die startups/checksheets/workcenter history, Plant KPI pages (Scorecard, Finance, Delivery, Quality, Maintenance, Supplier Performance with PO-type filter), ERP read pages (Container Trace, Inventory by Location, Adjustments, Part Master, Requisitions, Process Capability), Shipping & Receiving with the freight-lane map, Customers and Contacts, the Sales gate, Project Planner with McMaster pricing, Master Schedule with cascade, firm dates, schedule alerts, timeline links and cancel-job, Toolroom timeline, Designer SSO, Designer Analytics, early design work and activity types, in-app notifications including job-awarded alerts, the Windows service, Let's Encrypt HTTPS, and the background-job and ODBC-hang hardening.
- Running in limited mode: gate emails run in Preview, so nothing is emailed yet and users get in-app notifications only. EASE migration is built and live, with the cutover for new jobs planned for early 2027. PC&L job creation is behind a feature flag with a dry-run mode. Designer Analytics and Finance need roles assigned by hand before anyone sees them.
- Built, not deployed: Die Checklists (add-in-answered die design and error-proofing sub-tasks), the automation-first Purchasing Board redesign, and a retry fix for failed timeline scans.
- Known gaps: the main test project doesn't compile as a whole. The live frontend sometimes drifts ahead of the source tree, which the in-place patching works around but doesn't eliminate. Matching an Entra sign-in to a Plex work email is assumed, not verified for every user; the admin page flags people it can't find. Some Plex modules Mursix doesn't use (lots, ECR, purchasing RFQs, Plex quotes) can't be reported on, and the hang watchdog has not yet been tested against a real driver hang.