mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-21 11:01:14 +00:00
51b572108a
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>
80 lines
6.1 KiB
Markdown
80 lines
6.1 KiB
Markdown
# 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. Adds `source` (VARCHAR(32) NOT NULL DEFAULT `'google_maps'`) + `captured_at` (TIMESTAMP NOT NULL); backfills both for every pre-existing row; replaces 4-col `idx_tiles_unique_location` with 5-col `idx_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 EXISTS` patterns).
|
|
- **Backwards compatible**: pre-AZ-484 application code that reads `tiles` still works — `source` defaults to `'google_maps'`, `captured_at` is backfilled to `created_at`. Vestigial columns `version` / `maps_version` are preserved nullable.
|
|
- **No data loss**: the only DDL change is dropping `idx_tiles_unique_location` (replaced by `idx_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.md` storage 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:
|
|
|
|
1. Re-deploy the previous image (`registry.../azaion/satellite-provider:<previous-tag>`). The pre-AZ-484 code reads `*` from `tiles` and ignores the new columns — it will function correctly against the migrated schema.
|
|
2. The 5-col `idx_tiles_unique_location_source` is 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.
|
|
3. If a true schema rollback is ever needed, write a follow-up migration `014_RevertAz484.sql` rather than editing `013` in place.
|
|
|
|
## Post-deploy verification
|
|
|
|
After the new image is deployed and migrations have run:
|
|
|
|
1. Hit `GET /api/satellite/region/{any-existing-region-id}` — confirm 200 + status JSON (smoke test that the `tiles` reads still parse with the new entity shape).
|
|
2. Hit `GET /api/satellite/tiles/latlon?Latitude=...&Longitude=...&ZoomLevel=18` for a known cell — confirm 200 + tile bytes.
|
|
3. Run a single `psql` query: `SELECT count(*) FROM tiles WHERE source IS NULL OR captured_at IS NULL;` — expected `0`.
|
|
4. Tail Serilog logs for `Slow GetTilesByRegionAsync` warnings (>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`; `.env` not 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.
|