mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-21 18:41:14 +00:00
08451df027
Phase 6 (Verification): smoke run green (format gate + 200/200 unit + integration smoke). verification_report.md captures metric deltas vs Phase 0 baseline; all 5 ACs met, all 4 constraints honored, 0 regressions. Phase 7 (Documentation): - module-layout.md: corrected DataAccess->Common dependency (was mistakenly documented as "Imports from: (none)" by prior AZ-315 baseline; csproj reference + 7 import sites have actually been there since AZ-309). - architecture_compliance_baseline.md: F5 entry revised to reflect the actual layering invariant (one-way: Common MUST NOT import from DataAccess, but DataAccess MAY import from Common). - 00_discovery.md: added "Updates Since Baseline" section enumerating the AZ-309 split + AZ-350 27-change run + AZ-372 tooling additions; original tree kept as a 2026-05-10 snapshot. FINAL_report: complete run summary (10 batches, 27 tasks, 3 K=3 cumulative reviews, baseline->final metric table, remaining items, lessons learned). Autodev state: advance Step 8 -> Step 9 (New Task); sub_step reset to phase 0 awaiting-invocation. Co-authored-by: Cursor <cursoragent@cursor.com>
12 KiB
12 KiB
Codebase Discovery
Directory Tree
satellite-provider/
├── SatelliteProvider.sln
├── global.json
├── docker-compose.yml
├── docker-compose.tests.yml
├── goal.md
├── README.md
├── AGENTS.md
├── .woodpecker/
│ ├── 01-test.yml
│ └── 02-build-push.yml
├── SatelliteProvider.Api/
│ ├── Dockerfile
│ ├── Program.cs
│ ├── SatelliteProvider.Api.csproj
│ ├── Properties/launchSettings.json
│ ├── appsettings.json
│ └── appsettings.Development.json
├── SatelliteProvider.Common/
│ ├── SatelliteProvider.Common.csproj
│ ├── Configs/
│ │ ├── DatabaseConfig.cs
│ │ ├── MapConfig.cs
│ │ ├── ProcessingConfig.cs
│ │ └── StorageConfig.cs
│ ├── DTO/
│ │ ├── CreateRouteRequest.cs
│ │ ├── Direction.cs
│ │ ├── GeoPoint.cs
│ │ ├── GeofencePolygon.cs
│ │ ├── RegionRequest.cs
│ │ ├── RegionStatusResponse.cs
│ │ ├── RoutePoint.cs
│ │ ├── RoutePointDto.cs
│ │ ├── RouteResponse.cs
│ │ ├── SatTile.cs
│ │ └── TileMetadata.cs
│ ├── Interfaces/
│ │ ├── IRegionRequestQueue.cs
│ │ ├── IRegionService.cs
│ │ ├── IRouteService.cs
│ │ ├── ISatelliteDownloader.cs
│ │ └── ITileService.cs
│ └── Utils/
│ └── GeoUtils.cs
├── SatelliteProvider.DataAccess/
│ ├── SatelliteProvider.DataAccess.csproj
│ ├── DatabaseMigrator.cs
│ ├── Migrations/
│ │ ├── 001_CreateTilesTable.sql
│ │ ├── 002_CreateRegionsTable.sql
│ │ ├── 003_CreateIndexes.sql
│ │ ├── 004_AddVersionColumn.sql
│ │ ├── 005_CreateRoutesTables.sql
│ │ ├── 006_AddStitchTilesToRegions.sql
│ │ ├── 007_AddRouteMapFields.sql
│ │ ├── 008_AddGeofenceFlagToRouteRegions.sql
│ │ ├── 009_AddGeofencePolygonIndex.sql
│ │ ├── 010_AddTilesZipToRoutes.sql
│ │ └── 011_AddTileCoordinates.sql
│ ├── Models/
│ │ ├── RegionEntity.cs
│ │ ├── RouteEntity.cs
│ │ ├── RoutePointEntity.cs
│ │ └── TileEntity.cs
│ └── Repositories/
│ ├── IRegionRepository.cs
│ ├── IRouteRepository.cs
│ ├── ITileRepository.cs
│ ├── RegionRepository.cs
│ ├── RouteRepository.cs
│ └── TileRepository.cs
├── SatelliteProvider.Services/
│ ├── SatelliteProvider.Services.csproj
│ ├── GoogleMapsDownloaderV2.cs
│ ├── RegionProcessingService.cs
│ ├── RegionRequestQueue.cs
│ ├── RegionService.cs
│ ├── RouteProcessingService.cs
│ ├── RouteService.cs
│ └── TileService.cs
├── SatelliteProvider.Tests/
│ ├── SatelliteProvider.Tests.csproj
│ ├── GoogleMapsDownloaderTests.cs
│ └── appsettings.json
└── SatelliteProvider.IntegrationTests/
├── SatelliteProvider.IntegrationTests.csproj
├── Dockerfile
├── Program.cs
├── Models.cs
├── BasicRouteTests.cs
├── ComplexRouteTests.cs
├── ExtendedRouteTests.cs
├── RegionTests.cs
├── TileTests.cs
└── RouteTestHelpers.cs
Tech Stack
| Category | Technology | Version |
|---|---|---|
| Language | C# | 12 (.NET 8.0) |
| Framework | ASP.NET Core (Minimal API) | 8.0 |
| Database | PostgreSQL | 16 (Docker image) |
| ORM/Data Access | Dapper | 2.1.35 |
| DB Migrations | DbUp (PostgreSQL) | 6.0.3 |
| Logging | Serilog (Console + File) | 8.0.3 |
| Image Processing | SixLabors.ImageSharp | 3.1.11 |
| JSON Serialization | Newtonsoft.Json + System.Text.Json | 13.0.4 |
| API Docs | Swagger / Swashbuckle | 6.6.2 |
| HTTP Client | IHttpClientFactory | built-in |
| Containerization | Docker (multi-stage) | - |
| Orchestration | Docker Compose | - |
| CI/CD | Woodpecker CI | - |
| Unit Testing | xUnit + Moq + FluentAssertions | 2.5.3 / 4.20.72 / 8.8.0 |
| Integration Testing | Console app (custom harness) | - |
| SDK | .NET 8.0 (latestMinor rollForward) | 8.0.0+ |
Dependency Graph
Project References
SatelliteProvider.Common (leaf — no project references)
SatelliteProvider.DataAccess (leaf — no project references; NuGet: Dapper, Npgsql, DbUp)
SatelliteProvider.Services → Common, DataAccess
SatelliteProvider.Api → Common, DataAccess, Services
SatelliteProvider.Tests → Services, Common
SatelliteProvider.IntegrationTests (standalone console app, no project references)
Mermaid Dependency Diagram
graph TD
Api[SatelliteProvider.Api] --> Services[SatelliteProvider.Services]
Api --> DataAccess[SatelliteProvider.DataAccess]
Api --> Common[SatelliteProvider.Common]
Services --> DataAccess
Services --> Common
Tests[SatelliteProvider.Tests] --> Services
Tests --> Common
IntTests[SatelliteProvider.IntegrationTests] -.->|HTTP calls| Api
Topological Processing Order
Leaf modules first, then dependent modules:
- SatelliteProvider.Common — DTOs, interfaces, configs, geo utilities (no internal dependencies)
- SatelliteProvider.DataAccess — entities, repositories, migrations (no project dependencies)
- SatelliteProvider.Services — business logic (depends on Common + DataAccess)
- SatelliteProvider.Api — web layer, DI, endpoints (depends on all above)
- SatelliteProvider.Tests — unit tests (depends on Services + Common)
- SatelliteProvider.IntegrationTests — integration tests via HTTP (standalone)
Entry Points
- Application entry:
SatelliteProvider.Api/Program.cs— minimal API startup, DI registration, DB migration, endpoint mapping - Background services:
RegionProcessingService(queue consumer),RouteProcessingService(polling loop) - Integration test entry:
SatelliteProvider.IntegrationTests/Program.cs
Leaf Modules
SatelliteProvider.Common/Configs/*— configuration POCOsSatelliteProvider.Common/DTO/*— data transfer objectsSatelliteProvider.Common/Interfaces/*— service contractsSatelliteProvider.Common/Utils/GeoUtils.cs— static geo math utilitiesSatelliteProvider.DataAccess/Models/*— database entity classesSatelliteProvider.DataAccess/Migrations/*— SQL migration scripts
Cycles
No dependency cycles detected. The dependency graph is a clean DAG.
External Integrations
| Integration | Module | Protocol |
|---|---|---|
| Google Maps Tile API | GoogleMapsDownloaderV2 | HTTPS (tile.googleapis.com, mt*.google.com) |
| PostgreSQL | All repositories | TCP (Npgsql, port 5432) |
| File system (tiles) | StorageConfig, TileService, GoogleMapsDownloaderV2 | Local FS (./tiles/) |
| File system (output) | RegionService, RouteProcessingService | Local FS (./ready/) |
| File system (logs) | Serilog | Local FS (./logs/) |
Existing Documentation
README.md— comprehensive API docs, architecture overview, configuration guideAGENTS.md— agent-oriented documentation with architecture details and conventionsgoal.md— original requirements and TODO items- Swagger/OpenAPI — auto-generated at runtime (
/swagger)
Test Structure
- Unit tests:
SatelliteProvider.Tests/— xUnit, currently contains only a dummy test (DummyTests.Dummy_ShouldWork) - Integration tests:
SatelliteProvider.IntegrationTests/— console app that runs against a live API+DB instance in Docker. Tests cover tile downloads, region requests, route creation with intermediate points, geofencing, extended routes with map requests.
CI/CD
- Woodpecker CI pipelines in
.woodpecker/:01-test.yml: runsdotnet restore+dotnet teston push/PR to dev/stage/main (ARM64)02-build-push.yml: builds Docker image and pushes to private registry (depends on 01-test, ARM64 matrix with AMD64 slot commented out)
Updates Since Baseline
Treat the directory tree, dependency listing, and test-structure section above as a 2026-05-10 snapshot. Refer to module-layout.md for the current authoritative layout. Material changes since baseline:
2026-05-10 — AZ-309 (02-coupling-refactoring)
SatelliteProvider.Services/was split into three csprojs:SatelliteProvider.Services.TileDownloader,SatelliteProvider.Services.RegionProcessing,SatelliteProvider.Services.RouteManagement. Cross-sibling calls now flow only through interfaces inSatelliteProvider.Common.Interfaces.RateLimitExceptionmoved from Services intoSatelliteProvider.Common.Exceptions.- Per-component DI extension methods (
AddTileDownloader,AddRegionProcessing,AddRouteManagement) now own their registrations;Program.cscalls them.
2026-05-11 — AZ-350 (03-code-quality-refactoring), 27 changes C01..C27
- Format / static-analysis tooling added (AZ-372 / C19):
.editorconfigat repo root:indent_style=space,indent_size=4,end_of_line=lf,charset=utf-8(no BOM),trim_trailing_whitespace=true,insert_final_newline=true, file-scoped namespaces.Directory.Build.propsenablesMicrosoft.CodeAnalysis.NetAnalyzersrepository-wide; CA1001, CA1051, CA1816, CA2227 elevated to warning.- Coverlet (
coverlet.collector) wired intoSatelliteProvider.Tests;dotnet test --collect:"XPlat Code Coverage"writescobertura.xmltoTestResults/. scripts/run-tests.shrunsdotnet format whitespace --verify-no-changesas Step 0 (gating);--unit-only,--smoke,--fullmodes documented.
- HTTP / DI hardening:
IExceptionHandler-basedGlobalExceptionHandlersanitizes 5xx ProblemDetails (AZ-353 / C03).- Permissive CORS replaced with strict-by-default policy (AZ-354 / C04); permissive policy is opt-in per
CorsConfig.AllowAnyOriginand warns in production. - Stub endpoints
/api/satellite/tiles/mgrsand/api/satellite/uploadnow return HTTP 501 instead of 500 (AZ-356 / C05). - Idempotent POST contract for
/api/satellite/requestand/api/satellite/routereturns the existing resource on duplicate id without re-enqueueing (AZ-362 / C09). - Typed HttpClient
GoogleMapsTilesregistered in DI (AZ-374 / C21).
- Domain model cleanup:
RegionStatusandRoutePointTypeenums replace string status fields end-to-end with case-insensitive parse + lowercase write (AZ-370 / C17).- Tile
VersionandMapsVersiondeprecated (AZ-357 / C06, AZ-373 / C20); migration 012 dedupes existing rows and reshapes the unique index to(latitude, longitude, tile_zoom, tile_size_meters).
- Algorithmic / structural cleanup:
RouteProcessingServicegod-class decomposed (AZ-364 / C11);RouteService.CreateRouteAsyncdecomposed (AZ-365 / C12);IServiceProviderlookups replaced with explicit dependencies (AZ-360 / C08);RegionServicecatch ladder consolidated (AZ-359 / C07).- Shared helpers extracted:
TileCsvWriter(AZ-368 / C15),TileGridStitcher(AZ-367 / C14), Haversine + filename parser (AZ-366 / C13). - Inline DTOs moved out of
Program.csintoCommon.DTO(AZ-369 / C16). - Repository
ColumnListconstants extracted (AZ-379 / C26); per-cellFirstOrDefaulttile lookup replaced withHashSetmembership (AZ-375 / C22); Earth + tile-pixel constants consolidated toGeoUtilsandMapConfig.DefaultTileSizePixels(AZ-377 / C24). - Dead code removed:
FindExistingTileAsync(AZ-376 / C23),CalculatePolygonDiagonalDistance(AZ-380 / C27), unused write-only counters inRegionRequestQueue(AZ-363 / C10). - Empty catch in
ExtractTileCoordinatesFromFilenamereplaced with logging + sentinel return (AZ-352 / C02); null logger inDatabaseMigratorfixed (AZ-351 / C01). - Magic numbers promoted to
ProcessingConfig/MapConfig(AZ-371 / C18). - Unused repo logger fields removed from
RegionRepositoryandRouteRepository;TileRepositorykeeps its logger and emits slow-query warnings ≥ 500ms (AZ-378 / C25).
- Test growth: 37 unit tests → 200 unit tests (per AZ-37x batch test sweeps); smoke run extended with AZ-353/AZ-356/AZ-357/AZ-362/SEC-01..04/CORS scenarios.
For the authoritative current layout see _docs/02_document/module-layout.md. For the per-batch detail see _docs/03_implementation/batch_*_report.md and _docs/03_implementation/reviews/.