- Added TypeScript build info for frontend. - Created Vite configuration for React application. - Implemented pre-commit hook to run checks before commits. - Set up PostgreSQL Dockerfile with PostGIS support and initialization scripts. - Added database creation script for PostgreSQL with necessary extensions. - Established Python project configuration with dependencies and development tools. - Developed pre-commit script to enforce code quality checks for backend and frontend. - Created PowerShell script to set up Git hooks path.
23 KiB
Rail Game Architecture Documentation
This document follows the arc42 template for software architecture documentation.
1. Introduction and Goals
1.1 Requirements Overview
The Rail Game is a browser-based railway simulation game that allows users to build and manage their own railway networks using real-world railway maps from OpenStreetMap. Key features include:
- Visualization of real-world railway maps
- Interactive building and management of railway networks
- Dynamic train scheduling and simulation
- User authentication and profiles
- Leaderboards and achievements
- Potential multiplayer elements
1.2 Quality Goals
- Usability: Intuitive interfaces for map interaction and network management
- Performance: Smooth real-time updates and responsive UI
- Reliability: Robust error handling and data integrity
- Security: Secure user authentication and data protection
- Scalability: Support for growing user base and complex networks
1.3 Stakeholders
- Users: Players who build and manage railway networks
- Developers: Team maintaining and extending the application
- Administrators: Managing user accounts and system operations
2. Constraints
2.1 Technical Constraints
- Browser Compatibility: Must work on modern web browsers supporting HTML5, CSS3, and JavaScript
- Backend Language: Python-based using FastAPI or Flask frameworks
- Database: PostgreSQL with PostGIS for spatial data handling
- Mapping: Integration with Leaflet and OpenStreetMap data
2.2 Organizational Constraints
- Open-source project hosted on GitHub
- Follows standard web development practices and security guidelines
2.3 Conventions
- Use Git for version control with conventional commit messages
- Follow React best practices for frontend development
- Implement RESTful API design for backend services
3. Context and Scope
3.1 Business Context
The Rail Game provides an educational and entertaining simulation of railway network management. It leverages real-world geographical data to create an immersive experience for users interested in transportation systems and strategy games.
3.2 Technical Context
The system interacts with:
- OpenStreetMap: Source of real-world map and railway data
- Web Browsers: Primary interface for users
- PostgreSQL/PostGIS: Storage and spatial queries for railway data
- External APIs: Potential integrations for additional features (e.g., weather, real-time data)
3.3 System Scope
In Scope:
- User registration and authentication
- Railway network building and management
- Train scheduling and simulation
- Map visualization and interaction
- Leaderboards and user profiles
Out of Scope:
- Real-world train control systems
- Physical railway operations
- Multiplayer real-time collaboration (initial version)
4. Solution Strategy
4.1 Technology Choices
- Frontend: React-based single-page application for responsive UI
- Backend: Python FastAPI/Flask for RESTful APIs and real-time features
- Database: PostgreSQL with PostGIS for efficient spatial data handling
- Mapping: Leaflet library for interactive maps integrated with OpenStreetMap
4.2 Architectural Patterns
- Client-Server Architecture: Separation of frontend and backend concerns
- RESTful API: For communication between frontend and backend
- Component-Based UI: Using React for modular frontend development
- ORM: SQLAlchemy for database abstraction
4.3 Key Decisions
- Browser-native implementation for broad accessibility
- Spatial database for efficient geographical queries
- Modular architecture allowing for future extensions (e.g., multiplayer)
5. Building Block View
5.1 Whitebox Overall System
The Rail Game system is structured as a client-server architecture with the following top-level building blocks:
- Frontend Application: Browser-based React SPA handling user interface and interactions
- Backend API: Python-based RESTful API server managing game logic and data access
- Database: PostgreSQL with PostGIS for persistent storage and spatial queries
- External Services: OpenStreetMap and other third-party APIs for map data and additional features
graph TD
A[Frontend Application] -->|REST API| B[Backend API]
B -->|SQL Queries| C[Database]
B -->|API Calls| D[External Services]
A -->|Map Tiles| D
5.2 Level 1 Building Blocks
5.2.1 Frontend Application
Responsibility: Provides the user interface for railway network building, management, and visualization.
Interfaces:
- User interactions via browser
- RESTful API calls to Backend API
- Integration with Leaflet for map rendering
Key Components:
- Map View: Displays railway networks and allows interaction
- Network Builder: Tools for creating and editing railway tracks and stations
- Dashboard: User profile, resources, and game statistics
- Authentication UI: Login, registration, and profile management
5.2.2 Backend API
Responsibility: Handles game logic, data processing, and serves as the interface between frontend and database.
Interfaces:
- RESTful HTTP endpoints for frontend communication
- Database connections via SQLAlchemy ORM
- Potential WebSocket connections for real-time updates
Key Components:
- User Management: Authentication, profiles, and sessions
- Railway Engine: Logic for network building, route calculation, and scheduling
- Game Logic: Resource management, scoring, and achievements
- Data Access Layer: Abstraction for database operations
5.2.3 Database
Responsibility: Persistent storage of user data, railway networks, and game state.
Interfaces:
- SQL connections from Backend API
- Spatial queries via PostGIS extensions
Key Components:
- User Schema: Accounts, profiles, and authentication data
- Railway Schema: Tracks, stations, trains, and schedules
- Game Schema: Resources, achievements, and leaderboards
5.2.4 External Services
Responsibility: Provides external data sources and integrations.
Interfaces:
- API calls from Backend or Frontend
- Data feeds for map tiles, geographical information, and real-time data
Key Components:
- OpenStreetMap: Source of map tiles and railway data
- Authentication Providers: OAuth integrations (e.g., Google, GitHub)
- Analytics Services: User tracking and performance monitoring
5.3 Level 2 Building Blocks
5.3.1 Frontend Components
graph TD
A[Map Component] -->|Leaflet| B[Toolbar Component]
A -->|Leaflet| C[Modal Components]
A -->|Redux| D[State Management]
- Map Component: React Leaflet-based map showing OpenStreetMap tiles with station markers and track polylines drawn from the shared network snapshot models
- Toolbar Component: Tools for building tracks, placing stations, and managing trains
- Modal Components: Dialogs for settings, confirmations, and detailed views
- State Management: Redux store for game state and UI state
5.3.2 Backend Modules
graph TD
A[API Layer] -->|REST Endpoints| B[Health Router]
A -->|REST Endpoints| C[Network Router]
C -->|Domain Models| D[Network Service]
D -->|Shared Schemas| E[Frontend Data Contracts]
- Health Module: Lightweight readiness probes used by infrastructure checks.
- Network Module: Serves read-only snapshots of stations, tracks, and trains using shared domain models (camelCase aliases for client compatibility).
- Authentication Module: JWT-based user registration, authentication, and authorization. The current prototype supports on-the-fly account creation backed by an in-memory user store and issues short-lived access tokens to validate the client flow end-to-end.
- Railway Calculation Module: Algorithms for route optimization and scheduling (planned).
- Resource Management Module: Logic for game economy and progression (planned).
- Real-time Module: WebSocket handlers for live updates (if implemented).
5.3.3 Database Tables
- Users Table: User accounts and profile information
- Railways Table: User-created railway networks (spatial data)
- Trains Table: Train configurations and schedules
- Stations Table: Station locations and properties (spatial data)
- Achievements Table: User progress and leaderboard data
5.4 Project Directory Structure
The repository will be organized to mirror the logical architecture and isolate concerns between frontend, backend, infrastructure, and shared assets.
rail-game/
|-- backend/
| |-- app/
| | |-- api/ # FastAPI/Flask route handlers and request lifecycles
| | |-- core/ # Configuration, startup hooks, cross-cutting utilities
| | |-- models/ # SQLAlchemy models, Pydantic schemas, migrations helpers
| | |-- services/ # Domain services for scheduling, routing, resource logic
| | `-- websocket/ # Real-time transport adapters and event handlers
| |-- tests/ # Backend unit, integration, and contract tests
| `-- requirements/ # Dependency manifests and lockfiles per environment
|-- frontend/
| |-- public/ # Static assets served without processing
| |-- src/
| | |-- components/ # Reusable React UI components and widgets
| | |-- hooks/ # Custom hooks for map interaction, data fetching, state sync
| | |-- pages/ # Route-level views composing feature modules
| | |-- state/ # Redux/Context stores, slices, and middleware
| | |-- styles/ # Global stylesheets, design tokens, CSS modules
| | `-- utils/ # Frontend-only helpers for formatting and calculations
| `-- tests/ # Component, store, and integration tests (Jest/React Testing Library)
|-- docs/ # Architecture docs, ADRs, onboarding guides
|-- infra/ # Docker, Terraform, CI/CD workflows, deployment manifests
|-- scripts/ # Automation for setup, linting, database tasks, data imports
|-- data/ # Seed datasets, fixtures, export/import scripts (kept out of VCS if large)
`-- tests/ # Cross-cutting end-to-end suites and shared test utilities
Shared code that spans application layers should be surfaced through well-defined APIs within backend/app/services or exposed via frontend data contracts to keep coupling low. Infrastructure automation and CI/CD assets remain isolated under infra/ to support multiple deployment targets.
6. Runtime View
6.1 Overview
The runtime view illustrates the dynamic behavior of the Rail Game system during typical user interactions. It shows how the building blocks interact to fulfill user requests and maintain system state.
6.2 Key Runtime Scenarios
6.2.1 User Authentication
Scenario: A user signs up and logs into the game.
Description: From the authentication UI the user can either register a new profile or sign in with existing credentials. New registrations are persisted in the prototype's in-memory store. On login the backend verifies the credentials and issues a JWT token for subsequent requests.
sequenceDiagram
participant U as User
participant F as Frontend
participant B as Backend API
participant D as Database
U->>F: Submit signup/login form
alt Register new account
F->>B: POST /api/auth/register
B->>B: Persist user (in-memory prototype store)
end
F->>B: POST /api/auth/login
B->>D: Query user credentials
D-->>B: User data
B->>B: Validate password
B-->>F: JWT token
F-->>U: Redirect to dashboard
6.2.2 Loading Map and Railway Data
Scenario: User opens the game and loads their railway network.
Description: The frontend requests map tiles from OpenStreetMap and user-specific railway data from the backend, which retrieves it from the database.
sequenceDiagram
participant U as User
participant F as Frontend
participant B as Backend API
participant D as Database
participant OSM as OpenStreetMap
U->>F: Open game
F->>OSM: Request map tiles
OSM-->>F: Map tiles
F->>B: GET /api/railways/{userId}
B->>D: Query user railways
D-->>B: Railway data (spatial)
B-->>F: Railway network JSON
F->>F: Render map with railways
6.2.3 Fetching Network Snapshot (current implementation)
Scenario: The frontend loads a shared snapshot of stations, tracks, and trains using the domain models.
Description: After the React client authenticates and stores the issued access token, it calls the FastAPI /api/network endpoint with a bearer header. The backend constructs a NetworkSnapshot using immutable domain models and returns camelCase JSON for direct consumption by TypeScript interfaces. The frontend hydrates both summary lists and the React Leaflet map overlay with the resulting station and track geometry.
sequenceDiagram
participant F as Frontend (React)
participant H as Hook (useNetworkSnapshot)
participant A as API Router (/api/network)
participant S as Network Service
F->>H: Mount component
H->>A: GET /api/network (Bearer token)
A->>S: Build snapshot using domain models
S-->>A: Stations, tracks, trains (camelCase JSON)
A-->>H: 200 OK + payload
H-->>F: Update UI state (loading → success)
F->>F: Render Leaflet map and snapshot summaries
6.2.4 Building Railway Network
Scenario: User adds a new track segment to their railway network.
Description: The user interacts with the map to place a new track. The frontend sends the new track data to the backend, which validates and stores it in the database.
sequenceDiagram
participant U as User
participant F as Frontend
participant B as Backend API
participant D as Database
U->>F: Draw new track on map
F->>F: Validate track placement
F->>B: POST /api/tracks
B->>B: Validate track logic
B->>D: Insert new track (spatial)
D-->>B: Confirmation
B-->>F: Success response
F->>F: Update map display
6.2.5 Running Train Simulation
Scenario: User starts a train simulation on their network.
Description: The frontend requests simulation start, backend calculates train routes and schedules, updates database with simulation state, and sends real-time updates back to frontend.
sequenceDiagram
participant U as User
participant F as Frontend
participant B as Backend API
participant D as Database
U->>F: Click "Start Simulation"
F->>B: POST /api/simulation/start
B->>D: Query railway network
D-->>B: Network data
B->>B: Calculate routes & schedules
B->>D: Update train positions
D-->>B: Confirmation
B-->>F: Simulation started
loop Real-time updates
B->>B: Update train positions
B->>D: Save positions
B-->>F: WebSocket position updates
end
6.2.6 Saving Game Progress
Scenario: User saves their current game state.
Description: The frontend periodically or on user request sends current game state to backend for persistence.
sequenceDiagram
participant F as Frontend
participant B as Backend API
participant D as Database
F->>B: POST /api/save
B->>D: Update user progress
D-->>B: Confirmation
B-->>F: Save successful
6.3 Performance and Scalability Considerations
- Database Queries: Spatial queries for railway data are optimized using PostGIS indexes
- Caching: Frequently accessed map tiles and user data may be cached
- Real-time Updates: WebSocket connections for simulation updates, with fallback to polling
- Load Balancing: Backend API can be scaled horizontally for multiple users
- CDN: Static assets and map tiles served via CDN for faster loading
7. Deployment View
To be detailed in subsequent sections.
8. Concepts
8.1 Domain Concepts
8.1.1 Railway Network Model
The core domain concept is the railway network, consisting of:
- Tracks: Linear segments connecting geographical points, stored as spatial geometries
- Stations: Key points on the network where trains can stop, load/unload passengers or cargo
- Trains: Movable entities that follow routes along tracks according to schedules
- Schedules: Time-based plans for train movements and operations
Railway networks are user-created and managed, built upon real-world geographical data from OpenStreetMap.
8.1.2 Game Economy
Resource management drives gameplay:
- Currency: Earned through network operations and achievements
- Resources: Required for building and upgrading railway components
- Scoring: Based on network efficiency, passenger satisfaction, and operational success
8.1.3 Simulation Engine
Dynamic simulation of train operations:
- Route Calculation: Pathfinding algorithms to determine optimal train routes
- Schedule Optimization: Balancing train frequencies with network capacity
- Real-time Updates: Live position tracking and status reporting
8.1.4 Network Snapshot Contract
- Shared Models: The backend uses immutable Pydantic models with camelCase aliases that mirror TypeScript interfaces in
frontend/src/types/domain.ts. - Snapshot Service: Until persistence exists, a service synthesises demo stations, tracks, and trains to keep the client workflow functional.
- Client Hook:
useNetworkSnapshotorchestrates fetch status (idle/loading/success/error) and pushes data into the React view layer.
8.2 Architectural Concepts
8.2.1 Client-Server Architecture
- Frontend: Browser-based React SPA handling user interactions and UI rendering
- Backend: RESTful API server processing business logic and data operations
- Separation of Concerns: Clear boundaries between presentation, business logic, and data layers
8.2.2 Spatial Data Handling
- PostGIS Integration: Extension of PostgreSQL for geographical and spatial operations
- Coordinate Systems: Use of standard geographical projections (e.g., WGS84)
- Spatial Queries: Efficient querying of railway elements within geographical bounds
8.2.3 Real-time Communication
- WebSocket Protocol: For live updates during train simulations
- Fallback Mechanisms: Polling as alternative when WebSockets unavailable
- Event-Driven Updates: Push notifications for game state changes
8.3 User Interface Concepts
8.3.1 Component-Based Architecture
- React Components: Modular, reusable UI elements
- State Management: Centralized state using Redux or Context API
- Responsive Design: Adaptive layouts for various screen sizes and devices
8.3.2 Map Interaction
- Leaflet Integration: Interactive mapping library for geographical visualization
- Layer Management: Overlaying user railways on base OpenStreetMap tiles
- Gesture Handling: Mouse, keyboard, and touch interactions for map navigation and editing
8.3.3 Game Interface Patterns
- Toolbar: Contextual tools for building and editing railway elements
- Modal Dialogs: For configuration, confirmation, and detailed information display
- Dashboard: Overview of user progress, resources, and network statistics
8.4 Security Concepts
8.4.1 Authentication and Authorization
- JWT Tokens: Stateless authentication for API requests
- OAuth Integration: Support for third-party authentication providers
- Role-Based Access: Differentiated permissions for users and administrators
8.4.2 Data Protection
- Input Validation: Sanitization of all user inputs to prevent injection attacks
- HTTPS Encryption: Secure communication between client and server
- Data Privacy: Compliance with privacy regulations for user data handling
8.5 Persistence Concepts
8.5.1 Database Design
- Schema Overview: Core tables include
users,stations,tracks,trains, andtrain_schedules, each backed by UUID primary keys and timestamp metadata for auditing. - Users: Holds account metadata (
username,email,role, hashed password) with JSON-ready preference storage and soft defaults for player roles. - Stations: Stores OpenStreetMap references, station codes, and a
POINTgeometry (SRID 4326) to support spatial queries; a GiST index accelerates proximity searches. - Tracks: Models line segments between stations using
LINESTRINGgeometry plus operational attributes (length, speed limits, status, bidirectionality) and a uniqueness constraint on station pairs. - Trains & Schedules: Captures rolling stock capabilities and their ordered stop plans (
sequence_index, arrival/departure timestamps, dwell times) with cascading foreign keys for clean deletions. - Spatial Extensions: Alembic migrations provision
postgisandpgcryptoextensions; geometry columns use GeoAlchemy2 bindings for seamless ORM interactions.
8.5.2 Data Access Patterns
- ORM Layer: SQLAlchemy 2.0 declarative models (see
backend/app/db/models.py) expose typed entities that will feed repository and service layers. - Session Management: A centralized engine/session factory (
backend/app/db/session.py) pulls the database URL from environment-managed settings and keeps pooling under application control. - Environment Separation:
.envconfiguration exposesDATABASE_URL,TEST_DATABASE_URL, andALEMBIC_DATABASE_URL, allowing the runtime, tests, and migration tooling to target different Postgres instances. - Schema Evolution: Alembic configuration (
backend/alembic.ini,backend/migrations/) provides repeatable migrations—the initial revision creates the PostGIS-enabled schema and GiST indexes. - Transaction Management: Service-layer dependencies will acquire short-lived sessions (
SessionLocal) ensuring explicit commit/rollback boundaries around game operations.
8.6 Development and Deployment Concepts
8.6.1 Testing Strategy
- Unit Testing: Individual component and function testing
- Integration Testing: API endpoint and database interaction validation
- End-to-End Testing: Complete user workflow verification across browsers
8.6.2 Deployment Pipeline
- Containerization: Docker for consistent environments
- CI/CD: Automated testing and deployment workflows
- Static Hosting: CDN-based delivery of frontend assets
8.6.3 Performance Optimization
- Lazy Loading: On-demand loading of components and data
- Caching Layers: Redis for frequently accessed data
- Asset Optimization: Minification and compression of static resources
9. Design Decisions
To be detailed in subsequent sections.
10. Quality Requirements
To be detailed in subsequent sections.
11. Risks and Technical Debt
To be detailed in subsequent sections.
12. Glossary
To be detailed in subsequent sections.