38815-vm/replit_app_summary_full.html
2026-02-28 22:33:39 +00:00

808 lines
40 KiB
HTML

<!DOCTYPE html>
<html><head><meta charset='utf-8'><title>M-TRACK App Summary</title>
<style>
@media print { @page { margin: 0.75in; } }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif; font-size: 11pt; line-height: 1.6; color: #1a1a1a; max-width: 900px; margin: 0 auto; padding: 20px; }
h1 { font-size: 22pt; border-bottom: 3px solid #2563eb; padding-bottom: 8px; color: #111; }
h2 { font-size: 16pt; border-bottom: 1px solid #ddd; padding-bottom: 4px; margin-top: 28px; color: #1e40af; }
h3 { font-size: 13pt; margin-top: 20px; color: #333; }
code { background: #f3f4f6; padding: 1px 4px; border-radius: 3px; font-size: 10pt; }
pre { background: #f3f4f6; padding: 12px; border-radius: 6px; overflow-x: auto; font-size: 9pt; border: 1px solid #e5e7eb; }
pre code { background: none; padding: 0; }
ul, ol { padding-left: 24px; }
li { margin-bottom: 4px; }
hr { border: none; border-top: 2px solid #e5e7eb; margin: 24px 0; }
table { border-collapse: collapse; width: 100%; margin: 12px 0; font-size: 10pt; }
th, td { border: 1px solid #d1d5db; padding: 6px 10px; text-align: left; }
th { background: #f3f4f6; font-weight: 600; }
.print-btn { position: fixed; top: 20px; right: 20px; background: #2563eb; color: white; border: none; padding: 12px 24px; font-size: 14pt; border-radius: 8px; cursor: pointer; z-index: 1000; box-shadow: 0 2px 8px rgba(0,0,0,0.2); }
.print-btn:hover { background: #1d4ed8; }
@media print { .print-btn { display: none; } }
</style></head><body>
<button class="print-btn" onclick="window.print()">Save as PDF</button><h1>M-TRACK Manufacturing Control System - Complete Application Summary</h1>
<h2>Purpose</h2>
<p>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: <strong>Admins</strong> (managers who create jobs, assign work, and monitor production) and <strong>Workers</strong> (shop floor operators who execute tasks).</p>
<p>The system is self-hosted on a Windows machine and accessed remotely via web browser (including mobile devices on the shop floor).</p>
<hr>
<h2>Deployment</h2>
<ul>
<li>Self-hosted on a Windows machine</li>
<li>Remote web access via browser (desktop and mobile)</li>
<li>PostgreSQL database for data persistence</li>
<li>Single server process serves both the API and the frontend</li>
<li>Environment variable <code>DATABASE_URL</code> for database connection</li>
<li>Environment variable <code>SESSION_SECRET</code> for session encryption</li>
</ul>
<hr>
<h2>Authentication &amp; Access Control</h2>
<h3>Two-Tier Login System</h3>
<ul>
<li><strong>Workers</strong>: Select their name from a dropdown on the landing page. No password required. Instant login for minimal friction on the shop floor.</li>
<li><strong>Admins</strong>: Select their name, then must enter a 4-6 digit numeric PIN.</li>
</ul>
<h3>PIN Management</h3>
<ul>
<li>PINs are stored as bcrypt-hashed values in the database</li>
<li>Admins can set, reset, and initialize PINs for other admin users</li>
<li>A &quot;Bootstrap&quot; 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</li>
</ul>
<h3>Sessions</h3>
<ul>
<li>Express-session based with 24-hour expiration</li>
<li>Session data stored server-side (MemoryStore for development, database-backed sessions table available for production)</li>
</ul>
<h3>Role-Based Access</h3>
<ul>
<li>Two roles: <code>admin</code> and <code>worker</code></li>
<li>Workers can only use the simplified login flow (no PIN)</li>
<li>Workers have an <code>assignedProcesses</code> array (e.g., [&quot;cutting&quot;, &quot;welding&quot;]) that filters which operations they see in their work queue</li>
<li>Admin-only features: User management, inventory deletion, PIN management, time study reports, process type configuration, viewing all workers&#39; queues</li>
</ul>
<hr>
<h2>Core Data Model</h2>
<h3>Jobs</h3>
<p>A job represents a manufacturing order (e.g., building a specific machine for a customer).</p>
<p>Fields:</p>
<ul>
<li>Product name (the thing being built)</li>
<li>Customer name</li>
<li>Order number</li>
<li>Machine serial number</li>
<li>Description and details (free text)</li>
<li>Status: planned, in_progress, completed</li>
<li>Quantity (how many units to build, default 1)</li>
<li>Priority: integer 1-5 (1 = highest)</li>
<li>Due date</li>
<li>Is template flag (templates are reusable job blueprints)</li>
<li>Archived at timestamp (soft delete)</li>
<li>BOM file name and BOM file data (stored for re-download)</li>
</ul>
<h3>Components</h3>
<p>A component is a part or subassembly within a job. Components form a tree hierarchy (parent-child relationships).</p>
<p>Fields:</p>
<ul>
<li>Name</li>
<li>Type: &quot;material&quot; (raw part) or &quot;assembly&quot; (subassembly containing other parts)</li>
<li>Processes: array of strings (e.g., [&quot;cutting&quot;, &quot;bending&quot;, &quot;welding&quot;])</li>
<li>Status: pending, in_progress, completed</li>
<li>Quantity (default 1)</li>
<li>Job ID (belongs to a job)</li>
<li>Parent ID (self-referencing for hierarchy: assemblies contain sub-components)</li>
<li>Assigned to (user ID)</li>
<li>Notes (free text)</li>
<li>Thickness (e.g., &#39;0.125&quot;&#39;, &#39;3mm&#39;)</li>
<li>Material (e.g., &quot;Mild Steel&quot;, &quot;Aluminum 6061&quot;)</li>
<li>Thumbnail data (base64 image extracted from BOM file)</li>
<li>Blueprint URL</li>
<li>Order index (display ordering)</li>
<li>Priority weight (1-100, default 50, higher = more important within the job)</li>
<li>Ready for assembly flag</li>
</ul>
<h3>Operations</h3>
<p>An operation is a specific work step on a component (e.g., &quot;Cut this part&quot;, &quot;Weld this part&quot;).</p>
<p>Fields:</p>
<ul>
<li>Component ID (belongs to a component)</li>
<li>Name (descriptive task name)</li>
<li>Process type (e.g., &quot;cutting&quot;, &quot;Sheetmetal cutting&quot;, &quot;bending&quot;, &quot;welding&quot;, &quot;machining&quot;, &quot;assembly&quot;)</li>
<li>Order index (sequence within the component)</li>
<li>Estimated minutes</li>
<li>Instructions (free text)</li>
<li>Status: pending, in_progress, stalled, completed, skipped</li>
<li>Assigned to (user ID)</li>
<li>Completed at timestamp</li>
<li>Quantity made (for machining operations that produce countable output)</li>
<li>Fulfilled from inventory flag (machining operation fulfilled from existing stock)</li>
<li>Priority score (calculated integer, lower = higher priority)</li>
<li>Priority tier: hot, urgent, normal, backlog (calculated from days until due date)</li>
<li>Ready at timestamp</li>
<li>Blocked reason (text explaining why the operation cannot proceed)</li>
<li>Override fields: overriddenByUserId, overrideReason, overrideExpiresAt (admin can bypass blocking)</li>
</ul>
<h3>Operation Dependencies</h3>
<p>Explicit cross-component blocking relationships.</p>
<p>Fields:</p>
<ul>
<li>Operation ID (the operation that is blocked)</li>
<li>Depends on operation ID (must complete before this operation can start)</li>
<li>Depends on component ID (entire component must complete before this operation can start)</li>
</ul>
<h3>Inventory Items</h3>
<p>Unified inventory system for all materials, manufactured parts, and consumables.</p>
<p>Fields:</p>
<ul>
<li>Item number (auto-assigned by category: consumables 1000+, materials 5000+, manufactured 6000+)</li>
<li>Name, description</li>
<li>Category: material, manufactured, consumable</li>
<li>SKU</li>
<li>Unit: pcs, kg, meters, liters, etc.</li>
<li>Quantity (current stock level)</li>
<li>Restock point (yellow warning threshold)</li>
<li>Reorder point (red critical threshold, triggers automatic alerts)</li>
<li>Reorder quantity (suggested order amount)</li>
<li>Storage location</li>
<li>Supplier name, contact, email</li>
<li>Unit cost</li>
<li>Minimum order quantity</li>
<li>Lead time in days</li>
<li>Last restock date</li>
</ul>
<h3>Inventory Transactions</h3>
<p>Audit trail for every stock change.</p>
<p>Fields:</p>
<ul>
<li>Inventory item ID</li>
<li>Transaction type: restock, consume, adjust, manufacture</li>
<li>Quantity change</li>
<li>Previous quantity and new quantity</li>
<li>Note (reason for change)</li>
<li>User ID (who performed it)</li>
</ul>
<h3>Reorder Alerts</h3>
<p>Tracks inventory replenishment requests.</p>
<p>Fields:</p>
<ul>
<li>Inventory item ID</li>
<li>Status: pending, approved, ordered, received, dismissed</li>
<li>Triggered by: scan (manual QR scan) or auto (hit reorder point)</li>
<li>Scanned by user ID</li>
<li>Approved by user ID, approved at timestamp</li>
<li>Order quantity</li>
<li>Supplier email sent flag and timestamp</li>
<li>Note</li>
</ul>
<h3>Time Study Events</h3>
<p>Performance tracking log.</p>
<p>Fields:</p>
<ul>
<li>Operation ID, component ID, job ID</li>
<li>Worker ID (who performed the work)</li>
<li>Recorded by (who logged the event)</li>
<li>Event type: start, stalled, completed</li>
<li>Note</li>
<li>Occurred at timestamp</li>
</ul>
<h3>Users</h3>
<p>Fields:</p>
<ul>
<li>ID (UUID)</li>
<li>Username (unique, required)</li>
<li>Email, first name, last name, profile image URL (optional)</li>
<li>Role: admin or worker</li>
<li>Assigned processes: array of strings (e.g., [&quot;cutting&quot;, &quot;bending&quot;])</li>
<li>Has completed tutorial: boolean</li>
<li>PIN hash (bcrypt, for admin login)</li>
</ul>
<h3>Process Types</h3>
<p>Configurable list of available manufacturing processes (admin-managed).</p>
<p>Fields:</p>
<ul>
<li>Name (unique, e.g., &quot;cutting&quot;, &quot;Sheetmetal cutting&quot;, &quot;bending&quot;, &quot;welding&quot;, &quot;machining&quot;, &quot;assembly&quot;)</li>
<li>Order index (display ordering)</li>
</ul>
<h3>Other Tables</h3>
<ul>
<li><strong>Subtasks</strong>: Granular checklist items within a component (id, name, status, componentId)</li>
<li><strong>Consumables</strong>: Legacy table for small shop items</li>
<li><strong>Kanban Cards</strong>: Legacy cards for consumable tracking</li>
<li><strong>Machined Parts Inventory</strong>: Tracks stock of machined parts (partName, quantity)</li>
<li><strong>Sessions</strong>: Server-side session storage (sid, sess JSON, expire timestamp)</li>
<li><strong>Operation Assignment Log</strong>: Audit trail for operation assignments (operationId, userId, action, performedByUserId, reason)</li>
</ul>
<hr>
<h2>Key Features</h2>
<h3>1. Job Management</h3>
<p><strong>Creating Jobs:</strong></p>
<ul>
<li>Manually create jobs with product name, customer, serial number, priority, due date, description</li>
<li>Import from BOM (Bill of Materials) Excel files</li>
<li>Instantiate from saved templates</li>
</ul>
<p><strong>Job Templates:</strong></p>
<ul>
<li>Any job can be saved as a template</li>
<li>Templates preserve the full component tree and operation structure</li>
<li>Instantiating a template creates a new active job with all components and operations copied</li>
</ul>
<p><strong>Job Lifecycle:</strong></p>
<ul>
<li>Status progression: planned -&gt; in_progress -&gt; completed</li>
<li>Jobs can be archived (soft delete) and unarchived</li>
<li>Archived jobs are hidden from main views but preserved in the database</li>
</ul>
<p><strong>Job Priority:</strong></p>
<ul>
<li>Integer 1-5 (1 = Critical/highest, 5 = Lowest)</li>
<li>Priority drives the ordering of worker task queues</li>
<li>Combined with due date for automatic priority score calculation</li>
</ul>
<h3>2. BOM Import</h3>
<p><strong>File Format:</strong></p>
<ul>
<li>Accepts Excel files (.xlsx, .xls) and CSV</li>
<li>Uses the <code>xlsx</code> library to read data and <code>exceljs</code> to extract embedded thumbnail images</li>
</ul>
<p><strong>Column Detection:</strong></p>
<ul>
<li>Auto-detects columns by header name using exact and partial matching</li>
<li>Looks for: Item Number, Part Name, Quantity, Material, Thickness</li>
</ul>
<p><strong>Inventor File Name Parsing:</strong></p>
<ul>
<li>Designed to parse Autodesk Inventor file naming conventions</li>
<li>Format: <code>Model_MajorComponent_PartName.ipt</code> or <code>Model_MajorComponent_PartName.iam</code></li>
<li>File extensions (.iam, .ipt) are stripped</li>
<li>CamelCase is split into separate words (e.g., &quot;UpperCylinder&quot; -&gt; &quot;Upper Cylinder&quot;)</li>
<li>Underscores become spaces</li>
<li>Hyphens are preserved with spaces</li>
</ul>
<p><strong>Major Component Codes:</strong></p>
<ul>
<li>Recognizes codes like RB (Roaster Body), CC (Chaff Can), CT (Cooling Tray)</li>
<li>These codes determine which subassembly a part belongs to</li>
</ul>
<p><strong>Two-Pass Component Creation:</strong></p>
<ol>
<li>First pass: Creates subassemblies (items with whole-number IDs like &quot;1&quot;, &quot;2&quot;) as type &quot;assembly&quot;</li>
<li>Second pass: Creates parts (items with decimal IDs like &quot;1.1&quot;, &quot;1.2&quot;) as type &quot;material&quot;, assigned to their parent subassembly</li>
</ol>
<p><strong>Filtering Logic:</strong></p>
<ul>
<li>Parts must have a valid major component prefix (RB, CC, CT) in their file name</li>
<li>Parts must have material containing &quot;MCR&quot; to be imported</li>
<li>This filters out hardware, fasteners, and purchased parts</li>
</ul>
<p><strong>BOM Update:</strong></p>
<ul>
<li>Existing jobs can have their BOM re-imported</li>
<li>The update process preserves existing operations and work progress</li>
<li>New components are added, removed components are deleted, existing ones are updated</li>
<li>Returns counts of updated, added, and removed components</li>
</ul>
<p><strong>Thumbnail Extraction:</strong></p>
<ul>
<li>Embedded images in Excel files are extracted as base64 data</li>
<li>Matched to components by row position</li>
<li>Displayed as component thumbnails in the UI</li>
</ul>
<h3>3. Component Tree &amp; Hierarchy</h3>
<ul>
<li>Components form a tree: Jobs contain top-level assemblies, which contain sub-components</li>
<li>Parent-child relationships via parentId field</li>
<li>Components can be moved between parents via drag or API</li>
<li>Order index controls display ordering within a parent</li>
<li>Assembly components act as containers; their operations are blocked until all child components are completed</li>
</ul>
<h3>4. Operations &amp; Dependencies</h3>
<p><strong>Operation Creation:</strong></p>
<ul>
<li>Operations are created on individual components</li>
<li>Each operation has a process type (cutting, bending, welding, machining, assembly, etc.)</li>
<li>Operations have an order index that determines their sequence within a component</li>
</ul>
<p><strong>Bulk Operations:</strong></p>
<ul>
<li>Admin can assign operations in bulk across multiple components</li>
<li>Select multiple components and multiple process types to create operations for all combinations</li>
<li>Bulk delete also supported</li>
</ul>
<p><strong>Operation Reordering:</strong></p>
<ul>
<li>Operations within a component can be reordered by dragging or via API</li>
<li>Order determines sequential dependency (operation at index 0 must complete before index 1 can start)</li>
</ul>
<p><strong>Dependency System (Three Layers):</strong></p>
<ol>
<li><strong>Sequential</strong>: Within a component, operations must complete in order index sequence</li>
<li><strong>Hierarchical</strong>: Assembly operations are blocked until all child components are completed</li>
<li><strong>Explicit</strong>: Cross-component dependencies defined in the operation_dependencies table</li>
</ol>
<p><strong>Blocking Logic:</strong></p>
<ul>
<li>An operation is &quot;blocked&quot; if any of its dependencies (sequential, hierarchical, or explicit) are not yet completed</li>
<li>Blocked operations appear at the bottom of worker queues with a reason explaining the block</li>
<li>Admins can override blocks by providing an override reason (with optional expiration)</li>
</ul>
<p><strong>Priority Calculation:</strong></p>
<ul>
<li>Priority score = basePriority * (100 - componentWeight) / 100</li>
<li>basePriority = daysUntilDue * 100</li>
<li>Lower score = higher priority</li>
<li>Priority tiers assigned by days until due: hot (&lt;=2 days), urgent (&lt;=5 days), normal (&lt;=14 days), backlog (&gt;14 days)</li>
<li>Recalculation can be triggered manually via API</li>
</ul>
<h3>5. Batch Task Grouping (Cutting Operations Only)</h3>
<p><strong>What Gets Batched:</strong></p>
<ul>
<li>ONLY operations where the process type contains &quot;cutting&quot; or &quot;cut&quot; (case-insensitive), or equals &quot;material&quot;</li>
<li>Examples that batch: &quot;cutting&quot;, &quot;Sheetmetal cutting&quot;, &quot;Steel Tube cutting&quot;, &quot;material&quot;</li>
<li>Examples that do NOT batch: &quot;bending&quot;, &quot;welding&quot;, &quot;machining&quot;, &quot;assembly&quot;</li>
</ul>
<p><strong>Grouping Criteria:</strong></p>
<ul>
<li>Operations are grouped by: Process Type + Material + Thickness + Job ID</li>
<li>All operations sharing these attributes become a single batch that workers can start/complete together</li>
</ul>
<p><strong>Why Batching Exists:</strong></p>
<ul>
<li>In manufacturing, cutting is often done on a single machine for all parts of the same material and thickness</li>
<li>A worker sets up the machine once and cuts all parts, rather than switching materials repeatedly</li>
</ul>
<p><strong>Batch Display:</strong></p>
<ul>
<li>Batches show a count of operations (e.g., &quot;12 parts&quot;)</li>
<li>Individual parts within a batch are listed for reference</li>
</ul>
<h3>6. Task Naming Format (Two-Line Display)</h3>
<p>All work items (batches and individual operations) are displayed in a consistent two-line format:</p>
<p><strong>Line 1 (Title):</strong> <code>[Process] [Product] [Main Assembly] [Sub-Assembly]</code></p>
<ul>
<li>Process: &quot;Cut&quot; for cutting/material operations, otherwise the capitalized process name</li>
<li>Product: The job&#39;s product name</li>
<li>Main Assembly: The top-level assembly name (if the component has a parent hierarchy)</li>
<li>Sub-Assembly: The intermediate assembly name (if applicable)</li>
</ul>
<p><strong>Line 2 (Subtitle):</strong> <code>[Thickness] [Material] - [Customer] - [Serial Number]</code></p>
<ul>
<li>Parts are separated by &quot; - &quot; dash separators</li>
<li>Empty parts are omitted</li>
<li>Thickness: Displayed exactly as it comes from the BOM, with &quot; in&quot; suffix converted to double-quote (&quot;) for inches</li>
</ul>
<h3>7. Worker Queue / &quot;Next Work&quot; View</h3>
<p><strong>Purpose:</strong></p>
<ul>
<li>Shows each worker a prioritized list of tasks they should work on next</li>
<li>Filtered to only show operations matching the worker&#39;s assigned processes</li>
</ul>
<p><strong>Three Sections:</strong></p>
<ol>
<li><strong>In Progress</strong>: Tasks the worker has already started</li>
<li><strong>Stalled</strong>: Tasks that are paused with a reason</li>
<li><strong>Pending</strong>: Tasks available to start, ordered by priority</li>
</ol>
<p><strong>Mixed Content:</strong></p>
<ul>
<li>Cutting batches (grouped by material + thickness + job) appear as single items</li>
<li>All other operations (welding, bending, machining, assembly) appear as individual items</li>
<li>Both types are interleaved in a single prioritized list</li>
</ul>
<p><strong>Priority Ordering:</strong></p>
<ol>
<li>In-progress items appear at the top</li>
<li>Higher job priority (lower number) comes first</li>
<li>Earlier due dates come first (no due date goes to bottom)</li>
<li>Blocked items are pushed to the bottom with a reason displayed</li>
</ol>
<p><strong>Worker Actions:</strong></p>
<ul>
<li><strong>Start</strong>: Moves operation(s) from pending to in_progress, assigns to the current worker, records a time study &quot;start&quot; event</li>
<li><strong>Stalled</strong>: Pauses work; worker MUST provide a reason (e.g., &quot;missing hardware&quot;, &quot;machine down&quot;). Records a time study &quot;stalled&quot; event</li>
<li><strong>Done (Complete)</strong>: Marks operation(s) as completed with timestamp. Records a time study &quot;completed&quot; event. For batches, all operations in the batch are completed simultaneously</li>
<li><strong>Resume</strong>: Moves stalled tasks back to in_progress</li>
</ul>
<p><strong>Admin View:</strong></p>
<ul>
<li>Admins can select any worker from a dropdown to view their queue</li>
<li>Admins can reassign batches to different workers</li>
</ul>
<h3>8. Shop Floor View</h3>
<p><strong>Two Modes:</strong></p>
<p><strong>Batch View (Task-Based):</strong></p>
<ul>
<li>Shows all cutting batches grouped by material + thickness</li>
<li>Filter by process type</li>
<li>Mark batches as complete or stalled</li>
<li>Shows in-progress work at the top</li>
</ul>
<p><strong>Kanban Board (Component-Based):</strong></p>
<ul>
<li>Three columns: Pending, In Progress, Completed</li>
<li>Drag-and-drop components between columns to update status</li>
<li>Uses @hello-pangea/dnd library</li>
<li>Filter by process type</li>
<li>Expand components to view and manage subtasks</li>
</ul>
<h3>9. Dashboard</h3>
<p><strong>Stat Cards (Clickable):</strong></p>
<ul>
<li>Active Jobs: Count of in_progress jobs (click to see list)</li>
<li>Completed Units: Count of completed jobs (click to see list)</li>
<li>Low Stock Alert: Count of consumables below reorder level (click to see list)</li>
<li>Total Jobs: Total job count (click to see list)</li>
</ul>
<p><strong>Charts:</strong></p>
<ul>
<li>Job Status Bar Chart: Planned vs In Progress vs Completed job counts (using Recharts)</li>
<li>Recent Jobs List: 5 most recent jobs with status badges</li>
</ul>
<p><strong>Work Management:</strong></p>
<ul>
<li>Workers see their assigned &quot;Next Work&quot; items</li>
<li>Admins see a global view of all in-progress and stalled work</li>
<li>Admins can select specific workers to view their assigned work</li>
<li>Start/Stall/Done actions available directly from the dashboard</li>
<li>In-progress work section highlighted at the top</li>
</ul>
<p><strong>Job Detail Dialog:</strong></p>
<ul>
<li>Click a job to see metadata (quantity, due date, serial number)</li>
<li>Breakdown of incomplete vs completed tasks</li>
</ul>
<h3>10. Inventory Management</h3>
<p><strong>Three Categories (Tabs):</strong></p>
<ol>
<li><strong>Materials</strong>: Raw materials (steel, aluminum, etc.)</li>
<li><strong>Manufactured Parts</strong>: Parts produced in-house (machined parts with stock tracking)</li>
<li><strong>Consumables</strong>: Shop supplies (welding wire, grinding discs, etc.)</li>
</ol>
<p><strong>Item Number Auto-Assignment:</strong></p>
<ul>
<li>Consumables: 1000+</li>
<li>Materials: 5000+</li>
<li>Manufactured parts: 6000+</li>
</ul>
<p><strong>CRUD Operations:</strong></p>
<ul>
<li>Add, edit, delete inventory items</li>
<li>Quantity adjustment with transaction type (restock, consume, adjust, manufacture)</li>
<li>Every adjustment creates a transaction log entry</li>
</ul>
<p><strong>Low-Stock Alerting:</strong></p>
<ul>
<li>Two thresholds per item: restock point (warning) and reorder point (critical)</li>
<li>When quantity falls to or below reorder point, an automatic reorder alert is created</li>
<li>Manual alerts via QR code scanning</li>
</ul>
<p><strong>Reorder Alert Workflow:</strong></p>
<ul>
<li>Status progression: pending -&gt; approved -&gt; ordered -&gt; received (or dismissed)</li>
<li>Admins approve/dismiss alerts</li>
<li>System can generate pre-filled supplier email for ordering</li>
<li>Notification badge in sidebar shows pending alert count</li>
</ul>
<p><strong>QR Code / Kanban Cards:</strong></p>
<ul>
<li>Generate printable kanban cards with QR codes for physical inventory items</li>
<li>Workers scan QR codes to trigger reorder alerts</li>
<li>Camera-based QR scanning (requires HTTPS) or manual item ID entry</li>
</ul>
<p><strong>Machining Integration:</strong></p>
<ul>
<li>When a machining operation is completed, workers enter &quot;quantity made&quot;</li>
<li>If quantity exceeds what the job needs, excess is automatically added to machined parts inventory</li>
<li>Before starting a machining operation, the system checks if the part already exists in inventory</li>
<li>Workers can &quot;fulfill from inventory&quot; to skip machining and use existing stock</li>
</ul>
<h3>11. Time Study / Performance Reports</h3>
<p><strong>Event Tracking:</strong></p>
<ul>
<li>Every Start, Stalled, and Completed action on an operation creates a time study event</li>
<li>Events record: operation, component, job, worker, event type, timestamp, optional note</li>
</ul>
<p><strong>Reports (Admin Only):</strong></p>
<ul>
<li>Filter by worker and/or job</li>
<li>Shows total active time (time between start and completed events)</li>
<li>Shows total stalled time (time between stalled and resumed events)</li>
<li>Event log with timestamps for detailed analysis</li>
</ul>
<h3>12. Tutorial / Onboarding System</h3>
<p><strong>Automatic Trigger:</strong></p>
<ul>
<li>Tutorial appears automatically for any user who hasn&#39;t completed it (hasCompletedTutorial = false)</li>
</ul>
<p><strong>8 Steps:</strong></p>
<ol>
<li>Welcome to M-TRACK</li>
<li>Dashboard overview</li>
<li>Jobs Management</li>
<li>Shop Floor</li>
<li>Inventory</li>
<li>Your Work Queue</li>
<li>Settings</li>
<li>Completion (&quot;You&#39;re Ready!&quot;)</li>
</ol>
<p><strong>Controls:</strong></p>
<ul>
<li>Navigate with Next/Previous buttons or Arrow keys</li>
<li>Skip with Escape key or Skip button</li>
<li>Restart from Settings page</li>
<li>Completion status saved to database so it doesn&#39;t reappear</li>
</ul>
<p><strong>Implementation:</strong></p>
<ul>
<li>React Context (TutorialContext) manages state</li>
<li>Overlay component with Framer Motion animations</li>
<li>Persisted via API calls to mark completion/reset</li>
</ul>
<h3>13. Settings Page</h3>
<p><strong>For All Users:</strong></p>
<ul>
<li>View account info</li>
<li>Restart tutorial</li>
<li>View system architecture diagram</li>
</ul>
<p><strong>For Admins:</strong></p>
<ul>
<li>User Management: Create users, edit roles/usernames, assign work processes, manage PINs</li>
<li>Process Type Configuration: Add or remove manufacturing process categories</li>
</ul>
<h3>14. Architecture Diagram</h3>
<ul>
<li>Interactive Mermaid.js diagrams</li>
<li>Two views: System Architecture and User Workflow</li>
<li>Zoom in/out capability</li>
<li>Download as SVG</li>
<li>Shows how components relate (frontend, backend, database, user flows)</li>
</ul>
<hr>
<h2>UI Navigation</h2>
<h3>Sidebar</h3>
<ul>
<li>Dashboard</li>
<li>Jobs</li>
<li>Shop Floor</li>
<li>Worker Queue</li>
<li>Inventory</li>
<li>Scan (QR scanning)</li>
<li>Reorder Alerts (with notification badge showing pending count)</li>
<li>Time Study (admin only)</li>
<li>Settings</li>
<li>Architecture Diagram</li>
<li>Logout</li>
</ul>
<h3>Responsive Design</h3>
<ul>
<li>Works on desktop and mobile browsers</li>
<li>Sidebar collapses on mobile</li>
<li>Touch-friendly interactions for shop floor use</li>
</ul>
<hr>
<h2>Key Business Rules</h2>
<ol>
<li><p><strong>Cutting operations batch together</strong> by material + thickness + job. All other processes are individual operations.</p>
</li>
<li><p><strong>Operation blocking</strong> prevents workers from starting work out of sequence. Sequential order within a component, assembly hierarchy, and explicit cross-component dependencies all contribute to blocking.</p>
</li>
<li><p><strong>BOM updates preserve existing work.</strong> Re-importing a BOM updates metadata but does not delete operations that have already been started or completed.</p>
</li>
<li><p><strong>Machined parts can be fulfilled from inventory</strong> instead of re-machining, saving production time.</p>
</li>
<li><p><strong>Reorder alerts fire automatically</strong> when stock hits the reorder point, but can also be triggered manually via QR scan.</p>
</li>
<li><p><strong>Priority scoring is automatic</strong> based on due date and component weight, but jobs also have a manual priority override (1-5).</p>
</li>
<li><p><strong>Workers only see operations matching their assigned processes.</strong> A worker assigned to &quot;cutting&quot; and &quot;bending&quot; won&#39;t see welding tasks.</p>
</li>
<li><p><strong>Admins can override operation blocking</strong> with a reason and optional expiration time.</p>
</li>
<li><p><strong>Time study events are created automatically</strong> whenever a worker starts, stalls, or completes an operation.</p>
</li>
<li><p><strong>Process types are configurable</strong> - admins can add new process types without code changes.</p>
</li>
</ol>
<hr>
<h2>API Overview</h2>
<h3>Authentication</h3>
<ul>
<li><code>POST /api/login</code> - Worker login (select user, no PIN)</li>
<li><code>POST /api/auth/login-with-pin</code> - Admin login with PIN</li>
<li><code>GET /api/auth/user</code> - Get current session user</li>
<li><code>POST /api/logout</code> - End session</li>
<li><code>GET /api/auth/bootstrap-status</code> - Check if first-time setup needed</li>
<li><code>POST /api/auth/bootstrap-initialize</code> - Create/initialize first admin</li>
<li><code>GET /api/auth/check-pin/:userId</code> - Check if user requires PIN</li>
<li><code>POST /api/auth/set-pin</code> - Set own PIN</li>
<li><code>POST /api/auth/reset-pin/:userId</code> - Admin reset another user&#39;s PIN</li>
<li><code>POST /api/auth/initialize-pin/:userId</code> - Admin set PIN for another user</li>
<li><code>POST /api/auth/complete-tutorial</code> - Mark tutorial complete</li>
<li><code>POST /api/auth/reset-tutorial</code> - Reset tutorial for current user</li>
</ul>
<h3>Users</h3>
<ul>
<li><code>GET /api/users</code> - List all users</li>
<li><code>POST /api/users</code> - Create user (username, role, assignedProcesses)</li>
<li><code>PATCH /api/users/:id</code> - Update user</li>
</ul>
<h3>Jobs</h3>
<ul>
<li><code>GET /api/jobs</code> - List jobs (query: isTemplate=true/false)</li>
<li><code>GET /api/jobs/:id</code> - Get single job</li>
<li><code>POST /api/jobs</code> - Create job</li>
<li><code>PATCH /api/jobs/:id</code> - Update job</li>
<li><code>DELETE /api/jobs/:id</code> - Delete job</li>
<li><code>POST /api/jobs/:id/archive</code> - Soft delete</li>
<li><code>POST /api/jobs/:id/unarchive</code> - Restore archived job</li>
<li><code>GET /api/jobs/archived</code> - List archived jobs</li>
<li><code>POST /api/jobs/:id/instantiate</code> - Create job from template</li>
<li><code>POST /api/jobs/:id/save-template</code> - Save job as template</li>
<li><code>POST /api/jobs/import-bom</code> - Import BOM file (multipart/form-data)</li>
<li><code>GET /api/jobs/:id/bom</code> - Download original BOM file</li>
<li><code>POST /api/jobs/:id/bom/update</code> - Re-import BOM preserving existing work</li>
</ul>
<h3>Components</h3>
<ul>
<li><code>GET /api/components</code> - List (query: jobId, assignedTo)</li>
<li><code>POST /api/components</code> - Create component</li>
<li><code>PATCH /api/components/:id</code> - Update component</li>
<li><code>DELETE /api/components/:id</code> - Delete component</li>
<li><code>POST /api/components/move</code> - Move component to new parent</li>
</ul>
<h3>Operations</h3>
<ul>
<li><code>GET /api/operations</code> - List (query: componentId)</li>
<li><code>GET /api/operations/:id</code> - Get single operation</li>
<li><code>POST /api/operations</code> - Create operation</li>
<li><code>PATCH /api/operations/:id</code> - Update operation</li>
<li><code>DELETE /api/operations/:id</code> - Delete operation</li>
<li><code>POST /api/operations/reorder</code> - Reorder operations within a component</li>
<li><code>POST /api/operations/bulk</code> - Bulk create operations across components</li>
<li><code>DELETE /api/operations/bulk</code> - Bulk delete operations</li>
</ul>
<h3>Batch Tasks &amp; Worker Queue</h3>
<ul>
<li><code>GET /api/batch-tasks</code> - Get batch groups (query: processType, jobId, status)</li>
<li><code>POST /api/batch-tasks/start</code> - Start a batch (operationIds + userId)</li>
<li><code>POST /api/batch-tasks/complete</code> - Complete a batch</li>
<li><code>POST /api/batch-tasks/stall</code> - Stall a batch (with reason)</li>
<li><code>POST /api/batch-tasks/dismiss-stall</code> - Resume stalled batch</li>
<li><code>GET /api/batch-tasks/worker/:userId</code> - Get batches for a worker</li>
<li><code>GET /api/work/next/:userId</code> - Get unified next work (batches + individual ops)</li>
<li><code>GET /api/work/assigned</code> - Get current user&#39;s assigned work</li>
<li><code>GET /api/work/all-workers</code> - Get all workers&#39; current work (admin)</li>
</ul>
<h3>Inventory</h3>
<ul>
<li><code>GET /api/inventory</code> - List items (query: category)</li>
<li><code>POST /api/inventory</code> - Create item</li>
<li><code>PATCH /api/inventory/:id</code> - Update item</li>
<li><code>DELETE /api/inventory/:id</code> - Delete item (admin only)</li>
<li><code>POST /api/inventory/:id/adjust</code> - Adjust quantity with transaction log</li>
<li><code>GET /api/inventory/:id/transactions</code> - Get transaction history</li>
<li><code>GET /api/inventory-transactions</code> - Get all transactions</li>
</ul>
<h3>Machined Parts</h3>
<ul>
<li><code>GET /api/machined-parts</code> - List machined parts inventory</li>
<li><code>POST /api/operations/:id/complete-machining</code> - Complete machining with quantity tracking</li>
<li><code>POST /api/operations/:id/fulfill-from-inventory</code> - Use existing stock instead of machining</li>
<li><code>GET /api/machined-parts/check/:partName</code> - Check if part exists in inventory</li>
</ul>
<h3>Consumables (Legacy)</h3>
<ul>
<li><code>GET /api/consumables</code> - List consumables</li>
<li><code>POST /api/consumables</code> - Create consumable</li>
<li><code>PATCH /api/consumables/:id</code> - Update consumable</li>
</ul>
<h3>Alerts &amp; Scanning</h3>
<ul>
<li><code>GET /api/reorder-alerts</code> - List alerts (query: status)</li>
<li><code>GET /api/reorder-alerts/count</code> - Get pending alert count</li>
<li><code>POST /api/reorder-alerts</code> - Create manual alert</li>
<li><code>PATCH /api/reorder-alerts/:id</code> - Update alert status</li>
<li><code>POST /api/scan/:itemId</code> - Scan item to trigger reorder alert</li>
</ul>
<h3>Reports &amp; Config</h3>
<ul>
<li><code>GET /api/time-study/report</code> - Get time study data (query: workerId, jobId, componentId)</li>
<li><code>POST /api/time-study</code> - Record time study event</li>
<li><code>GET /api/process-types</code> - List configured process types</li>
<li><code>POST /api/process-types</code> - Add process type</li>
<li><code>DELETE /api/process-types/:id</code> - Remove process type</li>
<li><code>POST /api/recalculate-priorities</code> - Recalculate all operation priorities</li>
</ul>
<h3>Subtasks</h3>
<ul>
<li><code>GET /api/subtasks</code> - List (query: componentId)</li>
<li><code>POST /api/subtasks</code> - Create subtask</li>
<li><code>PATCH /api/subtasks/:id</code> - Update subtask</li>
<li><code>DELETE /api/subtasks/:id</code> - Delete subtask</li>
</ul>
<hr>
<h2>Architecture Diagram (Text)</h2>
<pre><code>+------------------+ HTTP/REST +------------------+ SQL +------------------+
| | &lt;===============&gt; | | &lt;==========&gt; | |
| 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 |
+--------------------------------------+
</code></pre>
<h2>User Flow Diagram (Text)</h2>
<pre><code> +------------------+
| 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 |
+-------------+ +-------------+
</code></pre>
<hr>
<h2>Important Implementation Notes for Recreation</h2>
<ol>
<li><p><strong>The &quot;isCuttingProcess&quot; helper</strong> must use case-insensitive matching. Check if processType.toLowerCase() includes &quot;cutting&quot; or &quot;cut&quot;, OR equals &quot;material&quot;. This is critical for batch grouping to work with process types like &quot;Sheetmetal cutting&quot; or &quot;Steel Tube cutting&quot;.</p>
</li>
<li><p><strong>BOM import uses two libraries</strong>: <code>xlsx</code> for reading spreadsheet data, and <code>exceljs</code> for extracting embedded images (thumbnails). They serve different purposes and both are needed.</p>
</li>
<li><p><strong>The worker queue mixes batched and individual items</strong> in a single prioritized list. Cutting operations are grouped into batches; everything else is individual. This is the &quot;Next Work&quot; endpoint.</p>
</li>
<li><p><strong>Operation status transitions</strong>: pending -&gt; in_progress -&gt; completed (or stalled from in_progress, then resumed back to in_progress). The &quot;skipped&quot; status exists for operations bypassed via inventory fulfillment.</p>
</li>
<li><p><strong>The task naming two-line format</strong> must use &quot; (double quote character) instead of &quot;in&quot; for inches in thickness. The thickness value should be displayed as it comes from the BOM with this one normalization.</p>
</li>
<li><p><strong>Subtitle parts are joined with &quot; - &quot; (space dash space)</strong> as separators. Empty parts are omitted entirely.</p>
</li>
<li><p><strong>Assembly blocking</strong>: An operation on an &quot;assembly&quot; type component is blocked until ALL child components (and their children, recursively) have status &quot;completed&quot;.</p>
</li>
<li><p><strong>Session-based auth</strong> means the server must support sessions. The worker login flow explicitly prevents admin role users from using it (they must use PIN).</p>
</li>
<li><p><strong>Inventory auto-numbering</strong> assigns the next available number in the category range when creating new items.</p>
</li>
<li><p><strong>Reorder alerts deduplicate</strong> - the system should check for existing pending alerts before creating duplicates.</p>
</li>
<li><p><strong>BOM update (re-import) preserves work</strong> - 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.</p>
</li>
<li><p><strong>The priority recalculation</strong> processes all active (non-template, non-archived) jobs and updates every operation&#39;s priorityScore and priorityTier based on current date vs. due date.</p>
</li>
</ol>
</body></html>