Files
gps-speedo/.planning/codebase/STRUCTURE.md
Mikkeli Matlock a686e6b0fb docs: map existing codebase
- STACK.md - Technologies and dependencies
- ARCHITECTURE.md - System design and patterns
- STRUCTURE.md - Directory layout
- CONVENTIONS.md - Code style and patterns
- TESTING.md - Test structure
- INTEGRATIONS.md - External services
- CONCERNS.md - Technical debt and issues
2026-02-09 18:51:11 +09:00

192 lines
8.1 KiB
Markdown

# Codebase Structure
**Analysis Date:** 2026-02-09
## Directory Layout
```
gps_speedo/
├── lib/ # Main Dart source code
│ ├── main.dart # App entry points and UI widgets
│ ├── gps_service.dart # GPS hardware abstraction
│ ├── speed_units.dart # Speed unit enum and conversion
│ ├── color_themes.dart # Theme data and definitions
│ └── services/
│ └── gps_data_manager.dart # GPS data processing singleton
├── android/ # Android native code and config
│ └── app/src/main/
│ ├── AndroidManifest.xml # GPS and system alert window permissions
│ └── kotlin/com/novoyuuparosk/speedo/ # Android entry point
├── fonts/ # Custom fonts
│ └── din1451alt.ttf # DIN 1451 Alt display font
├── icon/ # App launcher icon
│ └── speedo.png # Icon image for Android/iOS
├── pubspec.yaml # Flutter dependencies and project config
├── pubspec.lock # Dependency lock file
├── analysis_options.yaml # Dart analyzer configuration
├── test/ # Test files
│ └── widget_test.dart # Widget testing scaffold
└── .dart_tool/ # Dart/Flutter build artifacts (generated)
```
## Directory Purposes
**`lib/`:**
- Purpose: All application Dart source code
- Contains: Widgets, services, models, configuration enums
- Key files: `main.dart` is the central file containing 2 widget classes (44KB)
**`lib/services/`:**
- Purpose: Business logic services isolated from UI
- Contains: `GpsDataManager` singleton service
- Key files: `gps_data_manager.dart` (264 lines of GPS processing logic)
**`android/`:**
- Purpose: Android-specific configuration and permissions
- Contains: Manifest with GPS, overlay, and location permissions; Kotlin entry point
- Key files: `AndroidManifest.xml` defines FINE_LOCATION, COARSE_LOCATION, SYSTEM_ALERT_WINDOW, READ_PHONE_STATE
**`fonts/`:**
- Purpose: Custom font assets
- Contains: DIN 1451 Alt (single font file)
- Key files: `din1451alt.ttf` referenced in pubspec.yaml
**`icon/`:**
- Purpose: Launcher icon for Android and iOS
- Contains: Single PNG image (speedo.png)
- Key files: `speedo.png` (adaptive icon source)
## Key File Locations
**Entry Points:**
- `lib/main.dart` (lines 22-24): `void main()` - Standard Flutter app entry, runs `SpeedoApp()`
- `lib/main.dart` (lines 27-34): `void overlayMain()` - Overlay process entry marked with `@pragma("vm:entry-point")`, runs `OverlaySpeedometer`
- `android/app/src/main/AndroidManifest.xml`: Android app manifest with permissions and overlay metadata
**Configuration:**
- `pubspec.yaml`: Flutter project manifest with dependency versions (geolocator 14.0.2, flutter_overlay_window 0.5.0, etc.)
- `analysis_options.yaml`: Dart linter rules
- `android/app/src/main/AndroidManifest.xml`: GPS and system permissions
**Core Logic:**
- `lib/services/gps_data_manager.dart`: GPS data singleton, stream processing, stale data timeout (4 seconds)
- `lib/gps_service.dart`: GPS permission requests, position stream factory, heading formatting
- `lib/main.dart` (lines 56-837): `SpeedometerScreen` - Main app UI, GPS subscription, overlay lifecycle
- `lib/main.dart` (lines 839-1075): `OverlaySpeedometer` - Floating window UI, data listener
**UI & Data Models:**
- `lib/main.dart` (lines 499-548): `_buildSpeedDisplay()` - Speed display renderer with split decimal parts
- `lib/main.dart` (lines 574-703): `_buildPortraitLayout()` - Portrait screen layout with speed/heading sections
- `lib/main.dart` (lines 705-836): `_buildLandscapeLayout()` - Landscape screen layout with side-by-side sections
- `lib/color_themes.dart` (lines 21-63): `ColorThemes` static list with 4 theme variants
- `lib/speed_units.dart` (lines 1-20): `SpeedUnit` enum with km/h, mph, knots conversion factors
- `lib/services/gps_data_manager.dart` (lines 6-40): `ProcessedGpsData` immutable model class
**Testing:**
- `test/widget_test.dart`: Widget test skeleton (minimal)
## Naming Conventions
**Files:**
- Snake_case: `gps_service.dart`, `gps_data_manager.dart`, `speed_units.dart`, `color_themes.dart`, `main.dart`
- Exception: `main.dart` contains all entry points and main widgets
**Directories:**
- Lowercase: `lib/`, `services/`, `android/`, `fonts/`, `icon/`, `test/`
- Java-style package paths: `android/app/src/main/kotlin/com/novoyuuparosk/speedo/`
**Classes:**
- PascalCase: `SpeedometerScreen`, `GpsDataManager`, `ProcessedGpsData`, `ColorTheme`, `ColorThemes`, `SpeedUnit`, `GpsService`, `OverlaySpeedometer`
**Functions/Methods:**
- camelCase: `initState()`, `dispose()`, `_showFloatingWindow()`, `_onGpsDataUpdate()`, `_pushDataToOverlay()`, `_cycleTheme()`, `_cycleUnit()`
- Private prefix: Methods starting with `_` (e.g., `_initializeGpsManager()`, `_buildPortraitLayout()`)
**Variables:**
- camelCase for local/member: `_currentGpsData`, `_currentUnit`, `_currentThemeIndex`, `_isOverlayActive`, `speedText`, `displaySpeed`
- Constant ALL_CAPS: `_staleDataThreshold` (const Duration), `const directions` array
**Enums:**
- PascalCase: `SpeedUnit`, with lowercase members: `SpeedUnit.kmh`, `SpeedUnit.mph`, `SpeedUnit.knots`
## Where to Add New Code
**New Feature (e.g., Speed History Tracking):**
- Primary code: Create new file in `lib/services/speed_history_manager.dart` for business logic
- Singleton pattern: Follow `GpsDataManager` structure with stream broadcasting
- UI integration: Add stream subscription in `_SpeedometerScreenState.initState()`
- Display: Add widget in `_buildPortraitLayout()` or create separate widget method
- Tests: Add to `test/widget_test.dart`
**New UI Component/Widget:**
- Implementation: Add widget class directly in `lib/main.dart` if small (<100 lines), or create separate file
- Naming: Follow PascalCase class convention, e.g., `SpeedHistoryPanel`, `MetricsDisplay`
- Props: Pass required data as constructor parameters, avoid global state
- Tests: Add widget tests in `test/widget_test.dart`
**New Configuration/Enum:**
- Speed units variant: Add new enum member to `SpeedUnit` in `lib/speed_units.dart`, add multiplier
- Color theme: Add new `ColorTheme` instance to `ColorThemes.themes` list in `lib/color_themes.dart`
- GPS behavior constants: Add to `GpsDataManager` static fields (e.g., timeout durations)
**Utilities/Helpers:**
- Shared helpers: Create `lib/utils/` directory if adding 5+ utility functions
- Single-use helpers: Keep in same file as consumer (e.g., `customDebugPrint()` in `main.dart`)
- Formatting helpers: Add to relevant domain file (`GpsService` for GPS formatting, `SpeedUnit` for speed conversion)
**New Service:**
- Location: `lib/services/new_feature_manager.dart`
- Pattern: Singleton with internal state, public stream for subscribers, async initialize method
- Lifecycle: Call `initialize()` from `SpeedometerScreen.initState()`, add stream listener
- Cleanup: Call `dispose()` in widget `dispose()` method
## Special Directories
**`lib/services/`:**
- Purpose: Business logic services (no UI widgets)
- Generated: No
- Committed: Yes
- Content: `GpsDataManager` (only service currently, designed for expansion)
**`android/`:**
- Purpose: Android native configuration and permissions
- Generated: No (manually configured, but gradle build outputs go to `build/`)
- Committed: Yes
- Key file: `AndroidManifest.xml` defines permissions needed for GPS and overlay functionality
**`build/`:**
- Purpose: Flutter/Android build artifacts
- Generated: Yes (auto-generated by `flutter build`)
- Committed: No (in .gitignore)
**`.dart_tool/`:**
- Purpose: Dart analyzer and build cache
- Generated: Yes (auto-generated by Dart tooling)
- Committed: No (in .gitignore)
**`test/`:**
- Purpose: Automated tests
- Generated: No (manually written)
- Committed: Yes
- Current state: Minimal scaffold only
---
*Structure analysis: 2026-02-09*