Cycle-2 retrospective covering AZ-487 + AZ-488. Captures six patterns (duplicate JWT helpers diverged then both broke; pre-existing test bugs unmasked by downstream test pressure; cycle 1 perf-NFR action stopped adding scenarios but did not drain backlog; doc-path F1 carried over twice with no decision; integration test DB isolation = wallclock workaround; 8 SP friction observable even with user override). Top-3 improvement actions: consolidate JWT mint helpers, promote PT-07/PT-08/JWT-attach to real PBI, real integration DB-reset hook. LESSONS.md ring buffer now holds 6 entries (testing x3, process x2, estimation x1). Structural snapshot: 6 components / 12 PR edges unchanged; contract coverage 14% -> 29%; new external NuGet edges (JwtBearer 8.0.21 + ImageSharp 3.1.11) tied to cycle-2 security findings. Autodev pointer advances to cycle 3 / Step 9 New Task. Co-authored-by: Cursor <cursoragent@cursor.com>
6.2 KiB
Structural Snapshot — 2026-05-11 (post-cycle 2, AZ-487 + AZ-488)
Cycle 2 delta against structure_2026-05-11.md (post-cycle 1 baseline). Source of truth: _docs/02_document/module-layout.md + on-disk *.csproj graph + _docs/02_document/contracts/.
Components
| Layer | Component | csproj | Cycle 2 delta |
|---|---|---|---|
| 1 (Foundation) | Common | SatelliteProvider.Common |
+Configs/UavQualityConfig, +DTO/UavTileMetadata, +DTO/UavTileBatchUploadResponse (incl. UavTileUploadResultItem, UavTileUploadStatus, UavTileRejectReasons, UavTileBatchMetadataPayload) |
| 1 (Foundation) | DataAccess | SatelliteProvider.DataAccess |
unchanged (AZ-488 reuses AZ-484 schema; no new repository methods) |
| 3 (Application) | TileDownloader | SatelliteProvider.Services.TileDownloader |
+UavTileQualityGate (impl IUavTileQualityGate), +UavTileUploadHandler (impl IUavTileUploadHandler), +SixLabors.ImageSharp 3.1.11 NuGet ref |
| 3 (Application) | RegionProcessing | SatelliteProvider.Services.RegionProcessing |
unchanged |
| 3 (Application) | RouteManagement | SatelliteProvider.Services.RouteManagement |
unchanged |
| 4 (API / Entry) | WebApi | SatelliteProvider.Api |
+Authentication/AuthenticationServiceCollectionExtensions, +Authentication/PermissionsRequirement (+ handler + SatellitePermissions), +DTOs/UavTileBatchUploadRequest, -DTOs/UploadImageRequest (deleted), +Microsoft.AspNetCore.Authentication.JwtBearer 8.0.21 NuGet ref |
Component count: 6 (unchanged from cycle 1).
Cross-Component Import Edges (compile-time ProjectReference)
12 ProjectReference edges, unchanged from cycle 1. No new cross-component edges. No new cross-sibling Layer-3 edges. Verified via grep "ProjectReference Include" **/*.csproj.
Source-import sites — cycle 2 delta
| Importer | Imports from | Cycle 2 delta |
|---|---|---|
| TileDownloader | Common.Configs |
+1 site (UavTileQualityGate consumes UavQualityConfig) |
| TileDownloader | Common.DTO |
+2 sites (UavTileQualityGate returns reject reasons; UavTileUploadHandler returns batch response shape) |
| TileDownloader | SixLabors.ImageSharp |
+1 NEW external dependency edge (Image decode + L8 pixel access + Resize) |
| WebApi | Common.Configs |
+1 site (Program.cs binds UavQualityConfig and MapConfig for body-size math) |
| WebApi | Common.DTO |
+1 site (Program.cs accepts UavTileBatchUploadRequest + produces UavTileBatchUploadResponse) |
| WebApi | Services.TileDownloader |
+1 site (Program.cs resolves IUavTileUploadHandler) |
| WebApi | Microsoft.AspNetCore.Authentication.JwtBearer |
+1 NEW external dependency edge (JWT bearer middleware) |
Internal-graph topology unchanged; only call-site density and external NuGet edges grew.
Graph properties
- Cycles in component import graph: 0 (clean DAG — unchanged)
- Average ProjectReferences per component: 12 / 6 = 2.0 (unchanged)
- Max in-degree: Common (still highest at 5)
- Max out-degree: WebApi (still highest at 5)
Architecture violations
- Newly introduced this cycle: 0 (per batch_01_cycle2_review Phase 7 + batch_02_cycle2_review Phase 7)
- Resolved this cycle: 0
- Net delta: 0 (good — second clean cycle in a row)
Contracts
| Contract | Path | Status | Δ this cycle |
|---|---|---|---|
| tile-storage v1.0.0 | _docs/02_document/contracts/data-access/tile-storage.md |
frozen (cycle 1) | unchanged |
| uav-tile-upload v1.0.0 | _docs/02_document/contracts/api/uav-tile-upload.md |
frozen (this cycle) | +1 NEW |
Contract count: 2 (was 1). Contract coverage %: ~29% (2 frozen contracts / ~7 candidate contract surfaces, vs. ~14% post-cycle-1). Improvement of +15 pp.
Remaining unspecified contract surfaces (rough enumeration):
- HTTP endpoints other than
/api/satellite/upload:tiles/latlon,tiles/mgrs,request(region),region/{id},route,route/{id}(5 surfaces). Common.Interfaces(ITileService,IRegionService,IRouteService,IRegionRequestQueue) — single in-process consumer; lower priority.
Shared / Cross-Cutting (Common subfolders)
| Folder | Used by ≥2 components? | Cycle 2 delta |
|---|---|---|
| Common/DTO | yes | +UAV batch types now consumed by WebApi (request) + TileDownloader (response/handler return) |
| Common/Enums | yes | unchanged (TileSource still used; no new enums) |
| Common/Configs | yes | +UavQualityConfig consumed by TileDownloader + WebApi |
| Common/Interfaces | yes | unchanged |
| Common/Utils | yes | unchanged |
| Common/Exceptions | yes | unchanged |
| Common/Imaging | no — TileGridStitcher still only used by RouteManagement |
watch (cycle 3) — borderline status carried from cycle 1; if no second consumer emerges, consider relocating to RouteManagement. |
External NuGet edges added this cycle
| Component | Package | Version | Rationale |
|---|---|---|---|
| WebApi | Microsoft.AspNetCore.Authentication.JwtBearer |
8.0.21 | AZ-487 JWT bearer validation |
| TileDownloader | SixLabors.ImageSharp |
3.1.11 | AZ-488 Rule 3 (Image.Identify) + Rule 5 (Image.Load + Resize) |
| Tests | Microsoft.AspNetCore.Authentication.JwtBearer |
8.0.21 | unit-side AuthenticationServiceCollectionExtensionsTests |
| Tests | SixLabors.ImageSharp |
3.1.11 | UavTileImageFactory generates test JPEGs |
| IntegrationTests | SixLabors.ImageSharp |
3.1.11 | integration test image factories |
All version pins match the project's existing Microsoft.AspNetCore.* 8.0.21 line. ImageSharp 3.1.11 is the same line documented in cycle 1's _docs/05_security/dependency_scan.md.
Auto-lesson triggers checked
- Net Architecture delta this cycle (0) — no
architecturelesson triggered - No structural metric regressed by >20% — no
architecture/dependencieslesson triggered - Contract coverage % increased from ~14% to ~29% — no
architecturelesson triggered - New external NuGet edges introduce decode + crypto attack surface — covered by cycle 2 security audit's
F-AUTH-2andF-UAV-1Medium findings; NOT a new auto-lesson on top of the audit report