mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-21 08:51:13 +00:00
[AZ-487] [AZ-488] docs: cycle 2 doc sync (task mode)
Step 13 (Update Docs) for cycle 2. Most cross-cutting docs were already updated during Step 10 (architecture.md, glossary.md, components/03_tile_downloader, modules/api_program.md, data_model.md, contracts/api/uav-tile-upload.md). This commit completes the remaining module-level + module-layout updates and writes the cycle-2 ripple log. * modules/common_configs.md: + UavQualityConfig section and appsettings-section row (UavQuality). * modules/common_dtos.md: + UavTileMetadata, UavTileBatchMetadataPayload, UavTileBatchUploadResponse, UavTileUploadResultItem, UavTileUploadStatus, UavTileRejectReasons (closed enumeration v1.0.0). * module-layout.md: refresh Common (+ UavQualityConfig + UAV DTOs), TileDownloader (+ UavTileQualityGate, UavTileUploadHandler, + SixLabors.ImageSharp 3.1.11 PackageReference), and WebApi (+ Authentication/*, DTOs/UavTileBatchUploadRequest, + JwtBearer 8.0.21 PackageReference). Updates the "Last Updated" stamp to cycle 2. * modules/tests_unit.md: replace the obsolete "only a dummy test" description; add cycle-2 AZ-487 / AZ-488 test classes (AuthenticationServiceCollectionExtensionsTests, JwtTokenFactoryTests, UavTileQualityGateTests, UavTileUploadHandlerTests, UavTileFilePathTests, PermissionsRequirementTests) + new ProjectReference / package references. * modules/tests_integration.md: + JwtIntegrationTests, UavUploadTests (incl. wall-clock-seeded coordinate counter rationale from the Step 11 fix), and the StubAndErrorContractTests update for the removed 501 stub. * ripple_log_cycle2.md (new): cycle-2 reverse-dependency scan results showing every importer of the new symbols resolves inside the three already-updated components (WebApi, TileDownloader, Common). No unexpected ripple, no heuristic fallback needed. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
**Language**: csharp
|
**Language**: csharp
|
||||||
**Layout Convention**: custom (per-component .csproj per logical component)
|
**Layout Convention**: custom (per-component .csproj per logical component)
|
||||||
**Root**: ./
|
**Root**: ./
|
||||||
**Last Updated**: 2026-05-11 (post AZ-350 03-code-quality-refactoring run; corrects DataAccess→Common dependency)
|
**Last Updated**: 2026-05-11 (cycle 2 — AZ-487 JWT validation baseline + AZ-488 UAV tile upload added; supersedes prior post-AZ-350 update)
|
||||||
|
|
||||||
## Layout Rules
|
## Layout Rules
|
||||||
|
|
||||||
@@ -26,7 +26,8 @@
|
|||||||
- `SatelliteProvider.Common/Configs/StorageConfig.cs`
|
- `SatelliteProvider.Common/Configs/StorageConfig.cs`
|
||||||
- `SatelliteProvider.Common/Configs/ProcessingConfig.cs`
|
- `SatelliteProvider.Common/Configs/ProcessingConfig.cs`
|
||||||
- `SatelliteProvider.Common/Configs/DatabaseConfig.cs`
|
- `SatelliteProvider.Common/Configs/DatabaseConfig.cs`
|
||||||
- `SatelliteProvider.Common/DTO/*.cs` (all DTOs)
|
- `SatelliteProvider.Common/Configs/UavQualityConfig.cs` (added by AZ-488; UAV quality-gate + request-envelope knobs)
|
||||||
|
- `SatelliteProvider.Common/DTO/*.cs` (all DTOs; AZ-488 added `UavTileMetadata`, `UavTileBatchMetadataPayload`, `UavTileBatchUploadResponse`, `UavTileUploadResultItem`, `UavTileUploadStatus`, `UavTileRejectReasons` — placed in Common to keep `TileDownloader` from depending on the API layer)
|
||||||
- `SatelliteProvider.Common/Enums/RegionStatus.cs`
|
- `SatelliteProvider.Common/Enums/RegionStatus.cs`
|
||||||
- `SatelliteProvider.Common/Enums/RoutePointType.cs`
|
- `SatelliteProvider.Common/Enums/RoutePointType.cs`
|
||||||
- `SatelliteProvider.Common/Enums/TileSource.cs` (added by AZ-484; backed by the `tile-storage` v1.0.0 contract)
|
- `SatelliteProvider.Common/Enums/TileSource.cs` (added by AZ-484; backed by the `tile-storage` v1.0.0 contract)
|
||||||
@@ -67,10 +68,13 @@
|
|||||||
- **Public API**:
|
- **Public API**:
|
||||||
- `SatelliteProvider.Services.TileDownloader/GoogleMapsDownloaderV2.cs` (implements `ISatelliteDownloader`)
|
- `SatelliteProvider.Services.TileDownloader/GoogleMapsDownloaderV2.cs` (implements `ISatelliteDownloader`)
|
||||||
- `SatelliteProvider.Services.TileDownloader/TileService.cs` (implements `ITileService`)
|
- `SatelliteProvider.Services.TileDownloader/TileService.cs` (implements `ITileService`)
|
||||||
- `SatelliteProvider.Services.TileDownloader/TileDownloaderServiceCollectionExtensions.cs` (DI: `AddTileDownloader()`)
|
- `SatelliteProvider.Services.TileDownloader/UavTileQualityGate.cs` + `IUavTileQualityGate` (added by AZ-488; 5-rule synchronous validator over `ReadOnlyMemory<byte>` JPEGs, uses `SixLabors.ImageSharp` 3.1.11 + `TimeProvider`)
|
||||||
|
- `SatelliteProvider.Services.TileDownloader/UavTileUploadHandler.cs` + `IUavTileUploadHandler` (added by AZ-488; orchestrates batch validation → file-first persistence → `ITileRepository.InsertAsync` UPSERT; owns the UAV `./tiles/uav/{z}/{x}/{y}.jpg` path layout)
|
||||||
|
- `SatelliteProvider.Services.TileDownloader/TileDownloaderServiceCollectionExtensions.cs` (DI: `AddTileDownloader()` — also registers the AZ-488 quality gate and upload handler as singletons)
|
||||||
- **Internal**: (none)
|
- **Internal**: (none)
|
||||||
- **Owns**: `SatelliteProvider.Services.TileDownloader/**`
|
- **Owns**: `SatelliteProvider.Services.TileDownloader/**`
|
||||||
- **ProjectReferences**: `SatelliteProvider.Common`, `SatelliteProvider.DataAccess`
|
- **ProjectReferences**: `SatelliteProvider.Common`, `SatelliteProvider.DataAccess`
|
||||||
|
- **PackageReferences (added by AZ-488)**: `SixLabors.ImageSharp` 3.1.11 (image identify / `L8` decode / downsample for the variance heuristic).
|
||||||
- **Imports from**: Common, DataAccess
|
- **Imports from**: Common, DataAccess
|
||||||
- **Consumed by**: RegionProcessing (via `ITileService` from Common; no direct ProjectReference), WebApi
|
- **Consumed by**: RegionProcessing (via `ITileService` from Common; no direct ProjectReference), WebApi
|
||||||
|
|
||||||
@@ -107,10 +111,14 @@
|
|||||||
|
|
||||||
- **Directory**: `SatelliteProvider.Api/`
|
- **Directory**: `SatelliteProvider.Api/`
|
||||||
- **Public API**:
|
- **Public API**:
|
||||||
- `SatelliteProvider.Api/Program.cs` (minimal API endpoints, DI setup)
|
- `SatelliteProvider.Api/Program.cs` (minimal API endpoints, DI setup, middleware chain — `UseAuthentication` + `UseAuthorization` added in AZ-487; `/api/satellite/upload` rewired in AZ-488)
|
||||||
|
- `SatelliteProvider.Api/Authentication/AuthenticationServiceCollectionExtensions.cs` (added by AZ-487; `AddSatelliteJwt(IConfiguration)` registers `JwtBearer` with the suite-wide HS256 contract from `suite/_docs/10_auth.md`; validates `JWT_SECRET` ≥ 32 bytes at startup)
|
||||||
|
- `SatelliteProvider.Api/Authentication/PermissionsRequirement.cs` + `PermissionsAuthorizationHandler` + `SatellitePermissions` (added by AZ-488; custom requirement that accepts a `permissions` claim shaped as either a single string or a JSON array; powers the `UavUploadPolicy` requiring the `GPS` permission)
|
||||||
|
- `SatelliteProvider.Api/DTOs/UavTileBatchUploadRequest.cs` (added by AZ-488; multipart form binding envelope — kept in WebApi because it depends on `IFormFileCollection` + `[FromForm]`, both API-layer types)
|
||||||
- **Internal**: (none)
|
- **Internal**: (none)
|
||||||
- **Owns**: `SatelliteProvider.Api/**`
|
- **Owns**: `SatelliteProvider.Api/**`
|
||||||
- **Imports from**: Common, DataAccess, TileDownloader, RegionProcessing, RouteManagement
|
- **PackageReferences (added by AZ-487)**: `Microsoft.AspNetCore.Authentication.JwtBearer` 8.0.21 (pinned to the same minor as the existing ASP.NET Core 8 packages).
|
||||||
|
- **Imports from**: Common (incl. AZ-488 UAV DTOs + `UavQualityConfig`), DataAccess, TileDownloader (incl. AZ-488 `IUavTileUploadHandler`), RegionProcessing, RouteManagement
|
||||||
- **Consumed by**: (none — top-level entry point)
|
- **Consumed by**: (none — top-level entry point)
|
||||||
|
|
||||||
## Shared / Cross-Cutting
|
## Shared / Cross-Cutting
|
||||||
|
|||||||
@@ -26,6 +26,16 @@ Configuration POCOs that bind to `appsettings.json` sections via `IOptions<T>` p
|
|||||||
### DatabaseConfig
|
### DatabaseConfig
|
||||||
- `ConnectionString` (string): DB connection string (unused — connection string is resolved directly from `IConfiguration` in `Program.cs`)
|
- `ConnectionString` (string): DB connection string (unused — connection string is resolved directly from `IConfiguration` in `Program.cs`)
|
||||||
|
|
||||||
|
### UavQualityConfig
|
||||||
|
Knobs for the 5-rule UAV tile quality gate (`UavTileQualityGate`) and the multipart upload envelope. Bound from the `UavQuality` section in `appsettings.json`.
|
||||||
|
- `MinBytes` (int, default: `5 * 1024` = 5 KiB): lower bound for Rule 2 (`SIZE_OUT_OF_BAND`).
|
||||||
|
- `MaxBytes` (int, default: `5 * 1024 * 1024` = 5 MiB): upper bound for Rule 2; also drives `KestrelServerOptions.Limits.MaxRequestBodySize = MaxBatchSize * MaxBytes` and `FormOptions.MultipartBodyLengthLimit` in `Program.cs`.
|
||||||
|
- `MaxAgeDays` (int, default: 7): Rule 4 cutoff for `CAPTURED_AT_TOO_OLD`.
|
||||||
|
- `CapturedAtFutureSkewSeconds` (int, default: 30): Rule 4 forward clock-skew tolerance for `CAPTURED_AT_FUTURE`.
|
||||||
|
- `MinLuminanceVariance` (double, default: 10.0): Rule 5 threshold for `IMAGE_TOO_UNIFORM` measured on a downsampled `L8` image.
|
||||||
|
- `MaxBatchSize` (int, default: 100): hard cap on per-request batch length; violations return 400 envelope-level (see AC-8, RL-05).
|
||||||
|
- `LuminanceSampleSize` (int, default: 32): edge length of the square downsample fed into Rule 5; keeps the per-item gate cost bounded.
|
||||||
|
|
||||||
## Internal Logic
|
## Internal Logic
|
||||||
`StorageConfig.GetTileSubdirectoryPath` buckets tiles by dividing X/Y coordinates by 1000, preventing filesystem performance degradation from too many files in one directory.
|
`StorageConfig.GetTileSubdirectoryPath` buckets tiles by dividing X/Y coordinates by 1000, preventing filesystem performance degradation from too many files in one directory.
|
||||||
|
|
||||||
@@ -52,6 +62,7 @@ These classes **define** the configuration shape consumed by all services.
|
|||||||
| StorageConfig | `StorageConfig` |
|
| StorageConfig | `StorageConfig` |
|
||||||
| ProcessingConfig | `ProcessingConfig` |
|
| ProcessingConfig | `ProcessingConfig` |
|
||||||
| DatabaseConfig | (not wired — connection string read directly) |
|
| DatabaseConfig | (not wired — connection string read directly) |
|
||||||
|
| UavQualityConfig | `UavQuality` (added in AZ-488; consumed by `UavTileQualityGate`, `UavTileUploadHandler`, and `Program.cs` request-size limits) |
|
||||||
|
|
||||||
## External Integrations
|
## External Integrations
|
||||||
None.
|
None.
|
||||||
|
|||||||
@@ -72,6 +72,43 @@ Axis-aligned bounding box defined by NW and SE corners.
|
|||||||
Container for multiple geofence polygons.
|
Container for multiple geofence polygons.
|
||||||
- `Polygons` (List\<GeofencePolygon\>)
|
- `Polygons` (List\<GeofencePolygon\>)
|
||||||
|
|
||||||
|
### UavTileMetadata (added AZ-488)
|
||||||
|
Per-tile metadata payload inside a UAV batch upload (`POST /api/satellite/upload`). Indexed-correlated with the multipart `IFormFileCollection`.
|
||||||
|
- `Latitude`, `Longitude` (double)
|
||||||
|
- `TileZoom` (int)
|
||||||
|
- `TileSizeMeters` (double)
|
||||||
|
- `CapturedAt` (DateTime, UTC; subject to AZ-488 Rule 4 future-skew / age checks)
|
||||||
|
|
||||||
|
### UavTileBatchMetadataPayload (added AZ-488)
|
||||||
|
JSON envelope deserialized from the `metadata` form field of a UAV batch upload.
|
||||||
|
- `Items` (IReadOnlyList\<UavTileMetadata\>)
|
||||||
|
|
||||||
|
### UavTileBatchUploadResponse (added AZ-488)
|
||||||
|
Wire response for `POST /api/satellite/upload`. Returned with HTTP 200 regardless of per-item outcomes; envelope-level failures (auth, oversize, deserialization) bypass this shape.
|
||||||
|
- `Items` (List\<UavTileUploadResultItem\>)
|
||||||
|
|
||||||
|
### UavTileUploadResultItem (added AZ-488)
|
||||||
|
Per-item result inside `UavTileBatchUploadResponse`.
|
||||||
|
- `Index` (int): zero-based index into the request batch.
|
||||||
|
- `Status` (string): one of `UavTileUploadStatus.Accepted` / `UavTileUploadStatus.Rejected`.
|
||||||
|
- `TileId` (Guid?): set on accept (matches the new/updated `tiles.id`); null on reject.
|
||||||
|
- `RejectReason` (string?): closed-enum reason code from `UavTileRejectReasons`; null on accept.
|
||||||
|
- `RejectDetails` (string?): short human-readable note. MUST NOT leak server-internal paths / exception types / hostnames (AZ-488 Security NFR; covered by SEC-11).
|
||||||
|
|
||||||
|
### UavTileUploadStatus (added AZ-488, static string constants)
|
||||||
|
- `Accepted = "accepted"`
|
||||||
|
- `Rejected = "rejected"`
|
||||||
|
|
||||||
|
### UavTileRejectReasons (added AZ-488, static string constants — closed enumeration v1.0.0)
|
||||||
|
Authoritative reject-reason codes for the UAV upload quality gate. Adding a new code requires a minor-version bump of `_docs/02_document/contracts/api/uav-tile-upload.md`.
|
||||||
|
- `InvalidFormat = "INVALID_FORMAT"` — Rule 1 (content-type or JPEG magic bytes).
|
||||||
|
- `SizeOutOfBand = "SIZE_OUT_OF_BAND"` — Rule 2 (bytes outside `[MinBytes, MaxBytes]`).
|
||||||
|
- `WrongDimensions = "WRONG_DIMENSIONS"` — Rule 3 (image width/height ≠ `MapConfig.TileSizePixels`).
|
||||||
|
- `CapturedAtFuture = "CAPTURED_AT_FUTURE"` — Rule 4 (timestamp ahead of now + `CapturedAtFutureSkewSeconds`).
|
||||||
|
- `CapturedAtTooOld = "CAPTURED_AT_TOO_OLD"` — Rule 4 (timestamp older than `MaxAgeDays`).
|
||||||
|
- `ImageTooUniform = "IMAGE_TOO_UNIFORM"` — Rule 5 (luminance variance below `MinLuminanceVariance`).
|
||||||
|
- `StorageFailure = "STORAGE_FAILURE"` — reserved for the orphan-row-recovery path when the on-disk write succeeds but the DB UPSERT fails; surfaced per-item without failing the envelope (AZ-488 Reliability NFR).
|
||||||
|
|
||||||
## Internal Logic
|
## Internal Logic
|
||||||
- `GeoPoint` uses a precision tolerance of `0.00005` degrees (~5.5 meters) for equality comparison.
|
- `GeoPoint` uses a precision tolerance of `0.00005` degrees (~5.5 meters) for equality comparison.
|
||||||
- `SatTile` eagerly computes its bounding box corners on construction by calling `GeoUtils.TileToWorldPos`.
|
- `SatTile` eagerly computes its bounding box corners on construction by calling `GeoUtils.TileToWorldPos`.
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ Console application that runs end-to-end integration tests against a live API in
|
|||||||
- `ComplexRouteTests` — routes with geofencing
|
- `ComplexRouteTests` — routes with geofencing
|
||||||
- `ExtendedRouteTests` — routes with `requestMaps: true` and tile ZIP creation
|
- `ExtendedRouteTests` — routes with `requestMaps: true` and tile ZIP creation
|
||||||
- `MigrationTests` — direct PostgreSQL schema/index validation (no HTTP). AZ-484 cycle added: `NewUniqueConstraintIncludesSourceColumn_AZ484_AC1`, `BackfillUpdateAssignsGoogleMapsAndCapturedAt_AZ484_AC4`, `MultiSourceInsertCoexistsUnderNewIndex_AZ484_AC1`, `MostRecentAcrossSourcesSelection_AZ484_AC2`, `SameSourceUpsertReplacesPreviousRow_AZ484_AC3` (latter four use temp tables to keep production data untouched).
|
- `MigrationTests` — direct PostgreSQL schema/index validation (no HTTP). AZ-484 cycle added: `NewUniqueConstraintIncludesSourceColumn_AZ484_AC1`, `BackfillUpdateAssignsGoogleMapsAndCapturedAt_AZ484_AC4`, `MultiSourceInsertCoexistsUnderNewIndex_AZ484_AC1`, `MostRecentAcrossSourcesSelection_AZ484_AC2`, `SameSourceUpsertReplacesPreviousRow_AZ484_AC3` (latter four use temp tables to keep production data untouched).
|
||||||
|
- `JwtIntegrationTests` (added by AZ-487, cycle 2) — `AnonymousRequest_To_AnyEndpoint_Returns401`, `ExpiredToken_Returns401`, `InvalidSignature_Returns401`, `ValidToken_Returns200_OnHealthyEndpoint`, `SwaggerDocument_AdvertisesBearerSecurityScheme`. Helpers in `JwtTestHelpers` mint HS256 tokens; the test runner sets `JWT_SECRET` on the API container and attaches a Bearer token to every existing test's HTTP requests so the pre-cycle-2 suite continues to pass.
|
||||||
|
- `UavUploadTests` (added by AZ-488, cycle 2) — `HappyPathSingleItem_PersistsRow`, `MixedBatch_ReturnsPerItemResults`, `MultiSourceCoexistence_AZ484_Cycle2`, `SameSourceUpsert_AZ484_Cycle2`, `NoToken_Returns401`, `ValidTokenWithoutGpsPermission_Returns403`, `OversizedBatch_Returns400`. Uses a wall-clock-seeded coordinate counter (`_coordinateCounter` initialized from `DateTime.UtcNow`) so each docker-compose run picks a fresh coordinate band — the postgres named volume persists across runs and a naïve `int = 0` counter collided with prior runs on the per-source unique index (fixed mid-Step-11).
|
||||||
|
- `StubAndErrorContractTests` (existing) — updated in cycle 2 to drop the legacy `StubUpload_Returns501` expectation since AZ-488 implemented the endpoint.
|
||||||
|
|
||||||
### Supporting Classes
|
### Supporting Classes
|
||||||
- `Models.cs` — HTTP response DTOs for deserialization
|
- `Models.cs` — HTTP response DTOs for deserialization
|
||||||
|
|||||||
@@ -1,23 +1,35 @@
|
|||||||
# Module: Tests/SatelliteProvider.Tests
|
# Module: Tests/SatelliteProvider.Tests
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
Unit test project. Currently contains only a single dummy test as a placeholder.
|
Unit test project for component-internal logic. Original AZ-2/AZ-3 era had only a placeholder dummy; the suite has since grown across the AZ-285..AZ-380 baseline + cycle 1 (AZ-484) + cycle 2 (AZ-487, AZ-488) tracks. The "dummy test only" note in older revisions of this file is obsolete — the project now hosts the full unit suite executed by `scripts/run-tests.sh --unit-only` and CI's `01-test.yml`.
|
||||||
|
|
||||||
## Public Interface
|
## Public Interface (test classes)
|
||||||
|
|
||||||
### DummyTests
|
Existing baseline (pre-cycle-2) test classes cover `TileService`, `RegionService`, `RouteService`, geo math, repositories, validators, idempotency, and migration helpers — not enumerated exhaustively here. Cycle-2 additions:
|
||||||
- `Dummy_ShouldWork()`: asserts `1 == 1`
|
|
||||||
|
### AZ-487 — JWT validation baseline
|
||||||
|
- `Authentication/AuthenticationServiceCollectionExtensionsTests` — `AddSatelliteJwt_RegistersJwtBearerScheme`, `AddSatelliteJwt_ThrowsOnMissingSecret`, `AddSatelliteJwt_ThrowsOnShortSecret`.
|
||||||
|
- `Authentication/JwtTokenFactoryTests` — `Create_ProducesTokenValidatedByMatchingParameters`, `CreateExpired_TokenFailsValidationWithLifetimeException`, `Create_WithExtraClaims_PropagatesClaimsThroughValidation`.
|
||||||
|
- `TestUtilities/JwtTokenFactory` — helper that mints HS256 tokens with the same `TokenValidationParameters` used in production. Adjusts `notBefore` for negative-lifetime requests so `JwtSecurityToken` accepts the value and downstream lifetime validation can fire (`IDX12401` workaround documented inline).
|
||||||
|
|
||||||
|
### AZ-488 — UAV tile upload
|
||||||
|
- `UavTileQualityGateTests` — one happy path + ≥ 1 reject path per rule (Rule 1 INVALID_FORMAT × 2, Rule 2 SIZE_OUT_OF_BAND × 2, Rule 3 WRONG_DIMENSIONS × 1, Rule 4 CAPTURED_AT_FUTURE / _TOO_OLD × 2, Rule 5 IMAGE_TOO_UNIFORM × 1) + rule-ordering determinism. Uses a `FixedTimeProvider` for Rule-4 isolation and `UavTileImageFactory` for deterministic JPEG fixtures.
|
||||||
|
- `UavTileUploadHandlerTests` — end-to-end with a mocked `ITileRepository`: 1-item happy path, 3-item mixed batch (file written + `InsertAsync` called only for accepted), per-source UPSERT pass-through.
|
||||||
|
- `UavTileFilePathTests` — verifies `BuildUavTileFilePath` produces `tiles/uav/{z}/{x}/{y}.jpg` for sample (z, x, y) tuples and that integer-typed coordinates make string-injection of path traversal impossible.
|
||||||
|
- `Authentication/PermissionsRequirementTests` — `PermissionsAuthorizationHandler` correctly accepts a `permissions` claim shaped as a single string OR as a JSON array, rejects when the requested permission is absent, and short-circuits when the principal has no `permissions` claim at all.
|
||||||
|
- `TestUtilities/UavTileImageFactory` — programmatic JPEG factories used by the gate + handler tests: `CreateValidJpeg(width, height, seed)`, `CreateUniformJpeg`, `CreatePng` (for Rule 1 negative path).
|
||||||
|
|
||||||
## Internal Logic
|
## Internal Logic
|
||||||
No meaningful test logic.
|
- Tests follow Arrange / Act / Assert. Time-dependent paths inject a `FixedTimeProvider` (cycle-2 addition) so Rule 4 has deterministic age windows.
|
||||||
|
- `JwtSecurityTokenHandler.MapInboundClaims = false` is set explicitly in JWT tests so claims read by their original names (`sub`, `permissions`, …) rather than the framework-remapped names.
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
- Project references: `SatelliteProvider.Services.TileDownloader`, `SatelliteProvider.Services.RegionProcessing`, `SatelliteProvider.Services.RouteManagement`, `SatelliteProvider.Common`, `SatelliteProvider.DataAccess`
|
- Project references: `SatelliteProvider.Services.TileDownloader`, `SatelliteProvider.Services.RegionProcessing`, `SatelliteProvider.Services.RouteManagement`, `SatelliteProvider.Common`, `SatelliteProvider.DataAccess`, `SatelliteProvider.Api` (for the Authentication tests — added in AZ-487).
|
||||||
- NuGet: xUnit (2.5.3), Moq (4.20.72), FluentAssertions (8.8.0), coverlet.collector (6.0.0), Microsoft.NET.Test.Sdk (17.8.0), Microsoft.Extensions.* (Caching.Memory, Configuration, DI, Logging, Options, Http)
|
- NuGet: xUnit (2.5.3), Moq (4.20.72), FluentAssertions (8.8.0), coverlet.collector (6.0.0), Microsoft.NET.Test.Sdk (17.8.0), Microsoft.Extensions.* (Caching.Memory, Configuration, DI, Logging, Options, Http), `Microsoft.AspNetCore.Authentication.JwtBearer` 8.0.21 (added by AZ-487 for the DI + handler tests), `SixLabors.ImageSharp` 3.1.11 (added by AZ-488 for the gate tests).
|
||||||
- Has `appsettings.json` copied to output (empty config for potential future test setups)
|
- `appsettings.json` copied to output (used by Authentication tests for the `Jwt` section binding scenario).
|
||||||
|
|
||||||
## Consumers
|
## Consumers
|
||||||
- CI pipeline (`01-test.yml`) runs `dotnet test` against this project
|
- CI pipeline (`01-test.yml`) and `scripts/run-tests.sh --unit-only` run `dotnet test` against this project.
|
||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
This IS the test module. Coverage: effectively zero (only a dummy test).
|
This IS the test module. Cycle-2 added ~25 unit tests on top of the existing baseline; the full project executes in seconds (no external services required).
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
# Cycle 2 — Documentation Ripple Log
|
||||||
|
|
||||||
|
**Cycle**: 2 (AZ-487 JWT validation baseline + AZ-488 UAV tile upload)
|
||||||
|
**Generated by**: `/document` skill (task mode) during autodev Step 13
|
||||||
|
**Resolution method**: `Grep --type cs` against every new symbol introduced by the two tasks. C# `using`-based import analysis (`SatelliteProvider.Api.Authentication`, `SatelliteProvider.Common.Configs.UavQualityConfig`, the AZ-488 `UavTile*` DTOs, and the new `IUavTileQualityGate` / `IUavTileUploadHandler` interfaces). No static-analyzer (NDepend, etc.) was used — the search surface is small enough that a literal usage scan is exhaustive.
|
||||||
|
|
||||||
|
## Directly-changed source files (cycle 2)
|
||||||
|
|
||||||
|
- `SatelliteProvider.Api/Program.cs` (AZ-487 middleware + Authorize, AZ-488 endpoint rewire + Kestrel/FormOptions limits)
|
||||||
|
- `SatelliteProvider.Api/Authentication/AuthenticationServiceCollectionExtensions.cs` (AZ-487, new)
|
||||||
|
- `SatelliteProvider.Api/Authentication/PermissionsRequirement.cs` (AZ-488, new — also defines `PermissionsAuthorizationHandler` + `SatellitePermissions`)
|
||||||
|
- `SatelliteProvider.Api/DTOs/UavTileBatchUploadRequest.cs` (AZ-488, new)
|
||||||
|
- `SatelliteProvider.Api/DTOs/UploadImageRequest.cs` (AZ-488, deleted — legacy 501-stub DTO)
|
||||||
|
- `SatelliteProvider.Api/appsettings.json` (AZ-487 `Jwt` section, AZ-488 `UavQuality` section)
|
||||||
|
- `SatelliteProvider.Common/Configs/UavQualityConfig.cs` (AZ-488, new)
|
||||||
|
- `SatelliteProvider.Common/DTO/UavTileMetadata.cs` (AZ-488, new — incl. `UavTileBatchMetadataPayload`)
|
||||||
|
- `SatelliteProvider.Common/DTO/UavTileBatchUploadResponse.cs` (AZ-488, new — incl. `UavTileUploadResultItem`, `UavTileUploadStatus`, `UavTileRejectReasons`)
|
||||||
|
- `SatelliteProvider.Services.TileDownloader/UavTileQualityGate.cs` (AZ-488, new — incl. `IUavTileQualityGate`)
|
||||||
|
- `SatelliteProvider.Services.TileDownloader/UavTileUploadHandler.cs` (AZ-488, new — incl. `IUavTileUploadHandler`)
|
||||||
|
- `SatelliteProvider.Services.TileDownloader/TileDownloaderServiceCollectionExtensions.cs` (AZ-488, updated to register the new services)
|
||||||
|
- `SatelliteProvider.Services.TileDownloader/SatelliteProvider.Services.TileDownloader.csproj` (AZ-488, added `SixLabors.ImageSharp` 3.1.11)
|
||||||
|
- `SatelliteProvider.Tests/SatelliteProvider.Tests.csproj` (AZ-487 `JwtBearer`, AZ-488 `ImageSharp`; new `ProjectReference` to `SatelliteProvider.Api` for the Authentication tests)
|
||||||
|
- `SatelliteProvider.IntegrationTests/*` (AZ-487 `JwtTestHelpers`, AZ-488 `UavUploadTests` + multipart helpers; runner `Program.cs` invokes both suites)
|
||||||
|
|
||||||
|
## Importer scan results
|
||||||
|
|
||||||
|
| Symbol | Importer count | Importer files | Component touched |
|
||||||
|
|--------|----------------|----------------|-------------------|
|
||||||
|
| `AuthenticationServiceCollectionExtensions.AddSatelliteJwt` | 2 | `SatelliteProvider.Api/Program.cs`, `SatelliteProvider.Tests/Authentication/AuthenticationServiceCollectionExtensionsTests.cs` | WebApi, Tests (unit) |
|
||||||
|
| `PermissionsRequirement` / `PermissionsAuthorizationHandler` / `SatellitePermissions` | 2 | `SatelliteProvider.Api/Program.cs`, `SatelliteProvider.Tests/Authentication/PermissionsRequirementTests.cs` | WebApi, Tests (unit) |
|
||||||
|
| `UavTileBatchUploadRequest` | 1 | `SatelliteProvider.Api/Program.cs` | WebApi |
|
||||||
|
| `UavQualityConfig` | 4 | `Program.cs`, `UavTileQualityGate.cs`, `UavTileUploadHandler.cs`, `UavTileQualityGateTests.cs` | WebApi, TileDownloader, Tests (unit) |
|
||||||
|
| `UavTileMetadata` / `UavTileBatchMetadataPayload` | 3 | `Program.cs`, `UavTileUploadHandler.cs`, integration `UavUploadTests` (via JSON only) | WebApi, TileDownloader, Tests (integration) |
|
||||||
|
| `UavTileBatchUploadResponse` / `UavTileUploadResultItem` / `UavTileUploadStatus` / `UavTileRejectReasons` | 4 | `Program.cs`, `UavTileQualityGate.cs`, `UavTileUploadHandler.cs`, `UavUploadTests` (integration deserialization) | WebApi, TileDownloader, Tests (integration) |
|
||||||
|
| `IUavTileQualityGate` / `UavTileQualityGate` | 3 | `UavTileUploadHandler.cs` (consumer), `TileDownloaderServiceCollectionExtensions.cs` (DI registration), `UavTileQualityGateTests.cs` | TileDownloader, Tests (unit) |
|
||||||
|
| `IUavTileUploadHandler` / `UavTileUploadHandler` | 2 | `Program.cs` (consumer via DI), `TileDownloaderServiceCollectionExtensions.cs` | WebApi, TileDownloader |
|
||||||
|
|
||||||
|
## Doc refresh decisions
|
||||||
|
|
||||||
|
All importers land inside three components that already received targeted updates during Step 10 (Implement) and this Step 13:
|
||||||
|
|
||||||
|
- **WebApi** — `_docs/02_document/modules/api_program.md` updated during AZ-487/AZ-488 implementation (endpoint table, DTOs, DI, handler, config, security). Re-verified during Step 13; no further edits required this pass.
|
||||||
|
- **TileDownloader** — `_docs/02_document/components/03_tile_downloader/description.md` updated during implementation (UavTileQualityGate + UavTileUploadHandler service sections). Re-verified Step 13; no further edits required.
|
||||||
|
- **Common** — `_docs/02_document/modules/common_configs.md` (added `UavQualityConfig`) and `_docs/02_document/modules/common_dtos.md` (added UAV DTOs + reject-reason enum) updated in this Step-13 pass.
|
||||||
|
|
||||||
|
System-level docs also updated during implementation: `architecture.md` (Architecture Vision + Security Architecture + ADR-004 per-source layout), `glossary.md` (UAV + reject-reason terms), `data_model.md` (per-source `file_path` semantics), `contracts/api/uav-tile-upload.md` v1.0.0 (new frozen contract).
|
||||||
|
|
||||||
|
Step-13 additions to module-layout.md: Public API lines for Common (`UavQualityConfig` + UAV DTOs), TileDownloader (`UavTileQualityGate`, `UavTileUploadHandler` + ImageSharp PackageReference), and WebApi (`Authentication/*`, `DTOs/UavTileBatchUploadRequest.cs`, JwtBearer PackageReference). Tests module docs (`tests_unit.md`, `tests_integration.md`) refreshed with the new cycle-2 test classes; the obsolete "only a dummy test" claim in `tests_unit.md` was corrected.
|
||||||
|
|
||||||
|
## No-ripple components
|
||||||
|
|
||||||
|
These components were NOT touched by cycle-2 changes and require no doc update:
|
||||||
|
|
||||||
|
- DataAccess — no new symbols imported; `ITileRepository.InsertAsync` is consumed unchanged.
|
||||||
|
- RegionProcessing — no imports against cycle-2 symbols.
|
||||||
|
- RouteManagement — no imports against cycle-2 symbols.
|
||||||
|
|
||||||
|
## Parse-failure / heuristic notes
|
||||||
|
|
||||||
|
None — every symbol resolved via direct `Grep`. No fallback heuristic was needed.
|
||||||
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
## Current Step
|
## Current Step
|
||||||
flow: existing-code
|
flow: existing-code
|
||||||
step: 13
|
step: 14
|
||||||
name: Update Docs
|
name: Security Audit
|
||||||
status: in_progress
|
status: not_started
|
||||||
sub_step:
|
sub_step:
|
||||||
phase: 0
|
phase: 0
|
||||||
name: awaiting-invocation
|
name: awaiting-invocation
|
||||||
|
|||||||
Reference in New Issue
Block a user