"""temper_rejects — the Ausschuss-Station page-module for the SPRO gateway. A central, **login-free** reject-booking terminal for ALL presses' tempered carts (Werk Cadolzburg). Mounted into the SPRO Universal Gateway as a git submodule at ``/modules/temper_rejects/`` and discovered by the kernel module loader (``app.core.modules.load_modules``), which imports this package and calls ``register(app)``. It does two things: * mounts the built Vue SPA (``dist/``) as static files under ``/module/temper_rejects``; * exposes a small no-auth JSON API under ``/module/temper_rejects/api`` — reads (tempered carts per ``ttId`` + reject reasons) AND one narrow write (``POST /reject`` → one row in ``production.rejects``). No login / device context by design — this is a central shop-floor terminal. The existing device-scoped ``POST /press/rejects/send`` derives the press from the device JWT, which is useless for a multi-press terminal; hence the un-scoped variant here, which takes ``press`` + ``ttId`` from the request body. Non-sensitive shop-floor data. Security posture (network/reverse-proxy vs. a static token) is an open question — see this repo's README + ``.claude/memory/ausschuss-station.md``. See ``agent_docs/vue-page-modules.md`` in the gateway repo for the module runbook. """ from __future__ import annotations from pathlib import Path from fastapi import FastAPI from fastapi.staticfiles import StaticFiles MODULE_NAME = "temper_rejects" # MUST match vite.config.ts `base` (with a trailing slash on the Vite side). MODULE_PREFIX = "/module/temper_rejects" def register(app: FastAPI) -> None: """Mount the data API and the SPA onto the gateway app. API routes are registered FIRST — a ``StaticFiles`` mount captures everything under its prefix, so the ``/api`` routes must exist before the mount or they get shadowed. ``dist/`` MUST exist (it is committed) or this raises and the loader logs-and-skips the module (kernel stays up, page 404s). """ from .api import routes app.include_router(routes.router) dist = Path(__file__).resolve().parent / "dist" app.mount(MODULE_PREFIX, StaticFiles(directory=dist, html=True), name=MODULE_NAME)