SPA_TemperProductionOverview/README.md
Erik bd9103c172 chore: use yarn (fleet standard) + declare vite devDependency
- Switch package manager from npm to yarn 1.22.22 (pinned via packageManager,
  matches PressV/sp-ui-kit): remove package-lock.json, add yarn.lock (v1).
- Add "vite" as an explicit devDependency. npm 7+ auto-installed it as a peer of
  @vitejs/plugin-vue / @tailwindcss/vite, which masked the missing declaration; a
  clean `yarn install` (no peer auto-install) needs it explicit or the tsc build
  fails to resolve 'vite' / 'vite/client'.
- README: npm -> yarn (+ `corepack enable`).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 09:06:20 +02:00

160 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SPA_TemperProductionOverview — Temper-Linie · Live-Übersicht
A **login-free, read-only** whole-line temper overview, built as a Vue 3 SPA that
the **SPRO Universal Gateway** serves as a static page-module under
`/module/temper_overview/` and that is **embedded into Grafana via an `<iframe>`**.
> **Standalone orientation.** This repo is developed on its own (like `FastPress`,
> `PressV`, `sp-ui-kit` — sibling repos), but it only comes fully alive when mounted
> into the gateway as a git submodule at `modules/temper_overview/`. This README
> bakes in everything a fresh session needs — you shouldn't need the gateway repo
> open to work on the frontend.
Board it renders (dark, one connected line): **Pressen → (cyan ↓) → Ofen →
(green ↓) → Fertig**, carts hanging under their origin press, oven trays whose
background fills with dwell progress, a finished band, and a time-range picker that
scopes only the "Fertig" figures. Run `npm run dev` to see it.
---
## Quick start (standalone dev)
Package manager is **yarn 1.22.22** (pinned via `packageManager`; matches PressV /
the fleet). `corepack` provides it — no global yarn install needed.
```bash
# 0) let corepack honour the pinned yarn (one-time per machine)
corepack enable
# 1) auth for the private @sp-ui-kit design-token package (one-time)
cp .npmrc.example .npmrc # then paste a Gitea PAT with "package: Read" scope
# (yarn v1 reads .npmrc for the scoped registry)
# 2) install + run
yarn install
yarn dev # http://localhost:5173/module/temper_overview/
```
With **no gateway backend running**, the store falls back to **bundled sample data**
(`src/data/sample.ts`), so `yarn dev` shows the full design immediately (a
`DEMO-DATEN` tag appears in the header). `yarn build``dist/` (committed).
---
## How it's wired into the gateway (page-module contract)
This is a gateway module per `agent_docs/vue-page-modules.md` in the gateway repo.
The **repo root is a Python package** (`__init__.py`) so the kernel's module loader
can `import temper_overview` and call `register(app)`:
| File | Role |
|---|---|
| `__init__.py` | `register(app)` — mounts `dist/` at `MODULE_PREFIX` + includes the API router |
| `_db.py` | kernel DB seam (`run_select_query`) — used once real SQL is wired |
| `api/routes.py` | the no-auth read API (`GET /module/temper_overview/api/overview`) |
| `dist/` | **committed** build output — the gateway serves this (deploy host has no Node) |
| `src/` etc. | the Vue app source |
**URL prefix lives in two places that MUST match** — change both together:
`vite.config.ts``base: '/module/temper_overview/'` and `__init__.py`
`MODULE_PREFIX = "/module/temper_overview"`. The frontend derives its API base from
`import.meta.env.BASE_URL`, so it follows the prefix automatically.
Add it to a gateway checkout:
```bash
# in the gateway repo (fastAPI)
git submodule add https://git.sprodat.eu/Erik/SPA_TemperProductionOverview.git modules/temper_overview
# MODULES_ENABLED in .env must include temper_overview (or be empty = load all)
```
Restart the gateway; the log shows `loaded module: temper_overview`. Smoke-test
(mind the trailing slash): `http://localhost:8800/module/temper_overview/` and
`…/api/overview`.
> **Deploy rule:** always `yarn build` and **commit `dist/`** when the app changes,
> then bump the submodule pin in the gateway repo. Never build on the gateway host.
---
## Data API contract
`GET /module/temper_overview/api/overview?range=12h|1d|7d|14d|30d` → one JSON
payload for the whole line. The TypeScript shape is authoritative:
[`src/types/overview.ts`](src/types/overview.ts); the Python side builds the same
shape in [`api/routes.py`](api/routes.py). `range` scopes **only** the `finished`
figures — presses / on-the-way / oven are always real-time.
```jsonc
{
"plant": "Werk 1", "generatedAt": "…", "range": "1d",
"ovenTempC": 185, "ovenAvgMin": 120, "sample": true,
"presses": [{ "name":"P1","status":"run","orders":[{"orderNo":"O-4471","colorIndex":0}],
"good":1240,"cycleTime":"4.2","notVerladen":34,"note":null,"placeholder":false }],
"onWay": { "P3":[{ "cartId":"C-014a","orders":[{"orderNo":"O-4471","qty":54,"colorIndex":0}],"etaMin":3 }] },
"oven": [{ "cartId":"C-011","orders":[],"totalMin":120,"remainingMin":42 }],
"finished": { "carts":47,"parts":5120,"scrap":63,"avgOvenMin":118,
"byOrder":[{"orderNo":"O-4471","colorIndex":0,"parts":1680}] },
"finishedList": [{ "cartId":"C-010","orders":[],"ago":"vor 8 min" }]
}
```
### Wiring the REAL data (currently SAMPLE)
`api/routes.py` returns sample data today. To make it live (see the big `TODO` there
and `.claude/memory/temper-line-overview.md` in the gateway):
- Import the kernel proxy: `from .._db import run_select_query` (read-only).
- Reuse the temper status-derivation in `modules/fastpress/press/temper.py`
(`_temper_aggregates_all` derives on-way / in-oven / finished from planned
timestamps vs `NOW()`), un-scoped across **all** presses. Read
`production.temper_tracking` (carts grouped by `ttCartId`, keyed by origin press
`ttPress`) + `production.active_orders`/`finished_orders`.
- `notVerladen` = produced good parts (cycles) parts logged to temper. **Open
question:** per-press or plant-wide?
- Scope `finished` by `range` on `ttOutOfOvenAt`. Never echo customer/price fields.
Alternatively, add a public `GET /press/temper/overview` in fastpress and have the
frontend call that — decide before wiring; keep the payload shape above either way.
---
## Tech stack (matches PressV / the fleet)
Vue 3.5 · Vite 8 · TypeScript 5.9 · Pinia 3 · vue-router 4 (hash) · vue-i18n 10
(de default, `?lang=en`) · PrimeVue 4.5 (Nora + custom **Industrial** preset, sky
primary) · Tailwind v4 (CSS-first) · `@sp-ui-kit/tokens` (shared design tokens,
private registry) · Inter Variable. **Dark-first**, flat 2px corners, 0s
transitions, `prefers-reduced-motion` disables the conveyor animations.
**Store pattern** (mirrors PressV `productionOverview`): `src/stores/temperOverview.ts`
does `loadCache()` (sessionStorage) → `hydrate()` (spinner only on cold start) →
`refresh()` (background) → `startPolling(12000)`. Robust to a dev server's SPA
fallback: a response without a `presses[]` array is treated as "no backend" → sample.
### Design tokens (recognisable across SPRO apps)
Flow accents match PressV `--c-*`: press/machine `#a78bfa`, on-the-way/cart
`#22d3ee`, oven `#f97316` (hot `#ef4444`), finished `#34d399`. Order chips (from
PressV `orderColors.ts`): `#5794F2 #E8825A #B57EDC #4FB7A8`. Defined in
`src/style.css` (`:root` dark + `html:not(.dark)` light) and `src/data/orderColors.ts`.
> Not yet used but part of the fleet stack — add when needed: `@sp-ui-kit/ui-core`
> components and `echarts`/`vue-echarts`. The board's by-order bars are CSS today.
---
## Grafana embedding
The gateway sets no `X-Frame-Options`/CSP, so a Grafana **Text** panel (HTML mode,
`disable_sanitize_html = true`) can iframe it:
```html
<iframe src="http://<gateway-host>:8800/module/temper_overview/#/"
width="100%" height="900" style="border:0"></iframe>
```
Append `?lang=en` before the `#` for English. Design is locked as design #4
"Shop-floor Schematic" — see `.claude/memory/temper-line-overview.md` and the
prototype at `modules/fastpress/reference/temper-overview/` in the gateway repo.