# Plast Track MVP - Codex Prompt & UI Instructions ## 1. Codex Task Prompt Use this as the top-level prompt when opening a Codex session on this repository. ```text You are working on Plast Track MVP - a lightweight MES/IoT dashboard for supervising multi-brand injection molding machines. The stack is: Backend FastAPI + PostgreSQL + Mosquitto MQTT (Python) Frontend React + TypeScript (Vite, port 5173) Infra Docker Compose Repository layout: /backend FastAPI app, MQTT consumer, OEE logic, WebSocket /frontend React + TypeScript operator dashboard /edge-simulator Publishes simulated MQTT machine events /database init.sql + seed.sql /mqtt mosquitto.conf docker-compose.yml Key rules: - Never send commands back to the machines. Acquisition is read-only / passive. - All timestamps are UTC ISO-8601. - OEE = Availability x Performance x Quality (see README for exact formulas). - The WebSocket at /ws/dashboard pushes refresh notifications; the UI then refetches via REST. Do not push full payloads over the socket. - Machine status values: production | arret_non_qualifie | arret_qualifie | reglage | hors_planning Before writing code: 1. Read the relevant backend route or model file first. 2. Confirm the PostgreSQL schema in /database/init.sql for any DB changes. 3. Run `pytest` in /backend and `npm run build` in /frontend to verify changes. 4. Keep backend business logic inside service modules, not route handlers. 5. For frontend changes, follow the UI instructions below. ``` ## 2. UI Instructions for Codex Paste these instructions into any Codex task that touches the frontend. ### 2.1 Design System - Non-Negotiable Tokens All visual decisions must derive from these tokens. Do not introduce new color hex values, font families, or border-radius values without updating this table. #### Colors | Token name | Hex | Role | |------------------------|-----------|-----------------------------------------| | `--bg-base` | `#F5F7FA` | Page background | | `--bg-panel` | `#FFFFFF` | Panel and card surface | | `--bg-panel-alt` | derived | Alternate very light gray surface | | `--border` | derived | Anthracite tint border | | `--teal-900` | `#0A2F5A` | Primary industrial blue structure | | `--teal-700` | derived | Darker industrial blue | | `--teal-100` | derived | Industrial blue tint | | `--accent` | `#F28C28` | Technical orange accent and CTA | | `--accent-light` | derived | Technical orange tint | | `--text-primary` | `#2B2B2B` | Anthracite body text | | `--text-secondary` | derived | Anthracite metadata tint | | `--text-on-dark` | `#FFFFFF` | Text on dark surfaces | | `--status-production` | `#0A2F5A` | Industrial blue, machine running | | `--status-unqualified` | `#F28C28` | Technical orange, unqualified stop | | `--status-qualified` | `#2B2B2B` | Anthracite, qualified stop | | `--status-setup` | derived | Blue/orange mix, setup / reglage | | `--status-off-plan` | derived | Anthracite tint, outside planning | #### Typography | Role | Font family | Weight | Usage | |----------------|-------------------|--------|----------------------------------------| | Display / KPI | `Space Grotesk` | 600 | Headings, large numbers, machine codes | | Body / UI | `Instrument Sans` | 400 | Labels, descriptions, form fields | | Body emphasis | `Instrument Sans` | 600 | Sub-headings, table headers | | Caption / meta | `Instrument Sans` | 400 | Small labels, timestamps, hints | Type scale: ```css --text-xs: 0.75rem; --text-sm: 0.875rem; --text-base: 1rem; --text-lg: 1.125rem; --text-xl: 1.25rem; --text-2xl: 1.5rem; --text-3xl: 2rem; ``` #### Surfaces ```css border-radius: 12px; box-shadow: 0 1px 3px rgba(10, 47, 90, 0.06), 0 4px 12px rgba(10, 47, 90, 0.04); ``` Selected card: ```css box-shadow: 0 4px 16px rgba(10, 47, 90, 0.12), 0 0 0 2px var(--accent); ``` Inset surfaces: ```css background: var(--bg-panel-alt); border: 1px solid var(--border); border-radius: 6px; ``` ### 2.2 Layout Rules The current UI uses a tabbed module workspace, not a fixed action sidebar. ```text Hero Header Summary Ribbon Module Tabs Current Module Panel ``` Current modules: - `Atelier`: machine cards, filters, sorting, quick actions, fullscreen workshop mode - `Machine`: selected machine detail, cycle trend, events, downtime history - `TRS`: daily OEE/TRS - `OF`: production order creation and management - `Arrets`: downtime qualification - `Rebuts`: scrap declaration and scrap log - `Config`: passive signal and timing configuration Responsive rules: - Desktop: centered workspace, full tab row, split form/list modules where useful. - Tablet: tabs wrap, form/list modules stack. - Mobile: single column, no horizontal page scroll. ### 2.3 Component Conventions #### Machine Card - Card uses `min-height: 180px`. - Machine code uses `Space Grotesk 600`, `--text-xl`. - Status badge uses tokenized status color and text label. - State duration badge shows elapsed time since `status_since`. - No active order state must be visually distinct. - Quick actions route to OF, Rebuts, or Arrets modules. - Selected state uses the elevated `box-shadow`; do not use outline for the selected ring. #### Status Badge Use ``. Always include a text label; color is never the only state indicator. #### KPI Block Use for summary and machine detail metrics: - label: `--text-xs`, uppercase, `--text-secondary` - value: `--text-2xl`, `Space Grotesk 600` - optional sub-label: `--text-xs`, `--text-secondary` #### Forms - Fields use full width, `border-radius: 6px`, `border: 1px solid var(--border)`, `padding: 8px 12px`. - Primary action button uses `var(--accent)`, `border-radius: 8px`, `Space Grotesk 600`. - Inline validation appears below the field in `--status-qualified`. - API errors appear inside the active module, not as global alerts. - Success toasts appear inline and auto-dismiss after 3 seconds. #### Cycle Bar Mini-Chart - Use SVG directly; no third-party charting library. - Newest cycle appears on the right. - Theoretical cycle is a dashed `--teal-100` reference line. - Bars at or below theoretical are green. - Bars above theoretical by more than 10% are orange. - Tooltip shows exact cycle time in seconds. ### 2.4 Interaction Rules | Trigger | Expected behavior | |-------------------------|-------------------------------------------------------| | Click machine card body | Selects machine and opens Machine module | | Click quick OF action | Selects machine and opens OF module | | Click quick Rebut | Selects machine and opens Rebuts module | | Click quick Arret | Selects machine and opens Arrets module | | WebSocket refresh event | Re-fetch dashboard data without unmount flash | | Submit downtime qualify | Validate inline, send REST request, refresh on success | | Submit scrap | Validate inline, clear form on success | | Create production order | Add order; do not auto-start unless user starts it | Data fetching: - REST calls go to `http://localhost:8000/api/...`. - WebSocket connects to `ws://localhost:8000/ws/dashboard`. - On WS disconnect, show a small reconnecting banner and retry with exponential backoff up to 30 seconds. - Do not poll. Refresh is WebSocket-driven. ### 2.5 Accessibility Minimums - Interactive elements must be reachable by keyboard. - Status colors must have text labels. - Touch targets should be at least 44px high. - Respect `prefers-reduced-motion`. - Body text on panel backgrounds must pass WCAG AA contrast. ### 2.6 File Conventions | What | Where | |-------------------------------|-----------------------------------------------| | Global CSS variables / resets | `frontend/src/styles.css` | | Root app layout | `frontend/src/App.tsx` | | Machine card component | `frontend/src/components/MachineCard.tsx` | | Reusable panel wrapper | `frontend/src/components/Panel.tsx` | | New components | `frontend/src/components/.tsx` | | Types | `frontend/src/lib/types.ts` | Rules: - One component per file. - No inline styles in TSX. - No Tailwind. - No UI component library. - No charting library for cycle bars. - No machine command/control path. - No `localStorage` for production state. ### 2.7 Suggested Next Tasks 1. Add historian-style OEE and scrap reporting endpoints. 2. Add edge gateway buffering for MQTT outage periods. 3. Add a real passive gateway adapter specification with example payload mappings. 4. Add operator and supervisor views when role needs are defined. 5. Add richer downtime timelines and duration buckets.