[AZ-369] Refactor C16: move inline DTOs out of Program.cs

Move 5 cross-component DTOs (GetSatelliteTilesResponse, SatelliteTile,
SaveResult, DownloadTileResponse, RequestRegionRequest) to
SatelliteProvider.Common/DTO/. Keep UploadImageRequest in the API
project under SatelliteProvider.Api.DTOs (IFormFile depends on
Microsoft.AspNetCore.Http; pulling it into Common would force an
ASP.NET framework reference into the foundation layer and break the
module-layout "Common: Imports from: (none)" invariant). Move
ParameterDescriptionFilter to SatelliteProvider.Api.Swagger.

Program.cs shrinks from 366 to 257 lines and now contains only
endpoint wiring (AC-1). JSON wire shape and Swagger schema names are
preserved (AC-2). 84 unit + full integration suite green (AC-3).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-11 01:54:35 +03:00
parent 4c88201e5c
commit d2d9f6352b
11 changed files with 222 additions and 112 deletions
+2 -111
View File
@@ -1,8 +1,9 @@
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using SatelliteProvider.Api;
using SatelliteProvider.Api.DTOs;
using SatelliteProvider.Api.Swagger;
using SatelliteProvider.DataAccess;
using SatelliteProvider.DataAccess.Repositories;
using SatelliteProvider.Common.Configs;
@@ -254,113 +255,3 @@ async Task<IResult> GetRoute(Guid id, IRouteService routeService)
return Results.Ok(route);
}
public record GetSatelliteTilesResponse
{
public List<SatelliteTile> Tiles { get; set; } = new();
}
public record SatelliteTile
{
public string TileId { get; set; } = string.Empty;
public byte[] ImageData { get; set; } = Array.Empty<byte>();
public double Lat { get; set; }
public double Lon { get; set; }
public int ZoomLevel { get; set; }
}
public record UploadImageRequest
{
[Required]
public DateTime Timestamp { get; set; }
[Required]
public IFormFile? Image { get; set; }
[Required]
public double Lat { get; set; }
[Required]
public double Lon { get; set; }
[Required]
public double Height { get; set; }
[Required]
public double FocalLength { get; set; }
[Required]
public double SensorWidth { get; set; }
[Required]
public double SensorHeight { get; set; }
}
public record SaveResult
{
public bool Success { get; set; }
public string? Exception { get; set; }
}
public record DownloadTileResponse
{
public Guid Id { get; set; }
public int ZoomLevel { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public double TileSizeMeters { get; set; }
public int TileSizePixels { get; set; }
public string ImageType { get; set; } = string.Empty;
public string? MapsVersion { get; set; }
public int? Version { get; set; }
public string FilePath { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
public record RequestRegionRequest
{
[Required]
public Guid Id { get; set; }
[Required]
public double Latitude { get; set; }
[Required]
public double Longitude { get; set; }
[Required]
public double SizeMeters { get; set; }
[Required]
public int ZoomLevel { get; set; } = 18;
public bool StitchTiles { get; set; } = false;
}
public class ParameterDescriptionFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (operation.Parameters == null) return;
var parameterDescriptions = new Dictionary<string, string>
{
["lat"] = "Latitude coordinate where image was captured",
["lon"] = "Longitude coordinate where image was captured",
["mgrs"] = "MGRS coordinate string",
["squareSideMeters"] = "Square side size in meters",
["Latitude"] = "Latitude coordinate of the tile center",
["Longitude"] = "Longitude coordinate of the tile center",
["ZoomLevel"] = "Zoom level for the tile (higher values = more detail)"
};
foreach (var parameter in operation.Parameters)
{
if (parameterDescriptions.TryGetValue(parameter.Name, out var description))
{
parameter.Description = description;
}
}
}
}