Tournevia

Architecture and contracts

Modular application, worker, road engines and independent validation.

Components

Map tilesHTTPSRead / writeJobs and resultsTimes and routesOptimizationProposed resultBrowserReact · MapLibreBasemapOpenFreeMap · OSMAPI · FastAPISession, records, jobsPostgreSQLSources, jobs, plansCalculation workerSame image as the APIValhallaOSM graph · matrices · routesVROOMStop order and assignmentsIndependent validationConstraints and resultVROOM and validation run within the worker.
Solid arrows show application exchanges. The browser loads the basemap separately; it does not calculate routes.
  • FastAPI and PostgreSQL: company-owned accounts, sources, jobs and plans.
  • Worker from the same image: calculation execution and job recovery.
  • Valhalla: directed matrices and road geometry over an OSM graph.
  • VROOM: optimization using the supplied matrices.
  • React and MapLibre: the application planning workspace.

Independent validation checks coverage, schedules, loads, equipment, limits, geometry and modeled costs. A solver proposal is not proof of validity. The company's safety margin narrows only the windows given to the solver; validation checks the real windows.

How a calculation travels through the system

  1. The browser submits selected records and calculation settings to FastAPI.
  2. The API verifies the session, company ownership and request, then records a job in PostgreSQL.
  3. The worker retrieves the job and asks Valhalla for directed travel times and distances.
  4. VROOM proposes vehicle assignments and stop order. The worker obtains the route legs from Valhalla.
  5. Independent validation checks the result against the copied inputs. The worker stores the result or a failure; the interface reads the job status.
  6. A successful result remains a draft. A user reviews it before approval, CSV export and route sheets.

The API and worker share the application image but run as separate processes. PostgreSQL stores persistent data; map tiles are only the visual background.

Trace a result in the interface

Each plan shows how it was calculated: objective, road preference, safety margin, plan version and routing dataset, and states that tolls and an all-in total are not calculated. Recent calculations lists every attempt for the day by its time and status; pointing at one shows its full job identifier, which worker logs record as job_id=.

Recording of the actual interface, drawn pointer · fictional data · English interface · no audio. 0:07 · OpenFreeMap · © OpenMapTiles · © OpenStreetMap

Contracts

Forms display readable units; APIs use the units specified in generated schemas. Keep models, migrations, contracts, examples and tests consistent. Unsupported fields must be rejected or explicitly implemented. scripts/export_contracts.py generates the OpenAPI contract, the JSON schemas, the form limits the interface enforces, the CSV import columns the import screen and its template show (web/src/csv-columns.json) and the list of server messages that need a French translation; its --check mode fails on drift.

Plans are editable drafts protected by integer versions. Manual routes recalculate the requested legs without optimizing all assignments again.

Test coverage

Real-road benchmarks cover fictional Paris/Île-de-France cases, including 250 deliveries. They do not establish optimality, long-haul acceptance or multi-company capacity. Reproducible scenarios and commands are included in the technical guides in the kit.

Continuous integration (.github/workflows/ci.yml) runs on each change: Python lint, backend and launcher tests with isolated PostgreSQL databases, the contract drift check, the web formatting, lint, tests, generated API types and build, Linux process-supervision checks on the built images, the HTTPS overlay (TLS, cookies, CSRF, headers, log redaction), and role grants with backup and isolated restore against a disposable Compose database. A separate workflow (engines.yml), started manually and weekly, downloads the current Île-de-France extract, builds the graphs and runs the real-engine and worker suites.

On this page