Files
satellite-provider/plan.md
T
2025-11-01 15:32:52 +01:00

26 KiB

Satellite Provider Service - Implementation Plan

Executive Summary

This document outlines the detailed implementation plan for the Satellite Provider Service, which downloads satellite map tiles from Google Maps, stores them with metadata in PostgreSQL, and provides an API for requesting and retrieving map regions.

Current Implementation Status (Updated 2025-11-01)

Completed Features (Phases 1-7)

  • Database Layer: PostgreSQL with Dapper ORM, DbUp migrations
  • Tile Management: Download, cache, and store satellite tiles with year-based versioning
  • Region Processing: Background queue processing with image stitching
  • API Endpoints: Tile download, region request, and status endpoints
  • Docker Deployment: Full containerization with docker-compose
  • Integration Tests: Console-based test suite
  • Documentation: Comprehensive README with API docs

In Progress (Phase 8)

  • Route Planning: Split routes into overlapping regions with 200m spacing (NEW REQUIREMENT)

Key Enhancements Implemented

  1. Year-Based Tile Versioning: Automatic tile refresh each calendar year
  2. Image Stitching: Combines tiles into seamless regional images with coordinate markers
  3. Comprehensive Error Handling: Rate limiting, timeouts, network errors
  4. Rich Summary Reports: Detailed statistics and metadata for each region

1. Code Analysis

1.1 Legacy Code Comparison

Legacy Code (Azaion.Common/Services/SatelliteDownloader.cs):

  • Downloads tiles at 256x256 pixels (Google Maps standard)
  • Composes tiles into one large image
  • Splits and resizes to 512x512 TIFF files
  • Uses MediatR for status updates
  • Stores tiles in memory using ConcurrentDictionary
  • Session-based authentication with Google Maps API

Current Code (SatelliteProvider.Services/GoogleMapsDownloader.cs):

  • Downloads tiles at 256x256 pixels
  • Saves tiles directly to disk as JPG files
  • Simpler implementation without composing/splitting
  • Session-based authentication with Google Maps API
  • Uses concurrent queue for downloading

Decision: Use current code as base. It's simpler and more aligned with requirements (store tiles "as is"). The legacy code's image composition and resizing is unnecessary overhead for our use case.

1.2 Current Solution Structure

SatelliteProvider/
├── SatelliteProvider.Api          # Web API (ASP.NET 8.0)
├── SatelliteProvider.Common       # DTOs, interfaces, utilities
├── SatelliteProvider.Services     # Business logic (GoogleMapsDownloader)
└── SatelliteProvider.Tests        # Unit tests (XUnit)

1.3 Gap Analysis

Missing Components:

  1. Database layer (Dapper + PostgreSQL)
  2. Database migrations (DbUp)
  3. Tile metadata storage/retrieval
  4. Region request processing with background jobs
  5. File system management for /tiles and /ready directories
  6. API endpoints for region requests
  7. Docker and docker-compose configuration
  8. Integration tests as a separate console application

2. Architecture Design

2.1 Solution Structure (Updated)

SatelliteProvider/
├── SatelliteProvider.Api                  # Web API
├── SatelliteProvider.Common               # Shared DTOs, interfaces, utilities
├── SatelliteProvider.Services             # Business logic services
├── SatelliteProvider.DataAccess           # Database access layer (NEW)
├── SatelliteProvider.Tests                # Unit tests
├── SatelliteProvider.IntegrationTests     # Integration tests console app (NEW)
├── docker-compose.svc.yml                 # Service + dependencies (NEW)
└── docker-compose.tests.yml               # Tests + service + dependencies (NEW)

2.2 Data Model

Tiles Table Schema:

CREATE TABLE tiles (
    id UUID PRIMARY KEY,
    zoom_level INT NOT NULL,
    latitude DOUBLE PRECISION NOT NULL,
    longitude DOUBLE PRECISION NOT NULL,
    tile_size_meters DOUBLE PRECISION NOT NULL,
    tile_size_pixels INT NOT NULL,
    image_type VARCHAR(10) NOT NULL,
    maps_version VARCHAR(50),
    file_path VARCHAR(500) NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_tiles_composite ON tiles(latitude, longitude, tile_size_meters);
CREATE INDEX idx_tiles_zoom ON tiles(zoom_level);

Regions Table Schema:

CREATE TABLE regions (
    id UUID PRIMARY KEY,
    latitude DOUBLE PRECISION NOT NULL,
    longitude DOUBLE PRECISION NOT NULL,
    size_meters DOUBLE PRECISION NOT NULL,
    zoom_level INT NOT NULL,
    status VARCHAR(20) NOT NULL,
    csv_file_path VARCHAR(500),
    summary_file_path VARCHAR(500),
    tiles_downloaded INT DEFAULT 0,
    tiles_reused INT DEFAULT 0,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_regions_status ON regions(status);

Routes Table Schema (Phase 8 - New):

CREATE TABLE routes (
    id UUID PRIMARY KEY,
    name VARCHAR(200),
    description TEXT,
    total_distance_meters DOUBLE PRECISION NOT NULL,
    total_points INT NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE route_points (
    id UUID PRIMARY KEY,
    route_id UUID NOT NULL REFERENCES routes(id) ON DELETE CASCADE,
    sequence_number INT NOT NULL,
    latitude DOUBLE PRECISION NOT NULL,
    longitude DOUBLE PRECISION NOT NULL,
    point_type VARCHAR(20) NOT NULL, -- 'start', 'end', 'intermediate'
    segment_index INT NOT NULL,
    distance_from_previous DOUBLE PRECISION,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(route_id, sequence_number)
);

CREATE INDEX idx_route_points_route ON route_points(route_id, sequence_number);
CREATE INDEX idx_route_points_coords ON route_points(latitude, longitude);

2.3 Background Processing

In-Memory Queue Implementation:

  • Use System.Threading.Channels for thread-safe, async-friendly queue
  • Hosted service (IHostedService) to process queue items
  • Status tracking in database (processing, completed, failed)
  • Future migration path: Azure Storage Queue, AWS SQS, or RabbitMQ

2.4 Google Maps Tile Details

Tile Size:

  • Google Maps returns tiles at 256x256 pixels (standard)
  • We will store tiles as-is from Google Maps
  • Store tile_size_pixels = 256 in database

Maps Version:

  • Google Maps doesn't expose explicit version via API
  • Solution: Use download timestamp as version identifier
  • Store as maps_version = "downloaded_YYYY-MM-DD"
  • Consider ETags if available in HTTP response headers

Image Format:

  • Google Maps returns JPEG for satellite tiles
  • Store as JPG with image_type = "jpg"

3. Implementation Plan

Phase 1: Database Layer (Priority: High) COMPLETED

Task 1.1: Create DataAccess Project

  • Created project SatelliteProvider.DataAccess
  • Added Dapper NuGet package
  • Added Npgsql NuGet package for PostgreSQL support
  • Added DbUp NuGet package for migrations

Task 1.2: Implement Database Migrations

  • Created Migrations folder in DataAccess project
  • Script 001: Create tiles table
  • Script 002: Create regions table
  • Script 003: Create indexes
  • Script 004: Add version column for year-based versioning
  • Implemented DbUp migration runner in Program.cs startup

Task 1.3: Implement Repository Pattern

  • Created ITileRepository interface
  • Created TileRepository class implementing Dapper queries
  • Created IRegionRepository interface
  • Created RegionRepository class implementing Dapper queries
  • Added connection string management in appsettings.json

Task 1.4: Configuration

  • Added PostgreSQL connection string to appsettings.json
  • Added PostgreSQL connection string to appsettings.Development.json
  • Created configuration classes in Common project

Phase 2: Enhanced Tile Downloading and Storage (Priority: High) COMPLETED

Task 2.1: Update GoogleMapsDownloader

  • Created GoogleMapsDownloaderV2 with enhanced functionality
  • Returns list of downloaded tile metadata
  • Calculates tile size in meters (based on zoom level)
  • Stores maps version (download timestamp format)
  • Implemented error handling and retry logic with exponential backoff
  • Added rate limit exception handling

Task 2.2: Implement Tile Service

  • Created ITileService interface in Common
  • Created TileService class in Services
  • Implemented DownloadAndStoreTilesAsync(lat, lon, size, zoom)
  • Checks database for existing tiles before downloading (with year-based versioning)
  • Saves tile metadata to database after download
  • Returns list of tile paths and metadata

Task 2.3: File System Management

  • Configured /tiles directory path from appsettings.json
  • Directory creation on startup implemented
  • Implemented tile naming convention: tile_{zoom}_{x}_{y}_{timestamp}.jpg
  • File path storage in database

Phase 3: Background Processing System (Priority: High) COMPLETED

Task 3.1: Create Region Request Queue

  • Created IRegionRequestQueue interface
  • Implemented using System.Threading.Channels
  • Thread-safe enqueue/dequeue operations
  • Capacity limits and overflow handling

Task 3.2: Create Background Worker

  • Implemented RegionProcessingService : IHostedService
  • Dequeues region requests
  • Processes each region (download tiles, create CSV, create summary, stitch images)
  • Updates region status in database (queued → processing → completed/failed)
  • Error handling with specific exception types (RateLimitException, HttpRequestException)
  • Timeout handling (5 minutes per region)

Task 3.3: Implement Region Service

  • Created IRegionService interface
  • Created RegionService class
  • Method: RequestRegionAsync(id, lat, lon, size) - adds to queue and database
  • Method: GetRegionStatusAsync(id) - returns status and file paths
  • Method: ProcessRegionAsync(id) - called by background worker

Task 3.4: CSV and Summary File Generation

  • Created /ready directory management
  • Implemented CSV writer with tile coordinates and file paths
  • Generates region_{id}_ready.csv with ordered tiles (top-left to bottom-right)
  • Generates region_{id}_summary.txt with comprehensive statistics
  • Generates region_{id}_stitched.jpg with combined satellite imagery
  • Includes error summaries for failed regions

Phase 4: API Endpoints (Priority: High) COMPLETED

Task 4.1: Remove Old Endpoints ⚠️ PARTIALLY DONE

  • ⚠️ Some legacy endpoints still exist (GetSatelliteTilesByLatLon, GetSatelliteTilesByMgrs, UploadImage)
  • Main functionality implemented with new endpoints

Task 4.2: Implement Region Request Endpoint

  • POST /api/satellite/request
  • Request body: { id: UUID, latitude: double, longitude: double, sizeMeters: double, zoomLevel: int }
  • Validation: size between 100-10000 meters
  • Returns: { id: UUID, status: "queued", ... }
  • Enqueues region processing

Task 4.3: Implement Region Status Endpoint

  • GET /api/satellite/region/{id}
  • Returns: { id: UUID, status: string, csvPath: string?, summaryPath: string?, tilesDownloaded: int, tilesReused: int }
  • Status values: "queued", "processing", "completed", "failed"

Task 4.4: OpenAPI/Swagger Documentation

  • Updated Swagger configuration
  • Added endpoint descriptions
  • Documented request/response models
  • Custom operation filters for parameter descriptions

Phase 5: Docker Configuration (Priority: Medium) COMPLETED

Task 5.1: Create Dockerfiles

  • Dockerfile for SatelliteProvider.Api
  • Dockerfile for SatelliteProvider.IntegrationTests
  • Multi-stage builds for optimization
  • Base image: mcr.microsoft.com/dotnet/aspnet:8.0

Task 5.2: Create docker-compose.yml

  • Service: api (satellite-provider-api)
  • Service: postgres (PostgreSQL 16)
  • Volume: ./tiles mounted to host
  • Volume: ./ready mounted to host
  • Volume: ./logs mounted to host
  • Network configuration
  • Environment variables for configuration
  • Health checks for dependencies

Task 5.3: Create docker-compose.tests.yml

  • Services: postgres, api, integration-tests
  • Waits for API and database readiness
  • Runs tests and exits with test results
  • Separate test environment configuration

Task 5.4: Environment Configuration

  • Development configuration (appsettings.Development.json)
  • Production configuration (appsettings.json)
  • Environment-specific settings
  • Secrets management via environment variables

Phase 6: Integration Tests (Priority: Medium) COMPLETED

Task 6.1: Create Integration Tests Project

  • Created SatelliteProvider.IntegrationTests console app project
  • Added necessary NuGet packages (XUnit, FluentAssertions, etc.)
  • Configured to run as console application
  • Setup for database and API access

Task 6.2: Implement Test Scenarios

  • TileTests: Test tile download and caching
  • RegionTests: Test region request and processing
  • Verify CSV creation and content
  • Verify summary file creation
  • Verify stitched image creation
  • Test tile reuse functionality
  • Test region status endpoint
  • Test concurrent region requests

Task 6.3: Test Data Management

  • Database cleanup before tests
  • Test data validation
  • Isolated test environments via Docker

Task 6.4: CI/CD Integration

  • Docker-based test execution configured
  • CI/CD pipeline integration (depends on CI/CD setup)
  • Code coverage analysis (optional enhancement)

Phase 7: Additional Features and Improvements (Priority: Low) COMPLETED

Task 7.1: Monitoring and Logging

  • Structured logging with Serilog
  • File and console logging
  • Performance tracking in logs
  • Error tracking with context

Task 7.2: Caching Strategy

  • Implemented year-based versioning for automatic tile refresh
  • Tile reuse within the same year
  • Historical tile preservation

Task 7.3: API Rate Limiting

  • Rate limiting for API endpoints (not implemented)
  • Google Maps API error handling with retry logic
  • Exponential backoff for failed requests

Task 7.4: Documentation

  • Comprehensive README.md with API documentation
  • Configuration guide
  • Docker deployment instructions
  • Year-based versioning strategy documented

4. Technical Specifications

4.1 Technology Stack

  • Runtime: .NET 8.0
  • Web Framework: ASP.NET Core Web API
  • ORM: Dapper 2.1.35
  • Database: PostgreSQL (latest stable)
  • Migrations: DbUp
  • Testing: XUnit, Moq, FluentAssertions
  • Containerization: Docker, Docker Compose
  • Image Processing: SixLabors.ImageSharp 3.1.11
  • Logging: Microsoft.Extensions.Logging

4.2 NuGet Packages to Add

SatelliteProvider.DataAccess:

  • Dapper (2.1.35)
  • Npgsql (latest stable)
  • DbUp (latest stable)
  • Microsoft.Extensions.Configuration.Abstractions

SatelliteProvider.Api:

  • Npgsql (for PostgreSQL connection)

SatelliteProvider.IntegrationTests:

  • All existing test packages
  • System.CommandLine (for console app)
  • Testcontainers (optional, for Docker-based integration tests)

4.3 Configuration Structure

appsettings.json:

{
  "ConnectionStrings": {
    "DefaultConnection": "Host=localhost;Database=satelliteprovider;Username=postgres;Password=postgres"
  },
  "MapConfig": {
    "Service": "GoogleMaps",
    "ApiKey": "YOUR_API_KEY_HERE"
  },
  "StorageConfig": {
    "TilesDirectory": "/tiles",
    "ReadyDirectory": "/ready"
  },
  "ProcessingConfig": {
    "MaxConcurrentDownloads": 4,
    "DefaultZoomLevel": 20,
    "QueueCapacity": 100
  }
}

4.4 API Endpoints Summary

Method Endpoint Description Status
POST /api/satellite/tiles/download Download single tile at coordinates Implemented
POST /api/satellite/request Request tiles for a region Implemented
GET /api/satellite/region/{id} Get region status and file paths Implemented
POST /api/satellite/route Plan route and split into regions To be implemented
GET /api/satellite/route/{id} Get route information with points To be implemented

4.5 File Naming Conventions

Tiles:

/tiles/tile_{zoom}_{x}_{y}_{timestamp}.jpg
Example: /tiles/tile_20_12345_67890_20231015143022.jpg

CSV Files:

/ready/region_{id}_ready.csv
Example: /ready/region_550e8400-e29b-41d4-a716-446655440000_ready.csv

Summary Files:

/ready/region_{id}_summary.txt
Example: /ready/region_550e8400-e29b-41d4-a716-446655440000_summary.txt

4.6 CSV File Format

latitude,longitude,file_path
37.7749,-122.4194,/tiles/tile_20_12345_67890_20231015143022.jpg
37.7750,-122.4194,/tiles/tile_20_12346_67890_20231015143023.jpg

Rows ordered from top-left to bottom-right covering the requested region.

4.7 Summary File Format

Region Processing Summary
========================
Region ID: 550e8400-e29b-41d4-a716-446655440000
Center: 37.7749, -122.4194
Size: 500 meters
Zoom Level: 20

Processing Statistics:
- Tiles Downloaded: 45
- Tiles Reused from Cache: 12
- Total Tiles: 57
- Processing Time: 12.5 seconds
- Started: 2023-10-15 14:30:15
- Completed: 2023-10-15 14:30:28

Files Created:
- CSV: /ready/region_550e8400-e29b-41d4-a716-446655440000_ready.csv
- Summary: /ready/region_550e8400-e29b-41d4-a716-446655440000_summary.txt

5. Testing Strategy

5.1 Unit Tests

  • Test GeoUtils calculations
  • Test tile coordinate conversions
  • Test repository methods (with mocked database)
  • Test service business logic

5.2 Integration Tests

  • End-to-end region request flow
  • Database operations
  • File system operations
  • API endpoint testing
  • Background processing

5.3 Test Coverage Goals

  • Minimum 80% code coverage
  • 100% coverage for critical paths (downloading, storage, region processing)

6. Deployment Strategy

6.1 Development Environment

docker-compose -f docker-compose.svc.yml up

6.2 Running Integration Tests

docker-compose -f docker-compose.tests.yml up --abort-on-container-exit

6.3 Production Deployment

  • Use docker-compose.svc.yml as base
  • Override with production-specific configuration
  • Configure volumes for persistent storage
  • Set up backup strategy for PostgreSQL
  • Configure SSL/TLS for API
  • Set up monitoring and alerting

7. Security Considerations

  1. API Key Management: Store Google Maps API key in environment variables or secrets manager
  2. Database Security: Use strong passwords, restrict network access
  3. Input Validation: Validate all API inputs (coordinates, size limits)
  4. File System Security: Restrict write access to /tiles and /ready directories
  5. Rate Limiting: Implement to prevent abuse
  6. HTTPS: Enforce HTTPS in production

8. Performance Considerations

  1. Concurrent Downloads: Use 4 concurrent connections to Google Maps
  2. Database Indexing: Composite index on (latitude, longitude, tile_size_meters)
  3. Caching: Reuse existing tiles to minimize downloads
  4. Async Operations: All I/O operations are async
  5. Background Processing: Non-blocking region processing

9. Monitoring and Observability

  1. Logging: Structured logging for all operations
  2. Metrics: Track download counts, cache hit rates, processing times
  3. Health Checks: API and database health endpoints
  4. Error Tracking: Log errors with context for debugging

10. Future Enhancements

  1. Cloud Queue Integration: Replace in-memory queue with Azure/AWS queue
  2. CDN Integration: Serve tiles via CDN
  3. Tile Expiration: Implement automatic tile refresh
  4. Multiple Map Providers: Support for other satellite imagery providers
  5. WebSocket Support: Real-time progress updates
  6. Admin Dashboard: UI for monitoring and management
  7. Tile Stitching: API to stitch tiles into single large image

Phase 8: Route Planning Feature (Priority: High) NEW REQUIREMENT

Overview: Implement route planning functionality that splits a route into overlapping regions with intermediate points spaced no more than 200 meters apart.

Task 8.1: Database Schema for Routes

  • Create routes table to store route information
  • Create route_points table to store route points (start, end, intermediate)
  • Migration script 005: Create routes tables
  • Add indexes for efficient route querying

Task 8.2: Route Calculation Logic

  • Implement intermediate point calculation algorithm
  • Calculate distance between two points using GeoUtils
  • Generate intermediate points along the route with max 200m spacing
  • Ensure equal spacing between points

Task 8.3: Route Repository

  • Create IRouteRepository interface
  • Create RouteRepository class
  • CRUD operations for routes and route points
  • Query methods for retrieving routes with points

Task 8.4: Route Service

  • Create IRouteService interface
  • Create RouteService class
  • Method: CreateRouteAsync(points) - creates route with intermediate points
  • Method: GetRouteAsync(id) - retrieves route with all points

Task 8.5: Route API Endpoints

  • POST /api/satellite/route - create route from array of points
  • GET /api/satellite/route/{id} - get route information with intermediate points
  • Input validation (minimum 2 points, valid coordinates)
  • Return route with calculated intermediate points

Task 8.6: Integration with Region Processing

  • Each route point (including intermediate) represents a region center
  • Option to automatically request regions for all route points
  • Track processing status for route-based regions

Task 8.7: Tests

  • Unit tests for intermediate point calculation
  • Integration tests for route creation and retrieval
  • Test various scenarios (short routes < 200m, long routes > 200m, multi-segment routes)

Estimated Time: 2-3 days

11. Implementation Timeline

Total Estimated Time: 15-20 working days (Phases 1-7 completed, Phase 8 remaining)

Phase Duration Dependencies Status
Phase 1: Database Layer 2-3 days None COMPLETED
Phase 2: Enhanced Tile Downloading 2-3 days Phase 1 COMPLETED
Phase 3: Background Processing 3-4 days Phase 1, Phase 2 COMPLETED
Phase 4: API Endpoints 1-2 days Phase 3 COMPLETED
Phase 5: Docker Configuration 2-3 days Phase 4 COMPLETED
Phase 6: Integration Tests 3-4 days Phase 5 COMPLETED
Phase 7: Additional Features 2-3 days Phase 6 COMPLETED
Phase 8: Route Planning 2-3 days Phase 1, Phase 2 IN PROGRESS

Critical Path: Phase 1 → Phase 2 → Phase 3 → Phase 4 → Phase 5 → Phase 6Phase 8 (Route Planning)

12. Risk Assessment

Risk Impact Probability Mitigation
Google Maps API changes High Low Monitor API changes, version locking
API quota exceeded High Medium Implement caching, rate limiting
Disk space exhaustion Medium Medium Implement cleanup policy, monitoring
Database performance Medium Low Proper indexing, connection pooling
Concurrent processing issues Medium Low Thorough testing, proper locking

13. Success Criteria

  1. API successfully downloads and stores tiles - COMPLETED
  2. Metadata stored correctly in PostgreSQL - COMPLETED
  3. Region requests processed in background - COMPLETED
  4. CSV and summary files generated correctly - COMPLETED
  5. Tile caching works (reuses existing tiles) - COMPLETED
  6. Docker containers run successfully - COMPLETED
  7. Integration tests pass - COMPLETED
  8. API documentation complete - COMPLETED
  9. Performance meets requirements (< 30s for 1000m region) - COMPLETED
  10. Image stitching implemented - COMPLETED
  11. Route planning feature - IN PROGRESS (see Phase 8)

14. Open Questions and Decisions Made

Questions from Analysis:

  1. Legacy Code? Analyzed - Use current code as base
  2. Background Processing? In-memory queue with Channels
  3. Database Migrations? DbUp
  4. Tile Size? 256x256 pixels (Google Maps standard)
  5. Maps Version? Use download timestamp + year-based versioning
  6. Composite Key? Indexed composite key, UUID primary key
  7. Integration Tests? Separate console app project
  8. Image Stitching? Implemented with ImageSharp, generates region_{id}_stitched.jpg
  9. Tile Versioning? Year-based versioning for automatic annual refresh

New Questions for Phase 8 (Route Planning):

  1. Route Point Spacing?

    • Max 200m between consecutive points
    • Equal spacing along route segments
  2. Route Storage?

    • Store routes table with route metadata
    • Store route_points table with individual points and sequence
  3. Automatic Region Processing?

    • Decision needed: Should route creation automatically trigger region requests for all points?
    • Or: Manual trigger via separate endpoint?
  4. Route Point Metadata?

    • Track point type: start, end, or intermediate
    • Store segment information (which route segment the point belongs to)
  5. Route-Based Region Tracking?

    • Link regions to routes for progress tracking
    • Aggregate route completion status based on all region statuses

15. Next Steps

  1. Review and approve this implementation plan
  2. Set up development environment
  3. Create feature branches for each phase
  4. Begin Phase 1: Database Layer implementation
  5. Daily stand-ups to track progress
  6. Regular code reviews for each completed phase

Document Version: 2.0
Created: 2025-10-26
Last Updated: 2025-11-01
Author: AI Assistant
Status: Phases 1-7 Completed, Phase 8 (Route Planning) In Progress