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-based user interface with interactive map, station search, and account management. «container» Backend [Python 3.14 / FastAPI] RESTful API serving gas station data, user management, and data export. «container» Database [PostgreSQL 18] Persistent storage for user accounts, cars, history records, invitation keys, and gas station cache. «container» Monitoring [Uptime Kuma 2] Uptime and health monitoring dashboard for the deployed services. «person» German Car Driver End user of the application. «external_system» Tankerkönig API External REST API providing real-time gas price data from the German Market Transparency Unit for Fuels (MTS-K). «external_system» OpenStreetMap Public tile server providing raster map tiles for visualization. «external_system» CartoDB Dark Matter Public tile server providing dark-theme map tiles. Checks gas prices, tracks fillings [HTTPS] API calls for data [REST/HTTPS] Reads/writes persistent data [SQL/TCP] Fetches gas price data [REST/HTTPS] Loads map tiles (light theme) [HTTPS] Loads map tiles (dark theme) [HTTPS] «system_boundary» «boundary» Tanker24 [system] «container» Frontend [SvelteKit / Node.js 24] Provides the web-based user interface with interactive map, station search, and account management. «container» Backend [Python 3.14 / FastAPI] RESTful API serving gas station data, user management, and data export. «container» Database [PostgreSQL 18] Persistent storage for user accounts, cars, history records, invitation keys, and gas station cache. «container» Monitoring [Uptime Kuma 2] Uptime and health monitoring dashboard for the deployed services. «person» German Car Driver End user of the application. «external_system» Tankerkönig API External REST API providing real-time gas price data from the German Market Transparency Unit for Fuels (MTS-K). «external_system» OpenStreetMap Public tile server providing raster map tiles for visualization. «external_system» CartoDB Dark Matter Public tile server providing dark-theme map tiles. Checks gas prices, tracks fillings [HTTPS] API calls for data [REST/HTTPS] Reads/writes persistent data [SQL/TCP] Fetches gas price data [REST/HTTPS] Loads map tiles (light theme) [HTTPS] Loads map tiles (dark theme) [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 request parameters, handles HTTP errors. «component» Services [Business Logic Layer] Orchestrates business operations: station search, export, rate limiting. «component» Repositories [Data Access Layer] Encapsulates all database queries via SQLAlchemy async sessions. «component» ORM Models [SQLAlchemy Models] Defines the database schema: User, Car, HistoryRecord, Station, InvitationKey. «component» Schemas [Pydantic Models] Defines API request/response schemas for validation and serialization. «component» Auth Module [fastapi-users + JWT] Handles user registration, login, JWT token generation/validation, password policies. «component» Rate Limiter [SlowAPI + Token Bucket] Enforces per-user and per-endpoint rate limits. Uses in-memory token bucket for Tankerkönig API calls. «component» Station Cache [PostgreSQL-based] Caches Tankerkönig API responses with spatial and temporal tolerance to reduce external API calls. «component» Logging [Python logging + stdout] Structured logging with timestamps, log levels, and module names. Configured at 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 cached stations [via Repository] Fetches gas prices on cache 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 request parameters, handles HTTP errors. «component» Services [Business Logic Layer] Orchestrates business operations: station search, export, rate limiting. «component» Repositories [Data Access Layer] Encapsulates all database queries via SQLAlchemy async sessions. «component» ORM Models [SQLAlchemy Models] Defines the database schema: User, Car, HistoryRecord, Station, InvitationKey. «component» Schemas [Pydantic Models] Defines API request/response schemas for validation and serialization. «component» Auth Module [fastapi-users + JWT] Handles user registration, login, JWT token generation/validation, password policies. «component» Rate Limiter [SlowAPI + Token Bucket] Enforces per-user and per-endpoint rate limits. Uses in-memory token bucket for Tankerkönig API calls. «component» Station Cache [PostgreSQL-based] Caches Tankerkönig API responses with spatial and temporal tolerance to reduce external API calls. «component» Logging [Python logging + stdout] Structured logging with timestamps, log levels, and module names. Configured at 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 cached stations [via Repository] Fetches gas prices on cache 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:
User id : int email : str (UNIQUE) hashed_password : str forename : str surname : str is_active : bool is_superuser : bool is_verified : bool invitation_key_id : int (FK, nullable) InvitationKey id : int key : str (UNIQUE, 32 chars) Car id : int type : str license_plate_number : str (UNIQUE) owner_id : int (FK) HistoryRecord id : int car_id : int (FK) fuel_type_id : int (FK) timestamp : datetime mileage : float price_per_litre : float litres : float tankerkoenig_station_id: str FuelType id : int name : str (UNIQUE) Station id : int tankerkoenig_id : str (UNIQUE, UUID) name : str brand : str street : str (nullable) house_number : str (nullable) post_code : int (nullable) place : str (nullable) latitude : float longitude : float distance : float (nullable) diesel : float (nullable) e5 : float (nullable) e10 : float (nullable) is_open : bool cached_at : datetime cache_lat : float (nullable) cache_lon : float (nullable) cache_radius : float (nullable) activates owns has categorizes User id : int email : str (UNIQUE) hashed_password : str forename : str surname : str is_active : bool is_superuser : bool is_verified : bool invitation_key_id : int (FK, nullable) InvitationKey id : int key : str (UNIQUE, 32 chars) Car id : int type : str license_plate_number : str (UNIQUE) owner_id : int (FK) HistoryRecord id : int car_id : int (FK) fuel_type_id : int (FK) timestamp : datetime mileage : float price_per_litre : float litres : float tankerkoenig_station_id: str FuelType id : int name : str (UNIQUE) Station id : int tankerkoenig_id : str (UNIQUE, UUID) name : str brand : str street : str (nullable) house_number : str (nullable) post_code : int (nullable) place : str (nullable) latitude : float longitude : float distance : float (nullable) diesel : float (nullable) e5 : float (nullable) e10 : float (nullable) is_open : bool cached_at : datetime cache_lat : float (nullable) cache_lon : float (nullable) cache_radius : float (nullable) activates owns has categorizes
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 for backend REST calls: auth_api, stations_api, export_api. «component» Utilities [request.ts] Centralized fetch wrapper with base URL, auth token injection, and error handling. «component» Stores [Svelte Stores] Reactive state: fuelType, locale (i18n), privacy consent, theme (light/dark). «component» i18n [Internationalization] Translation system supporting English and German 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 for backend REST calls: auth_api, stations_api, export_api. «component» Utilities [request.ts] Centralized fetch wrapper with base URL, auth token injection, and error handling. «component» Stores [Svelte Stores] Reactive state: fuelType, locale (i18n), privacy consent, theme (light/dark). «component» i18n [Internationalization] Translation system supporting English and German 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