Skip to content

[EPAC-2288]: Expose bill diff deployment route#812

Merged
riddim-developer-bot[bot] merged 1 commit into
mainfrom
symphony/epac-2288-expose-the-bill-diff-route-in-deployment-manifes
Jun 14, 2026
Merged

[EPAC-2288]: Expose bill diff deployment route#812
riddim-developer-bot[bot] merged 1 commit into
mainfrom
symphony/epac-2288-expose-the-bill-diff-route-in-deployment-manifes

Conversation

@riddim-developer-bot

Copy link
Copy Markdown
Contributor

Scope

  • Declares GET /api/v1/bills/{id}/diff for the bills service in both staging and production deployment manifests.
  • Adds a Bills OpenAPI-to-manifest parity guard to check_backend_manifest_deployment.py so missing routes and method/path drift fail before AWS topology reads.
  • Adds a default bills:diff-route smoke check that distinguishes API Gateway {"message":"Not Found"} from the bills service's own missing-parameter response, plus an opt-in --mode full seeded C-8 diff payload check.

Bugfix SPEC

  • Spec: EPAC-2288
  • Trace ID: N/A - Linear implementation issue.

Testing notes

  • Automated tests run:
    • python3 -m pytest scripts/ci/tests scripts/ci/test_backend_staging_smoke.py scripts/ci/test_ios_coverage_report.py
    • cd backend/openapi && go test ./...
    • jq empty backend/manifest/deployment-services.json backend/openapi/openapi.json
  • Manual verification:
    • python3 scripts/ci/backend_staging_smoke.py --list | rg "bills:(list|diff-route|diff-full)|hansard-search|cabinet-lobbying-overview|lobbyist-organizations"
    • Local OpenAPI/manifest parity probe returns no failures for staging or production.
  • Skipped checks: Live staging/production smoke requests were not run locally because they require deployed AWS API state; the backend deploy workflows run route sync, manifest topology/readiness, and smoke checks.
  • CLI surface score: 84/100. Worst findings: existing scripts still do not expose quiet/verbose modes; the manifest deployment checker has no first-byte banner before normal AWS reads; TTY behavior is line-oriented but not explicitly mode-aware. No blocking findings for this scoped change.

Screenshots

N/A - backend deployment and CI script change.

Related issue

  • Closes: EPAC-2288

Release-Note: Exposes the bills version diff backend route through staging and production deployment wiring.

@riddim-developer-bot riddim-developer-bot Bot enabled auto-merge (squash) June 14, 2026 17:35
@riddim-developer-bot riddim-developer-bot Bot merged commit dd1b135 into main Jun 14, 2026
61 of 62 checks passed
@riddim-developer-bot riddim-developer-bot Bot deleted the symphony/epac-2288-expose-the-bill-diff-route-in-deployment-manifes branch June 14, 2026 17:38
riddim-developer-bot Bot added a commit that referenced this pull request Jun 14, 2026
…aging smoke (#817)

## Scope

Completes the staging-smoke half of EPAC-2285 by adding the one
deterministic assertion the issue's risk note calls out as "the
regression that created the current miss": distinguishing an **API
Gateway route-missing 404** (`{"message":"Not Found"}`) from the bills
service's **own application-level 404** for an unknown bill/version.

The rest of EPAC-2285 already landed on `main` via the sibling EPAC-2288
(PR #812): the `GET /api/v1/bills/{id}/diff` route in the
staging+production manifest, the OpenAPI↔manifest parity guard in
`check_backend_manifest_deployment.py`, and the `bills:diff-route` /
`bills:diff-full` smoke checks. EPAC-2288's `bills:diff-route` only
exercises the missing-parameter HTTP 400 path, so the application-level
404 path was never driven by a default-mode check.

This PR adds **`bills:diff-unknown`**:

- `GET /api/v1/bills/ZZ-9999/diff?from=v1&to=v2` — an unknown bill id
with `from`/`to` present, so the bills Lambda reaches `lookupBillID`,
returns `ErrBillNotFound`, and the handler responds `404 {"error":"bill
not found"}` **before any version/diff lookup**. No backfilled diff data
is required, so it runs in default contract mode.
- The validator fails on the API Gateway 404, requires a service-owned
`error` body (proving the request reached the Lambda), asserts the 404
is a documented not-found message, and tolerates a warming `503`.
- `service="bills"`, default mode (not `full_only`), so it runs in both
staging and production smoke whenever bills is deployed. It mirrors the
existing `riding-boundary:unknown-slug` negative-check pattern.

### Acceptance criteria

| Criterion | Status |
|---|---|
| Manifest declares `GET /api/v1/bills/{id}/diff` for bills (staging +
production) | Met on `main` (EPAC-2288) |
| OpenAPI aligned (route, `id`/`from`/`to`, 200/204/400/404/429/500/503)
| Met on `main` (EPAC-2288) |
| Deployment checker fails when the route is missing from API Gateway |
Met on `main` (EPAC-2288, with tests) |
| Staging smoke includes a deterministic bill diff assertion |
`bills:diff-route` (existing) **+ `bills:diff-unknown` (this PR)** —
completes the API-Gateway-404-vs-app-404 distinction |
| Production has equivalent route sync/readiness coverage |
`bills:diff-unknown` is default-mode for bills, run by
`backend-production.yml` |
| Existing backend smoke checks continue to pass | Yes — 65 tests pass;
no other check changed |

**DoD** — "the staging smoke contract would have failed on the current
API Gateway 404 state": both `bills:diff-route` and the new
`bills:diff-unknown` fail on `{"message":"Not Found"}` via
`is_api_gateway_not_found`.

## Bugfix SPEC
* **Spec:**
[EPAC-2285](https://linear.app/riddimsoftware/issue/EPAC-2285/wire-bill-diff-route-deployment-checks)
— Linear implementation issue (not a bug-intake SPEC).
* **Trace ID:** N/A

## Testing notes
* **Automated tests run:**
- `python3 -m pytest scripts/ci/tests
scripts/ci/test_backend_staging_smoke.py
scripts/ci/test_ios_coverage_report.py` → **65 passed** (exact
`pr-build.yml` invocation; +2 new validator tests).
- `python3 scripts/ci/backend_staging_smoke.py --list | grep bills:diff`
confirms `bills:diff-unknown [bills]` runs in default contract mode (no
`[full]` marker), alongside `bills:diff-route`.
* **Manual verification:** Traced the handler contract in
`backend/bills/main.go` (`mapBillVersionDiffError`) and
`internal/usecase/bills.go` / `adapter/sqlite/repository.go`
(`lookupBillID` → `ErrBillNotFound` for an unknown bill via
`sql.ErrNoRows`) to confirm an unknown bill id deterministically yields
a service-owned 404 before any version/diff data is needed.
* **Skipped checks:** Live staging/production smoke requests were not
run locally — they require deployed AWS API state. The
`backend-staging.yml` / `backend-production.yml` workflows run the smoke
(default contract mode) and the manifest deployment checker against live
infrastructure on deploy.

## Screenshots
N/A — backend CI / smoke-test change, no UI surface.

## Related issue
- Closes: EPAC-2285

Release-Note: N/A — CI smoke-test coverage only; no user-facing change.

Co-authored-by: riddim-developer-bot <developer-bot@riddimsoftware.com>
riddim-developer-bot Bot added a commit that referenced this pull request Jun 14, 2026
## What & why

Post-implementation **architecture verification** of the *Bill diff
backend completion* Project
([EPAC-2293](https://linear.app/riddimsoftware/issue/EPAC-2293/architecture-verification-for-bill-diff-backend-completion)).
This is an `arch-team` Project Verification gate — not a PR review and
not an implementation change. It scores the *merged* Project state on
`origin/main` and records the result as a checked-in scorecard, mirrored
to a Linear comment on EPAC-2293.

Docs-only: adds
`docs/architecture/bill-diff-backend-completion-verification-epac2293.md`.
No application/backend code is touched (the issue's "no implementation
PR / no code patching" constraint is preserved).

## Verdict

**7.5 / 10.0 — Healthy (high pass).** No Cardinal Sin, no Hidden
Dependency.

What holds:
- Dependency direction holds in both Go services (`domain` imports no
use case/adapter/SDK; use cases depend on ports; `main.go` is the
composition root).
- Serving split is correct: `LoadBillVersionDiff` owns the 204-vs-404
policy, the handler is thin, the repository owns SQLite.
- **Civic-content provenance is clean** — verbatim XML→clause text
end-to-end, structural `change_type` only, honest `nil` Hansard anchors;
no generated/summarized parliamentary text.
- Deployment smoke distinguishes API Gateway 404 from app-level 404 —
directly targeting the original regression.
- OpenAPI + use-case catalog updated by the implementing PRs.

Deductions (−2.5): Behavioral Leakage −1.0 + Catalog Drift −1.0
(clause-diff policy lives in the LEGISinfo source adapter, not the
cataloged indexer use case) → **EPAC-2303**; Enforcement Gap −0.5 (bills
SQLite artifact schema is an unverified cross-adapter contract; sparse
served version metadata) → **EPAC-2304**.

## Reconstructed inputs

Originally-named siblings EPAC-2283/2284 were re-scoped (still in
Backlog). Actual merged work scored: EPAC-2286 (#810), EPAC-2298 (#814),
EPAC-2287 (#811), EPAC-2299 (#815), EPAC-2288 (#812), EPAC-2285 (#817),
EPAC-2289 (#818), via `git fetch origin main` + merged commits.

## Follow-ups filed (non-blocking, `arch`, est. 4)

- [EPAC-2303](https://linear.app/riddimsoftware/issue/EPAC-2303) —
Implement `ComputeBillVersionDiff` use case in the bills-indexer
application layer.
- [EPAC-2304](https://linear.app/riddimsoftware/issue/EPAC-2304) — Lock
the bills SQLite artifact schema with a producer-to-consumer seam test.

## Verification evidence

- Scope is docs-only (`git diff origin/main..HEAD --stat`: 1 file,
+117). No Go/Swift/CI code changed, so no build or simulator run
applies; `pr-build` covers the change.
- EPAC-2293 attached to the *Bill diff backend completion* Project;
scorecard comment posted on the issue.

Release-Note: none (docs-only architecture verification record).

Co-authored-by: riddim-developer-bot <developer-bot@riddimsoftware.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants