Captures the post-implementation autodev gates for AZ-484 multi-source tile storage: - Step 12 (Test-Spec Sync): added 7 AC rows (AZ-484 AC-1..AC-7) and a PT-07 NFR row to traceability-matrix.md; added PT-07 scenario to performance-tests.md. - Step 13 (Update Docs): refreshed data_model.md (tiles columns + indexes + selection rule + UPSERT contract + migrations 012/013), module-layout.md (Common/Enums section with L-001 guidance, DataAccess imports-from now lists 6 sites), 6 module / component docs to reflect the new repo signatures, source/captured_at fields, and Dapper enum bypass workaround. ripple_log_cycle1.md records zero out-of-scope ripple. - Step 14 (Security Audit): PASS_WITH_WARNINGS - 0 Critical, 0 High, 5 Medium, 5 Low. AZ-484 itself added zero new findings. Hardening items (Postgres default creds, .env in build context, GMaps key rotation, ASP.NET Core 8.0.21 -> 8.0.25, rate limiter) recorded for separate tickets. - Step 15 (Performance Test): all PT-01..PT-07 scenarios Unverified (non-blocking); PT-07 baseline-comparison harness deferred to a leftover for next cycle. - Step 16 (Deploy): cycle deploy report covering migration safety, rollback path, post-deploy verification, security caveats. Co-authored-by: Cursor <cursoragent@cursor.com>
6.1 KiB
Deploy Report — Cycle 1 (AZ-484)
Date: 2026-05-11 Cycle: 1 Scope: Multi-source tile storage schema (AZ-484) and supporting documentation/security artifacts.
What is shipping
Code changes (already committed)
| Commit | Subject |
|---|---|
5ba58b6 |
[AZ-484] [AZ-483] Add task spec + tile-storage v1.0.0 contract draft |
687d6bd |
[AZ-484] Multi-source tile storage: source + captured_at |
e9d6db0 |
[AZ-484] Fix multi-source tile reads: drop Dapper enum handler |
Database migration
013_AddTileSourceAndCapturedAt.sql— runs on first startup of the new image. Transactional (BEGIN; … COMMIT;), idempotent against partial replays. Addssource(VARCHAR(32) NOT NULL DEFAULT'google_maps') +captured_at(TIMESTAMP NOT NULL); backfills both for every pre-existing row; replaces 4-colidx_tiles_unique_locationwith 5-colidx_tiles_unique_location_source.
Documentation, test-spec, audit artifacts (uncommitted in working tree, scoped to this deploy commit below)
_docs/02_document/data_model.md,module-layout.md, 6 module / component docs — Step 13 (Update Docs)._docs/02_document/ripple_log_cycle1.md— Step 13 ripple analysis._docs/02_document/tests/performance-tests.md,traceability-matrix.md— Step 12 (Test-Spec Sync) — added AZ-484 ACs and PT-07._docs/05_security/(5 files) — Step 14 (Security Audit) — verdict PASS_WITH_WARNINGS._docs/06_metrics/perf_2026-05-11_cycle1_az484.md— Step 15 (Performance Test) — all scenarios Unverified, non-blocking._docs/_process_leftovers/2026-05-11_perf-pt07-harness.md— deferred PT-07 harness work._docs/_autodev_state.md— autodev pointer.
Pre-deploy checks (recap)
| Gate | Outcome |
|---|---|
| Step 11 — Run Tests | All unit + integration tests pass against the post-AZ-484 build (213 unit + 5 new AZ-484 integration). |
| Step 14 — Security Audit | PASS_WITH_WARNINGS — 0 Critical, 0 High, 5 Medium, 5 Low. AZ-484 itself added zero new findings. Top hardening items recorded in _docs/05_security/security_report.md. |
| Step 15 — Performance Test | All scenarios Unverified (PT-07 harness deferred to next cycle). Non-blocking per test-run perf-mode rules. |
dotnet format whitespace --verify-no-changes |
Passed (part of scripts/run-tests.sh). |
Migration safety
- Idempotent: re-running migration 013 against an already-migrated database is a no-op (
ADD COLUMN IF NOT EXISTS,DROP INDEX IF EXISTS,CREATE UNIQUE INDEX IF NOT EXISTSpatterns). - Backwards compatible: pre-AZ-484 application code that reads
tilesstill works —sourcedefaults to'google_maps',captured_atis backfilled tocreated_at. Vestigial columnsversion/maps_versionare preserved nullable. - No data loss: the only DDL change is dropping
idx_tiles_unique_location(replaced byidx_tiles_unique_location_source); rows are not touched except by the backfill UPDATE. - Lock duration: ALTER TABLE on a tiles table with O(100K-1M) rows takes a few seconds for ADD COLUMN (metadata-only in PG 11+) and a few seconds for the UPDATE backfill on existing data. Acceptable for a maintenance window-free deploy assuming current row counts (
_docs/02_document/data_model.mdstorage estimate: 100K-1M tiles).
Rollback plan
The migration is forward-only by DbUp design (no automatic down migrations). In the unlikely event AZ-484 needs to be reverted in production:
- Re-deploy the previous image (
registry.../azaion/satellite-provider:<previous-tag>). The pre-AZ-484 code reads*fromtilesand ignores the new columns — it will function correctly against the migrated schema. - The 5-col
idx_tiles_unique_location_sourceis a strict superset of the pre-AZ-484 4-col index for the only producer pre-AZ-484 sees (source = 'google_maps'); pre-AZ-484 UPSERT on(lat, lon, tile_zoom, tile_size_meters, version)would fail conflict detection against the new index — so do not roll the schema back, only roll the application back. The schema is forward-compatible with the old code. - If a true schema rollback is ever needed, write a follow-up migration
014_RevertAz484.sqlrather than editing013in place.
Post-deploy verification
After the new image is deployed and migrations have run:
- Hit
GET /api/satellite/region/{any-existing-region-id}— confirm 200 + status JSON (smoke test that thetilesreads still parse with the new entity shape). - Hit
GET /api/satellite/tiles/latlon?Latitude=...&Longitude=...&ZoomLevel=18for a known cell — confirm 200 + tile bytes. - Run a single
psqlquery:SELECT count(*) FROM tiles WHERE source IS NULL OR captured_at IS NULL;— expected0. - Tail Serilog logs for
Slow GetTilesByRegionAsyncwarnings (>500ms) for the first hour. A spike here would be the earliest signal of a perf regression vs. the (unmeasured) pre-AZ-484 baseline.
CI/CD path
The project's .woodpecker/02-build-push.yml builds and pushes the image on push to dev, stage, main. The dev branch is the standard target per .cursor/rules/git-workflow.mdc. Pushing the new commit to origin/dev triggers the pipeline; no manual deploy steps are needed beyond the git push.
Push policy: per git-workflow.mdc, the autodev does NOT push without explicit user request. The next user prompt will offer the push as an explicit option.
Security caveats carried into this deploy
The Security Audit (Step 14) flagged 5 Medium findings that should be tracked as separate hardening tasks before public-network exposure but do NOT block this internal deploy:
- S1+S2+I5 — Postgres default credentials in
appsettings.json+docker-compose.yml;.envnot in.dockerignore. - S4 — Google Maps API key needs rotation +
.env.example. - D1 — Bump
Microsoft.AspNetCore.OpenApi 8.0.21 → 8.0.25(CVE-2026-26130 SignalR DoS — not reachable in this app). - I3 — Wire
Microsoft.AspNetCore.RateLimiting.
None of these are AZ-484 regressions; they are pre-existing items that today's audit surfaced. Tracking them as separate Jira tickets is recommended but not enforced by this gate.