[AZ-777] Phase 1 hotfix (z/x/y) + Phase 2 Derkachi seed + ops

Phase 1 hotfix:
- C11 HttpTileDownloader adapted to satellite-provider v2.0.0
  z/x/y inventory contract (bulk POST keyed by slippy-map coords).
- Unit tests rewritten to exercise the new inventory schema.
- E2E smoke test updated to match the v2.0.0 wire.

Phase 2 (Derkachi seed + smoke-validated on Jetson):
- tests/fixtures/derkachi_c6/{README,bbox.yaml,seed_region.py}
  drives POST /api/satellite/region against satellite-provider
  with Google Maps as the imagery source. Smoke run produced
  4 regions, 175 tiles, inventory 32/32.
- scripts/mint_dev_jwt.py + run-tests-jetson.sh auto-mint and
  export SATELLITE_PROVIDER_API_KEY using JWT_SECRET / JWT_ISSUER
  / JWT_AUDIENCE env vars (no host port mappings; e2e-runner
  reaches SP via internal docker network only).

Spec amendment: AZ-777 todo spec updated to record the
Google Maps imagery source decision and STOP-gate state.

AZ-777 Phase 3+ work is superseded by Epic AZ-835 (see next
commit).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-22 17:39:21 +03:00
parent 811b04e605
commit b15454b9a9
9 changed files with 924 additions and 182 deletions
+14
View File
@@ -14,6 +14,7 @@ Usage::
python scripts/mint_dev_jwt.py
python scripts/mint_dev_jwt.py --lifetime-hours 12 --subject e2e-runner
python scripts/mint_dev_jwt.py --permission GPS # unlocks /api/satellite/upload
export SATELLITE_PROVIDER_API_KEY="$(python scripts/mint_dev_jwt.py)"
"""
@@ -85,6 +86,17 @@ def main() -> int:
default=".env.test",
help="Fallback env file (default: .env.test in CWD).",
)
parser.add_argument(
"--permission",
action="append",
default=None,
metavar="NAME",
help=(
"Add a value to the `permissions` JWT claim. Repeatable "
"(e.g. --permission GPS --permission FL). Use `GPS` to unlock "
"/api/satellite/upload on the satellite-provider."
),
)
args = parser.parse_args()
env_file_values = _load_env_file(Path(args.env_file))
@@ -127,6 +139,8 @@ def main() -> int:
"nbf": int(now.timestamp()),
"exp": int((now + timedelta(hours=args.lifetime_hours)).timestamp()),
}
if args.permission:
payload["permissions"] = list(args.permission)
token = jwt.encode(payload, secret, algorithm="HS256")
sys.stdout.write(token + "\n")
+18
View File
@@ -81,6 +81,21 @@ if [ "${#JWT_SECRET}" -lt 32 ]; then
exit 70
fi
# AZ-777 Phase 1: the e2e-runner needs a Bearer token to call the real
# satellite-provider. If the caller didn't pre-export SATELLITE_PROVIDER_API_KEY
# (preferred for CI / repeatable runs), mint a fresh dev JWT here using the
# same JWT_SECRET / JWT_ISSUER / JWT_AUDIENCE the producer validates against.
if [ -z "${SATELLITE_PROVIDER_API_KEY:-}" ]; then
echo "[run-tests-jetson] minting fresh dev JWT via scripts/mint_dev_jwt.py"
if ! SATELLITE_PROVIDER_API_KEY=$(python3 "${SCRIPT_DIR}/mint_dev_jwt.py" \
--subject e2e-runner-jetson 2>&1); then
echo "ERROR: mint_dev_jwt.py failed:" >&2
echo "${SATELLITE_PROVIDER_API_KEY}" >&2
exit 71
fi
export SATELLITE_PROVIDER_API_KEY
fi
# Pre-quote the env vars for safe heredoc injection. `${var@Q}` would be
# cleaner but it requires bash 4.4+; macOS ships bash 3.2 and we want to
# stay portable. `printf %q` is in bash 2+.
@@ -88,6 +103,7 @@ JWT_SECRET_Q=$(printf '%q' "${JWT_SECRET}")
JWT_ISSUER_Q=$(printf '%q' "${JWT_ISSUER}")
JWT_AUDIENCE_Q=$(printf '%q' "${JWT_AUDIENCE}")
GOOGLE_MAPS_API_KEY_Q=$(printf '%q' "${GOOGLE_MAPS_API_KEY:-}")
SATELLITE_PROVIDER_API_KEY_Q=$(printf '%q' "${SATELLITE_PROVIDER_API_KEY}")
# ----------------------------------------------------------------------
# Pre-flight
@@ -208,6 +224,7 @@ export JWT_SECRET=${JWT_SECRET_Q}
export JWT_ISSUER=${JWT_ISSUER_Q}
export JWT_AUDIENCE=${JWT_AUDIENCE_Q}
export GOOGLE_MAPS_API_KEY=${GOOGLE_MAPS_API_KEY_Q}
export SATELLITE_PROVIDER_API_KEY=${SATELLITE_PROVIDER_API_KEY_Q}
cd "${REMOTE_DIR}"
docker compose -f "${COMPOSE_FILE}" build e2e-runner satellite-provider
EOF
@@ -226,6 +243,7 @@ export JWT_SECRET=${JWT_SECRET_Q}
export JWT_ISSUER=${JWT_ISSUER_Q}
export JWT_AUDIENCE=${JWT_AUDIENCE_Q}
export GOOGLE_MAPS_API_KEY=${GOOGLE_MAPS_API_KEY_Q}
export SATELLITE_PROVIDER_API_KEY=${SATELLITE_PROVIDER_API_KEY_Q}
cd "${REMOTE_DIR}"
exec docker compose -f "${COMPOSE_FILE}" up \
--abort-on-container-exit \