mirror of
https://github.com/Sea-Haven-Industries/procurement-ingest.git
synced 2026-09-30 13:03:14 +00:00
Implements docs/shoc-webhook-plan.md Phases 1-5 (PR-2 of the SHOC call-and-be-called effort). Everything ships DARK: both DynamoDB event source mappings deploy enabled=False; activation is a deliberate one-line follow-up PR gated on the SHOC receiver passing the shared HMAC test vectors. - Streams: NEW_AND_OLD_IMAGES on WorkOrders + WorkOrderComments (in-place update, RETAIN + logical IDs untouched; no existing consumers — verified live, neither table had a stream). - workorder-shoc-emitter (Py3.12/ARM64): stream -> envelope -> HMAC-signed POST per docs/shoc-webhook-contract.md; strict per-shard ordering (parallelization 1, bisect off, retry until 24h age, ReportBatchItemFailures); 429/5xx/timeout block the shard in order, other 4xx park to workorder-shoc-emitter-rejected; ESM failures -> workorder-shoc-emitter-failures (metadata; replay rebuilds from DynamoDB). Echo guard skips write_origin=shoc-write-api. - Secret workorder-ingest/shoc-webhook-hmac on a dedicated CMK (alias workorder-ingest-shoc-webhook-kms); cross-account GetSecretValue/DescribeSecret + kms:Decrypt granted to exactly arn:aws:iam::396287094661:role/shoc-backend-dev. RemovalPolicy DESTROY deliberately (machine-generated material; avoids the fixed-name RETAIN-orphan deadlock). - workorder-shoc-hmac-rotator: 30-day rotation, dual-key overlap, 64-hex keys, kid = UTC %Y-%m-%dT%H. - Alarms (ALARM-only -> site-alerts): emitter errors/throttles/ duration + iterator-age (>=10 min) + failures/rejected queue depth; rotator standard trio. - scripts/replay_shoc_webhooks.py: dry-run-default operator replay (rebuilds from tables, replay:true envelopes). - Tests: 742 passing, 85.56% aggregate; golden HMAC vectors shared with SHOC in docs/shoc-webhook-test-vectors.json (emitter + replay signing pinned to identical vectors); bundle-consistency AST pins for both new bundles. - README: WO stack + webhook feed section, alarm table, runbooks; removed stale seahaven-slack-bot consumer references.
27 lines
1.2 KiB
INI
27 lines
1.2 KiB
INI
[pytest]
|
|
; Three test roots: cross-pipeline tests/, plus each pipeline's own
|
|
; email_processor/tests/ offline suite (deterministic template parser +
|
|
; Bedrock fallback dispatch + healthcheck, per pipeline).
|
|
testpaths =
|
|
tests
|
|
lambdas/wo/email_processor/tests
|
|
lambdas/po/email_processor/tests
|
|
addopts =
|
|
--cov=lambdas/po/email_processor
|
|
--cov=lambdas/wo/email_processor
|
|
--cov=lambdas/po/web_ui
|
|
--cov=lambdas/wo/web_ui
|
|
--cov=lambdas/po/site_extractor
|
|
--cov=lambdas/api
|
|
--cov=lambdas/shared
|
|
--cov=lambdas/wo/shoc_emitter
|
|
--cov=lambdas/wo/shoc_hmac_rotator
|
|
--cov-report=term-missing
|
|
--cov-fail-under=80
|
|
; The 80% floor is an aggregate whole-suite gate, enforced in CI by the
|
|
; reusable ci-python-sam workflow's bare `pytest` run (which inherits these
|
|
; addopts). Because the floor is inherited by every invocation, running a
|
|
; single root or file for local iteration (e.g. `pytest tests/test_web_ui_auth.py`)
|
|
; under-measures the fixed --cov set and red-exits even when the selected tests
|
|
; pass. That is expected: append `--cov-fail-under=0` (or `-p no:cov`) to a
|
|
; subset run to skip the floor while iterating. The full-suite run still gates.
|