Two integration-test failures uncovered after the initial commit:
1) GetTilesByRegionAsync outer ORDER BY referenced 'updated_at' but
the inner DISTINCT ON subquery aliased it to 'UpdatedAt' (Postgres
folds to 'updatedat'). DISTINCT ON already guarantees one row per
(latitude, longitude, ...) so the third tiebreak was unreachable;
removed it.
2) Dapper 2.1.35 silently bypasses SqlMapper.TypeHandler<T> for enum
types during read deserialization (Dapper issue #259). The
TileSourceTypeHandler worked for writes but reads fell through to
Enum.TryParse, which cannot map 'google_maps' to GoogleMaps.
Pivoted: TileEntity.Source is now a string (the wire value).
TileSource enum stays as the public producer surface in
Common.Enums; TileSourceConverter (Common.Enums) provides
ToWireValue / FromWireValue / IsValidWireValue at the boundary.
TileSourceTypeHandler deleted; registration removed from
DapperEnumTypeHandlers.RegisterAll.
tile-storage.md Inv-5 amended to document the storage choice.
_docs/LESSONS.md L-001 records the Dapper bypass for future cycles.
Full suite passes (213 unit + integration suite incl. AZ-484
AC-1..AC-5, security SEC-01..SEC-04, AZ-356/362/357).
Co-authored-by: Cursor <cursoragent@cursor.com>
Wires the C19 tooling baseline so dotnet format and Coverlet gate the
test script and a small NetAnalyzers ruleset (CA1001, CA1051, CA1816,
CA2227) at warning severity is visible from the next build.
- .editorconfig (new, root=true): whitespace rules, per-extension
indent sizes, C# style preferences as suggestions, initial CA rules.
- Directory.Build.props (new): EnableNETAnalyzers=true,
AnalysisLevel=latest, AnalysisMode=None so only rules explicitly
enabled in .editorconfig fire; EnforceCodeStyleInBuild=false to keep
build clean from style.
- scripts/run-tests.sh: Step 0 runs dotnet format whitespace
--verify-no-changes via Docker SDK; unit/integration test calls now
collect XPlat Code Coverage into TestResults/. New --skip-format
escape hatch.
- .gitignore: TestResults/, coverage.cobertura.xml, *.coverage.
- SatelliteProvider.Tests/ToolingConfigurationTests.cs (new, 6 tests):
runtime assertions that the config files, script wiring, and
coverlet.collector reference are all in place; mirrors the
AcceptanceCriteriaRT2Tests pattern.
Whitespace cleanup that the new format gate uncovers is staged for the
next commit (per AZ-372 spec: "commit cleanup as a separate batch").
Co-authored-by: Cursor <cursoragent@cursor.com>