Continuous Integration / config (pull_request) Successful in 12s
Continuous Integration / changes (pull_request) Successful in 22s
Continuous Integration / backend-build (pull_request) Successful in 5m53s
Continuous Integration / vulnerability-scan (pull_request) Successful in 5m46s
Continuous Integration / frontend-prepare (pull_request) Successful in 1m54s
Continuous Integration / backend-test (pull_request) Successful in 7m37s
Continuous Integration / frontend-build (pull_request) Successful in 2m14s
Continuous Integration / frontend-test (pull_request) Successful in 4m59s
Continuous Integration / frontend-lint (pull_request) Successful in 2m2s
Continuous Integration / publish-production (pull_request) Skipped
Continuous Integration / deploy-production (pull_request) Skipped
Continuous Integration / publish-test (pull_request) Successful in 7m34s
Continuous Integration / deploy-test (pull_request) Skipped
Implements Unit 2 "Offerings" (backend module, admin CRUD UI with drag-and-drop reordering, public GET /api/v1/offerings endpoint) and executes the feature's D-15 CI/CD cutover, switching the deploy pipeline's build/publish target from SlpModularCms.Api to SlpModularCms.Api.SlpSoftware. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FWyStNL2ZsjrS7FLd7xvvN
60 lines
3.6 KiB
Markdown
60 lines
3.6 KiB
Markdown
# NFR Requirements Plan — Unit: Offerings
|
|
|
|
Investigated before drafting questions:
|
|
- `SlpModularCms.Core.Observability.SecurityEvents` (the existing structured security-alerting mechanism, `RateLimitTriggered` etc.) is purpose-built for **alertable anomalies** (brute force, forged tokens) — Warning-level, feeds Sentry alert rules (SECURITY-14). A routine "admin edited an offering" event is not an anomaly and would pollute that exact alerting mechanism if bolted on. SECURITY-13 (audit trail) is better served by plain `LogInformation`-level structured logging in `OfferingsService`, not by extending `SecurityEvents`.
|
|
- `ServiceCollectionExtensions.AddCmsRateLimiting` already defines three named policies (`login`, `refresh`, `sentry-tunnel`) via `appsettings.json`'s `RateLimiting:*` section — adding an `offerings` (or `offerings-public`/`offerings-admin`) policy would follow the exact same established pattern.
|
|
|
|
## Uitvoeringschecklist
|
|
|
|
- [x] Stap A — `nfr-requirements.md`: NFR's voor deze unit vastleggen (rate limiting, caching, audit-trail-afronding, testdekking)
|
|
- [x] Stap B — `tech-stack-decisions.md`: bevestigen dat geen nieuwe backend-technologie nodig is; vastleggen welke `RateLimiting`-policy(s) worden toegevoegd
|
|
|
|
---
|
|
|
|
## Vragen
|
|
|
|
### Vraag 1 — Rate limiting op de nieuwe endpoints
|
|
De publieke `GET /api/v1/offerings` en de admin-CRUD-endpoints hebben nog geen rate-limiting-policy (in tegenstelling tot Login/Refresh/SentryTunnel).
|
|
|
|
Welke endpoints moeten een rate-limiting-policy krijgen?
|
|
|
|
A) Alleen de publieke `GET`-endpoint (tegen scraping/misbruik van een anonieme, veelgebruikte endpoint) — admin-endpoints zijn al achter authenticatie, dus lager risico
|
|
B) Zowel de publieke `GET` als de admin-mutatie-endpoints — consistente verdediging in de diepte (SECURITY-11), ook al zijn admin-endpoints al geauthenticeerd
|
|
C) Geen van beide nu — dit achterwege laten, eventueel later toevoegen
|
|
X) Anders (beschrijf hieronder na de [Answer]:-tag)
|
|
|
|
[Answer]:A
|
|
|
|
### Vraag 2 — HTTP-caching op de publieke endpoint
|
|
De externe hand-off-doc noemt expliciet: "adding reasonable HTTP caching is welcome since this content changes rarely" voor `GET /api/v1/offerings`.
|
|
|
|
Wil je dit nu meenemen?
|
|
|
|
A) Ja — een simpele `Cache-Control: public, max-age=<N>` header op de publieke `GET`-response (bijv. 60-300 seconden); geen ETag/conditional-requests-complexiteit voor nu
|
|
B) Nee — geen caching-headers in deze unit; de frontend gebruikt toch al TanStack Query zonder custom staleTime (ziet er functioneel niet uit als een probleem)
|
|
X) Anders (beschrijf hieronder na de [Answer]:-tag)
|
|
|
|
[Answer]:B
|
|
|
|
### Vraag 3 — SECURITY-13-afronding: "wie" naast "wanneer"
|
|
Functional Design voegde `CreatedAt`/`UpdatedAt` toe aan `Offering` (het "wanneer"-deel van SECURITY-13). Het "wie"-deel (welke admin de wijziging maakte) staat nog los.
|
|
|
|
Wil je dat ook vastleggen?
|
|
|
|
A) Ja — voeg `LastModifiedByUserId` (of vergelijkbaar) toe aan `Offering`, gevuld vanuit de geauthenticeerde admin-gebruiker bij elke create/update/delete
|
|
B) Nee — `CreatedAt`/`UpdatedAt` is voldoende voor nu; "wie" blijft een bekend, geaccepteerd gat (net als de rest van SECURITY-13, al genoteerd als open item in requirements.md)
|
|
X) Anders (beschrijf hieronder na de [Answer]:-tag)
|
|
|
|
[Answer]: A
|
|
|
|
### Vraag 4 — Testdekkingsnorm
|
|
De `master-cms-module`-feature hanteerde een bestaande projectnorm van ≥80% testdekking voor nieuwe modules (NFR-MASTER-05).
|
|
|
|
Geldt dezelfde norm voor de Offerings-module?
|
|
|
|
A) Ja — zelfde ≥80%-norm aanhouden
|
|
B) Nee — andere norm (geef aan welke na de [Answer]:-tag)
|
|
X) Anders (beschrijf hieronder na de [Answer]:-tag)
|
|
|
|
[Answer]:A
|