39a6f62089178bdc3c9b23ece22fb2c84f370e8d
4 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
78816dfe8c |
fix(ui): una cornice sola, e smette di spostarsi sotto le dita
Punto 14. La segnalazione dell'operatore del 28/07 non era stata circoscritta sul codice: «le dimensioni delle viste cambiano a seconda del menu». Sono quattro meccanismi distinti, tutti leggibili senza avere il tablet in mano. Ogni vista si dichiarava la propria larghezza: sette valori diversi su diciassette template, e nessuno coincideva con quello della navbar, che sta a max-w-7xl su tutte. Il contenuto era quindi disallineato dalla barra sopra di sé, e il disallineamento cambiava a ogni pagina. Il percorso dell'operatore faceva 1280 → 1024 → tutto schermo → 1280 in quattro passaggi. Il padding verticale mescolava py-8 e py-6 fra viste consecutive, così la prima card cambiava altezza a ogni schermata. La barra di scorrimento è classica da 8px e occupa spazio: una pagina lunga la mostrava, una corta no, e la schermata di misura la toglie sempre. A ogni navigazione tutto il contenuto centrato — navbar compresa — si spostava di 8px. La schermata di misura era alta 100vh, che su Android e iOS è l'altezza con la barra dell'indirizzo nascosta: su un tablet il piede, dove stanno «Fine ciclo misura» e il tastierino, finiva sotto il bordo. Ora: .tmf-page e .tmf-page-narrow in themes.css, con i valori esatti della navbar; scrollbar-gutter: stable; 100dvh dove serve. Due larghezze in tutto il prodotto al posto di sette, e il criterio è il tipo di pagina — liste, tabelle e tele stanno larghe, i moduli stanno stretti. Login e schermata di misura tengono la loro geometria, per i motivi scritti in docs/architecture/LAYOUT.md e ripetuti in EXEMPT dentro il test: la prima non ha navbar a cui allinearsi, la seconda non deve scorrere mentre si misura. Il test è statico e guarda i sorgenti: la vista scritta domani copierà la cornice dalla vicina, ed è lì che la deriva ricomincia. Resta da chiedere all'operatore su quale schermo l'ha vista: in verticale su un tablet quasi tutte quelle larghezze collassano e il difetto non si nota. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
bde8fafd77 |
feat(production): la misura torna a cercare l'operatore
Il conto alla rovescia non si ferma piu' a zero. Oltre la scadenza continua nell'altro senso e dice da quanto la linea e' in ritardo, in rosso, su tutte le schermate del percorso di misura: lista task, riepilogo, scelta ricetta. Un ritardo va letto, non dedotto. Allo scadere dell'intervallo la misura si ripropone da sola: cicalino, un avviso di cinque secondi, e l'operatore torna al primo task di misura da qualunque schermata si trovi. Un ciclo copre tutti i task di misura della ricetta, quindi solo l'ultimo lo chiude e fa ripartire l'intervallo. Farlo ripartire al primo avrebbe fatto misurare una ricetta con tre task di misura tre volte piu' spesso di come e' configurata. E' il server a decidere quale task chiude il ciclo, perche' e' lui a conoscere la sequenza: la lista dei task di misura viaggia con la produzione (measurement_task_ids), che e' anche cio' che permette a una schermata qualsiasi di sapere dove riportare l'operatore. Aggiunta la rimisura: si gira il pezzo e si misura di nuovo dentro lo stesso ciclo, senza chiudere niente e senza guadagnare tempo sulla scadenza. Le due letture restano entrambe in statistica, che e' il motivo per cui si prendono. Chi sta gia' misurando quando l'intervallo scade e' in ritardo, non perso: la banda diventa rossa e lo si lascia lavorare. Portarlo altrove a meta' ciclo cancellerebbe quote che ha davanti agli occhi senza guadagnare nulla. Sistemato anche il pulsante "Conferma ciclo" dell'overlay: alzava una bandierina locale e basta, quindi il ciclo non veniva mai registrato sul server da quella strada. Ora passa da confirmCycle come il pulsante della barra. Migrazione 008: il registro eventi della produzione impara task_measured e remeasure, e la colonna task_id — un task_measured che non dice quale task non registra niente di utile. I valori nuovi entrano tutti insieme perche' allargare una enum MySQL riscrive la tabella, stesso ragionamento dei tipi di task in 007. Verificata su SQLite (batch mode) e in MySQL con --sql. La logica dell'orologio — come si legge un ritardo, quando suona, dove sta la misura — vive in un solo posto (production-clock.js) e la schermata di misura la usa invece di riscriverla. Test: +10 (265). Coprono il ciclo che non riparte a meta', la rimisura che non sposta la scadenza, il rifiuto a linea ferma, la sequenza dei task di misura esposta dalla produzione, i proxy Flask e la validita' JS della lista task. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
e4eb4cd932 |
docs: refresh stato + roadmap with smoke-test findings; fix sort syntax
STATO_PROGETTO.md - Bumped snapshot date to 2026-04-27. - Added "Hardening post-restructure (smoke test 2026-04-26)" section recording the four runtime regressions surfaced by the local smoke test (env_file path, missing Station import, UPLOAD_DIR default, apostrophe-in-translation in Alpine), plus the recipe-assignment modal UX rework and the new node-based JS syntax test guard. - Added "Smoke test status" section listing the verified end-to-end flow (MySQL up, alembic, seed, login, admin pages, MeasurementTec workflow, hot reload). - Bumped frontend test count 44 → 46 to reflect test_template_js_syntax.py. ROADMAP.md - Added a tech-debt entry for the user-reported task_complete riepilogo rendering anomaly (still under investigation: the curl fetch returns the table populated, but the user reports an empty body in the browser). - Added a tech-debt entry for the still-pending Docker container smoke test of the new uv-based Dockerfiles. src/frontend/flask_app/templates/measure/task_complete.html - Replaced sort(attribute='task_info.order_index,subtask.marker_number') with two chained stable sorts. Jinja's sort filter does not accept a comma-separated multi-attribute string; the previous form sorted on a non-existent attribute and only worked by accident because the API already returned rows in the desired order. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
1a0431366f |
chore(v2): restructure monorepo to src/ layout with uv
Aligns the repo with the python-project-spec-design.md template chosen for V2.0.0. Big move, no logic changes. The 3 pre-existing test failures (test_recipes::test_update_recipe, test_recipes:: test_recipe_versioning, test_tasks::test_reorder_tasks, plus the client test_save_measurement_proxy) survive unchanged. Layout changes - server/ -> src/backend/ - server/middleware/ -> src/backend/api/middleware/ - server/routers/ -> src/backend/api/routers/ - server/models/ -> src/backend/models/orm/ - server/schemas/ -> src/backend/models/api/ - server/uploads/ -> uploads/ (project root, mounted volume) - server/tests/ -> src/backend/tests/ - client/ -> src/frontend/flask_app/ (Flask kept; React deroga is documented in CLAUDE.md, justified by tablet UX, USB caliper/barcode workflow and Fabric.js integration) Tooling - pyproject.toml: monorepo with [project] core deps and optional-dependencies server / client / dev. Replaces both server/requirements.txt and client/requirements.txt. - uv.lock + .python-version (3.11) committed for reproducible builds. - Dockerfile (root, backend) and Dockerfile.frontend rewritten to use uv sync --frozen --no-dev --extra server|client; legacy Dockerfiles preserved as Dockerfile.legacy for reference but excluded from build context via .dockerignore. - docker-compose.dev.yml + docker-compose.yml: build context now ".", dockerfile pointing to the root files. Code adjustments forced by the move - Every "from config|database|models|schemas|services|routers|middleware import ..." rewritten to its src.backend.* equivalent (50+ files including indented inline imports inside test bodies). - src/backend/migrations/env.py: insert project root into sys.path so alembic can resolve src.backend.* imports regardless of cwd. - src/backend/config.py: env_file ../../.env (was ../.env), upload_path resolves project root via parents[2]. - src/backend/tests/conftest.py + tests: import ... from src.backend.* instead of bare names; old per-directory pytest.ini files removed in favor of root pyproject.toml [tool.pytest.ini_options]. - .gitignore: uploads/ at root, src/frontend/flask_app/static/css/ tailwind.css path; .dockerignore tightened. - CLAUDE.md: rewrote sections "Layout del repository", "Comandi di Sviluppo", "Database & Migrations", "Test", "i18n", and all path references throughout the architecture sections. Verified - uv lock resolves 77 packages; uv sync --extra server --extra client --extra dev installs cleanly. - uv run pytest: 171 passed, 4 pre-existing failures. - uv run alembic -c src/backend/migrations/alembic.ini check loads config and metadata (errors only on the absent local MySQL). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |