Add analytics and documentation updates

This commit is contained in:
Janpeter Visser 2026-04-25 15:11:51 +02:00
parent e0efb65efb
commit b5e967d8d3
15 changed files with 414 additions and 37 deletions

View file

@ -11,6 +11,7 @@ import { cookies } from 'next/headers'
import { z } from 'zod'
import { prisma } from '@/lib/prisma'
import { SessionData, sessionOptions } from '@/lib/session'
import { productAccessFilter } from '@/lib/product-access'
const schema = z.object({
productId: z.string().cuid(),
@ -32,9 +33,9 @@ export async function createPbi(formData: FormData) {
})
if (!parsed.success) return { error: parsed.error.flatten().fieldErrors }
// 3. Eigenaarschap controleren
// 3. Toegang controleren: eigenaar of gekoppeld product member
const product = await prisma.product.findFirst({
where: { id: parsed.data.productId, user_id: session.userId }
where: { id: parsed.data.productId, ...productAccessFilter(session.userId) }
})
if (!product) return { error: 'Product niet gevonden' }
@ -51,3 +52,13 @@ export async function createPbi(formData: FormData) {
return { success: true, pbi }
}
```
## Security-invarianten
- Controleer auth en `session.isDemo` voordat er geschreven wordt.
- Gebruik `productAccessFilter(userId)` voor resources waar eigenaar en gekoppelde Developer beide toegang hebben.
- Gebruik eigenaar-only filters (`user_id: session.userId`) alleen voor eigenaarsacties zoals product archiveren, teamleden beheren of persoonlijke todos.
- Vertrouw nooit losse client-ID's. Als een action meerdere IDs ontvangt, haal ze eerst op met `id in (...)` plus de parent-scope en weiger de operatie als het aantal gevonden records niet exact gelijk is.
- Weiger dubbele IDs in reorder-lijsten of beslissingsobjecten.
- Leid denormalized foreign keys af uit de database-parent. Voorbeeld: gebruik `pbi.product_id` bij story creation, niet `formData.get('productId')`.
- Delete pas nadat ownership/scoping bewezen is; gebruik scoped `deleteMany` als een directe unique `delete` anders een cross-user record kan raken.