Files
svg-backend/backend/docs/smoke-regression.md
greebo 0f9c2a1cbd feat(backend): add operational smoke tooling and safe pricing cleanup endpoints
- add backend README and refresh API map and smoke regression docs
- add full backend smoke regression script
- add admin pricing cleanup preview and dry-run endpoints
- add helper script for test pricing cleanup
- verify typed error contracts, draft flow, publish readiness and preview flows
- verify publish preview retention and clean backend startup behavior
2026-03-19 22:54:12 +03:00

8.6 KiB

Smoke regression checklist

This file is the backend manual regression baseline for svg-service.

Preconditions

  • docker compose stack is up
  • backend responds on port 9020
  • valid admin API key is available
  • test scheme exists

Environment

Use these variables in shell:

export API_URL="http://127.0.0.1:9020" export API_KEY="admin-local-dev-key" export SCHEME_ID="82086336d385427f9d56244f9e1dd772"

Main script

Primary operator regression:

backend/scripts/smoke_regression.sh

The script is expected to fail fast on any contract break or unexpected 5xx.

1. Health / system

  • GET /healthz -> 200
  • GET /api/v1/ping -> 200
  • GET /api/v1/db/ping -> 200
  • GET /api/v1/manifest -> 200

2. Scheme registry

  • GET /api/v1/schemes -> 200
  • GET /api/v1/schemes/{scheme_id} -> 200
  • GET /api/v1/schemes/{scheme_id}/current -> 200
  • GET /api/v1/schemes/{scheme_id}/versions -> 200

Validate:

  • scheme_id is stable
  • current version exists
  • version list contains current version
  • status and counts are consistent

3. Editor entry flow

  • GET /api/v1/schemes/{scheme_id}/editor/context -> 200
  • POST /api/v1/schemes/{scheme_id}/draft/ensure -> 200

Validate:

  • editor context returns current_scheme_version_id
  • editor context distinguishes draft vs published state correctly
  • ensure endpoint is idempotent on current draft
  • ensure endpoint creates a new draft from published current when needed
  • returned scheme_version_id is reusable as expected_scheme_version_id

4. Draft read model

Using current draft version id from draft/ensure:

  • GET /api/v1/schemes/{scheme_id}/draft/summary?expected_scheme_version_id={draft_version_id} -> 200
  • GET /api/v1/schemes/{scheme_id}/draft/structure?expected_scheme_version_id={draft_version_id} -> 200
  • GET /api/v1/schemes/{scheme_id}/draft/validation?expected_scheme_version_id={draft_version_id} -> 200
  • GET /api/v1/schemes/{scheme_id}/draft/compare-preview?expected_scheme_version_id={draft_version_id} -> 200

Validate:

  • summary returns total_seats / total_sectors / total_groups
  • summary returns validation_summary / structure_diff_summary / publish_readiness
  • structure returns lists for seats / sectors / groups
  • validation is deterministic
  • compare preview returns stable diff structure
  • stale expected_scheme_version_id returns typed 409 conflict

5. Draft entity reads

  • GET /api/v1/schemes/{scheme_id}/draft/seats/records/{seat_record_id} -> 200
  • GET /api/v1/schemes/{scheme_id}/draft/sectors/records/{sector_record_id} -> 200
  • GET /api/v1/schemes/{scheme_id}/draft/groups/records/{group_record_id} -> 200

Validate:

  • record endpoints return exact draft entities
  • unknown record id returns 404
  • stale expected_scheme_version_id returns typed 409 conflict

6. Structure read model

  • GET /api/v1/schemes/{scheme_id}/current/sectors -> 200
  • GET /api/v1/schemes/{scheme_id}/current/groups -> 200
  • GET /api/v1/schemes/{scheme_id}/current/seats -> 200

Validate:

  • total counts are non-negative
  • known sample scheme returns expected object lists
  • seats contain seat_id / sector_id / group_id contract where applicable

7. SVG / display pipeline

  • GET /api/v1/schemes/{scheme_id}/current/svg -> 200
  • GET /api/v1/schemes/{scheme_id}/current/svg/display -> 200
  • GET /api/v1/schemes/{scheme_id}/current/svg/display/meta -> 200
  • GET /api/v1/schemes/{scheme_id}/current/svg/display?mode=optimized -> 200 or explicit controlled failure
  • GET /api/v1/schemes/{scheme_id}/current/svg/display/meta?mode=optimized -> 200 or explicit controlled failure

Validate:

  • response content type for svg endpoints is image/svg+xml
  • meta returns scheme_id, scheme_version_id, view_box, width, height
  • no 500 on passthrough mode
  • unsupported mode returns 422

8. Pricing read model

  • GET /api/v1/schemes/{scheme_id}/pricing -> 200
  • GET /api/v1/schemes/{scheme_id}/pricing/coverage -> 200
  • GET /api/v1/schemes/{scheme_id}/pricing/unpriced-seats -> 200
  • GET /api/v1/schemes/{scheme_id}/pricing/explain/{seat_id} -> 200
  • GET /api/v1/schemes/{scheme_id}/pricing/rules/diagnostics -> 200
  • GET /api/v1/schemes/{scheme_id}/current/seats/{seat_id}/price -> 200 for priced seat
  • GET /api/v1/schemes/{scheme_id}/test/seats/{seat_id} -> 200 for known seat

Validate:

  • pricing bundle contains categories and rules arrays
  • coverage values are internally consistent
  • unpriced seats list explains reason_code / reason_message
  • explain endpoint shows matched rule for priced seat and null for unpriced seat
  • diagnostics returns orphan/active rule visibility
  • test seat preview explains selectable / has_price state
  • priced test seat amount is serialized as string

9. Draft mutations and validation guards

For current draft version:

  • POST /api/v1/schemes/{scheme_id}/draft/sectors -> 200 or 422
  • POST /api/v1/schemes/{scheme_id}/draft/groups -> 200 or 422
  • PATCH /api/v1/schemes/{scheme_id}/draft/seats/records/{seat_record_id} -> 200 or 422
  • POST /api/v1/schemes/{scheme_id}/draft/seats/bulk -> 200 or 422
  • POST /api/v1/schemes/{scheme_id}/draft/remap/preview -> 200 or 422
  • POST /api/v1/schemes/{scheme_id}/draft/remap/apply -> 200 or 422
  • POST /api/v1/schemes/{scheme_id}/draft/repair-references -> 200

Validate:

  • duplicate ids return typed 422
  • duplicate element binding returns typed 422
  • unknown sector/group references return typed 422
  • remap without filters returns typed 422
  • stale expected_scheme_version_id returns typed 409
  • published current version rejects draft mutations with typed draft_not_editable conflict

10. Draft publish preview

  • POST /api/v1/schemes/{scheme_id}/draft/pricing/snapshot -> 200 when scheme is in draft
  • GET /api/v1/schemes/{scheme_id}/draft/publish-preview?refresh=true -> 200
  • GET /api/v1/schemes/{scheme_id}/draft/publish-preview -> 200
  • GET /api/v1/schemes/{scheme_id}/draft/publish-preview?refresh=true&baseline_scheme_version_id={published_version_id} -> 200

Validate:

  • refresh and cached read both succeed
  • preview summary contains is_publishable / has_structure_changes / has_artifacts / snapshot_available
  • pricing_coverage is internally consistent
  • baseline override returns override strategy when explicit baseline is provided
  • preview retention does not grow unbounded for same version+variant

11. Publish readiness and publish flow

For current draft version:

  • GET /api/v1/schemes/{scheme_id}/draft/publish-readiness -> 200
  • POST /api/v1/schemes/{scheme_id}/publish?expected_scheme_version_id={draft_version_id} -> 200 or 409

Validate:

  • readiness explicitly shows snapshot_available and pricing gate state
  • publish with stale expected version returns typed 409
  • publish without draft state returns typed 409
  • publish success updates current status to published
  • audit trail contains scheme.published event

12. Admin / ops

  • GET /api/v1/admin/schemes/{scheme_id}/current/artifacts -> 200
  • GET /api/v1/admin/schemes/{scheme_id}/current/validation -> 200
  • GET /api/v1/admin/artifacts/publish-preview/audit -> 200
  • POST /api/v1/admin/artifacts/publish-preview/cleanup?dry_run=true -> 200
  • GET /api/v1/admin/schemes/{scheme_id}/pricing/categories/cleanup-preview -> 200
  • POST /api/v1/admin/schemes/{scheme_id}/pricing/categories/cleanup with dry_run=true -> 200

Validate:

  • artifact audit does not report orphan files or missing files for DB rows in normal state
  • validation report is readable and deterministic
  • pricing cleanup preview returns matched candidates and safe_to_delete_count
  • pricing cleanup dry-run returns deleted_count=0 and would_delete_count>0
  • admin routes do not produce 500 for healthy scheme state

13. Audit trail

  • GET /api/v1/schemes/{scheme_id}/audit -> 200

Validate:

  • recent publish preview / pricing / version / publish events are present when corresponding operations were run
  • audit total is non-negative
  • event payloads stay JSON-serializable

14. Fail criteria

Regression is considered failed if any of the following happen:

  • health or db ping fails
  • any stable read endpoint returns 500
  • passthrough display endpoint fails on known-good sample
  • publish preview refresh or cached read returns 500
  • publish readiness returns 500
  • editor context or draft ensure returns 500
  • draft summary / structure / validation / compare-preview returns 500
  • pricing bundle or diagnostics contract changes unexpectedly
  • admin audit/cleanup endpoints fail on healthy environment
  • pricing cleanup dry-run mutates data
  • artifact retention grows without bound for repeated preview refresh on same variant

15. Operator note

Run this checklist after:

  • schema changes
  • pricing schema/repository refactors
  • artifact lifecycle changes
  • display pipeline changes
  • route reorganization
  • startup/import/config changes
  • draft lifecycle changes
  • publish readiness changes
  • admin cleanup changes