# M-TRACK App Summary

# M-TRACK Manufacturing Control System - Complete Application Summary

## Purpose

M-TRACK is an internal manufacturing control system for a shop floor environment. It manages jobs, components (parts), operations (work steps), inventory, and worker task assignments. The app is designed for two user types: Admins (managers who create jobs, assign work, and monitor production) and Workers (shop floor operators who execute tasks).

The system is self-hosted on a Windows machine and accessed remotely via web browser (including mobile devices on the shop floor).

## Deployment

- Self-hosted on a Windows machine
- Remote web access via browser (desktop and mobile)
- PostgreSQL database for data persistence
- Single server process serves both the API and the frontend
- Environment variable `DATABASE_URL` for database connection
- Environment variable `SESSION_SECRET` for session encryption

## Authentication & Access Control

### Two-Tier Login System

- Workers: Select their name from a dropdown on the landing page. No password required. Instant login for minimal friction on the shop floor.
- Admins: Select their name, then must enter a 4-6 digit numeric PIN.

### PIN Management

- PINs are stored as bcrypt-hashed values in the database
- Admins can set, reset, and initialize PINs for other admin users
- A "Bootstrap" mode exists for first-time setup: if no admin has a PIN configured, the landing page shows a setup dialog to create/initialize the first admin account

### Sessions

- Express-session based with 24-hour expiration
- Session data stored server-side (MemoryStore for development, database-backed sessions table available for production)

### Role-Based Access

- Two roles: `admin` and `worker`
- Workers can only use the simplified login flow (no PIN)
- Workers have an `assignedProcesses` array (e.g., ["cutting", "welding"]) that filters which operations they see in their work queue
- Admin-only features: User management, inventory deletion, PIN management, time study reports, process type configuration, viewing all workers' queues

## Core Data Model

### Jobs

A job represents a manufacturing order (e.g., building a specific machine for a customer).

Fields:

- Product name (the thing being built)
- Customer name
- Order number
- Machine serial number
- Description and details (free text)
- Status: planned, in_progress, completed
- Quantity (how many units to build, default 1)
- Priority: integer 1-5 (1 = highest)
- Due date
- Is template flag (templates are reusable job blueprints)
- Archived at timestamp (soft delete)
- BOM file name and BOM file data (stored for re-download)

### Components

A component is a part or subassembly within a job. Components form a tree hierarchy (parent-child relationships).

Fields:

- Name
- Type: "material" (raw part) or "assembly" (subassembly containing other parts)
- Processes: array of strings (e.g., ["cutting", "bending", "welding"])
- Status: pending, in_progress, completed
- Quantity (default 1)
- Job ID (belongs to a job)
- Parent ID (self-referencing for hierarchy: assemblies contain sub-components)
- Assigned to (user ID)
- Notes (free text)
- Thickness (e.g., '0.125"', '3mm')
- Material (e.g., "Mild Steel", "Aluminum 6061")
- Thumbnail data (base64 image extracted from BOM file)
- Blueprint URL
- Order index (display ordering)
- Priority weight (1-100, default 50, higher = more important within the job)
- Ready for assembly flag

### Operations

An operation is a specific work step on a component (e.g., "Cut this part", "Weld this part").

Fields:

- Component ID (belongs to a component)
- Name (descriptive task name)
- Process type (e.g., "cutting", "Sheetmetal cutting", "bending", "welding", "machining", "assembly")
- Order index (sequence within the component)
- Estimated minutes
- Instructions (free text)
- Status: pending, in_progress, stalled, completed, skipped
- Assigned to (user ID)
- Completed at timestamp
- Quantity made (for machining operations that produce countable output)
- Fulfilled from inventory flag (machining operation fulfilled from existing stock)
- Priority score (calculated integer, lower = higher priority)
- Priority tier: hot, urgent, normal, backlog (calculated from days until due date)
- Ready at timestamp
- Blocked reason (text explaining why the operation cannot proceed)
- Override fields: overriddenByUserId, overrideReason, overrideExpiresAt (admin can bypass blocking)

### Operation Dependencies

Explicit cross-component blocking relationships.

Fields:

- Operation ID (the operation that is blocked)
- Depends on operation ID (must complete before this operation can start)
- Depends on component ID (entire component must complete before this operation can start)

### Inventory Items

Unified inventory system for all materials, manufactured parts, and consumables.

Fields:

- Item number (auto-assigned by category: consumables 1000+, materials 5000+, manufactured 6000+)
- Name, description
- Category: material, manufactured, consumable
- SKU
- Unit: pcs, kg, meters, liters, etc.
- Quantity (current stock level)
- Restock point (yellow warning threshold)
- Reorder point (red critical threshold, triggers automatic alerts)
- Reorder quantity (suggested order amount)
- Storage location
- Supplier name, contact, email
- Unit cost
- Minimum order quantity
- Lead time in days
- Last restock date

### Inventory Transactions

Audit trail for every stock change.

Fields:

- Inventory item ID
- Transaction type: restock, consume, adjust, manufacture
- Quantity change
- Previous quantity and new quantity
- Note (reason for change)
- User ID (who performed it)

### Reorder Alerts

Tracks inventory replenishment requests.

Fields:

- Inventory item ID
- Status: pending, approved, ordered, received, dismissed
- Triggered by: scan (manual QR scan) or auto (hit reorder point)
- Scanned by user ID
- Approved by user ID, approved at timestamp
- Order quantity
- Supplier email sent flag and timestamp
- Note

### Time Study Events

Performance tracking log.

Fields:

- Operation ID, component ID, job ID
- Worker ID (who performed the work)
- Recorded by (who logged the event)
- Event type: start, stalled, completed
- Note
- Occurred at timestamp

### Users

Fields:

- ID (UUID)
- Username (unique, required)
- Email, first name, last name, profile image URL (optional)
- Role: admin or worker
- Assigned processes: array of strings (e.g., ["cutting", "bending"])
- Has completed tutorial: boolean
- PIN hash (bcrypt, for admin login)

### Process Types

Configurable list of available manufacturing processes (admin-managed).

Fields:

- Name (unique, e.g., "cutting", "Sheetmetal cutting", "bending", "welding", "machining", "assembly")
- Order index (display ordering)

### Other Tables

- Subtasks: Granular checklist items within a component (id, name, status, componentId)
- Consumables: Legacy table for small shop items
- Kanban Cards: Legacy cards for consumable tracking
- Machined Parts Inventory: Tracks stock of machined parts (partName, quantity)
- Sessions: Server-side session storage (sid, sess JSON, expire timestamp)
- Operation Assignment Log: Audit trail for operation assignments (operationId, userId, action, performedByUserId, reason)

## Key Features

### 1. Job Management

Creating Jobs:

- Manually create jobs with product name, customer, serial number, priority, due date, description
- Import from BOM (Bill of Materials) Excel files
- Instantiate from saved templates

Job Templates:

- Any job can be saved as a template
- Templates preserve the full component tree and operation structure
- Instantiating a template creates a new active job with all components and operations copied

Job Lifecycle:

- Status progression: planned -> in_progress -> completed
- Jobs can be archived (soft delete) and unarchived
- Archived jobs are hidden from main views but preserved in the database

Job Priority:

- Integer 1-5 (1 = Critical/highest, 5 = Lowest)
- Priority drives the ordering of worker task queues
- Combined with due date for automatic priority score calculation

### 2. BOM Import

File Format:

- Accepts Excel files (.xlsx, .xls) and CSV
- Uses the `xlsx` library to read data and `exceljs` to extract embedded thumbnail images

Column Detection:

- Auto-detects columns by header name using exact and partial matching
- Looks for: Item Number, Part Name, Quantity, Material, Thickness

Inventor File Name Parsing:

- Designed to parse Autodesk Inventor file naming conventions
- Format: `Model_MajorComponent_PartName.ipt` or `Model_MajorComponent_PartName.iam`
- File extensions (.iam, .ipt) are stripped
- CamelCase is split into separate words (e.g., "UpperCylinder" -> "Upper Cylinder")
- Underscores become spaces
- Hyphens are preserved with spaces

Major Component Codes:

- Recognizes codes like RB (Roaster Body), CC (Chaff Can), CT (Cooling Tray)
- These codes determine which subassembly a part belongs to

Two-Pass Component Creation:

1. First pass: Creates subassemblies (items with whole-number IDs like "1", "2") as type "assembly"
2. Second pass: Creates parts (items with decimal IDs like "1.1", "1.2") as type "material", assigned to their parent subassembly

Filtering Logic:

- Parts must have a valid major component prefix (RB, CC, CT) in their file name
- Parts must have material containing "MCR" to be imported
- This filters out hardware, fasteners, and purchased parts

BOM Update:

- Existing jobs can have their BOM re-imported
- The update process preserves existing operations and work progress
- New components are added, removed components are deleted, existing ones are updated
- Returns counts of updated, added, and removed components

Thumbnail Extraction:

- Embedded images in Excel files are extracted as base64 data
- Matched to components by row position
- Displayed as component thumbnails in the UI

### 3. Component Tree & Hierarchy

- Components form a tree: Jobs contain top-level assemblies, which contain sub-components
- Parent-child relationships via parentId field
- Components can be moved between parents via drag or API
- Order index controls display ordering within a parent
- Assembly components act as containers; their operations are blocked until all child components are completed

### 4. Operations & Dependencies

Operation Creation:

- Operations are created on individual components
- Each operation has a process type (cutting, bending, welding, machining, assembly, etc.)
- Operations have an order index that determines their sequence within a component

Bulk Operations:

- Admin can assign operations in bulk across multiple components
- Select multiple components and multiple process types to create operations for all combinations
- Bulk delete also supported

Operation Reordering:

- Operations within a component can be reordered by dragging or via API
- Order determines sequential dependency (operation at index 0 must complete before index 1 can start)

Dependency System (Three Layers):

1. Sequential: Within a component, operations must complete in order index sequence
2. Hierarchical: Assembly operations are blocked until all child components are completed
3. Explicit: Cross-component dependencies defined in the operation_dependencies table

Blocking Logic:

- An operation is "blocked" if any of its dependencies (sequential, hierarchical, or explicit) are not yet completed
- Blocked operations appear at the bottom of worker queues with a reason explaining the block
- Admins can override blocks by providing an override reason (with optional expiration)

Priority Calculation:

- Priority score = basePriority * (100 - componentWeight) / 100
- basePriority = daysUntilDue * 100
- Lower score = higher priority
- Priority tiers assigned by days until due: hot (<=2 days), urgent (<=5 days), normal (<=14 days), backlog (>14 days)
- Recalculation can be triggered manually via API

### 5. Batch Task Grouping (Cutting Operations Only)

What Gets Batched:

- ONLY operations where the process type contains "cutting" or "cut" (case-insensitive), or equals "material"
- Examples that batch: "cutting", "Sheetmetal cutting", "Steel Tube cutting", "material"
- Examples that do NOT batch: "bending", "welding", "machining", "assembly"

Grouping Criteria:

- Operations are grouped by: Process Type + Material + Thickness + Job ID
- All operations sharing these attributes become a single batch that workers can start/complete together

Why Batching Exists:

- In manufacturing, cutting is often done on a single machine for all parts of the same material and thickness
- A worker sets up the machine once and cuts all parts, rather than switching materials repeatedly

Batch Display:

- Batches show a count of operations (e.g., "12 parts")
- Individual parts within a batch are listed for reference

### 6. Task Naming Format (Two-Line Display)

All work items (batches and individual operations) are displayed in a consistent two-line format:

Line 1 (Title): `[Process] [Product] [Main Assembly] [Sub-Assembly]`

- Process: "Cut" for cutting/material operations, otherwise the capitalized process name
- Product: The job's product name
- Main Assembly: The top-level assembly name (if the component has a parent hierarchy)
- Sub-Assembly: The intermediate assembly name (if applicable)

Line 2 (Subtitle): `[Thickness] [Material] - [Customer] - [Serial Number]`

- Parts are separated by " - " dash separators
- Empty parts are omitted
- Thickness: Displayed exactly as it comes from the BOM, with " in" suffix converted to double-quote (") for inches

### 7. Worker Queue / "Next Work" View

Purpose:

- Shows each worker a prioritized list of tasks they should work on next
- Filtered to only show operations matching the worker's assigned processes

Three Sections:

1. In Progress: Tasks the worker has already started
2. Stalled: Tasks that are paused with a reason
3. Pending: Tasks available to start, ordered by priority

Mixed Content:

- Cutting batches (grouped by material + thickness + job) appear as single items
- All other operations (welding, bending, machining, assembly) appear as individual items
- Both types are interleaved in a single prioritized list

Priority Ordering:

1. In-progress items appear at the top
2. Higher job priority (lower number) comes first
3. Earlier due dates come first (no due date goes to bottom)
4. Blocked items are pushed to the bottom with a reason displayed

Worker Actions:

- Start: Moves operation(s) from pending to in_progress, assigns to the current worker, records a time study "start" event
- Stalled: Pauses work; worker MUST provide a reason (e.g., "missing hardware", "machine down"). Records a time study "stalled" event
- Done (Complete): Marks operation(s) as completed with timestamp. Records a time study "completed" event. For batches, all operations in the batch are completed simultaneously
- Resume: Moves stalled tasks back to in_progress

Admin View:

- Admins can select any worker from a dropdown to view their queue
- Admins can reassign batches to different workers

### 8. Shop Floor View

Two Modes:

Batch View (Task-Based):

- Shows all cutting batches grouped by material + thickness
- Filter by process type
- Mark batches as complete or stalled
- Shows in-progress work at the top

Kanban Board (Component-Based):

- Three columns: Pending, In Progress, Completed
- Drag-and-drop components between columns to update status
- Uses @hello-pangea/dnd library
- Filter by process type
- Expand components to view and manage subtasks

### 9. Dashboard

Stat Cards (Clickable):

- Active Jobs: Count of in_progress jobs (click to see list)
- Completed Units: Count of completed jobs (click to see list)
- Low Stock Alert: Count of consumables below reorder level (click to see list)
- Total Jobs: Total job count (click to see list)

Charts:

- Job Status Bar Chart: Planned vs In Progress vs Completed job counts (using Recharts)
- Recent Jobs List: 5 most recent jobs with status badges

Work Management:

- Workers see their assigned "Next Work" items
- Admins see a global view of all in-progress and stalled work
- Admins can select specific workers to view their assigned work
- Start/Stall/Done actions available directly from the dashboard
- In-progress work section highlighted at the top

Job Detail Dialog:

- Click a job to see metadata (quantity, due date, serial number)
- Breakdown of incomplete vs completed tasks

### 10. Inventory Management

Three Categories (Tabs):

1. Materials: Raw materials (steel, aluminum, etc.)
2. Manufactured Parts: Parts produced in-house (machined parts with stock tracking)
3. Consumables: Shop supplies (welding wire, grinding discs, etc.)

Item Number Auto-Assignment:

- Consumables: 1000+
- Materials: 5000+
- Manufactured parts: 6000+

CRUD Operations:

- Add, edit, delete inventory items
- Quantity adjustment with transaction type (restock, consume, adjust, manufacture)
- Every adjustment creates a transaction log entry

Low-Stock Alerting:

- Two thresholds per item: restock point (warning) and reorder point (critical)
- When quantity falls to or below reorder point, an automatic reorder alert is created
- Manual alerts via QR code scanning

Reorder Alert Workflow:

- Status progression: pending -> approved -> ordered -> received (or dismissed)
- Admins approve/dismiss alerts
- System can generate pre-filled supplier email for ordering
- Notification badge in sidebar shows pending alert count

QR Code / Kanban Cards:

- Generate printable kanban cards with QR codes for physical inventory items
- Workers scan QR codes to trigger reorder alerts
- Camera-based QR scanning (requires HTTPS) or manual item ID entry

Machining Integration:

- When a machining operation is completed, workers enter "quantity made"
- If quantity exceeds what the job needs, excess is automatically added to machined parts inventory
- Before starting a machining operation, the system checks if the part already exists in inventory
- Workers can "fulfill from inventory" to skip machining and use existing stock

### 11. Time Study / Performance Reports

Event Tracking:

- Every Start, Stalled, and Completed action on an operation creates a time study event
- Events record: operation, component, job, worker, event type, timestamp, optional note

Reports (Admin Only):

- Filter by worker and/or job
- Shows total active time (time between start and completed events)
- Shows total stalled time (time between stalled and resumed events)
- Event log with timestamps for detailed analysis

### 12. Tutorial / Onboarding System

Automatic Trigger:

- Tutorial appears automatically for any user who hasn't completed it (hasCompletedTutorial = false)

8 Steps:

1. Welcome to M-TRACK
2. Dashboard overview
3. Jobs Management
4. Shop Floor
5. Inventory
6. Your Work Queue
7. Settings
8. Completion ("You're Ready!")

Controls:

- Navigate with Next/Previous buttons or Arrow keys
- Skip with Escape key or Skip button
- Restart from Settings page
- Completion status saved to database so it doesn't reappear

Implementation:

- React Context (TutorialContext) manages state
- Overlay component with Framer Motion animations
- Persisted via API calls to mark completion/reset

### 13. Settings Page

For All Users:

- View account info
- Restart tutorial
- View system architecture diagram

For Admins:

- User Management: Create users, edit roles/usernames, assign work processes, manage PINs
- Process Type Configuration: Add or remove manufacturing process categories

### 14. Architecture Diagram

- Interactive Mermaid.js diagrams
- Two views: System Architecture and User Workflow
- Zoom in/out capability
- Download as SVG
- Shows how components relate (frontend, backend, database, user flows)

## UI Navigation

### Sidebar

- Dashboard
- Jobs
- Shop Floor
- Worker Queue
- Inventory
- Scan (QR scanning)
- Reorder Alerts (with notification badge showing pending count)
- Time Study (admin only)
- Settings
- Architecture Diagram
- Logout

### Responsive Design

- Works on desktop and mobile browsers
- Sidebar collapses on mobile
- Touch-friendly interactions for shop floor use

## Key Business Rules

1. Cutting operations batch together by material + thickness + job. All other processes are individual operations.

2. Operation blocking prevents workers from starting work out of sequence. Sequential order within a component, assembly hierarchy, and explicit cross-component dependencies all contribute to blocking.

3. BOM updates preserve existing work. Re-importing a BOM updates metadata but does not delete operations that have already been started or completed.

4. Machined parts can be fulfilled from inventory instead of re-machining, saving production time.

5. Reorder alerts fire automatically when stock hits the reorder point, but can also be triggered manually via QR scan.

6. Priority scoring is automatic based on due date and component weight, but jobs also have a manual priority override (1-5).

7. Workers only see operations matching their assigned processes. A worker assigned to "cutting" and "bending" won't see welding tasks.

8. Admins can override operation blocking with a reason and optional expiration time.

9. Time study events are created automatically whenever a worker starts, stalls, or completes an operation.

10. Process types are configurable - admins can add new process types without code changes.

## API Overview

### Authentication

- `POST /api/login` - Worker login (select user, no PIN)
- `POST /api/auth/login-with-pin` - Admin login with PIN
- `GET /api/auth/user` - Get current session user
- `POST /api/logout` - End session
- `GET /api/auth/bootstrap-status` - Check if first-time setup needed
- `POST /api/auth/bootstrap-initialize` - Create/initialize first admin
- `GET /api/auth/check-pin/:userId` - Check if user requires PIN
- `POST /api/auth/set-pin` - Set own PIN
- `POST /api/auth/reset-pin/:userId` - Admin reset another user's PIN
- `POST /api/auth/initialize-pin/:userId` - Admin set PIN for another user
- `POST /api/auth/complete-tutorial` - Mark tutorial complete
- `POST /api/auth/reset-tutorial` - Reset tutorial for current user

### Users

- `GET /api/users` - List all users
- `POST /api/users` - Create user (username, role, assignedProcesses)
- `PATCH /api/users/:id` - Update user

### Jobs

- `GET /api/jobs` - List jobs (query: isTemplate=true/false)
- `GET /api/jobs/:id` - Get single job
- `POST /api/jobs` - Create job
- `PATCH /api/jobs/:id` - Update job
- `DELETE /api/jobs/:id` - Delete job
- `POST /api/jobs/:id/archive` - Soft delete
- `POST /api/jobs/:id/unarchive` - Restore archived job
- `GET /api/jobs/archived` - List archived jobs
- `POST /api/jobs/:id/instantiate` - Create job from template
- `POST /api/jobs/:id/save-template` - Save job as template
- `POST /api/jobs/import-bom` - Import BOM file (multipart/form-data)
- `GET /api/jobs/:id/bom` - Download original BOM file
- `POST /api/jobs/:id/bom/update` - Re-import BOM preserving existing work

### Components

- `GET /api/components` - List (query: jobId, assignedTo)
- `POST /api/components` - Create component
- `PATCH /api/components/:id` - Update component
- `DELETE /api/components/:id` - Delete component
- `POST /api/components/move` - Move component to new parent

### Operations

- `GET /api/operations` - List (query: componentId)
- `GET /api/operations/:id` - Get single operation
- `POST /api/operations` - Create operation
- `PATCH /api/operations/:id` - Update operation
- `DELETE /api/operations/:id` - Delete operation
- `POST /api/operations/reorder` - Reorder operations within a component
- `POST /api/operations/bulk` - Bulk create operations across components
- `DELETE /api/operations/bulk` - Bulk delete operations

### Batch Tasks & Worker Queue

- `GET /api/batch-tasks` - Get batch groups (query: processType, jobId, status)
- `POST /api/batch-tasks/start` - Start a batch (operationIds + userId)
- `POST /api/batch-tasks/complete` - Complete a batch
- `POST /api/batch-tasks/stall` - Stall a batch (with reason)
- `POST /api/batch-tasks/dismiss-stall` - Resume stalled batch
- `GET /api/batch-tasks/worker/:userId` - Get batches for a worker
- `GET /api/work/next/:userId` - Get unified next work (batches + individual ops)
- `GET /api/work/assigned` - Get current user's assigned work
- `GET /api/work/all-workers` - Get all workers' current work (admin)

### Inventory

- `GET /api/inventory` - List items (query: category)
- `POST /api/inventory` - Create item
- `PATCH /api/inventory/:id` - Update item
- `DELETE /api/inventory/:id` - Delete item (admin only)
- `POST /api/inventory/:id/adjust` - Adjust quantity with transaction log
- `GET /api/inventory/:id/transactions` - Get transaction history
- `GET /api/inventory-transactions` - Get all transactions

### Machined Parts

- `GET /api/machined-parts` - List machined parts inventory
- `POST /api/operations/:id/complete-machining` - Complete machining with quantity tracking
- `POST /api/operations/:id/fulfill-from-inventory` - Use existing stock instead of machining
- `GET /api/machined-parts/check/:partName` - Check if part exists in inventory

### Consumables (Legacy)

- `GET /api/consumables` - List consumables
- `POST /api/consumables` - Create consumable
- `PATCH /api/consumables/:id` - Update consumable

### Alerts & Scanning

- `GET /api/reorder-alerts` - List alerts (query: status)
- `GET /api/reorder-alerts/count` - Get pending alert count
- `POST /api/reorder-alerts` - Create manual alert
- `PATCH /api/reorder-alerts/:id` - Update alert status
- `POST /api/scan/:itemId` - Scan item to trigger reorder alert

### Reports & Config

- `GET /api/time-study/report` - Get time study data (query: workerId, jobId, componentId)
- `POST /api/time-study` - Record time study event
- `GET /api/process-types` - List configured process types
- `POST /api/process-types` - Add process type
- `DELETE /api/process-types/:id` - Remove process type
- `POST /api/recalculate-priorities` - Recalculate all operation priorities

### Subtasks

- `GET /api/subtasks` - List (query: componentId)
- `POST /api/subtasks` - Create subtask
- `PATCH /api/subtasks/:id` - Update subtask
- `DELETE /api/subtasks/:id` - Delete subtask

## Architecture Diagram (Text)

    +------------------+     HTTP/REST     +------------------+     SQL      +------------------+
    |                  | <===============> |                  | <==========> |                  |
    |   React SPA      |                   |   Express.js     |              |   PostgreSQL     |
    |   (Frontend)     |                   |   (Backend)      |              |   (Database)     |
    |                  |                   |                  |              |                  |
    |  - Dashboard     |                   |  - REST API      |              |  - Jobs          |
    |  - Jobs          |                   |  - Session Auth  |              |  - Components    |
    |  - Shop Floor    |                   |  - BOM Parser    |              |  - Operations    |
    |  - Worker Queue  |                   |  - Batch Logic   |              |  - Dependencies  |
    |  - Inventory     |                   |  - Priority Calc |              |  - Inventory     |
    |  - Settings      |                   |  - File Upload   |              |  - Time Study    |
    |  - Time Study    |                   |                  |              |  - Users         |
    |  - Scan (QR)     |                   |                  |              |  - Sessions      |
    |                  |                   |                  |              |                  |
    +------------------+                   +------------------+              +------------------+
            |                                      |
            |  Single server process               |
            |  serves both frontend                |
            |  static files and API                |
            +--------------------------------------+

## User Flow Diagram (Text)

                        +------------------+
                        |   Landing Page   |
                        |  (User Select)   |
                        +--------+---------+
                                 |
                        +--------+---------+
                        |  Worker or Admin? |
                        +--------+---------+
                                 |
                  +--------------+--------------+
                  |                             |
         +--------v---------+        +---------v--------+
         |  Worker Login     |        |  Admin PIN Entry |
         |  (No PIN needed)  |        |  (4-6 digits)    |
         +--------+----------+        +---------+--------+
                  |                             |
                  +-------------+---------------+
                                |
                       +--------v---------+
                       |    Dashboard      |
                       | (Role-specific)   |
                       +--------+---------+
                                |
            +-------------------+-------------------+
            |           |           |               |
       +----v----+ +---v----+ +----v-----+  +------v------+
       |  Jobs   | | Shop   | | Worker   |  | Inventory   |
       |         | | Floor  | | Queue    |  |             |
       +---------+ +--------+ +----+-----+  +------+------+
                                    |               |
                             +------v------+  +-----v-------+
                             | Start/Stall |  | Reorder     |
                             | Done Actions|  | Alerts      |
                             +-------------+  +-------------+

## Important Implementation Notes for Recreation

1. The "isCuttingProcess" helper must use case-insensitive matching. Check if processType.toLowerCase() includes "cutting" or "cut", OR equals "material". This is critical for batch grouping to work with process types like "Sheetmetal cutting" or "Steel Tube cutting".

2. BOM import uses two libraries: `xlsx` for reading spreadsheet data, and `exceljs` for extracting embedded images (thumbnails). They serve different purposes and both are needed.

3. The worker queue mixes batched and individual items in a single prioritized list. Cutting operations are grouped into batches; everything else is individual. This is the "Next Work" endpoint.

4. Operation status transitions: pending -> in_progress -> completed (or stalled from in_progress, then resumed back to in_progress). The "skipped" status exists for operations bypassed via inventory fulfillment.

5. The task naming two-line format must use " (double quote character) instead of "in" for inches in thickness. The thickness value should be displayed as it comes from the BOM with this one normalization.

6. Subtitle parts are joined with " - " (space dash space) as separators. Empty parts are omitted entirely.

7. Assembly blocking: An operation on an "assembly" type component is blocked until ALL child components (and their children, recursively) have status "completed".

8. Session-based auth means the server must support sessions. The worker login flow explicitly prevents admin role users from using it (they must use PIN).

9. Inventory auto-numbering assigns the next available number in the category range when creating new items.

10. Reorder alerts deduplicate - the system should check for existing pending alerts before creating duplicates.

11. BOM update (re-import) preserves work - when updating a BOM, existing operations with status in_progress or completed must not be deleted. Only add new components, remove components that no longer exist in the BOM, and update metadata on existing ones.

12. The priority recalculation processes all active (non-template, non-archived) jobs and updates every operation's priorityScore and priorityTier based on current date vs. due date.