[AZ-373] Refactor C20: drop MapsVersion from new writes (option a)

- Stop writing "downloaded_YYYY-MM-DD" into tiles.maps_version: new rows
  bind @MapsVersion to NULL via TileService.BuildTileEntity.
- Retain the tiles.maps_version column (coderule.mdc forbids unprompted
  column drops); pre-existing rows keep their values for forensics.
- Remove MapsVersion property from DownloadTileResponse (API wire shape)
  and TileMetadata (internal DTO); OpenAPI schema regenerates from the
  DTO via Swashbuckle.
- Add 3 AC tests in TileServiceTests covering the captured-entity write
  (AC-1) and the DTO/wire-shape removal (AC-2).
- Update integration-test local DTO + console output; refresh docs in
  common_dtos.md, services_tile_service.md, data_model.md.
- Archive AZ-373 task file: todo/ -> done/.

174 unit + 5 smoke pass.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-11 04:05:40 +03:00
parent 45f7852fb2
commit 7c37636fdf
11 changed files with 55 additions and 14 deletions
@@ -207,6 +207,54 @@ public class TileServiceTests
captured!.Version.Should().BeNull("AZ-357: new code never writes the deprecated year-based version");
}
[Fact]
public void BuildTileEntity_DoesNotPopulateMapsVersion_AZ373_AC1()
{
// Arrange
var downloader = new Mock<ISatelliteDownloader>();
var tileRepo = new Mock<ITileRepository>();
TileEntity? captured = null;
tileRepo
.Setup(r => r.InsertAsync(It.IsAny<TileEntity>()))
.Callback<TileEntity>(e => captured = e)
.ReturnsAsync(Guid.NewGuid());
downloader
.Setup(d => d.DownloadSingleTileAsync(It.IsAny<double>(), It.IsAny<double>(), It.IsAny<int>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new DownloadedTileInfoV2(1, 2, 18, 47.46, 37.65, "tiles/18/1/2.jpg", 100.0));
var service = BuildService(downloader, tileRepo);
// Act
_ = service.DownloadAndStoreSingleTileAsync(47.46, 37.65, 18).GetAwaiter().GetResult();
// Assert
captured.Should().NotBeNull();
captured!.MapsVersion.Should().BeNull(
"AZ-373 option (a): new code never writes a MapsVersion value; the column is retained for forensics on pre-existing rows only");
}
[Fact]
public void DownloadTileResponse_DoesNotExposeMapsVersion_AZ373_AC2()
{
// Act
var property = typeof(DownloadTileResponse).GetProperty("MapsVersion");
// Assert
property.Should().BeNull(
"AZ-373 AC-2 option (a): MapsVersion is removed from the HTTP response shape");
}
[Fact]
public void TileMetadata_DoesNotExposeMapsVersion_AZ373_AC1()
{
// Act
var property = typeof(TileMetadata).GetProperty("MapsVersion");
// Assert
property.Should().BeNull(
"AZ-373 AC-1: TileMetadata DTO no longer carries MapsVersion (consistent with the HTTP response removal)");
}
[Fact]
public async Task GetTileAsync_KnownId_ReturnsMappedMetadata()
{