docs(PBI-96/T-1075): demo-policy audit — drie lagen volledig

Audit-rapport in docs/recommendations/PBI-96-demo-audit-2026-05-16.md.
Bevestigt dat alle 3 lagen van de demo-policy volledig zijn:

- Laag 1 (proxy.ts): n.v.t. — geen REST-routes in v1
- Laag 2 (server-actions): alle 4 writes hebben isDemo-guard; list-action
  bewust niet (demo MAG lezen volgens plan §B.4)
- Laag 3 (UI): alle write-knoppen DemoTooltip-wrapped + disabled in demo

Geen actie nodig. Manual e2e (stap 9 uit plan-verificatie) blijft als
beheerder-taak vóór merge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Janpeter Visser 2026-05-16 14:36:50 +02:00
parent 23cce4f35b
commit 9cbbabe469
2 changed files with 64 additions and 0 deletions

View file

@ -131,6 +131,7 @@ Auto-generated on 2026-05-16 from front-matter and headings.
| [Review — M8 bootstrap-wizard plan v3.4](./recommendations/bootstrap-wizard-plan-v3-4-review-2026-05-14.md) | `recommendations/bootstrap-wizard-plan-v3-4-review-2026-05-14.md` | — | — |
| [Aanbeveling — Claude VM jobflow en gitstrategie](./recommendations/claude-vm-job-flow-git-strategy.md) | `recommendations/claude-vm-job-flow-git-strategy.md` | draft | 2026-05-09 |
| [Load/render implementatie review](./recommendations/load-render-implementation-review-2026-05-10.md) | `recommendations/load-render-implementation-review-2026-05-10.md` | review | 2026-05-10 |
| [PBI-96 demo-policy audit](./recommendations/PBI-96-demo-audit-2026-05-16.md) | `recommendations/PBI-96-demo-audit-2026-05-16.md` | review | 2026-05-16 |
| [Agent-flow: open issues & decision log](./runbooks/agent-flow-pitfalls.md) | `runbooks/agent-flow-pitfalls.md` | active | 2026-05-03 |
| [Auto-PR flow: van story-DONE naar gemergde PR](./runbooks/auto-pr-flow.md) | `runbooks/auto-pr-flow.md` | active | 2026-05-06 |
| [Branch, PR & Commit Strategy](./runbooks/branch-and-commit.md) | `runbooks/branch-and-commit.md` | active | 2026-05-03 |

View file

@ -0,0 +1,63 @@
---
title: "PBI-96 demo-policy audit"
status: review
audience: [maintainer]
language: nl
last_updated: 2026-05-16
applies_to: PBI-96
---
# PBI-96 — Demo-policy audit (T-1075)
Verifieert dat de drie-laagse demo-policy (CLAUDE.md hardstop) volledig is geïmplementeerd voor de Product Docs feature. Audit-methode: grep + handmatige cross-check tegen plan §B.4.
## Laag 1 — proxy.ts
**Status: ✅ N.v.t.**
`proxy.ts` blokkeert niet-GET requests op API-paden voor demo-users. PBI-96 voegt **geen REST-routes** toe in v1 — alle mutations gaan via server-actions (Next.js `/_next/`-internals), die niet door `proxy.ts` worden gefilterd. Demo-policy laag 2 vangt dit op.
Indien in v1.1 een REST-endpoint wordt toegevoegd voor MCP-tools (`/api/product-docs/...`): demo-user wordt automatisch 403 door bestaande catch-all.
## Laag 2 — server-actions (`actions/product-docs.ts`)
**Status: ✅ Volledig**
| Action | Regel | Demo-guard regel | Verwacht gedrag |
|---|---|---|---|
| `createProductDocAction` | 64 | 69 | demo → 403 |
| `updateProductDocAction` | 170 | 176 | demo → 403 |
| `deleteProductDocAction` | 266 | 269 | demo → 403 |
| `toggleProductDocFolderAction` | 317 | 322 | demo → 403 |
| `listProductDocsAction` | 387 | (geen) | demo MAG lezen — bewust geen guard |
Alle 4 write-actions hebben `if (session.isDemo) return { error: 'Niet beschikbaar in demo-modus', code: 403 }` direct na de 401-check, vóór rate-limit en validatie. List-action is read-only — demo-user kan dus alle docs in toegankelijke producten lezen, conform plan §B.4.
Tests bevestigen 403-gedrag in `__tests__/actions/product-docs.test.ts` voor alle 4 write-actions.
## Laag 3 — UI
**Status: ✅ Volledig**
Alle write-knoppen zijn `<DemoTooltip show={isDemo}>`-wrapped en `disabled={isDemo}`:
| Component | Knop | Locatie | Status |
|---|---|---|---|
| `new-product-doc-dialog.tsx` | "Nieuwe doc" trigger | :160-175 | ✅ |
| `delete-product-doc-button.tsx` | "Verwijderen" trigger | :62-80 | ✅ |
| `product-doc-folder-toggle.tsx` | Folder-checkboxes (per checkbox) | :109-130 | ✅ |
| `[folder]/[slug]/page.tsx` | "Bewerken"-button | :97 (`isFolderEnabled && !isDemo`) | ✅ |
`isDemo` wordt op elke server-page geladen via `session.isDemo ?? false` en als prop doorgegeven aan de client-componenten.
## Bevindingen
Geen actie nodig. Demo-policy is volledig conform CLAUDE.md hardstop ("Demo: drie lagen — proxy.ts + server action + UI disabled knop").
## Manual e2e (uit te voeren bij review)
10-stappen smoke uit `docs/plans/PBI-96-product-docs.md` §Verificatie. Demo-stappen zijn:
- **Stap 9**: Login als demo → docs/inhoud lezen werkt; "Nieuwe doc"/"Bewerken"/"Verwijderen"/folder-toggle knoppen disabled met tooltip; directe action-call (via DevTools) → 403.
Te valideren door beheerder vóór merge. Audit is gereed.