# themylogin/french_tolls architecture

> Architecture diagram of the GitHub repository themylogin/french_tolls, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-12). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/themylogin/french_tolls
- Repository: https://github.com/themylogin/french_tolls

## Overview

French Tolls helps drivers compare toll costs and route options across French roads, with optional refuelling plans and Telegram interaction. A user supplies locations; the bot orchestrates routing, toll analysis, and route refinement, then presents alternatives and driving links. Separately, builder tools prepare booth inventories, operator prices, and toll-weighted routing data. The README documents gas-station updates and web access as additional capabilities. Several connections below rely on explicit README descriptions or SOURCE INDEX references; unsampled implementation details are not assumed.

Main entry points: [`french_tolls/route.py`](https://github.com/themylogin/french_tolls/blob/master/french_tolls/route.py) (Route orchestration), [`french_tolls/bot.py`](https://github.com/themylogin/french_tolls/blob/master/french_tolls/bot.py) (Telegram bot), [`builder/build_toll_extent.py`](https://github.com/themylogin/french_tolls/blob/master/builder/build_toll_extent.py) (Toll extents), [`french_tolls/refine.py`](https://github.com/themylogin/french_tolls/blob/master/french_tolls/refine.py) (Google refinement)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_journey["Journey planning"]
  node_bot["Telegram bot<br/>[bot.py]"]
  node_route["Route orchestration<br/>[route.py]"]
  node_web["Web entry<br/>[web.py]"]
  node_autocomplete["Location search<br/>[autocomplete.py]"]
end

subgraph group_routing["Routing and pricing"]
  node_waypoints["Waypoint planning<br/>[waypoints.py]"]
  node_osrm["OSRM clients<br/>[osrm.py]"]
  node_tolls["Toll pricing<br/>[tolls.py]"]
  node_booths["Booth inventory<br/>[booths.py]"]
  node_splits["Route splitting<br/>[splits.py]"]
  node_equivalence["Route equivalence<br/>[equivalence.py]"]
  node_refine["Google refinement<br/>[refine.py]"]
  node_overlap["Geometry overlap<br/>[overlap.py]"]
end

subgraph group_driver["Driver services"]
  node_car["Car profile<br/>[car.py]"]
  node_refuel["Refuel planning<br/>[refuel.py]"]
  node_gas["Fuel stations<br/>[gas_stations.py]"]
  node_spending["Google request budget<br/>[spending.py]"]
  node_store[("Application database<br/>[db.py]")]
  node_models["Stored models<br/>[models.py]"]
end

subgraph group_data["Toll data preparation"]
  node_osm_gas["OSM station import"]
  node_booth_build["Booth grouping<br/>[booth_groups.py]"]
  node_route_set["Route-set builder<br/>[build_route_set.py]"]
  node_vinci_prices["Operator prices"]
  node_direct_prices["Direct prices"]
  node_segment_weights["Segment weighting"]
  node_toll_extent["Toll extents"]
  node_overrides["Manual overrides<br/>[overrides.py]"]
end

node_driver(("Driver"))
node_google["Google Directions"]
node_routers["OSRM services"]

node_driver -->|"sends journey"| node_bot
node_bot -->|"requests routes"| node_route
node_bot -->|"loads profile"| node_car
node_bot -->|"plans refuel"| node_refuel
node_bot -->|"reads budget"| node_spending
node_bot -.->|"offers search"| node_autocomplete
node_route -->|"requests routes"| node_osrm
node_route -->|"plans waypoints"| node_waypoints
node_route -->|"prices crossings"| node_tolls
node_route -->|"checks crossings"| node_booths
node_route -->|"splits routes"| node_splits
node_route -->|"compares geometry"| node_equivalence
node_route -.->|"refines route"| node_refine
node_route -->|"queries"| node_routers
node_osrm -->|"sends requests"| node_routers
node_refine -->|"requests directions"| node_google
node_refine -->|"reserves requests"| node_spending
node_refine -->|"measures drift"| node_overlap
node_equivalence -->|"matches routes"| node_osrm
node_equivalence -->|"finds tolls"| node_tolls
node_car -->|"reads and writes"| node_store
node_car -->|"persists profile"| node_models
node_spending -->|"reads and writes"| node_store
node_spending -->|"persists usage"| node_models
node_refuel -->|"uses profile"| node_car
node_refuel -->|"finds stations"| node_gas
node_refuel -->|"routes detours"| node_osrm
node_gas -->|"updates stations"| node_store
node_gas -->|"stores stations"| node_models
node_driver -->|"opens site"| node_web
node_osm_gas -->|"supplies station locations"| node_gas
node_booth_build -->|"groups inventory"| node_route_set
node_route_set -->|"applies decisions"| node_overrides
node_vinci_prices -->|"applies adjustments"| node_overrides
node_direct_prices -->|"applies adjustments"| node_overrides
node_toll_extent -->|"uses groups"| node_booth_build
node_toll_extent -->|"uses tariffs"| node_vinci_prices
node_toll_extent -->|"uses tariffs"| node_direct_prices
node_toll_extent -->|"applies decisions"| node_overrides
node_segment_weights -->|"reads tariffs"| node_vinci_prices
node_segment_weights -->|"reads tariffs"| node_direct_prices

click node_bot "https://github.com/themylogin/french_tolls/blob/master/french_tolls/bot.py"
click node_route "https://github.com/themylogin/french_tolls/blob/master/french_tolls/route.py"
click node_web "https://github.com/themylogin/french_tolls/blob/master/french_tolls/web.py"
click node_autocomplete "https://github.com/themylogin/french_tolls/blob/master/french_tolls/autocomplete.py"
click node_waypoints "https://github.com/themylogin/french_tolls/blob/master/french_tolls/waypoints.py"
click node_osrm "https://github.com/themylogin/french_tolls/blob/master/french_tolls/osrm.py"
click node_tolls "https://github.com/themylogin/french_tolls/blob/master/french_tolls/tolls.py"
click node_booths "https://github.com/themylogin/french_tolls/blob/master/french_tolls/booths.py"
click node_splits "https://github.com/themylogin/french_tolls/blob/master/french_tolls/splits.py"
click node_equivalence "https://github.com/themylogin/french_tolls/blob/master/french_tolls/equivalence.py"
click node_refine "https://github.com/themylogin/french_tolls/blob/master/french_tolls/refine.py"
click node_overlap "https://github.com/themylogin/french_tolls/blob/master/french_tolls/overlap.py"
click node_car "https://github.com/themylogin/french_tolls/blob/master/french_tolls/car.py"
click node_refuel "https://github.com/themylogin/french_tolls/blob/master/french_tolls/refuel.py"
click node_gas "https://github.com/themylogin/french_tolls/blob/master/french_tolls/gas_stations.py"
click node_spending "https://github.com/themylogin/french_tolls/blob/master/french_tolls/spending.py"
click node_store "https://github.com/themylogin/french_tolls/blob/master/french_tolls/db.py"
click node_models "https://github.com/themylogin/french_tolls/blob/master/french_tolls/models.py"
click node_osm_gas "https://github.com/themylogin/french_tolls/blob/master/french_tolls/osm_gas_stations.py"
click node_booth_build "https://github.com/themylogin/french_tolls/blob/master/builder/booth_groups.py"
click node_route_set "https://github.com/themylogin/french_tolls/blob/master/builder/build_route_set.py"
click node_vinci_prices "https://github.com/themylogin/french_tolls/blob/master/builder/build_vinci_prices.py"
click node_direct_prices "https://github.com/themylogin/french_tolls/blob/master/builder/build_vinci_direct_prices.py"
click node_segment_weights "https://github.com/themylogin/french_tolls/blob/master/builder/build_segment_weights.py"
click node_toll_extent "https://github.com/themylogin/french_tolls/blob/master/builder/build_toll_extent.py"
click node_overrides "https://github.com/themylogin/french_tolls/blob/master/builder/overrides.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_bot,node_route,node_web,node_autocomplete toneBlue
class node_waypoints,node_osrm,node_tolls,node_booths,node_splits,node_equivalence,node_refine,node_overlap toneAmber
class node_car,node_refuel,node_gas,node_spending,node_store,node_models toneMint
class node_osm_gas,node_booth_build,node_route_set,node_vinci_prices,node_direct_prices,node_segment_weights,node_toll_extent,node_overrides toneRose
class node_driver,node_google,node_routers toneIndigo
```

## Components

### Journey planning

- [Telegram bot](https://github.com/themylogin/french_tolls/blob/master/french_tolls/bot.py): `french_tolls/bot.py`
- [Route orchestration](https://github.com/themylogin/french_tolls/blob/master/french_tolls/route.py): `french_tolls/route.py`
- [Web entry](https://github.com/themylogin/french_tolls/blob/master/french_tolls/web.py): `french_tolls/web.py`
- [Location search](https://github.com/themylogin/french_tolls/blob/master/french_tolls/autocomplete.py): `french_tolls/autocomplete.py`

### Routing and pricing

- [Waypoint planning](https://github.com/themylogin/french_tolls/blob/master/french_tolls/waypoints.py): `french_tolls/waypoints.py`
- [OSRM clients](https://github.com/themylogin/french_tolls/blob/master/french_tolls/osrm.py): `french_tolls/osrm.py`
- [Toll pricing](https://github.com/themylogin/french_tolls/blob/master/french_tolls/tolls.py): `french_tolls/tolls.py`
- [Booth inventory](https://github.com/themylogin/french_tolls/blob/master/french_tolls/booths.py): `french_tolls/booths.py`
- [Route splitting](https://github.com/themylogin/french_tolls/blob/master/french_tolls/splits.py): `french_tolls/splits.py`
- [Route equivalence](https://github.com/themylogin/french_tolls/blob/master/french_tolls/equivalence.py): `french_tolls/equivalence.py`
- [Google refinement](https://github.com/themylogin/french_tolls/blob/master/french_tolls/refine.py): `french_tolls/refine.py`
- [Geometry overlap](https://github.com/themylogin/french_tolls/blob/master/french_tolls/overlap.py): `french_tolls/overlap.py`

### Driver services

- [Car profile](https://github.com/themylogin/french_tolls/blob/master/french_tolls/car.py): `french_tolls/car.py`
- [Refuel planning](https://github.com/themylogin/french_tolls/blob/master/french_tolls/refuel.py): `french_tolls/refuel.py`
- [Fuel stations](https://github.com/themylogin/french_tolls/blob/master/french_tolls/gas_stations.py): `french_tolls/gas_stations.py`
- [Google request budget](https://github.com/themylogin/french_tolls/blob/master/french_tolls/spending.py): `french_tolls/spending.py`
- [Application database](https://github.com/themylogin/french_tolls/blob/master/french_tolls/db.py): `french_tolls/db.py`
- [Stored models](https://github.com/themylogin/french_tolls/blob/master/french_tolls/models.py): `french_tolls/models.py`

### Toll data preparation

- [OSM station import](https://github.com/themylogin/french_tolls/blob/master/french_tolls/osm_gas_stations.py): `french_tolls/osm_gas_stations.py`
- [Booth grouping](https://github.com/themylogin/french_tolls/blob/master/builder/booth_groups.py): `builder/booth_groups.py`
- [Route-set builder](https://github.com/themylogin/french_tolls/blob/master/builder/build_route_set.py): `builder/build_route_set.py`
- [Operator prices](https://github.com/themylogin/french_tolls/blob/master/builder/build_vinci_prices.py): `builder/build_vinci_prices.py`
- [Direct prices](https://github.com/themylogin/french_tolls/blob/master/builder/build_vinci_direct_prices.py): `builder/build_vinci_direct_prices.py`
- [Segment weighting](https://github.com/themylogin/french_tolls/blob/master/builder/build_segment_weights.py): `builder/build_segment_weights.py`
- [Toll extents](https://github.com/themylogin/french_tolls/blob/master/builder/build_toll_extent.py): `builder/build_toll_extent.py`
- [Manual overrides](https://github.com/themylogin/french_tolls/blob/master/builder/overrides.py): `builder/overrides.py`

### Other components

- **Driver**
- **Google Directions**
- **OSRM services**

## Connections

- Driver → Telegram bot: sends journey
- Telegram bot → Route orchestration: requests routes (evidence: `french_tolls/bot.py`)
- Telegram bot → Car profile: loads profile (evidence: `french_tolls/bot.py`)
- Telegram bot → Refuel planning: plans refuel (evidence: `french_tolls/bot.py`)
- Telegram bot → Google request budget: reads budget (evidence: `french_tolls/bot.py`)
- Telegram bot → Location search: offers search
- Route orchestration → OSRM clients: requests routes (evidence: `french_tolls/route.py`)
- Route orchestration → Waypoint planning: plans waypoints (evidence: `french_tolls/route.py`)
- Route orchestration → Toll pricing: prices crossings (evidence: `french_tolls/route.py`)
- Route orchestration → Booth inventory: checks crossings (evidence: `french_tolls/route.py`)
- Route orchestration → Route splitting: splits routes (evidence: `french_tolls/route.py`)
- Route orchestration → Route equivalence: compares geometry (evidence: `french_tolls/route.py`)
- Route orchestration → Google refinement: refines route
- Route orchestration → OSRM services: queries (evidence: `french_tolls/route.py`)
- OSRM clients → OSRM services: sends requests (evidence: `french_tolls/osrm.py`)
- Google refinement → Google Directions: requests directions (evidence: `french_tolls/refine.py`)
- Google refinement → Google request budget: reserves requests (evidence: `french_tolls/refine.py`)
- Google refinement → Geometry overlap: measures drift (evidence: `french_tolls/refine.py`)
- Route equivalence → OSRM clients: matches routes (evidence: `french_tolls/equivalence.py`)
- Route equivalence → Toll pricing: finds tolls (evidence: `french_tolls/equivalence.py`)
- Car profile → Application database: reads and writes (evidence: `french_tolls/car.py`)
- Car profile → Stored models: persists profile (evidence: `french_tolls/car.py`)
- Google request budget → Application database: reads and writes (evidence: `french_tolls/spending.py`)
- Google request budget → Stored models: persists usage (evidence: `french_tolls/spending.py`)
- Refuel planning → Car profile: uses profile (evidence: `french_tolls/refuel.py`)
- Refuel planning → Fuel stations: finds stations (evidence: `french_tolls/refuel.py`)
- Refuel planning → OSRM clients: routes detours (evidence: `french_tolls/refuel.py`)
- Fuel stations → Application database: updates stations (evidence: `french_tolls/gas_stations.py`)
- Fuel stations → Stored models: stores stations (evidence: `french_tolls/gas_stations.py`)
- Driver → Web entry: opens site
- OSM station import → Fuel stations: supplies station locations
- Booth grouping → Route-set builder: groups inventory (evidence: `builder/build_route_set.py`)
- Route-set builder → Manual overrides: applies decisions (evidence: `builder/build_route_set.py`)
- Operator prices → Manual overrides: applies adjustments (evidence: `builder/build_vinci_prices.py`)
- Direct prices → Manual overrides: applies adjustments (evidence: `builder/build_vinci_direct_prices.py`)
- Toll extents → Booth grouping: uses groups (evidence: `builder/build_toll_extent.py`)
- Toll extents → Operator prices: uses tariffs (evidence: `builder/build_toll_extent.py`)
- Toll extents → Direct prices: uses tariffs (evidence: `builder/build_toll_extent.py`)
- Toll extents → Manual overrides: applies decisions (evidence: `builder/build_toll_extent.py`)
- Segment weighting → Operator prices: reads tariffs (evidence: `builder/build_segment_weights.py`)
- Segment weighting → Direct prices: reads tariffs (evidence: `builder/build_segment_weights.py`)
