mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-21 19:51:14 +00:00
23ab05766d
Replaces bare strings with two enums in Common/Enums/:
RegionStatus { Queued, Processing, Completed, Failed }
RoutePointType { Start, End, Action, Intermediate }
Adds a Dapper EnumStringTypeHandler<T> (DataAccess/TypeHandlers/)
that round-trips enums to/from lowercase strings, registered once
at startup via DapperEnumTypeHandlers.RegisterAll(). DataAccess now
references Common (project ref) so entities can carry the enum types.
Sites converted: RegionService (5), RouteProcessingService (3),
RoutePointGraphBuilder (4), entity Status/PointType columns. Log
message and summary file format preserved via .ToLowerInvariant().
API JSON contract preserved by adding JsonStringEnumConverter with
JsonNamingPolicy.CamelCase to the http JSON options — single-word
enum members serialize to the same lowercase strings as before.
DTO renamed: Common.DTO.RegionStatus -> RegionStatusResponse to
free the RegionStatus name for the new enum (forced by the task's
explicit enum name); the renamed DTO has no public-API impact at
the JSON wire level. Stale doc references updated.
AC RT2 in _docs/00_problem/acceptance_criteria.md now lists all 4
point types (start/end/action/intermediate).
Tests: 171 / 171 unit + 5 / 5 smoke green (was 141 + 5; +30 new tests
covering type handler round-trip, set/parse, unknown-value rejection,
idempotent registration, and the AC RT2 doc check).
Co-authored-by: Cursor <cursoragent@cursor.com>
3.3 KiB
3.3 KiB
Acceptance Criteria
Tile Download
| # | Criterion | Measurable Value | Source |
|---|---|---|---|
| T1 | Tiles are cached and not re-downloaded | 0 duplicate downloads for same (lat, lon, zoom, version) | Unique index idx_tiles_unique_location |
| T2 | Concurrent download limit is enforced | Max 4 simultaneous HTTP requests to Google Maps | ProcessingConfig.MaxConcurrentDownloads |
| T3 | Tile stored on disk with correct path | File exists at ./tiles/{zoom}/{x}/{y}.jpg |
TileService storage logic |
| T4 | Tile metadata persisted in database | TileEntity row created with all fields populated | TileRepository.InsertAsync |
Region Processing
| # | Criterion | Measurable Value | Source |
|---|---|---|---|
| R1 | Region transitions through correct states | pending → processing → completed (or failed) | RegionProcessingService state updates |
| R2 | CSV manifest generated on completion | File exists at ./ready/region_{id}_ready.csv |
RegionService.ProcessRegionAsync |
| R3 | Summary file generated on completion | File exists at ./ready/region_{id}_summary.txt |
RegionService.GenerateSummaryFileAsync |
| R4 | Stitched image generated when requested | File exists at ./ready/region_{id}_stitched.jpg when stitch_tiles=true |
RegionService.StitchTilesAsync |
| R5 | Stitched image has valid content | File size > 1024 bytes | Integration test assertion |
| R6 | Region processing is bounded | Max 20 concurrent regions | ProcessingConfig.MaxConcurrentRegions |
Route Management
| # | Criterion | Measurable Value | Source |
|---|---|---|---|
| RT1 | Points interpolated at correct interval | Intermediate points every ~200m along path | RouteService (InterpolatePoints) |
| RT2 | Point types correctly assigned | "start" for first waypoint, "end" for last waypoint, "action" for middle waypoints, "intermediate" for generated points | RoutePointEntity.PointType |
| RT3 | Total distance calculated | Haversine sum matches within acceptable precision | RouteService.CreateRoute |
| RT4 | Geofence filtering applied | Only points inside geofence rectangles generate regions | RouteService (point-in-rectangle check) |
| RT5 | ZIP archive within size limit | ≤ 50 MB | RouteProcessingService ZIP generation |
| RT6 | Route map stitched when maps requested | Stitched image > 1024 bytes when request_maps=true | Integration test assertion |
API Behavior
| # | Criterion | Measurable Value | Source |
|---|---|---|---|
| A1 | Region request returns immediately | HTTP 200 with region_id (async processing) | POST /api/satellite/request |
| A2 | Status endpoint reflects real state | Returns current status and file paths | GET /api/satellite/region/{id} |
| A3 | Route creation returns computed metadata | Response includes total_points, total_distance_meters | POST /api/satellite/route |
System Reliability
| # | Criterion | Measurable Value | Source |
|---|---|---|---|
| S1 | Database migrations run on startup | All numbered scripts executed in order | DatabaseMigrator.Migrate() |
| S2 | Queue rejects when full | Channel capacity = 1000, bounded wait | RegionRequestQueue (BoundedChannelOptions) |
| S3 | Failed regions marked as failed | Status = "failed" on unrecoverable error | RegionProcessingService error handling |