Brengt de docs gelijk met de werkelijkheid na PBI-46/47/50/58/59/61/63 en M12. Belangrijkste fixes: - data-model.md herschreven naar prisma/schema.prisma: nieuwe entiteiten (Idea, IdeaLog, IdeaProduct, UserQuestion, ClaudeQuestion, ClaudeJob, SprintRun, SprintTaskExecution, ClaudeWorker, LoginPairing, PushSubscription, ModelPrice, ProductMember), nieuwe enums (FAILED/EXCLUDED, OPEN/CLOSED/ARCHIVED, ADMIN, etc.) en codes (PBI/ST/T/SP-N) toegevoegd; verwijderde todos-tabel verwijderd. - glossary.md: Sprint zonder "max 1 actief" (PBI-63), Story/Task incl. FAILED/EXCLUDED, Todo verwijderd, Idea/SprintRun/ClaudeJob/ verify_result toegevoegd. - project-structure.md: app/(app)/todos vervangen door ideas/insights/jobs/manual/admin/solo; api-tree volledig. - overview.md: "geen realtime in v1" en Docker-rationale herschreven — Postgres LISTEN/NOTIFY + SSE, claude_jobs als queue, opt-in Docker-deploy-flow. - functional.md: F-08 Todo-lijst -> Ideeen-laag, F-09 multi-sprint, F-10 Task-status incl. FAILED/EXCLUDED, F-11 endpoint-lijst, navigatiestructuur, datamodel-schets en Flow 3 bijgewerkt. - README.md API-tabel: /api/todos weg, ideas/jobs/users/profile/health toegevoegd, kort over realtime/auth-pair/internal/cron. - patterns + mcp-integration runbook: Todo-/ACTIVE-references vervangen door Idea/OPEN; create_todo MCP-tool note over verwijdering. Linkcheck groen (105 files), INDEX hergegenereerd (98 docs). Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
53 lines
1.4 KiB
Markdown
53 lines
1.4 KiB
Markdown
---
|
|
title: "Proxy (route protection)"
|
|
status: active
|
|
audience: [ai-agent, contributor]
|
|
language: nl
|
|
last_updated: 2026-05-08
|
|
when_to_read: "When adding or modifying route-level access control in proxy.ts."
|
|
---
|
|
|
|
# Patroon: Proxy (route protection)
|
|
|
|
In Next.js 16 hernoemd van `middleware.ts` naar `proxy.ts`, functienaam van `middleware` naar `proxy`.
|
|
|
|
```ts
|
|
// proxy.ts
|
|
import { NextResponse } from 'next/server'
|
|
import type { NextRequest } from 'next/server'
|
|
import { sessionOptions } from '@/lib/session'
|
|
|
|
const protectedRoutes = [
|
|
'/dashboard',
|
|
'/products',
|
|
'/ideas',
|
|
'/solo',
|
|
'/jobs',
|
|
'/insights',
|
|
'/manual',
|
|
'/settings',
|
|
]
|
|
const authRoutes = ['/login', '/register']
|
|
|
|
export function proxy(request: NextRequest) {
|
|
const path = request.nextUrl.pathname
|
|
const isProtected = protectedRoutes.some(r => path.startsWith(r))
|
|
const isAuthRoute = authRoutes.some(r => path.startsWith(r))
|
|
|
|
// Cookie-aanwezigheid controleren — volledige sessievalidatie in layout.tsx
|
|
const hasSession = !!request.cookies.get(sessionOptions.cookieName)?.value
|
|
|
|
if (isProtected && !hasSession) {
|
|
return NextResponse.redirect(new URL('/login', request.url))
|
|
}
|
|
if (isAuthRoute && hasSession) {
|
|
return NextResponse.redirect(new URL('/dashboard', request.url))
|
|
}
|
|
|
|
return NextResponse.next()
|
|
}
|
|
|
|
export const config = {
|
|
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
|
|
}
|
|
```
|