Skip to content

5. Building Block View

The following figure shows the internal structure of Tanker24 at C4-Model Level 2 (Container) and Level 3 (Component).

5.1 Whitebox Overall System (Level 2)

Tanker24 is composed of four main building blocks. The building blocks are decomposed by their responsibilities in the application. The decomposition points to attached external providers as well:

Tanker24[system]«container»Frontend[SvelteKit / Node.js 24] Provides the web-baseduser interface withinteractive map, stationsearch, and accountmanagement.«container»Backend[Python 3.14 / FastAPI] RESTful API serving gasstation data, usermanagement, and dataexport.«container»Database[PostgreSQL 18] Persistent storage for useraccounts, cars, historyrecords, invitation keys, andgas station cache.«container»Monitoring[Uptime Kuma 2] Uptime and healthmonitoring dashboard forthe deployed services.«person»German Car Driver End user of the application.«external_system»Tankerkönig API External REST API providingreal-time gas price datafrom the German MarketTransparency Unit for Fuels(MTS-K).«external_system»OpenStreetMap Public tile server providingraster map tiles forvisualization.«external_system»CartoDB Dark Matter Public tile server providingdark-theme map tiles.Checks gas prices, tracksfillings[HTTPS]API calls for data[REST/HTTPS]Reads/writes persistentdata[SQL/TCP]Fetches gas price data[REST/HTTPS]Loads map tiles (lighttheme)[HTTPS]Loads map tiles (darktheme)[HTTPS]
«system_boundary»«boundary»Tanker24[system]«container»Frontend[SvelteKit / Node.js 24] Provides the web-baseduser interface withinteractive map, stationsearch, and accountmanagement.«container»Backend[Python 3.14 / FastAPI] RESTful API serving gasstation data, usermanagement, and dataexport.«container»Database[PostgreSQL 18] Persistent storage for useraccounts, cars, historyrecords, invitation keys, andgas station cache.«container»Monitoring[Uptime Kuma 2] Uptime and healthmonitoring dashboard forthe deployed services.«person»German Car Driver End user of the application.«external_system»Tankerkönig API External REST API providingreal-time gas price datafrom the German MarketTransparency Unit for Fuels(MTS-K).«external_system»OpenStreetMap Public tile server providingraster map tiles forvisualization.«external_system»CartoDB Dark Matter Public tile server providingdark-theme map tiles.Checks gas prices, tracksfillings[HTTPS]API calls for data[REST/HTTPS]Reads/writes persistentdata[SQL/TCP]Fetches gas price data[REST/HTTPS]Loads map tiles (lighttheme)[HTTPS]Loads map tiles (darktheme)[HTTPS]
Building Block Description
Frontend SvelteKit application (Svelte 5) with TypeScript, TailwindCSS 4, and Leaflet for interactive maps. Communicates exclusively with the backend via REST API. Renders map tiles directly from OpenStreetMap/CDN tile servers.
Backend FastAPI application written in Python 3.14. Provides REST endpoints for station data, user authentication, and data export. Implements caching, rate limiting, and integration with the Tankerkönig external API.
PostgreSQL Relational database (v18) used for persistent storage. Stores user accounts, vehicles, fueling history records, invitation keys, and cached gas station data from the Tankerkönig API.
Uptime Kuma Lightweight monitoring service that periodically checks the health of the frontend and backend services and provides a dashboard for uptime status.

5.2 Backend — Component View (Level 3)

The backend follows a layered architecture with clear separation of concerns:

Backend (FastAPI / Python)[container]«component»Routers[FastAPI Router] Exposes REST endpoints,validates requestparameters, handles HTTPerrors.«component»Services[Business Logic Layer] Orchestrates businessoperations: station search,export, rate limiting.«component»Repositories[Data Access Layer] Encapsulates all databasequeries via SQLAlchemyasync sessions.«component»ORM Models[SQLAlchemy Models] Defines the databaseschema: User, Car,HistoryRecord, Station,InvitationKey.«component»Schemas[Pydantic Models] Defines APIrequest/response schemasfor validation andserialization.«component»Auth Module[fastapi-users + JWT] Handles user registration,login, JWT tokengeneration/validation,password policies.«component»Rate Limiter[SlowAPI + Token Bucket] Enforces per-user andper-endpoint rate limits.Uses in-memory tokenbucket for Tankerkönig APIcalls.«component»Station Cache[PostgreSQL-based] Caches Tankerkönig APIresponses with spatial andtemporal tolerance toreduce external API calls.«component»Logging[Python logging + stdout] Structured logging withtimestamps, log levels, andmodule names. Configuredat application startup.«container»PostgreSQL[Relational Database]«external_container»Tankerkönig API[External Gas Price API]Calls business logic[Python method call]Reads/writes data[Python method call]SQL queries[async SQLAlchemy/TCP]Writes/reads cachedstations[via Repository]Fetches gas prices oncache miss[REST/HTTPS]Protects endpoints[FastAPI Depends]Applies rate limits[SlowAPI decorator]Validates I/O[Pydantic validation]Uses ORM mappings[SQLAlchemy]
«container_boundary»«boundary»Backend (FastAPI / Python)[container]«component»Routers[FastAPI Router] Exposes REST endpoints,validates requestparameters, handles HTTPerrors.«component»Services[Business Logic Layer] Orchestrates businessoperations: station search,export, rate limiting.«component»Repositories[Data Access Layer] Encapsulates all databasequeries via SQLAlchemyasync sessions.«component»ORM Models[SQLAlchemy Models] Defines the databaseschema: User, Car,HistoryRecord, Station,InvitationKey.«component»Schemas[Pydantic Models] Defines APIrequest/response schemasfor validation andserialization.«component»Auth Module[fastapi-users + JWT] Handles user registration,login, JWT tokengeneration/validation,password policies.«component»Rate Limiter[SlowAPI + Token Bucket] Enforces per-user andper-endpoint rate limits.Uses in-memory tokenbucket for Tankerkönig APIcalls.«component»Station Cache[PostgreSQL-based] Caches Tankerkönig APIresponses with spatial andtemporal tolerance toreduce external API calls.«component»Logging[Python logging + stdout] Structured logging withtimestamps, log levels, andmodule names. Configuredat application startup.«container»PostgreSQL[Relational Database]«external_container»Tankerkönig API[External Gas Price API]Calls business logic[Python method call]Reads/writes data[Python method call]SQL queries[async SQLAlchemy/TCP]Writes/reads cachedstations[via Repository]Fetches gas prices oncache miss[REST/HTTPS]Protects endpoints[FastAPI Depends]Applies rate limits[SlowAPI decorator]Validates I/O[Pydantic validation]Uses ORM mappings[SQLAlchemy]

5.2.1 Router Layer

The router layer specifies all outward facing interfaces. They specify secured (where necessary) endpoints for interacting with the application.

Router Prefix Purpose
health.py / Health check (/health) and root welcome endpoint (/). Unauthenticated.
auth.py /api/v0/auth/jwt, /api/v0/users Login/JWT token, registration, user profile management. Powered by fastapi-users.
stations.py /api/v0/stations List cached stations and nearby station search with caching. Most endpoints require authentication.
export.py /api/v0/export JSON and CSV export of user's car and fueling history data. Requires authentication.
fillings.py /api/v0/fillings REST endpoint for inserting and deleting filling data. Requires authentication.

5.2.2 Service Layer

The service layer provides an abstraction layer for the business logic of the application. It seperates the data handling from the interface to minimize the business logic in the interfaces. Any interface implementation may consume the information provided by service implementation.

Service Responsibility
GasStationService (abstract) Interface for gas station data providers. Currently implemented by TankerkoenigGasStationService.
TankerkoenigGasStationService Communicates with the Tankerkönig REST API (creativecommons.tankerkoenig.de/json/). Supports area search (list.php) and detail lookup (detail.php).
NearbyStationsService Orchestrates station search with caching: checks the database cache first; on miss, calls the API, applies rate limiting, and updates the cache.
ExportDataService (abstract) Interface for data export. Implemented by NestedExportDataService (JSON) and FlatExportDataService (CSV).
RateLimiter Token-bucket-based rate limiter for Tankerkönig API calls. Configured at 100 requests per minute.
FillingsDataService Handles the logic required for inserting, getting and deleting fillings with the repository layer. Transforms data where necessary.

5.2.3 Repository Layer

The repository layer provides an abstraction for querying information from the database. It enforces prepared SQL queries which are located in one place instead of being distributed across the application.

Repository Entity Key Operations
StationRepository Station Cache lookup with spatial tolerance, upsert with stale record cleanup, list all cached stations
CarRepository Car Create and read cars by owner
HistoryRecordRepository HistoryRecord Create, read and delete history records by car
InvitationKeyRepository InvitationKey CRUD for invitation keys, lookup users by key
FuelTypeRepository FuelType Read the fuel types by name from the database.

5.2.4 Data Model (ORM)

The database schema is defined in backend/app/models.py using SQLAlchemy declarative models:

Userid : intemail : str (UNIQUE)hashed_password : strforename : strsurname : stris_active : boolis_superuser : boolis_verified : boolinvitation_key_id : int (FK, nullable)InvitationKeyid : intkey : str (UNIQUE, 32 chars)Carid : inttype : strlicense_plate_number : str (UNIQUE)owner_id : int (FK)HistoryRecordid : intcar_id : int (FK)fuel_type_id : int (FK)timestamp : datetimemileage : floatprice_per_litre : floatlitres : floattankerkoenig_station_id: strFuelTypeid : intname : str (UNIQUE)Stationid : inttankerkoenig_id : str (UNIQUE, UUID)name : strbrand : strstreet : str (nullable)house_number : str (nullable)post_code : int (nullable)place : str (nullable)latitude : floatlongitude : floatdistance : float (nullable)diesel : float (nullable)e5 : float (nullable)e10 : float (nullable)is_open : boolcached_at : datetimecache_lat : float (nullable)cache_lon : float (nullable)cache_radius : float (nullable)activatesownshascategorizes
Userid : intemail : str (UNIQUE)hashed_password : strforename : strsurname : stris_active : boolis_superuser : boolis_verified : boolinvitation_key_id : int (FK, nullable)InvitationKeyid : intkey : str (UNIQUE, 32 chars)Carid : inttype : strlicense_plate_number : str (UNIQUE)owner_id : int (FK)HistoryRecordid : intcar_id : int (FK)fuel_type_id : int (FK)timestamp : datetimemileage : floatprice_per_litre : floatlitres : floattankerkoenig_station_id: strFuelTypeid : intname : str (UNIQUE)Stationid : inttankerkoenig_id : str (UNIQUE, UUID)name : strbrand : strstreet : str (nullable)house_number : str (nullable)post_code : int (nullable)place : str (nullable)latitude : floatlongitude : floatdistance : float (nullable)diesel : float (nullable)e5 : float (nullable)e10 : float (nullable)is_open : boolcached_at : datetimecache_lat : float (nullable)cache_lon : float (nullable)cache_radius : float (nullable)activatesownshascategorizes

5.3 Frontend — Component View (Level 3)

The frontend follows SvelteKit's file-based routing pattern with a service/stores layer:

Frontend (SvelteKit)[container]«component»Routes & Pages[Svelte Pages] File-based routing: home,map, login, register,account, impressum,privacy.«component»UI Components[Svelte Components] Reusable UI elements:Navbar, Footer, Button,Logo, ConsentModal,AuthRequiredModal,LanguageSwitcher.«component»API Services[TypeScript Modules] Typed wrappers forbackend REST calls:auth_api, stations_api,export_api.«component»Utilities[request.ts] Centralized fetch wrapperwith base URL, auth tokeninjection, and errorhandling.«component»Stores[Svelte Stores] Reactive state: fuelType,locale (i18n), privacyconsent, theme (light/dark).«component»i18n[Internationalization] Translation systemsupporting English andGerman using svelte-i18n.«external_container»Backend API[REST/HTTPS]«external_container»Map Tile Servers[OpenStreetMap / CartoDB]Composes UI[Svelte imports]Calls backend[TypeScript method call]Uses HTTP wrapper[TypeScript import]REST API calls[HTTPS/JSON]Reads/writes state[Svelte store subscription]Translates UI[svelte-i18n]Renders map tiles[HTTPS (Leaflet)]
«container_boundary»«boundary»Frontend (SvelteKit)[container]«component»Routes & Pages[Svelte Pages] File-based routing: home,map, login, register,account, impressum,privacy.«component»UI Components[Svelte Components] Reusable UI elements:Navbar, Footer, Button,Logo, ConsentModal,AuthRequiredModal,LanguageSwitcher.«component»API Services[TypeScript Modules] Typed wrappers forbackend REST calls:auth_api, stations_api,export_api.«component»Utilities[request.ts] Centralized fetch wrapperwith base URL, auth tokeninjection, and errorhandling.«component»Stores[Svelte Stores] Reactive state: fuelType,locale (i18n), privacyconsent, theme (light/dark).«component»i18n[Internationalization] Translation systemsupporting English andGerman using svelte-i18n.«external_container»Backend API[REST/HTTPS]«external_container»Map Tile Servers[OpenStreetMap / CartoDB]Composes UI[Svelte imports]Calls backend[TypeScript method call]Uses HTTP wrapper[TypeScript import]REST API calls[HTTPS/JSON]Reads/writes state[Svelte store subscription]Translates UI[svelte-i18n]Renders map tiles[HTTPS (Leaflet)]

5.3.1 Route Structure

Route Page Description
/ +page.svelte Landing page with project introduction
/map +page.svelte Interactive map for searching nearby gas stations
/login +page.svelte User login form
/register +page.svelte User registration with invitation key
/account +page.svelte User account management
/impressum +page.svelte Legal imprint (German requirement)
/privacy +page.svelte Privacy policy

5.3.2 Key Dependencies

Library Version Purpose
Svelte / SvelteKit 5 UI framework and full-stack routing
Tailwind CSS 4 Utility-first CSS styling
Leaflet 1.x Interactive map rendering with marker support
svelte-i18n latest Internationalization (English, German)
Playwright latest End-to-end browser testing
Vitest latest Unit testing framework
Vite latest Build tool and development server

5.4 External Interfaces

The services listed below are required for running the application.

Interface Provider Protocol Purpose
Tankerkönig API creativecommons.tankerkoenig.de REST/JSON over HTTPS Retrieves gas station lists (area search) and details (by ID)
OpenStreetMap Tiles tile.openstreetmap.org HTTPS Standard raster map tiles (light theme)
CartoDB Dark Matter basemaps.cartocdn.com HTTPS Dark raster map tiles (dark theme)
GitHub Container Registry ghcr.io Docker Registry API Hosts built container images for deployment
SonarCloud sonarcloud.io REST/HTTPS Static code analysis and quality gate
ReadTheDocs readthedocs.io HTTPS Hosts MkDocs-based project documentation