Files
Oleksandr Bezdieniezhnykh d7d1c0ed6a [AZ-PENDING-1] [AZ-PENDING-2] Step 4 close-out: verification + docs
Phase 6 smoke (Docker, _docs/04_refactoring/01-testability-refactoring/
smoke-compose.yml):
  - Annotations app boots clean under ASPNETCORE_ENVIRONMENT=E2ETest.
  - /health 200 OK; /annotations with bearer returns 401 with the
    JWT library's own malformed-token rejection.
  - 0 IDX20108 occurrences in logs (C01 verified).
  - 0 IPAddress.Parse FormatException occurrences; FailsafeProducer
    reaches the broker via Docker DNS (C02 verified).
  - Full smoke report in verification.md.

Phase 7 docs:
  - architecture.md: retire Open Risks §6 (testability blocker
    resolved). Update the constraints block to describe the
    ASPNETCORE_ENVIRONMENT-gated RequireHttps behavior.
  - components/06_platform/description.md: one-liner on JwtExtensions
    JWKS gating.
  - components/02_annotations-realtime-sync/description.md: one-liner
    on FailsafeProducer host resolution accepting literal IP or DNS.
  - tests/test-data.md: refresh the JWKS URL configuration section to
    point at the resolved implementation instead of the open risk.

Task housekeeping:
  - _docs/02_tasks/todo/01_*.md -> done/
  - _docs/02_tasks/todo/02_*.md -> done/
  - _docs/_autodev_state.md: advance to Step 5 (Refactor Backlog Triage).

Tracker IDs remain placeholders pending Atlassian MCP availability —
real IDs to be assigned per
_docs/_process_leftovers/2026-05-14_testability-tracker.md.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-14 20:38:14 +03:00

100 lines
4.1 KiB
YAML

# Phase 6 smoke compose for the testability refactor.
#
# This is NOT the e2e harness (that lives in e2e/docker-compose.test.yml and is built in autodev Step 6).
# Purpose: prove the two testability fixes in the absence of a full test suite.
# - C01 (JWKS HTTPS env gate) — annotations boots with ASPNETCORE_ENVIRONMENT=E2ETest and an HTTP JWKS URL; the app should NOT log IDX20108 when fetching.
# - C02 (RabbitMQ host DNS resolution) — annotations boots with RABBITMQ_HOST=rabbitmq (Docker DNS service name); the FailsafeProducer drain cycle should NOT log a FormatException or "An invalid IP address was specified".
#
# Used by: smoke-run.sh (in this same folder), invoked manually as part of the refactor Phase 6 verification.
# Lifetime: ephemeral; tear down with `docker compose -f smoke-compose.yml down -v` after the smoke completes.
services:
postgres:
image: postgres:13
environment:
POSTGRES_DB: annotations
POSTGRES_USER: annotations
POSTGRES_PASSWORD: annotations
healthcheck:
test: ["CMD-SHELL", "pg_isready -U annotations -d annotations"]
interval: 2s
timeout: 3s
retries: 30
rabbitmq:
image: rabbitmq:3.13-management
environment:
RABBITMQ_DEFAULT_USER: annotations
RABBITMQ_DEFAULT_PASS: annotations
command: >
bash -c "rabbitmq-plugins enable --offline rabbitmq_stream rabbitmq_management
&& exec docker-entrypoint.sh rabbitmq-server"
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "ping"]
interval: 5s
timeout: 5s
retries: 30
# Stub JWKS server. Serves a minimal valid JWKS over plain HTTP at /.well-known/jwks.json.
# The key in this JWKS is intentionally unrelated to any real signing key — we only need
# the JWKS retrieval path to fire so we can observe whether IDX20108 (HTTPS-only) trips
# under ASPNETCORE_ENVIRONMENT=E2ETest. We do NOT validate any tokens during the smoke.
jwks-stub:
image: python:3.12-alpine
working_dir: /work
command:
- /bin/sh
- -c
- |
mkdir -p /work/.well-known
cat > /work/.well-known/jwks.json <<'JWKS'
{"keys":[{"kty":"EC","crv":"P-256","x":"f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU","y":"x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0","kid":"stub-smoke","use":"sig","alg":"ES256"}]}
JWKS
cd /work && exec python -m http.server 8080
healthcheck:
# 127.0.0.1 (not localhost) — alpine resolves localhost to IPv6 first and python -m http.server binds IPv4 only
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:8080/.well-known/jwks.json"]
interval: 2s
timeout: 3s
retries: 30
annotations:
# Run the annotations app directly via the .NET SDK container with the repo
# mounted, instead of building the production image. The production Dockerfile
# (src/Dockerfile) has a separate build-context bug that is OUT OF SCOPE for
# this testability refactor. Step 6 of the autodev flow will fix the
# production Dockerfile as part of the full test harness build.
image: mcr.microsoft.com/dotnet/sdk:10.0
working_dir: /repo
command: ["dotnet", "run", "--project", "src/Azaion.Annotations.csproj", "--no-launch-profile", "--urls", "http://0.0.0.0:8080"]
volumes:
- ../../..:/repo
environment:
ASPNETCORE_ENVIRONMENT: E2ETest
DATABASE_URL: postgresql://annotations:annotations@postgres:5432/annotations
JWT_ISSUER: https://e2e-issuer.test
JWT_AUDIENCE: annotations-smoke
JWT_JWKS_URL: http://jwks-stub:8080/.well-known/jwks.json
CorsConfig__AllowedOrigins__0: http://localhost
RABBITMQ_HOST: rabbitmq
RABBITMQ_STREAM_PORT: "5552"
RABBITMQ_PRODUCER_USER: annotations
RABBITMQ_PRODUCER_PASS: annotations
AZAION_REVISION: smoke-${USER:-local}
depends_on:
postgres:
condition: service_healthy
rabbitmq:
condition: service_healthy
jwks-stub:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:8080/health >/dev/null || exit 1"]
interval: 3s
timeout: 3s
retries: 30
networks:
default:
name: refactor-01-smoke-net