Commit Graph

15 Commits

Author SHA1 Message Date
Adriano 486e1288bf Backend: UTC nel DB, +00:00 nelle API, ora italiana solo in presentazione (#42)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 11:41:22 +02:00
Adriano 8b43e7a601 fix(deploy): X-Frame-Options coerente fra Traefik e nginx (#38.11)
traefik.http.middlewares.tmflow-headers.headers.frameDeny=true dava
DENY in produzione, mentre nginx.conf (dev) usa SAMEORIGIN. Sostituito
con customFrameOptionsValue=SAMEORIGIN per allineare le due vie di deploy.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 23:22:50 +02:00
Adriano 2de226f1fd fix(deploy): APP_ENV esplicito nei compose (#33)
docker-compose.yml (produzione) non impostava APP_ENV: la guardia
_refuse_default_secrets_outside_dev in src/backend/config.py non
scattava mai perché il default è "dev". Aggiunto APP_ENV: production
al servizio server; docker-compose.dev.yml imposta APP_ENV: dev in
modo esplicito. Tabella env in docs/DEPLOYMENT.md aggiornata.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 23:22:39 +02:00
Adriano 10261b66f0 deploy(compose): volume uploads in sola lettura nel container vision (#38)
Il worker di visione legge le immagini di riferimento già caricate dal
server, non le scrive. Montato :ro su entrambi i compose (prod e dev).
GIF/WebP animati nelle miniature: MANCA, decisione di prodotto.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 22:35:44 +02:00
Adriano 7a21ec4e44 deploy(traefik): label Traefik v3, dominio da APP_DOMAIN, middleware anche su tmflow-api (#38)
Punto 11: rimossi SSLRedirect e browserXSSFilter (non esistono più in
Traefik v3), aggiunto frameDeny; rule di entrambi i router da
${APP_DOMAIN:?manca APP_DOMAIN}, non più il dominio cablato. Middleware
tmflow-headers ora applicato anche al router API, non solo al web.

Resto del punto 10: rimosso il PathPrefix(`/uploads/`) dalla rule
dell'API — stesso motivo della location nginx già tolta: nessun mount,
i file passano da /api/files.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 22:35:25 +02:00
Adriano ac9bc14f5d deploy(compose): healthcheck su server e client, depends_on condizionati (#38)
server: healthcheck su /api/health. client: healthcheck su /auth/login
(pagina di login, raggiungibile senza sessione). depends_on passa a
condition: service_healthy dove dipende da server/client (client->server,
nginx->server+client in dev). Aggiunge WEB_CONCURRENCY=4 e
TRUSTED_PROXY_COUNT=1 nell'environment del server (li legge il backend).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 22:33:32 +02:00
Adriano 920ab2fb73 deploy(compose): segreti obbligatori in produzione, senza default (#33)
docker-compose.yml: DB_ROOT_PASSWORD, DB_PASSWORD, SERVER_SECRET_KEY,
CLIENT_SECRET_KEY senza default, `config` si rifiuta se mancano.
docker-compose.dev.yml resta con i default (sviluppo). .env.example
documenta l'obbligo in produzione.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 22:28:50 +02:00
Adriano 46566ebfa5 fix(vision): build fallisce senza VISION_ENGINE_VERSION, healthcheck vero
Un build senza la variabile produceva un'immagine che partiva e
rispondeva "healthy" pur fallendo ogni richiesta, /health incluso: non
c'era un healthcheck a dirlo. Tre correzioni: RUN test -n
"$VISION_ENGINE_VERSION" in Dockerfile.vision dopo l'ARG, fallisce
subito con il comando da lanciare; healthcheck su /health nel servizio
vision di entrambi i compose; VISION_ENGINE_VERSION documentata in
.env.example accanto a VISION_WORKER_URL, che già c'era.

Verificato con docker build reale: senza la variabile fallisce al passo
del test con il messaggio atteso; con la variabile impostata l'immagine
si costruisce, il container parte, e python3 -c
"urllib.request.urlopen('http://localhost:8100/health')" - lo stesso
comando usato nell'healthcheck - risponde 200 con l'engine_version
giusta.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014BBnuACZSCJqXrMYC3LUMU
2026-08-16 19:43:20 +02:00
Adriano 71da162e1f feat(vision): il worker che espone il runner, versione stampata al build
Container FastAPI separato (Dockerfile.vision, python:3.13-slim) che
espone run_graph/engine_version del Task 2 via POST /run e GET /health,
cosi' l'immagine del server principale non importa mai VisionSuite.

engine_version() ora legge VISION_ENGINE_VERSION se impostata, altrimenti
ricade su git rev-parse nel checkout di sviluppo, e non inventa mai un
valore: senza nessuna delle due solleva un errore esplicito. Nel container
il fallback a git non puo' funzionare (.git del submodule punta fuori dal
build context), quindi Dockerfile.vision prende il commit come build arg
e lo fissa in ambiente; i compose file lo passano da VISION_ENGINE_VERSION.

Nessuna porta pubblicata e nessuna label Traefik sul servizio vision: e'
raggiungibile solo dal server, su tmflow-net.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014BBnuACZSCJqXrMYC3LUMU
2026-08-16 18:12:04 +02:00
Adriano Dal Pastro b325eb3512 fix(deploy): attach prod stack to the real Traefik network
The prod compose joined the external network 'root_default', but the
running Traefik instance is configured with --providers.docker.network=traefik
and 'root_default' is empty. Traefik therefore had no reachable address for
the tmflow-web/tmflow-api routers and served 404 for tieflow.tielogic.xyz.

Point traefik-net at the external network 'traefik'. After redeploying with
docker-compose.yml the site routes correctly (HTTPS 200, valid ACME cert,
/api/ path-prefix router working).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 08:12:20 +00:00
Adriano 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>
2026-04-25 12:26:47 +02: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 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 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 dbdbb77daf feat: FASE 0 - Setup progetto TieMeasureFlow
Struttura monorepo completa con server FastAPI e client Flask:
- Server: FastAPI + SQLAlchemy 2.0 async + Alembic migrations
- Client: Flask + blueprints (auth, measure, maker, statistics)
- Database: docker-compose MySQL 8.0 + Alembic async config
- Config: pydantic-settings, TailwindCSS, Flask-Babel i18n
- Piano implementazione completo (18 sezioni, 1600 righe)

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