Files
gps-speedo/.planning/phases/01-foundation/01-02-PLAN.md
T
Mikkeli Matlock 7f8075b76d docs(01): create phase plan
Phase 01: Foundation
- 2 plan(s) in 2 wave(s)
- 2 autonomous, 0 checkpoint-only
- Ready for execution

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 21:08:34 +09:00

11 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, must_haves
phase plan type wave depends_on files_modified autonomous must_haves
01-foundation 02 execute 2
01-01
lib/screens/speedometer_screen.dart
lib/screens/overlay_screen.dart
lib/main.dart
true
truths artifacts key_links
App compiles with flutter analyze showing zero errors
main.dart contains only entry points (main, overlayMain), SpeedoApp widget, and imports — under 60 lines
SpeedometerScreen lives in screens/speedometer_screen.dart with all its state and methods intact
OverlaySpeedometer lives in screens/overlay_screen.dart with all its state and methods intact
All existing functionality preserved — speed display, heading, themes, units, overlay, haptics, lifecycle all work identically
path provides contains
lib/screens/speedometer_screen.dart Main speedometer screen widget and state class SpeedometerScreen
path provides contains
lib/screens/overlay_screen.dart Overlay floating window widget and state class OverlaySpeedometer
path provides min_lines
lib/main.dart App entry points and SpeedoApp widget only 15
from to via pattern
lib/main.dart lib/screens/speedometer_screen.dart import and use as MaterialApp home import.*screens/speedometer_screen
from to via pattern
lib/main.dart lib/screens/overlay_screen.dart import and use in overlayMain() import.*screens/overlay_screen
from to via pattern
lib/screens/speedometer_screen.dart lib/services/gps_data_manager.dart GPS data subscription and display import.*services/gps_data_manager
from to via pattern
lib/screens/speedometer_screen.dart lib/models/overlay_message.dart Overlay IPC messaging import.*models/overlay_message
from to via pattern
lib/screens/overlay_screen.dart lib/config/color_themes.dart Theme rendering in overlay import.*config/color_themes
Extract SpeedometerScreen and OverlaySpeedometer from the monolithic main.dart into dedicated screen files, leaving main.dart as a slim entry point.

Purpose: Completes the Phase 1 code organization by splitting the 1133-line main.dart into focused, single-responsibility files. This is the final structural change — after this, ORG-07 and ORG-08 are satisfied and the foundation phase is complete.

Output: speedometer_screen.dart (~780 lines), overlay_screen.dart (~240 lines), slimmed main.dart (~50 lines).

<execution_context> @C:\Users\SKSup.claude/get-shit-done/workflows/execute-plan.md @C:\Users\SKSup.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/01-foundation/01-CONTEXT.md @.planning/phases/01-foundation/01-01-SUMMARY.md

Source files (post Plan 01): @lib/main.dart

Task 1: Extract SpeedometerScreen to screens/speedometer_screen.dart lib/screens/speedometer_screen.dart lib/main.dart 1. Create `lib/screens/speedometer_screen.dart` by extracting the `SpeedometerScreen` widget class and its `_SpeedometerScreenState` class from main.dart.
**What to move (everything from the SpeedometerScreen class through end of _SpeedometerScreenState):**
- `class SpeedometerScreen extends StatefulWidget` and its state
- All state variables, methods, build methods, layout builders
- The `_getOverlaySize()` method
- All timer management, lifecycle observer, overlay messaging, GPS subscription
- The `_buildSpeedDisplay()`, `_buildPortraitLayout()`, `_buildLandscapeLayout()` methods

**Imports needed in the new file** (derive from what SpeedometerScreen actually uses):
```dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; // HapticFeedback
import 'dart:async';
import 'dart:math' as math;
import 'package:wakelock_plus/wakelock_plus.dart';
import 'package:flutter_overlay_window/flutter_overlay_window.dart';
import 'package:bg_launcher/bg_launcher.dart';
import '../config/speed_unit.dart';
import '../config/color_themes.dart';
import '../config/timing_constants.dart';
import '../config/overlay_constants.dart';
import '../models/overlay_message.dart';
import '../models/processed_gps_data.dart';
import '../services/gps_data_manager.dart';
import '../services/logger.dart';
```

**Do NOT include** in this file:
- `void main()` — stays in main.dart
- `void overlayMain()` — stays in main.dart
- `class SpeedoApp` — stays in main.dart
- `class OverlaySpeedometer` — goes to overlay_screen.dart in Task 2

**Critical: preserve ALL business logic, method signatures, and widget structure exactly.** This is a pure file move, not a refactor. Every line of SpeedometerScreen code must appear in the new file unchanged (except import paths).

2. Remove SpeedometerScreen class and _SpeedometerScreenState from main.dart. Leave only: imports, main(), overlayMain(), SpeedoApp, and OverlaySpeedometer (OverlaySpeedometer will be moved in Task 2).

3. Update main.dart imports to add:
```dart
import 'screens/speedometer_screen.dart';
```

4. Verify main.dart still references SpeedometerScreen correctly in SpeedoApp.build().
- Run `flutter analyze` — zero errors - Verify SpeedometerScreen class exists in lib/screens/speedometer_screen.dart - Verify SpeedometerScreen class does NOT exist in lib/main.dart - Verify main.dart still has SpeedoApp referencing SpeedometerScreen SpeedometerScreen fully extracted to screens/speedometer_screen.dart with all state, methods, and layout builders. main.dart imports it correctly. App compiles. Task 2: Extract OverlaySpeedometer to screens/overlay_screen.dart and slim down main.dart lib/screens/overlay_screen.dart lib/main.dart 1. Create `lib/screens/overlay_screen.dart` by extracting the `OverlaySpeedometer` widget class and its `_OverlaySpeedometerState` class from main.dart.
**What to move:**
- `class OverlaySpeedometer extends StatefulWidget` and its state
- All state variables: _speedText, _unitText, _headingText, _heading, _currentThemeIndex, _systemScreenWidth, _overlayWidth, _overlayHeight
- All methods: _getSystemScreenSize(), _listenToMainAppMessages(), build()
- The entire gesture detection layer and overlay UI

**Imports needed in the new file:**
```dart
import 'package:flutter/material.dart';
import 'dart:math' as math;
import 'package:flutter_overlay_window/flutter_overlay_window.dart';
import '../config/color_themes.dart';
import '../config/overlay_constants.dart';
import '../models/overlay_message.dart';
import '../services/logger.dart';
```

**Critical: preserve ALL widget structure, gesture handling, and overlay communication exactly.** Pure file move.

2. Remove OverlaySpeedometer class and _OverlaySpeedometerState from main.dart.

3. Update main.dart to add import and reference overlay_screen.dart in overlayMain():
```dart
import 'screens/overlay_screen.dart';
```

4. **Clean up main.dart** to be a slim entry point. After extraction, main.dart should contain ONLY:
- Package imports (flutter/material.dart, flutter/foundation.dart)
- Local imports (screens/speedometer_screen.dart, screens/overlay_screen.dart, services/logger.dart)
- `void main()` function
- `@pragma("vm:entry-point") void overlayMain()` function
- `class SpeedoApp extends StatelessWidget`

The file should be approximately 40-55 lines. Remove any now-unused imports (dart:async, wakelock_plus, bg_launcher, speed_units, color_themes, gps_data_manager, dart:math, flutter/services.dart — these are all used by SpeedometerScreen which is now in its own file).

5. Verify the overlayMain() function references OverlaySpeedometer correctly.
- Run `flutter analyze` — zero errors - Verify OverlaySpeedometer class exists in lib/screens/overlay_screen.dart - Verify OverlaySpeedometer class does NOT exist in lib/main.dart - Verify main.dart is under 60 lines - Verify main.dart contains only: main(), overlayMain(), SpeedoApp class - Grep for `class ` in main.dart — should find only SpeedoApp OverlaySpeedometer fully extracted to screens/overlay_screen.dart. main.dart slimmed to ~50 lines containing only entry points and SpeedoApp widget. All imports correct. App compiles with zero errors. Complete Phase 1 restructure: monolithic main.dart split into modular file structure with extracted models, typed overlay messages, centralized constants, and proper logger. 1. Build and run the app on a physical Android device: `flutter run` 2. Verify speed display works (shows current GPS speed or '--' when stationary) 3. Tap the speed number to cycle through themes (Yuzuki, Yuuparo, Yuzuki Light, Yuuparo Light) 4. Tap the unit label to cycle units (km/h, mph, kts) 5. Tap the compass/navigation area to launch the floating overlay window 6. Verify overlay shows speed and heading data 7. Long-press the overlay to close it 8. Rotate device to verify landscape layout works 9. Check debug console for Logger output format (colored tags, timestamps, caller names) Type "approved" if all functionality works identically to before restructure, or describe any issues. After both tasks complete:
  1. flutter analyze returns zero errors
  2. main.dart is under 60 lines, containing only entry points and SpeedoApp
  3. SpeedometerScreen lives in lib/screens/speedometer_screen.dart
  4. OverlaySpeedometer lives in lib/screens/overlay_screen.dart
  5. No widget classes remain in main.dart except SpeedoApp
  6. All imports resolve correctly (no "Target of URI doesn't exist" errors)
  7. Grep for class SpeedometerScreen — found only in screens/speedometer_screen.dart
  8. Grep for class OverlaySpeedometer — found only in screens/overlay_screen.dart

Requirements coverage: ORG-07 (SpeedometerScreen extracted), ORG-08 (OverlaySpeedometer extracted), ORG-01 (complete — all directories populated)

<success_criteria>

  • App compiles cleanly with flutter analyze showing zero errors
  • main.dart is a slim entry point under 60 lines
  • All screen widgets live in dedicated files under screens/
  • Combined with Plan 01, ALL Phase 1 requirements (ORG-01 through ORG-08) are satisfied
  • App runs on physical device with identical behavior to pre-restructure </success_criteria>
After completion, create `.planning/phases/01-foundation/01-02-SUMMARY.md`