- 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>
- 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>
Add tojson_attr Jinja2 filter that escapes double quotes to "
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>
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>
Implementazione completa del frontend Flask:
- Layout base.html con TailwindCSS CDN, dark/light theme, flash messages
- Navbar responsive role-based (Maker, MeasurementTec, Metrologist, Admin)
- Login page professionale con form + API integration
- Profilo utente: nome, lingua, tema, badge ruoli
- Sistema tema dark/light: CSS variables + Alpine.js store + localStorage
- i18n completo IT/EN: Flask-Babel (.po) + alpinejs-i18n (JSON)
- API Client riscritto: error handling normalizzato, no crash su 4xx/5xx
- CSRF protection con Flask-WTF su tutti i form
- Logo aziendale dinamico da system_settings
- Asset SVG: tmflow-logo.svg + tmflow-icon.svg (favicon)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>