From e3cd3885773ddfc6e0d02985b9fd19d8406cc533 Mon Sep 17 00:00:00 2001 From: Oleksandr Bezdieniezhnykh Date: Tue, 12 May 2026 00:04:05 +0300 Subject: [PATCH] [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 --- _docs/02_document/module-layout.md | 18 ++++-- _docs/02_document/modules/common_configs.md | 11 ++++ _docs/02_document/modules/common_dtos.md | 37 ++++++++++++ .../02_document/modules/tests_integration.md | 3 + _docs/02_document/modules/tests_unit.md | 32 ++++++---- _docs/02_document/ripple_log_cycle2.md | 60 +++++++++++++++++++ _docs/_autodev_state.md | 6 +- 7 files changed, 149 insertions(+), 18 deletions(-) create mode 100644 _docs/02_document/ripple_log_cycle2.md diff --git a/_docs/02_document/module-layout.md b/_docs/02_document/module-layout.md index 39fa7d3..0df9550 100644 --- a/_docs/02_document/module-layout.md +++ b/_docs/02_document/module-layout.md @@ -5,7 +5,7 @@ **Language**: csharp **Layout Convention**: custom (per-component .csproj per logical component) **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 @@ -26,7 +26,8 @@ - `SatelliteProvider.Common/Configs/StorageConfig.cs` - `SatelliteProvider.Common/Configs/ProcessingConfig.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/RoutePointType.cs` - `SatelliteProvider.Common/Enums/TileSource.cs` (added by AZ-484; backed by the `tile-storage` v1.0.0 contract) @@ -67,10 +68,13 @@ - **Public API**: - `SatelliteProvider.Services.TileDownloader/GoogleMapsDownloaderV2.cs` (implements `ISatelliteDownloader`) - `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` 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) - **Owns**: `SatelliteProvider.Services.TileDownloader/**` - **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 - **Consumed by**: RegionProcessing (via `ITileService` from Common; no direct ProjectReference), WebApi @@ -107,10 +111,14 @@ - **Directory**: `SatelliteProvider.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) - **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) ## Shared / Cross-Cutting diff --git a/_docs/02_document/modules/common_configs.md b/_docs/02_document/modules/common_configs.md index 2236510..6c90b55 100644 --- a/_docs/02_document/modules/common_configs.md +++ b/_docs/02_document/modules/common_configs.md @@ -26,6 +26,16 @@ Configuration POCOs that bind to `appsettings.json` sections via `IOptions` p ### DatabaseConfig - `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 `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` | | ProcessingConfig | `ProcessingConfig` | | 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 None. diff --git a/_docs/02_document/modules/common_dtos.md b/_docs/02_document/modules/common_dtos.md index f61d0f7..59f6886 100644 --- a/_docs/02_document/modules/common_dtos.md +++ b/_docs/02_document/modules/common_dtos.md @@ -72,6 +72,43 @@ Axis-aligned bounding box defined by NW and SE corners. Container for multiple geofence polygons. - `Polygons` (List\) +### 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\) + +### 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 (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 - `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`. diff --git a/_docs/02_document/modules/tests_integration.md b/_docs/02_document/modules/tests_integration.md index 9f60ace..ba7daba 100644 --- a/_docs/02_document/modules/tests_integration.md +++ b/_docs/02_document/modules/tests_integration.md @@ -12,6 +12,9 @@ Console application that runs end-to-end integration tests against a live API in - `ComplexRouteTests` — routes with geofencing - `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). +- `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 - `Models.cs` — HTTP response DTOs for deserialization diff --git a/_docs/02_document/modules/tests_unit.md b/_docs/02_document/modules/tests_unit.md index b2635c0..e8b3b05 100644 --- a/_docs/02_document/modules/tests_unit.md +++ b/_docs/02_document/modules/tests_unit.md @@ -1,23 +1,35 @@ # Module: Tests/SatelliteProvider.Tests ## 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 -- `Dummy_ShouldWork()`: asserts `1 == 1` +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: + +### 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 -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 -- Project references: `SatelliteProvider.Services.TileDownloader`, `SatelliteProvider.Services.RegionProcessing`, `SatelliteProvider.Services.RouteManagement`, `SatelliteProvider.Common`, `SatelliteProvider.DataAccess` -- 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) -- Has `appsettings.json` copied to output (empty config for potential future test setups) +- 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), `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). +- `appsettings.json` copied to output (used by Authentication tests for the `Jwt` section binding scenario). ## 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 -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). diff --git a/_docs/02_document/ripple_log_cycle2.md b/_docs/02_document/ripple_log_cycle2.md new file mode 100644 index 0000000..2aba24f --- /dev/null +++ b/_docs/02_document/ripple_log_cycle2.md @@ -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. diff --git a/_docs/_autodev_state.md b/_docs/_autodev_state.md index 410d78e..22e9263 100644 --- a/_docs/_autodev_state.md +++ b/_docs/_autodev_state.md @@ -2,9 +2,9 @@ ## Current Step flow: existing-code -step: 13 -name: Update Docs -status: in_progress +step: 14 +name: Security Audit +status: not_started sub_step: phase: 0 name: awaiting-invocation