Completes Operations phase: Monitoring Setup and Production Readiness Validation

Confirms existing tag-based Sentry alerting and domain-based UptimeRobot/
Umami monitoring already cover the Offerings module and the Api.SlpSoftware
cutover with no new configuration. Closes the SECURITY-13 audit-trail open
item and records the final production-readiness traceability, completing
the slpsoftware-api feature's AI-DLC lifecycle.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FWyStNL2ZsjrS7FLd7xvvN
This commit is contained in:
2026-08-02 16:35:00 +02:00
co-authored by Claude Sonnet 5
parent cfb06b28b6
commit 81af6cd151
7 changed files with 223 additions and 9 deletions
@@ -0,0 +1,46 @@
# Monitoring Setup Plan — slpsoftware-api
## Investigation (Before Drafting Anything)
Read `gitea-deployment-workflow/operations/monitoring/monitoring-instructions.md` in full, then
checked whether anything this feature added (the Offerings module, the D-15 cutover) needs new or
changed monitoring configuration.
- **Sentry alert rules (FR-19, tag-based)**: the six existing rules filter on the `security_event`
Sentry tag, not on message text or endpoint. Read `SlpModularCms.Core.Hosting.ServiceCollectionExtensions.AddCmsRateLimiting`'s
shared `OnRejected` callback — it calls `SecurityEvents.RateLimitTriggered` (tag
`rate_limit_triggered`) for **any** rejected policy, by name, not per-policy-hardcoded. The new
`offerings-public` policy added in Code Generation is therefore already covered by the existing
`rate_limit_triggered` alert rule with zero new configuration.
- **Authorization denials**: read `SecurityAuthorizationResultHandler.cs` — it's a global
`IAuthorizationMiddlewareResultHandler`, wired once in `Core`, firing `authorization_denied`
(tag) for **any** policy failure on **any** endpoint. `OfferingsController`'s `AdminOnly`-protected
actions are covered automatically; nothing Offerings-specific needed wiring.
- **No new alertable event type**: NFR-OFF-03's audit logging (`OfferingsService`'s
`LogInformation` calls) was deliberately kept **out of** `SecurityEvents`/Sentry (see NFR
Requirements' investigation) — routine content mutations are not alertable anomalies. Nothing to
add here by design.
- **UptimeRobot (D-23)**: the six monitors (`/health`, `/`, `/admin` × test/production) check
domains and paths, not a specific `.dll`. They already point at `test.slpsoftware.nl`/
`slpsoftware.nl` — the D-15 cutover changes which process answers behind those URLs, invisible to
a monitor that only checks the HTTP response. No new monitor needed; the public
`GET /api/v1/offerings` endpoint was never in scope for dedicated uptime monitoring (D-23 covers
liveness/static-hosting/admin-SPA checks only, not every individual API route).
- **Umami**: two website entries for the admin SPA, same URLs before and after the cutover. No
change.
- **Gitea variables**: `VITE_SENTRY_DSN`, `VITE_UMAMI_*`, `SECURITY_ALLOWED_SCRIPT_ORIGINS_*` all
already exist and are unaffected — same Sentry project (D-19), same Umami instance, same CSP
origins, none of which are tied to which project publishes the artifact.
## Why No Questions, No New Configuration
Every piece of monitoring infrastructure this feature could plausibly need is already covered by
`gitea-deployment-workflow`'s existing, tag-based/domain-based design — none of it hardcodes a
project name or is scoped to a specific endpoint in a way the cutover or the new module would break.
This stage's output is a documented confirmation, not new setup.
## Checklist
- [x] Create `operations/monitoring/monitoring-instructions.md` as a feature-local pointer document
recording this investigation and its "no changes needed" conclusion, so a future reader isn't
left wondering whether Offerings' monitoring was simply forgotten