e4eb4cd932cb8bc931d4d1e1b3fd70a6dedc806d
5 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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> |
||
|
|
2a2d40bec9 |
fix(admin): two more apostrophe-in-translation regressions + UX rework
UX rework — recipe assignment modal on /admin/stations
- Replace the single "select recipe + Assegna" dropdown with a two-
column layout: Ricette disponibili (left) and Assegnate alla
stazione (right), each row with an inline action button. Top search
filter narrows both columns at once. Empty states explain *why* the
list is empty (no recipes in system, all already assigned, no match
for the filter).
- Rationale: the old dropdown silently hid every option once a recipe
was assigned, leaving the user unable to tell whether the system
was broken or simply out of unassigned recipes.
Apostrophe regressions
- /admin/stations alert/errorMsg literals reworded with double-quoted
outer JS strings ("Errore nella eliminazione" / "...assegnazione").
- /admin/users toggle confirm modal: x-text expression contained
'{{ _('… l\'utente') }}'. Inside a Jinja-rendered HTML attribute,
the apostrophe in "l'utente" closed the JS literal early, killing
the binding. Fixed by using " as the JS string delimiter so
the inner apostrophe is harmless.
Alpine x-if templates can't host nested templates
- Replaced two nested-template empty-state blocks with x-text bound
to computed getters (unassignedEmptyMessage,
assignedEmptyMessage). Alpine errored with
"Cannot set properties of null (setting '_x_dataStack')" when the
outer template's child wasn't a single root element.
Test guard widened
- src/frontend/flask_app/tests/test_template_js_syntax.py now also
parses every Alpine attribute (x-*, @*, :*) on the rendered HTML
and runs `node --check` on each expression wrapped in `void (…)`.
Previously it only inspected inline <script> bodies, which is why
the x-text bug on /admin/users slipped through. Verified the
extended test catches the original l'utente regression by reverting
+ running + restoring.
Layout regression — UPLOAD_DIR defaulted to server/uploads
- The previous .env.example shipped UPLOAD_DIR=server/uploads, which
matched the V1.x layout but pointed outside the new project tree.
Updated to UPLOAD_DIR=uploads so files land in the project-root
uploads/ volume that src/backend/config.py.upload_path resolves.
- Added uploads/general/ to .gitignore (per-user uploads, not source).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
6e284b0c0c |
fix(admin): apostrophe-in-translation broke /admin/stations Alpine bindings
Two error messages on /admin/stations rendered Italian translations
that contain an apostrophe inside a single-quoted JS literal:
alert(result.detail || '{{ _("Errore nell\'eliminazione") }}');
Jinja outputs the apostrophe verbatim, so the JS string closed
prematurely:
alert(result.detail || 'Errore nell'eliminazione');
That syntax error blew up the entire <script> block, which means
stationManagement() was never defined and EVERY Alpine binding on the
page failed silently. Symptom: clicking "Nuova Stazione" did nothing,
DevTools showed "Alpine Expression Error: openCreateModal is not
defined".
Fix: swap outer JS quotes to double quotes and reword the IT string so
the apostrophe disappears anyway ("Errore nella eliminazione",
"Errore nella assegnazione"). Same for the assignment-error path.
Regression guard: src/frontend/flask_app/tests/test_template_js_syntax.py
renders /admin/stations and /admin/users with the IT locale forced,
extracts every inline <script>, and runs `node --check` on each. The
test is skipped if `node` is not on PATH so CI without Node still
passes. Verified the test catches the original bug (revert + run +
fail) before re-applying the fix.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
e4b29c0b2d |
chore(docs): consolidate documentation, drop dead files
Cleanup - Remove src/backend/Dockerfile.legacy and src/frontend/flask_app/Dockerfile.legacy (history is in git, build uses the new uv-based root Dockerfile / Dockerfile.frontend). - Remove src/frontend/flask_app/verify_i18n.py (had hardcoded paths pointing at the old client/ tree). Group docs/ - New docs/README.md indexes everything in one place. - New docs/architecture/STATO_PROGETTO.md: snapshot of what works in V2.0.0 (inherited V1.0.7 features, rev04 Phase 1 stations, worker scaling, src/ restructure, test status, stack, decisions). - New docs/architecture/ROADMAP.md: what's next — Phases 2-7 of the rev04 migration with status, open client decisions (D-0.1 through D-0.10), tech debt and time estimates for M1 / M2. - Move PIANO_IMPLEMENTAZIONE.md (90KB V1.0.0 plan) to docs/archive/2026-02-06-piano-implementazione-v1.md (historical). - Move Schema sviluppo SW TieFlow_rev04-2026.docx to docs/specs/ with ISO date filename so the customer spec is now tracked. - Move src/frontend/flask_app/I18N_SETUP.md to docs/I18N_SETUP.md and rewrite paths to the new src/frontend/flask_app/ tree. .dockerignore: simplified now that legacy Dockerfiles are gone; docs/ stays excluded from the build context. 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> |