Files
gps-denied-onboard/.planning/codebase/STRUCTURE.md
T
Yuzviak 2dd60a0e37 Add codebase map to .planning/codebase/
7 structured documents covering stack, integrations, architecture,
structure, conventions, testing, and concerns.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 20:26:52 +03:00

12 KiB

Codebase Structure

Analysis Date: 2026-04-01

Directory Layout

gps-denied-onboard/
├── src/
│   └── gps_denied/             # Main package
│       ├── __init__.py         # Package version
│       ├── __main__.py         # Entry point (uvicorn runner)
│       ├── app.py              # FastAPI app factory + lifespan
│       ├── config.py           # Pydantic-settings configuration classes
│       ├── api/
│       │   ├── __init__.py
│       │   ├── deps.py         # FastAPI dependency providers (singletons)
│       │   └── routers/
│       │       ├── __init__.py
│       │       └── flights.py  # All /flights/* endpoints
│       ├── core/
│       │   ├── processor.py    # FlightProcessor — main orchestrator
│       │   ├── pipeline.py     # ImageInputPipeline — image ingestion/queuing
│       │   ├── vo.py           # SequentialVisualOdometry (SuperPoint+LightGlue)
│       │   ├── satellite.py    # SatelliteDataManager (tile fetch/cache)
│       │   ├── gpr.py          # GlobalPlaceRecognition (AnyLoc/DINOv2)
│       │   ├── metric.py       # MetricRefinement (LiteSAM homography alignment)
│       │   ├── graph.py        # FactorGraphOptimizer (GTSAM/mock pose graph)
│       │   ├── chunk_manager.py # RouteChunkManager (disconnected segments)
│       │   ├── recovery.py     # FailureRecoveryCoordinator (tracking loss handling)
│       │   ├── rotation.py     # ImageRotationManager (360° sweep, heading tracking)
│       │   ├── coordinates.py  # CoordinateTransformer (ENU↔GPS, pixel→GPS)
│       │   ├── models.py       # ModelManager + MockInferenceEngine
│       │   ├── results.py      # ResultManager (DB + SSE publish)
│       │   └── sse.py          # SSEEventStreamer (per-flight async queues)
│       ├── db/
│       │   ├── __init__.py
│       │   ├── engine.py       # Async SQLAlchemy engine + session factory
│       │   ├── models.py       # ORM table definitions (8 tables)
│       │   └── repository.py   # FlightRepository DAO (all SQL operations)
│       ├── schemas/
│       │   ├── __init__.py     # GPSPoint, CameraParameters, Polygon, Geofences
│       │   ├── flight.py       # Flight CRUD request/response schemas
│       │   ├── image.py        # ImageBatch, ImageData, ProcessedBatch schemas
│       │   ├── vo.py           # Features, Matches, Motion, RelativePose
│       │   ├── gpr.py          # TileCandidate, DatabaseMatch
│       │   ├── metric.py       # AlignmentResult, ChunkAlignmentResult, Sim3Transform
│       │   ├── satellite.py    # TileCoords, TileBounds
│       │   ├── graph.py        # Pose, OptimizationResult, FactorGraphConfig
│       │   ├── chunk.py        # ChunkHandle, ChunkStatus enum
│       │   ├── rotation.py     # RotationResult, HeadingHistory
│       │   ├── model.py        # InferenceEngine base schema
│       │   └── events.py       # SSEMessage, SSEEventType, FrameProcessedEvent, etc.
│       └── utils/
│           └── mercator.py     # Slippy map tile math (lat/lon↔tile x/y/bounds)
├── _docs/
│   ├── _autopilot_state.md     # GSD planning state tracker
│   ├── 01_solution/
│   │   └── solution.md         # Master architecture document (finalized draft 06)
│   └── 02_document/
│       └── tests/              # Test scenario specifications (43 scenarios)
├── .planning/
│   └── codebase/               # GSD mapping documents (this directory)
├── .venv/                      # Python virtual environment (committed or local)
├── pyproject.toml              # Project metadata and dependencies
└── flight_data.db              # SQLite DB (runtime artifact, not committed)

Directory Purposes

src/gps_denied/:

  • Purpose: Top-level Python package; everything importable from here
  • Key files: app.py (create_app factory), config.py (all settings), __main__.py (entrypoint)

src/gps_denied/api/:

  • Purpose: HTTP API surface only — routing, request/response handling, dependency injection
  • Contains: One router (flights.py) with 9 endpoints, deps.py with 3 singleton providers
  • Key files: routers/flights.py (all endpoints), deps.py (ProcessorDep, SessionDep, RepoDep)

src/gps_denied/core/:

  • Purpose: All processing logic — state machines, algorithms, pipeline components
  • Module count: 14 files
  • Key files: processor.py (orchestrator), models.py (inference abstraction), graph.py (pose graph)
  • Note: Each component has a matching I* ABC interface defined in the same file

src/gps_denied/db/:

  • Purpose: Database access only — no business logic
  • Contains: Engine setup, ORM models, one repository class
  • Key files: models.py (8 ORM tables), repository.py (all DB operations)

src/gps_denied/schemas/:

  • Purpose: Pydantic data contracts; shared across API, core, and DB layers
  • Contains: 12 schema files covering every domain concept
  • Key files: __init__.py (GPSPoint, CameraParameters — imported everywhere), flight.py (largest — all REST schemas)

src/gps_denied/utils/:

  • Purpose: Pure utility functions with no side effects
  • Contains: mercator.py — Mercator projection math for tile coordinate conversion
  • Used by: satellite.py exclusively

_docs/:

  • Purpose: Architecture documentation and planning artifacts — not source code
  • Key files: 01_solution/solution.md (the authoritative design doc), _autopilot_state.md (GSD planning tracker)

Key File Locations

Entry Points:

  • src/gps_denied/__main__.py: Invoked by python -m gps_denied; starts uvicorn
  • src/gps_denied/app.py: create_app() factory; app module-level instance used by uvicorn

Configuration:

  • src/gps_denied/config.py: All settings via pydantic-settings; reads from .env and env vars
    • DB_URL → SQLAlchemy connection string (default: SQLite)
    • TILES_ZOOM_LEVEL, TILES_CACHE_DIR, TILES_API_KEY → satellite tile provider
    • MODEL_WEIGHTS_DIR, MODEL_SUPERPOINT_PATH, etc. → model file paths
    • RECOVERY_*, ROTATION_* → algorithm thresholds

Core Orchestration:

  • src/gps_denied/core/processor.py: FlightProcessor — only class that calls other pipeline components

Dependency Wiring:

  • src/gps_denied/api/deps.py: Single location where singletons (FlightProcessor, SSEEventStreamer) are created and wired; ProcessorDep type alias used in all routers

Database Schema:

  • src/gps_denied/db/models.py: All 8 ORM tables with cascade deletes; ground truth for DB schema

Pydantic Contracts:

  • src/gps_denied/schemas/__init__.py: GPSPoint and CameraParameters — imported by nearly every module

Naming Conventions

Files:

  • snake_case.py throughout
  • Core components named after their function: vo.py, gpr.py, metric.py, graph.py
  • Interfaces co-located with implementation in the same file (ISequentialVisualOdometry and SequentialVisualOdometry both in vo.py)

Classes:

  • Implementation classes: PascalCase noun phrases (FlightProcessor, RouteChunkManager)
  • Interfaces: I prefix + implementation name (IRouteChunkManager)
  • ORM models: suffixed with Row (FlightRow, WaypointRow)
  • Pydantic models: suffixed with Request/Response for API schemas; bare names for internal data

Functions:

  • snake_case
  • Async functions throughout API and DB layers; sync in core (except process_frame which is async)

Constants/Enums:

  • TrackingState: str, Enum with lowercase values ("normal", "lost", "recovery")
  • SSEEventType: str, Enum with snake_case values
  • ChunkStatus: str, Enum

Where to Add New Code

New API endpoint:

  • Add route function to src/gps_denied/api/routers/flights.py
  • Add request/response Pydantic models to src/gps_denied/schemas/flight.py
  • Add business logic method to src/gps_denied/core/processor.py
  • If new router prefix needed: create src/gps_denied/api/routers/{name}.py and register in app.py

New pipeline component:

  • Create src/gps_denied/core/{component_name}.py
  • Define I{ComponentName}(ABC) interface and {ComponentName} implementation in same file
  • Add schemas to src/gps_denied/schemas/{component_name}.py
  • Add component instantiation to app.py lifespan block
  • Inject via FlightProcessor.attach_components() and call from process_frame()

New database table:

  • Add {Name}Row(Base) to src/gps_denied/db/models.py
  • Add CRUD methods to src/gps_denied/db/repository.py
  • Add foreign key + relationship to FlightRow if flight-scoped

New configuration setting:

  • Add field to the appropriate BaseSettings subclass in src/gps_denied/config.py
  • Use ENV_PREFIX__FIELD_NAME env var pattern

New schema type:

  • Add to src/gps_denied/schemas/{relevant_file}.py or create new file
  • If broadly shared (like GPSPoint), add to src/gps_denied/schemas/__init__.py

Utility functions:

  • Add to src/gps_denied/utils/mercator.py if geospatial math
  • Create src/gps_denied/utils/{name}.py for other pure utilities

Special Directories

.venv/:

  • Purpose: Python virtual environment
  • Generated: Yes (via python -m venv or uv)
  • Committed: Present in tree (check .gitignore)

_docs/:

  • Purpose: Architecture docs, test specs, GSD planning artifacts
  • Generated: No (hand-authored)
  • Committed: Yes

.planning/:

  • Purpose: GSD (Get Stuff Done) planning system — phase plans, codebase maps
  • Generated: By GSD commands
  • Committed: Yes (used by CI/planning tools)

.image_storage/ (runtime):

  • Purpose: Disk storage for uploaded UAV images per flight
  • Created by: ImageInputPipeline.store_images()
  • Path: Relative to process CWD; configurable via ImageInputPipeline(storage_dir=...)

.satellite_cache/ (runtime):

  • Purpose: diskcache directory for satellite tiles
  • Created by: SatelliteDataManager.__init__()
  • Size limit: 10GB default

Module Dependency Graph (simplified)

api/routers/flights.py
    → api/deps.py
        → core/processor.py
            → core/pipeline.py       (image ingestion)
            → core/results.py        (DB + SSE publish)
            → core/sse.py            (event streaming)
            → [via attach_components]
                → core/vo.py         → core/models.py
                → core/gpr.py        → core/models.py
                → core/metric.py     → core/models.py
                → core/graph.py      (optional: gtsam)
                → core/chunk_manager.py → core/graph.py
                → core/recovery.py   → core/chunk_manager.py
                                     → core/gpr.py
                                     → core/metric.py
                → core/rotation.py
        → db/repository.py
            → db/models.py
        → core/sse.py
    → db/engine.py

core/satellite.py     (standalone — not wired into processor yet)
core/coordinates.py   (standalone — not wired into processor yet)
utils/mercator.py     → only used by core/satellite.py
schemas/*             → imported by all layers (no internal imports)
config.py             → imported by db/engine.py, and anywhere settings needed

Notably standalone (not connected to processor):

  • src/gps_denied/core/satellite.py: SatelliteDataManager — instantiated nowhere in app.py or processor.py; satellite tiles fetched inline with mock in processor.py
  • src/gps_denied/core/coordinates.py: CoordinateTransformer — not instantiated in the pipeline; convert_object_to_gps in processor returns a hardcoded stub (GPSPoint(lat=48.0, lon=37.0))

Structure analysis: 2026-04-01