Commit Graph

56 Commits

Author SHA1 Message Date
Adriano a4a849920f feat(client): add get_station_recipes helper on APIClient
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 23:24:19 +02:00
Adriano 958f6ac0b0 feat(client): add STATION_CODE env var and config attribute
Reads STATION_CODE from the environment and exposes it as Config.STATION_CODE
(None when unset or empty). Adds the variable to .env.example with a
per-station deployment note, and covers both read and missing-key paths with
new pytest tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 23:18:24 +02:00
Adriano 2e4db53f6a feat(setup): seed ST-DEFAULT station and assign existing recipes
Add _seed_default_station() helper to /api/setup/seed endpoint that
creates the ST-DEFAULT station and assigns all active recipes to it,
preserving existing behaviour after migration 002 runs on live DBs.
Helper is idempotent and is called on both the normal seed path and
the early-return path (when demo data already exists).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 23:04:41 +02:00
Adriano a79ab37add fix(api): improve Station router - review feedback
- Rinomina _RecipeSummary -> RecipeSummary: il leading underscore
  segnalava "privato" ma la classe e usata come response_model pubblico
  ed esposta nell'OpenAPI schema.
- Aggiunge commento esplicativo sopra /by-code/{code}/recipes sul perche
  l'ordine di dichiarazione conta (protezione gia data dal tipo int di
  station_id, ma esplicito per prevenire regressioni durante refactor).
- Detail message del 404 by-code uniformato a "Station not found"
  (senza distinguere not-found vs inactive, evita leak di esistenza).
- Aggiunge 3 test mancanti sul router:
  * test_admin_can_list_stations (copertura happy path + active_only)
  * test_assign_recipe_not_found_returns_404
  * test_duplicate_assignment_returns_409

Feedback da code-reviewer su Task 5. Full suite: 11/11 passed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 22:46:54 +02:00
Adriano 338f21fba0 feat(api): add /api/stations router with CRUD and assignments
Implements the /api/stations FastAPI router (admin-only CRUD, recipe
assignment endpoints) and the public /by-code/{code}/recipes operator
endpoint. Registers the router in main.py and adds 8 integration tests.
2026-04-17 22:37:16 +02:00
Adriano e8cd1f05aa feat(services): add station_service with CRUD and assignment logic
Implements create/update/delete station, assign/unassign recipe,
list_station_recipes (active only, ordered by code), and get_station_by_code.
Explicit ORM-level assignment deletion in delete_station ensures cascade
works engine-agnostically (SQLite tests + MySQL production). 10 TDD tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 22:31:16 +02:00
Adriano 559e740d64 feat(schemas): add Station and assignment Pydantic schemas 2026-04-17 22:25:42 +02:00
Adriano e36bbbb7d7 fix(models): align Station unique constraint + extend tests
- Station.code: usa UniqueConstraint("code", name="uq_stations_code")
  esplicito in __table_args__ invece di unique=True sulla colonna,
  per allineamento con la migration 002 ed evitare drift Alembic.
- Aggiunge test test_duplicate_assignment_is_rejected per coprire
  il vincolo uq_station_recipe (regola business centrale del modello).
- Sposta import IntegrityError a module-level per consistenza.

Feedback da code-reviewer su Task 2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 22:22:14 +02:00
Adriano 5959c9c92a feat(models): add Station and StationRecipeAssignment models
TDD: test written first, confirmed failing with ModuleNotFoundError,
then model implemented; all 3 new tests pass. conftest updated to
import new models so Base.metadata.create_all picks up the tables.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 21:56:22 +02:00
Adriano 2963d3d647 fix(db): portability and dedup in migration 002
- server_default='1' anziche sa.true() per compatibilita con SQLite
  (usato come DB in-memory nei test)
- Rimuove Index ix_stations_code ridondante con UniqueConstraint
  uq_stations_code (InnoDB crea gia un indice per i vincoli UNIQUE)

Feedback da code-reviewer su Task 1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 21:40:15 +02:00
Adriano fa5d641238 chore: track alembic migrations in git
Le migrations Alembic sono essenziali per il deploy riproducibile:
rimuove la regola in .gitignore che le escludeva e aggiunge al
tracking la migration 001 (image_path) gia esistente ma mai committata.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 21:30:27 +02:00
Adriano abd04d633c feat(db): add migration 002 for stations and assignments 2026-04-17 21:17:14 +02:00
Adriano f71bbf398e docs: add rev04 migration master roadmap and phase1 plan
Aggiunge il master plan di migrazione V1.0.7 -> V1.1.0 (rev04-2026)
con le sette fasi organizzate in milestone M1 (demo cliente) e M2
(produzione), piu il piano TDD dettagliato della Fase 1 (Stazioni e
identita per-tablet) con 17 task eseguibili.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 21:13:01 +02:00
Adriano 767bd7f947 docs: fix middleware order and add missing details to CLAUDE.md
Correct the middleware stack order (was documented backwards due to
Starlette's add_middleware wrapping behavior), document fabric-debug.js
local copy, and note full 50-900 shade palettes for Tailwind colors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 14:24:02 +01:00
Adriano 1578398f0f docs: rewrite README with cleaner structure and less duplication
Restructure README to be more concise: add feature overview section,
architecture diagram with security note, tabular stack listing,
streamlined quick start, and env vars reference table. Move VPS
deployment details to docs/DEPLOYMENT.md to avoid duplication.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 12:00:47 +01:00
Adriano 429c94da94 fix: improve SPC dashboard UX — hover toolbar, visible report errors
- Change Plotly modebar to hover-only mode to avoid overlapping chart content
- Remove redundant Plotly titles (container headers already provide them)
- Add Content-Type check and inline error display for report downloads
- Fix setup login validation and seed idempotency for existing data

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 16:42:47 +01:00
Adriano e07a4e4f89 feat: add demo measurements to seed and user management to setup page
Seed now generates 180 realistic measurements (30 per subtask) with
Gaussian distribution for SPC testing. Setup page gains full user CRUD
with list, create/edit, password change, and activate/deactivate.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:49:58 +01:00
Adriano 272685e554 docs: fix inaccuracies and add missing details to CLAUDE.md
Correct client conftest patching (4 blueprints, not 5 - admin excluded),
add middleware stack order with CORSMiddleware, fix RecipeVersionAudit
enum (add ACTIVATE), clarify server/client Docker workers (uvicorn vs
gunicorn), document tojson_attr filter, measure AJAX routes, Tailwind
custom colors, and dark mode config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:03:57 +01:00
Adriano e9a3e8e42b fix: rewrite subtask editing to reuse add form instead of inline table row
Edit button now opens the same "Nuova Misurazione" form pre-filled with
existing data, showing "Modifica Misurazione" title and "Aggiorna Misurazione"
button. Also adds marker_number to SubtaskUpdate schema so edits persist.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 19:07:55 +01:00
Adriano ecf700eadf feat: improve recipe preview image UI with replace/remove buttons
Replace drop-zone with action buttons (Sostituisci/Rimuovi) when image
exists, matching the task editor pattern. Add upload overlay with
spinner on the image during file upload.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 19:10:59 +01:00
Adriano dbfb5591c5 fix: separate recipe preview image from task images
Recipe image_path is now used as preview thumbnail only. Removed
auto-creation of "Technical Drawing" task from recipe upload, and
removed recipe image strip from task_execute view. Each task displays
its own file_path independently.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 18:29:27 +01:00
Adriano 22804a609d feat: add production docker-compose with Traefik reverse proxy
Production compose with Traefik labels for auto-SSL via Let's Encrypt.
Requires external traefik-net (root_default) network.
Dev compose (docker-compose.dev.yml) remains unchanged with Nginx.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 11:59:01 +01:00
Adriano 6bd6e229e5 feat: redesign task_execute with 3-column layout and subtask images
Refactor measurement execution page from 2-column to 3-column layout:
- Left: vertical marker sidebar with status indicators
- Center: image area with subtask image switching (per-subtask detail
  images override task annotation viewer) + optional recipe image strip
- Right: compact info panel with tolerances, feedback, and numpad

Also: compact header bar, use window.__data pattern for tojson escaping,
fetch recipe image_path in measure blueprint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 11:58:55 +01:00
Adriano 13986f05d7 feat: add admin user management page with CRUD and i18n
- New admin blueprint with CRUD proxy endpoints for users
- Admin user management template with search, create, edit, toggle active
- Navbar: add admin link for is_admin users (desktop + mobile)
- Register admin blueprint in app factory
- Add IT/EN translations for all admin UI strings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 11:58:47 +01:00
Adriano 5cc576cec9 feat: add image_path to recipe/subtask and user password change API
- Recipe model: add image_path field for recipe-level image
- RecipeSubtask model: add image_path for per-subtask detail images
- Schemas: add image_path to create/update/response for recipe and subtask
- Task router: pass image_path when creating tasks and subtasks
- Recipe service: copy image_path in versioning and update-in-place
- Users router: add PUT /{user_id}/password endpoint (admin only)
- User schema: add UserPasswordChange model

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 11:58:41 +01:00
Adriano 08bcb87d6b docs: update README with Traefik deployment, correct blueprints, fix commands
- Architecture: document dual compose (dev Nginx / prod Traefik)
- Stack: remove htmx (unused), pin Fabric.js to 5.3.1
- Fix blueprint names (measure, statistics, admin instead of measurement, metrologist)
- Fix alembic commands with -c migrations/alembic.ini flag
- Fix .env variable names to match actual config
- Update testing section with real examples (not "da implementare")
- Replace Certbot/Nginx SSL section with Traefik auto-SSL
- Document is_admin capabilities (user CRUD)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 11:57:04 +01:00
Adriano 6c8c60900b docs: update CLAUDE.md with admin blueprint, dual docker-compose setup
Align documentation with current codebase state: add admin blueprint to
client architecture, document dev (Nginx) vs prod (Traefik) compose files,
fix blueprint count in test section.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 11:53:25 +01:00
Adriano 945c873d38 docs: update CLAUDE.md with conditional versioning, measurement workflow, and JS components
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 13:48:04 +01:00
Adriano 9502388064 docs: improve CLAUDE.md with architecture details, patterns, and fixes
Fix Alembic commands (add -c migrations/alembic.ini flag), add Fabric.js
annotation editor patterns, Alpine.js/Jinja2 escaping rules, template
structure, test infrastructure details, and Docker configuration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 21:25:16 +01:00
Adriano e4c2cc3ed4 chore: exclude .omc/ from git and fix Fabric.js version in README
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 19:39:14 +01:00
Adriano e8b88d48c1 feat: measurement workflow improvements and recipe update-in-place
- Auto-advance to next task after completing all subtask measurements
- 1s pause between measurements to show pass/fail/warning result
- Colored marker strip (green/red/amber) based on measurement status
- Replace duplicate measurements instead of appending (fixes progress bar)
- Add Task column and Date/Time column to measurement summary table
- Enrich summary with task_info for each measurement
- Update-in-place for recipe versions without measurements (no copy-on-write)
- Dark theme improvements and navbar cleanup
- Server config: ignore extra env vars

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 19:36:42 +01:00
Adriano 4854966bf7 chore: add fabric-debug.js and nul to .gitignore
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 16:15:47 +01:00
Adriano 9e1bb20b36 fix: canvas fits image exactly, chained annotation loading, arrow move tracking
- Canvas now sizes to match the scaled image dimensions (zero empty space)
  instead of using a fixed aspect ratio, fixing coordinate mismatch between
  editor and viewer
- Annotations load only after background image is ready via _pendingAnnotations
  pattern, preventing placement at wrong coordinates
- Arrow endpoints (arrowX1/Y1/X2/Y2) update on object:modified using
  transform delta, so moved arrows serialize at correct position
- Coordinate scaling on load: coordScale = currentImageScale / savedImageScale
  handles annotations saved at different screen widths

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 16:10:21 +01:00
Adriano f2df6be060 fix: enable resize/rotate controls on single-click object selection
In setMode('select'), explicitly set hasControls, hasBorders, and evented
on all objects. In drawing modes, disable selectable/evented to prevent
accidental interaction. Fixes controls only appearing on multi-select drag.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 10:45:56 +01:00
Adriano f665bffb7a fix: Task back button navigates to correct recipe (not version_id)
- Add recipe_id property to RecipeTask model (via version relationship)
- Add recipe_id to TaskResponse schema
- Eager-load version in _get_task_or_404 query
- Use task.recipe_id instead of task.version_id in task_execute template URLs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 10:34:23 +01:00
Adriano 00d6c68b2f fix: enable scale/rotation on annotation objects and restore transforms on load
- Remove hasControls:false and lockScaling from markers so resize/rotate handles appear
- Add setActiveObject() after creating arrows and rectangles for immediate control visibility
- Restore angle, scaleX, scaleY when loading saved annotations (all object types)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 10:29:30 +01:00
Adriano dfc1c3ed95 fix: i18n translations and annotation property changes on selected objects
- Complete English translation catalog (44 entries fixed/added)
- Fix Fabric.js Group cache invalidation (active.dirty = true) so color,
  thickness and line-dash changes are visible on selected markers/arrows
- Fix Italian .po placeholder mismatch (%(detail)s -> %(error)s)
- Bump annotation-editor.js cache buster to v8

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 01:44:46 +01:00
Adriano 582543e821 fix: bump annotation-viewer.js cache buster to v4
Browser was serving stale cached version without editor format
support (objects array). Bumped ?v=4 on all three templates:
recipe_preview, task_execute, task_editor.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 01:26:20 +01:00
Adriano ffec59a105 fix: annotation overlay in recipe preview and measure view
annotationViewer.drawAnnotations() now handles the editor format
(objects array with marker/arrow/area) in addition to the legacy
format (markers array). This fixes missing overlay in recipe preview
and task execution views.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 01:22:30 +01:00
Adriano 6ea94cca47 feat: per-task image/annotations, annotation editor toolbar, Tailwind compiled
- Add per-task file upload with image preview in task editor
- Add dedicated annotation editor page (task_drawing.html) with Fabric.js
- Add color picker, stroke width, and line dash controls to annotation toolbar
- Apply property changes to selected objects in real-time
- Disable style controls until a drawing tool or object is selected
- Remove zoom/pan from annotation toolbar (simplified UX)
- Auto-switch to select mode after placing annotation elements
- Show annotation overlay on task image previews (read-only canvas)
- Add file proxy route in measure blueprint for task file access
- Add file_path/file_type fields to TaskCreate/TaskUpdate Pydantic schemas
- Replace Tailwind CDN with compiled CSS (tailwind.config.js with full shades)
- Fix Alpine.js x-init crash: extract annotations JSON to <script> tags
  (recipe_preview.html, task_execute.html) to avoid HTML attribute breakage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 01:20:34 +01:00
Adriano b075115cef fix: file display, persistence, PDF support and save error handling
- Add file proxy route in maker blueprint (X-API-Key auth for browser requests)
- Persist file_path/annotations_json to DB via RecipeCreate/RecipeUpdate schemas
- Fix canvas sizing using grandparent container instead of Fabric.js wrapper div
- Defer canvas init with requestAnimationFrame for x-show timing
- Add PDF.js support in annotation-editor and annotation-viewer
- Fix annotations_json double-serialization (parse string to object before send)
- Handle FastAPI 422 validation error arrays in api_client and JS error display
- Update template URLs to use /maker/api/files/ proxy path

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 22:04:45 +01:00
Adriano d262ef68af fix: version badge rendering, Jinja2 scoping, navbar i18n, missing GET task endpoint
- Fix version badge showing [object Object] or Python dict dump in
  select_recipe, task_list, and task_complete templates by accessing
  current_version.version_number instead of the whole object
- Fix recipe_editor.html Internal Server Error caused by Jinja2 block
  scoping: {% set %} variables from block content were invisible in
  block extra_js, replaced with direct recipe.* references
- Fix task_editor.html SyntaxError from Italian apostrophe in
  nell'eliminazione breaking JS string literals, switched to |tojson
- Add i18n {{ _() }} wrappers to all hardcoded navbar strings (desktop
  and mobile menus) so language toggle works correctly
- Add app title text "TieMeasureFlow" next to logo in navbar
- Add missing GET /api/tasks/{task_id} endpoint on server that caused
  405 Method Not Allowed when starting measurements

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 20:44:33 +01:00
Adriano 2453e552fb fix: Alpine.js x-data broken by inner double quotes + API list response crash
- Extract JSON data to <script> tags instead of tojson_attr in x-data attributes
- Remove literal " from CSS selector in x-data (meta[name=csrf-token])
- Move Alpine.js defer script after extra_js block in base.html
- Add isinstance(resp, dict) guard before .get("error") in measure.py and maker.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 20:13:22 +01:00
Adriano 004f794c75 fix: Alpine.js JSON parsing error in x-data HTML attributes
Add tojson_attr Jinja2 filter that escapes double quotes to &#34;
for safe embedding in HTML attributes. The browser decodes entities
before Alpine.js evaluates, so JSON parses correctly.

Replaces |tojson with |tojson_attr in x-data attributes (select_recipe,
recipe_list, base flash messages). Script tag usages are unaffected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 19:31:49 +01:00
Adriano 6d5660b20d fix: Docker build failures for client and server containers
- Pin tailwindcss@3 in client Dockerfile (v4 removed standalone CLI)
- Replace gunicorn --factory with callable syntax app:create_app()
- Fix Alembic config path with -c flag and %(here)s script_location

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 19:04:49 +01:00
Adriano cf2bf427fc docs: rewrite CLAUDE.md with comprehensive project guidance for Claude Code
Add dev commands (test, migrations, i18n, Docker), architecture overview,
critical patterns (copy-on-write versioning, pass/fail, SPC, auth flow),
and dependency/configuration reference.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 18:45:32 +01:00
Adriano c9d9c0f9dd feat: V1.0.1 - Setup page, Docker, README
Add password-protected setup page (/api/setup) for DB initialization,
admin creation, and demo data seeding. Dockerize the full stack with
server, client, nginx reverse proxy, and MySQL services. Add project
README with architecture overview, quick start, and VPS deployment guide.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 18:00:29 +01:00
Adriano dd2ebf863a feat: FASE 7 - Polish & Testing (security, i18n, test suite, docs)
Security hardening: CORS lockdown, rate limiting middleware con sliding
window e eviction IP stale, security headers (CSP, HSTS, X-Frame-Options),
session cookie hardening, filename sanitization upload.

i18n completion: internazionalizzati barcode.js e csv-export.js con bridge
window.BARCODE_I18N/CSV_I18N, aggiornati .po IT/EN con 27 nuove stringhe.

Tablet UX: touch target 44px per dispositivi coarse pointer.

Test suite: 101 test totali (76 server + 25 client), copertura completa
di tutti i router API, autenticazione, ruoli, CRUD, SPC, file upload,
security integration. Infrastruttura SQLite async in-memory con fixtures.

Fix critici: MissingGreenlet in recipe_service (selectinload eager),
route ordering tasks.py, auth_service bcrypt diretto, Measurement.id
Integer per SQLite.

Documentazione: API.md (riferimento completo 40+ endpoint),
DEPLOYMENT.md (guida produzione con Docker/Nginx/SSL),
USER_GUIDE.md (manuale utente per ruolo).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 17:10:24 +01:00
Adriano 26e5b9343d feat: FASE 6.5 - Report PDF (WeasyPrint + Kaleido)
Add PDF report generation for Metrologist dashboard with SPC and
measurement reports including SVG charts, capability indices, and
company logo embedding.

New files:
- server/services/report_service.py (Jinja2 + Plotly/Kaleido + WeasyPrint)
- server/routers/reports.py (2 GET endpoints with auth)
- server/templates/reports/ (base, spc, measurement HTML templates)

Modified:
- server/main.py (register reports router)
- client dashboard (download buttons + proxy routes)
- i18n strings IT/EN

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 15:24:32 +01:00
Adriano bcd807e57d feat: FASE 5b/6.1+6.2 - SPC Backend + Dashboard Metrologist (Plotly.js)
Aggiunge servizio SPC con calcoli Cp/Cpk/Pp/Ppk, carta di controllo (UCL/LCL),
istogramma con curva normale. Router FastAPI con 5 endpoint statistics, blueprint
Flask con proxy AJAX, dashboard interattiva Alpine.js + Plotly.js con filtri per
ricetta/subtask/date, riepilogo pass/fail, gauge Cpk e i18n IT/EN completo.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 15:00:05 +01:00