feat(audit-policy): implement audit-scope/summary E5 (B7 / SITES-47089) - #3032
Open
sandsinh wants to merge 1 commit into
Open
feat(audit-policy): implement audit-scope/summary E5 (B7 / SITES-47089)#3032sandsinh wants to merge 1 commit into
sandsinh wants to merge 1 commit into
Conversation
Real implementation of GET /sites/{siteId}/audit-scope/summary, replacing
the 501 stub. Reads v_audit_scope_summary (mysticat-data-service migration
20260811193840_audit_scope_summary_view.sql), maps to the R8 shape via a
new AuditScopeSummaryDto, falls back to defaultDocument() (budget 5000 /
strategyName tiered) when the site has no rows yet — same convention as
AuditPolicyDto.defaultDocument.
OpenAPI: audit-scope-summary now documents 200 + AuditScopeSummary schema
with a response example, plus 400/401/403/404/500 matching the sibling
audit-scope-pages block. getScopeSections stays a 501 stub (E6, out of
scope for this ticket).
Tests: split getScopeSummary out of the E4-E6 501-stub loop, added 5 unit
tests (DTO shape, site_id filter, default-fallback, 403, 500). IT: split
API-15 so only /audit-scope/sections asserts 501; added a describe.skip'd
block for /audit-scope/summary, gated on the mysticat-data-service Docker
image pin (test/it/postgres/docker-compose.yml, v5.90.0) catching up to a
release containing v_audit_scope_summary — same gating E4 originally used.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Please ensure your pull request adheres to the following guidelines:
describe here the problem you're solving.
If the PR is changing the API specification:
yet. Ideally, return a 501 status code with a message explaining the feature is not implemented yet.
(
getScopeSections/ E6 stays a 501 stub — out of scope here,audit-scope-sectionspath unchanged.)If the PR is changing the API implementation or an entity exposed through the API:
If the PR is introducing a new audit type: N/A
Related Issues
SITES-47089 —
[Spec] B7 — scope observability + section aggregation APIs (R8/R14/R15)(sub-task of SITES-44768, Audit Policy epic). This PR covers R8 only (E5,
audit-scope/summary). R14/E6 (audit-scope/sections) stays 501, tracked separatelyunder the same ticket.
Companion data-layer PR (must land first / together):
adobe/mysticat-data-service#899 — adds
v_audit_scope_summary, the view this endpoint reads.Summary
Replaces the
501stub forGET /sites/{siteId}/audit-scope/summarywith a realimplementation: R8 reconciliation counts over
page_inventory.Request
No query parameters,
siteIdpath param only (same sharedsiteIdparameter everyother endpoint in this file uses).
Response (200)
{ "inList": 1400, "audited": 950, "excluded": 120, "lifecycleSuppressed": 80, "keptStaleDetection": 5, "notYetScanned": 245, "budget": 5000, "strategyName": "tiered" } // inList = audited + excluded + lifecycleSuppressed + keptStaleDetection + notYetScannedOn a site with no rows/policy yet:
{ inList: 0, audited: 0, excluded: 0, lifecycleSuppressed: 0, keptStaleDetection: 0, notYetScanned: 0, budget: 5000, strategyName: "tiered" }(AuditScopeSummaryDto.defaultDocument(), same convention asAuditPolicyDto.defaultDocument()).This example is also now inline in
docs/openapi/audit-policy-api.yamlunder the200response, per the template requirement above.
Key decision carried over from the companion PR
Three of the five buckets in the response depend on blocks that don't exist yet: B5
(exclusion application, writes
page_inventory.excluded_reason), B4 v1.1 (AEM-onlycut/staleness guard, populates
cms_type), B6 (lifecycle transitions). Considered buildingthe exclusion-glob matcher (D7) in this cycle so
excludedwould show real numbersimmediately — rejected, because it would duplicate logic B5 owns and risks the summary
and the future exclusion-application logic disagreeing (the exact anti-pattern design
decision D10 calls out). Went with reading only from columns/predicates that already
exist (
excluded_reason,cms_type/cms_confidence/cms_source_fresh_until) — bothbuckets correctly compute to
0today and will report real numbers automatically onceB4/B5 ship, no changes needed on this endpoint when that happens. Full detail in the
data-service PR's description.
Changes
src/controllers/audit-policy.js—getScopeSummarynow readsv_audit_scope_summaryvia
.from().eq('site_id', ...).maybeSingle()(same shape asgetPolicy/getScopePages),maps through the new DTO, falls back to the zeroed default document when no row exists.
getScopeSections(E6) untouched, still501.src/dto/audit-policy.js— newAuditScopeSummaryDto(toJSON+defaultDocument),reuses the existing
DEFAULTSconst.docs/openapi/audit-policy-api.yaml—audit-scope-summarypath:200+ newAuditScopeSummaryschema + inline response example +400/401/403/404/500(matching the sibling
audit-scope-pagesblock); added a request-example note in thedescription since this is a GET with no body.
docs/index.html— regenerated (npm run docs:build).getScopeSummaryout of theE4-E6 scope-read 501 stubsloop (renamed toE6 scope-read 501 stub, onlygetScopeSectionsleft in it); added a newE5 getScopeSummarydescribe block — DTO shape + identity check,site_idfilterassertion, default-fallback when no row, 403 without querying, 500 + log on PostgREST
error. 78/78 unit tests passing.
API-15so only/audit-scope/sectionsasserts501; added adescribe.skip'd block for/audit-scope/summary(API-13per the contract doc'stest matrix) — skipped because the pinned
mysticat-data-serviceimage intest/it/postgres/docker-compose.yml(v5.90.0) predates the view added in thecompanion PR. Un-skip once that pin bumps to a release containing
20260811193840_audit_scope_summary_view.sql— same sequencing E4(
v_audit_scope_pages) went through.Verification
npx eslintclean on all changed filesnpx mocha test/controllers/audit-policy.test.js— 78/78 passingnpm run docs:lint— valid, no new warnings against this filenpm run docs:build— succeedsbehavior against a real local Postgres (see companion data-service PR for the query
output)
Thanks for contributing!
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com