mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-21 21:21:15 +00:00
af4219fce6
Step 12 (Test-Spec Sync) - cycle-update mode
- traceability-matrix: 8 AZ-500 AC rows + .NET 10 runtime
restriction supersession + Cycle-4 coverage shape note
(no new tests; ACs verified by re-running existing 78-test
suite + build pipeline + manifest grep)
Step 13 (Update Docs) - task mode
- FINAL_report, 00_discovery, architecture, module-layout,
api_program, tests_unit: .NET 8 -> .NET 10 / C# 12 -> 14 /
Swashbuckle 6.6.2 -> 10.1.7 + Microsoft.OpenApi 2.x
refactor note in api_program; Serilog.AspNetCore 8.0.3
fallback documented inline per AZ-500 Risk #4
- deployment/{containerization, ci_cd_pipeline}: Docker
aspnet/sdk:8.0 -> :10.0
- ripple_log_cycle4: empty import-graph ripple recorded
(Program.cs is entry point; ParameterDescriptionFilter only
consumed by Program.cs; csproj/global.json/Dockerfile have
no import edges)
Step 14 (Security Audit) - resume mode
- dependency_scan_cycle4: AZ-500 19-package delta scanned;
cycle-3 D1+D3 (CVE-2026-26130) closed by major-version
bump; cycle-3 D2 (Test.Sdk 17.8.0 NuGet.Frameworks flag)
carried over - explicitly out of AZ-500 scope
- security_report_cycle4: PASS_WITH_WARNINGS (only carry-over
Medium open; AZ-500 introduced 0 new Critical/High); cycle-3
static_analysis/owasp_review/infrastructure_review carried
forward unchanged (AZ-500 made no source-level edits to
those surfaces)
Step 15 (Performance Test) - perf mode, full default-param run
- perf_2026-05-12_cycle4: 7 Pass + 1 Unverified (PT-08 hit
pre-existing scripts/run-performance-tests.sh:417 grep-
pipefail bug, NOT a .NET 10 regression)
- PT-07 warm p95 = 301ms (7.7x improvement vs cycle-3 short
variant - .NET 10 pipeline + N=20 dilution); cold p95 =
2782ms (-14%); PT-06 90ms (-49%)
- AZ-500 NFR (Performance) MET for 7/8 scenarios
- Cycle-3 perf-harness leftover updated with replay #3
results; STAYS OPEN per AZ-500 Constraint (deletes only on
fully clean run)
Recommended follow-up PBIs (out of cycle-4 scope, surfaced for
the backlog):
- 1 SP fix scripts/run-performance-tests.sh:416-417 grep-
pipefail (replace grep -o ... | wc -l with grep -c ... ||
true) - unblocks PT-08 + closes the cycle-3 perf leftover
- 3 SP migrate WithOpenApi(...) callsites to ASP.NET Core 10
minimal-API metadata extensions (clears 8 ASPDEPR002
warnings; recorded in batch_01_cycle4_review.md)
- 1 SP Microsoft.OpenApi 2.x nullable cleanup (CS8604 in
ParameterDescriptionFilter.cs:25)
- 1 SP bump Microsoft.NET.Test.Sdk 17.8.0 -> 17.13.0+
(closes cycle-3 D2 NuGet.Frameworks transitive flag)
Co-authored-by: Cursor <cursoragent@cursor.com>
246 lines
13 KiB
Markdown
246 lines
13 KiB
Markdown
# 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# | 14 (.NET 10) — was C# 12 / .NET 8.0 through cycle 3 (AZ-500) |
|
|
| Framework | ASP.NET Core (Minimal API) | 10.0 — was 8.0 through cycle 3 (AZ-500) |
|
|
| 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 (Serilog.AspNetCore — fallback retained on .NET 10 per AZ-500 Risk #4: no 10.x line published; restores cleanly via netstandard 2.0) |
|
|
| Image Processing | SixLabors.ImageSharp | 3.1.11 |
|
|
| JSON Serialization | Newtonsoft.Json + System.Text.Json | 13.0.4 |
|
|
| API Docs | Swagger / Swashbuckle | 10.1.7 (was 6.6.2; bumped by AZ-500 to land Microsoft.OpenApi 2.x compat — required by ASP.NET Core 10) |
|
|
| 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 10 (latestMinor rollForward) | 10.0.0+ — was .NET 8.0 / 8.0.0+ through cycle 3 (AZ-500) |
|
|
|
|
## 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
|
|
|
|
```mermaid
|
|
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:
|
|
|
|
1. **SatelliteProvider.Common** — DTOs, interfaces, configs, geo utilities (no internal dependencies)
|
|
2. **SatelliteProvider.DataAccess** — entities, repositories, migrations (no project dependencies)
|
|
3. **SatelliteProvider.Services** — business logic (depends on Common + DataAccess)
|
|
4. **SatelliteProvider.Api** — web layer, DI, endpoints (depends on all above)
|
|
5. **SatelliteProvider.Tests** — unit tests (depends on Services + Common)
|
|
6. **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 POCOs
|
|
- `SatelliteProvider.Common/DTO/*` — data transfer objects
|
|
- `SatelliteProvider.Common/Interfaces/*` — service contracts
|
|
- `SatelliteProvider.Common/Utils/GeoUtils.cs` — static geo math utilities
|
|
- `SatelliteProvider.DataAccess/Models/*` — database entity classes
|
|
- `SatelliteProvider.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 guide
|
|
- `AGENTS.md` — agent-oriented documentation with architecture details and conventions
|
|
- `goal.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`: runs `dotnet restore` + `dotnet test` on 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 in `SatelliteProvider.Common.Interfaces`.
|
|
- `RateLimitException` moved from Services into `SatelliteProvider.Common.Exceptions`.
|
|
- Per-component DI extension methods (`AddTileDownloader`, `AddRegionProcessing`, `AddRouteManagement`) now own their registrations; `Program.cs` calls them.
|
|
|
|
**2026-05-11 — AZ-350 (03-code-quality-refactoring), 27 changes C01..C27**
|
|
- Format / static-analysis tooling added (AZ-372 / C19):
|
|
- `.editorconfig` at 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.props` enables `Microsoft.CodeAnalysis.NetAnalyzers` repository-wide; CA1001, CA1051, CA1816, CA2227 elevated to warning.
|
|
- Coverlet (`coverlet.collector`) wired into `SatelliteProvider.Tests`; `dotnet test --collect:"XPlat Code Coverage"` writes `cobertura.xml` to `TestResults/`.
|
|
- `scripts/run-tests.sh` runs `dotnet format whitespace --verify-no-changes` as Step 0 (gating); `--unit-only`, `--smoke`, `--full` modes documented.
|
|
- HTTP / DI hardening:
|
|
- `IExceptionHandler`-based `GlobalExceptionHandler` sanitizes 5xx ProblemDetails (AZ-353 / C03).
|
|
- Permissive CORS replaced with strict-by-default policy (AZ-354 / C04); permissive policy is opt-in per `CorsConfig.AllowAnyOrigin` and warns in production.
|
|
- Stub endpoints `/api/satellite/tiles/mgrs` and `/api/satellite/upload` now return HTTP 501 instead of 500 (AZ-356 / C05).
|
|
- Idempotent POST contract for `/api/satellite/request` and `/api/satellite/route` returns the existing resource on duplicate id without re-enqueueing (AZ-362 / C09).
|
|
- Typed HttpClient `GoogleMapsTiles` registered in DI (AZ-374 / C21).
|
|
- Domain model cleanup:
|
|
- `RegionStatus` and `RoutePointType` enums replace string status fields end-to-end with case-insensitive parse + lowercase write (AZ-370 / C17).
|
|
- Tile `Version` and `MapsVersion` deprecated (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:
|
|
- `RouteProcessingService` god-class decomposed (AZ-364 / C11); `RouteService.CreateRouteAsync` decomposed (AZ-365 / C12); `IServiceProvider` lookups replaced with explicit dependencies (AZ-360 / C08); `RegionService` catch 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.cs` into `Common.DTO` (AZ-369 / C16).
|
|
- Repository `ColumnList` constants extracted (AZ-379 / C26); per-cell `FirstOrDefault` tile lookup replaced with `HashSet` membership (AZ-375 / C22); Earth + tile-pixel constants consolidated to `GeoUtils` and `MapConfig.DefaultTileSizePixels` (AZ-377 / C24).
|
|
- Dead code removed: `FindExistingTileAsync` (AZ-376 / C23), `CalculatePolygonDiagonalDistance` (AZ-380 / C27), unused write-only counters in `RegionRequestQueue` (AZ-363 / C10).
|
|
- Empty catch in `ExtractTileCoordinatesFromFilename` replaced with logging + sentinel return (AZ-352 / C02); null logger in `DatabaseMigrator` fixed (AZ-351 / C01).
|
|
- Magic numbers promoted to `ProcessingConfig` / `MapConfig` (AZ-371 / C18).
|
|
- Unused repo logger fields removed from `RegionRepository` and `RouteRepository`; `TileRepository` keeps 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/`.
|