Document Prisma ERD generation
This commit is contained in:
parent
b5e967d8d3
commit
4ec0683f88
9 changed files with 3997 additions and 25 deletions
28
README.md
28
README.md
|
|
@ -116,17 +116,40 @@ Vul daarna `DATABASE_URL` en `SESSION_SECRET` in. `DIRECT_URL` is optioneel loka
|
||||||
npx prisma db push
|
npx prisma db push
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Seed testdata indien nodig:
|
4. Genereer Prisma Client en de ERD:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run db:erd
|
||||||
|
```
|
||||||
|
|
||||||
|
Deze command voert `prisma generate` uit. Daardoor worden zowel de Prisma Client als `docs/erd.svg` opnieuw opgebouwd.
|
||||||
|
|
||||||
|
5. Seed testdata indien nodig:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx prisma db seed
|
npx prisma db seed
|
||||||
```
|
```
|
||||||
|
|
||||||
5. Start de app:
|
6. Start de app:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run dev
|
npm run dev
|
||||||
```
|
```
|
||||||
|
## Database
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
De databasevisualisatie wordt gegenereerd uit `prisma/schema.prisma` via `prisma-erd-generator`.
|
||||||
|
|
||||||
|
Handmatige generatie:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run db:erd
|
||||||
|
```
|
||||||
|
|
||||||
|
Tijdens lokale development draait `npm run dev` naast Next.js ook `npm run db:erd:watch`. Bij wijzigingen in `prisma/schema.prisma` wordt `docs/erd.svg` automatisch opnieuw gegenereerd.
|
||||||
|
|
||||||
|
Gebruik `npx prisma db push` alleen om het schema naar de database te synchroniseren. Gebruik `npm run db:erd` om Prisma Client en de ERD te genereren.
|
||||||
|
|
||||||
De app draait standaard op `http://localhost:3000`.
|
De app draait standaard op `http://localhost:3000`.
|
||||||
|
|
||||||
|
|
@ -137,6 +160,7 @@ npm run dev # lokale development server
|
||||||
npm run lint # ESLint
|
npm run lint # ESLint
|
||||||
npm test # Vitest test suite
|
npm test # Vitest test suite
|
||||||
npm run build # productiebuild zoals Vercel die verwacht
|
npm run build # productiebuild zoals Vercel die verwacht
|
||||||
|
npm run db:erd # Prisma Client + docs/erd.svg genereren
|
||||||
```
|
```
|
||||||
|
|
||||||
### Environment variables
|
### Environment variables
|
||||||
|
|
|
||||||
75
app/page.tsx
75
app/page.tsx
|
|
@ -1,7 +1,26 @@
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
|
import { cookies } from 'next/headers'
|
||||||
|
import { getIronSession } from 'iron-session'
|
||||||
import { AppIcon } from '@/components/shared/app-icon'
|
import { AppIcon } from '@/components/shared/app-icon'
|
||||||
|
import { SessionData, sessionOptions } from '@/lib/session'
|
||||||
|
import packageJson from '@/package.json'
|
||||||
|
|
||||||
|
const buildDate = process.env.NEXT_PUBLIC_BUILD_DATE
|
||||||
|
? new Date(process.env.NEXT_PUBLIC_BUILD_DATE).toLocaleDateString('nl-NL', {
|
||||||
|
day: 'numeric',
|
||||||
|
month: 'short',
|
||||||
|
year: 'numeric',
|
||||||
|
})
|
||||||
|
: '—'
|
||||||
|
|
||||||
|
const version = process.env.NEXT_PUBLIC_APP_VERSION ?? packageJson.version
|
||||||
|
|
||||||
|
export default async function LandingPage() {
|
||||||
|
const session = process.env.SESSION_SECRET
|
||||||
|
? await getIronSession<SessionData>(await cookies(), sessionOptions)
|
||||||
|
: null
|
||||||
|
const isLoggedIn = Boolean(session?.userId)
|
||||||
|
|
||||||
export default function LandingPage() {
|
|
||||||
return (
|
return (
|
||||||
<div className="h-screen bg-background text-foreground flex flex-col overflow-hidden">
|
<div className="h-screen bg-background text-foreground flex flex-col overflow-hidden">
|
||||||
|
|
||||||
|
|
@ -12,18 +31,43 @@ export default function LandingPage() {
|
||||||
Scrum4Me
|
Scrum4Me
|
||||||
</Link>
|
</Link>
|
||||||
<nav className="ml-auto flex items-center gap-2">
|
<nav className="ml-auto flex items-center gap-2">
|
||||||
<Link
|
{isLoggedIn ? (
|
||||||
href="/login"
|
<>
|
||||||
className="px-3 py-1.5 rounded-md text-sm text-muted-foreground hover:text-foreground hover:bg-surface-container transition-colors"
|
<Link
|
||||||
>
|
href="/dashboard"
|
||||||
Inloggen
|
className="px-3 py-1.5 rounded-md text-sm text-muted-foreground hover:text-foreground hover:bg-surface-container transition-colors"
|
||||||
</Link>
|
>
|
||||||
<Link
|
Producten
|
||||||
href="/register"
|
</Link>
|
||||||
className="px-4 py-1.5 rounded-md text-sm bg-primary text-primary-foreground hover:opacity-90 transition-opacity font-medium"
|
<Link
|
||||||
>
|
href="/todos"
|
||||||
Registreren
|
className="px-3 py-1.5 rounded-md text-sm text-muted-foreground hover:text-foreground hover:bg-surface-container transition-colors"
|
||||||
</Link>
|
>
|
||||||
|
Todo's
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="/settings"
|
||||||
|
className="px-3 py-1.5 rounded-md text-sm text-muted-foreground hover:text-foreground hover:bg-surface-container transition-colors"
|
||||||
|
>
|
||||||
|
Instellingen
|
||||||
|
</Link>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Link
|
||||||
|
href="/login"
|
||||||
|
className="px-3 py-1.5 rounded-md text-sm text-muted-foreground hover:text-foreground hover:bg-surface-container transition-colors"
|
||||||
|
>
|
||||||
|
Inloggen
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="/register"
|
||||||
|
className="px-4 py-1.5 rounded-md text-sm bg-primary text-primary-foreground hover:opacity-90 transition-opacity font-medium"
|
||||||
|
>
|
||||||
|
Registreren
|
||||||
|
</Link>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
@ -279,10 +323,7 @@ export default function LandingPage() {
|
||||||
{/* ── Footer ─────────────────────────────────────────────────── */}
|
{/* ── Footer ─────────────────────────────────────────────────── */}
|
||||||
<footer className="shrink-0 border-t border-border bg-surface-container-low px-6 py-4 flex items-center justify-between text-xs text-muted-foreground">
|
<footer className="shrink-0 border-t border-border bg-surface-container-low px-6 py-4 flex items-center justify-between text-xs text-muted-foreground">
|
||||||
<span>© {new Date().getFullYear()} Scrum4Me</span>
|
<span>© {new Date().getFullYear()} Scrum4Me</span>
|
||||||
<div className="flex gap-4">
|
<span>v{version} · gebouwd op {buildDate}</span>
|
||||||
<Link href="/login" className="hover:text-foreground transition-colors">Inloggen</Link>
|
|
||||||
<Link href="/register" className="hover:text-foreground transition-colors">Registreren</Link>
|
|
||||||
</div>
|
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ export function NavBar({ isDemo }: NavBarProps) {
|
||||||
return (
|
return (
|
||||||
<header className="bg-surface-container-low border-b border-border h-14 flex items-center px-4 gap-4 shrink-0">
|
<header className="bg-surface-container-low border-b border-border h-14 flex items-center px-4 gap-4 shrink-0">
|
||||||
{/* Logo */}
|
{/* Logo */}
|
||||||
<Link href="/dashboard" className="flex items-center gap-2 font-medium text-foreground">
|
<Link href="/" className="flex items-center gap-2 font-medium text-foreground">
|
||||||
<AppIcon size={24} />
|
<AppIcon size={24} />
|
||||||
<span className="text-primary font-semibold">Scrum4Me</span>
|
<span className="text-primary font-semibold">Scrum4Me</span>
|
||||||
{isDemo && (
|
{isDemo && (
|
||||||
|
|
|
||||||
1
docs/erd.svg
Normal file
1
docs/erd.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 317 KiB |
|
|
@ -39,3 +39,35 @@ export default defineConfig({
|
||||||
migrations: { path: 'prisma/migrations' },
|
migrations: { path: 'prisma/migrations' },
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Prisma generators
|
||||||
|
|
||||||
|
`prisma/schema.prisma` bevat twee generators:
|
||||||
|
|
||||||
|
```prisma
|
||||||
|
generator client {
|
||||||
|
provider = "prisma-client-js"
|
||||||
|
}
|
||||||
|
|
||||||
|
generator erd {
|
||||||
|
provider = "prisma-erd-generator"
|
||||||
|
output = "../docs/erd.svg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`prisma generate` bouwt dus twee artifacts:
|
||||||
|
|
||||||
|
- Prisma Client in `node_modules/@prisma/client`
|
||||||
|
- het ERD-diagram in `docs/erd.svg`
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
| Command | Gebruik |
|
||||||
|
|---|---|
|
||||||
|
| `npx prisma db push` | Schema synchroniseren naar de database |
|
||||||
|
| `npx prisma db seed` | Seeddata laden |
|
||||||
|
| `npm run db:erd` | `prisma generate`: Prisma Client en `docs/erd.svg` genereren |
|
||||||
|
| `npm run db:erd:watch` | `prisma/schema.prisma` watchen en ERD opnieuw genereren |
|
||||||
|
| `npm run dev` | Next.js dev server plus ERD watcher starten |
|
||||||
|
|
||||||
|
Belangrijk: `db push` schrijft naar de database, maar genereert geen ERD. Gebruik na schemawijzigingen `npm run db:erd` of laat `npm run dev` de watcher draaien.
|
||||||
|
|
|
||||||
|
|
@ -770,6 +770,7 @@ NODE_ENV="development"
|
||||||
**CI/CD:** GitHub Actions → lint + typecheck + `prisma validate` op elke PR; Vercel deploy automatisch bij merge naar `main`
|
**CI/CD:** GitHub Actions → lint + typecheck + `prisma validate` op elke PR; Vercel deploy automatisch bij merge naar `main`
|
||||||
**Database (cloud):** Neon — migraties via `prisma migrate deploy` in de Vercel build-stap
|
**Database (cloud):** Neon — migraties via `prisma migrate deploy` in de Vercel build-stap
|
||||||
**Database (lokaal):** Neon (gratis tier) — `npx prisma db push` synchroniseert schema
|
**Database (lokaal):** Neon (gratis tier) — `npx prisma db push` synchroniseert schema
|
||||||
|
**Prisma generatie:** `npm run db:erd` voert `prisma generate` uit en bouwt zowel Prisma Client als `docs/erd.svg`
|
||||||
**Seeding:** `npx prisma db seed` laadt de testdata uit het Product Backlog document
|
**Seeding:** `npx prisma db seed` laadt de testdata uit het Product Backlog document
|
||||||
|
|
||||||
### Deployment checklist (pre-launch)
|
### Deployment checklist (pre-launch)
|
||||||
|
|
|
||||||
3866
package-lock.json
generated
3866
package-lock.json
generated
File diff suppressed because it is too large
Load diff
12
package.json
12
package.json
|
|
@ -1,16 +1,18 @@
|
||||||
{
|
{
|
||||||
"name": "scrum4me",
|
"name": "scrum4me",
|
||||||
"version": "0.2.0",
|
"version": "0.3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "concurrently \"next dev\" \"npm run db:erd:watch\"",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "eslint",
|
"lint": "eslint",
|
||||||
"test": "vitest run",
|
"test": "vitest run",
|
||||||
"test:watch": "vitest",
|
"test:watch": "vitest",
|
||||||
"prepare": "husky",
|
"prepare": "husky",
|
||||||
"postinstall": "prisma generate"
|
"postinstall": "prisma generate",
|
||||||
|
"db:erd": "prisma generate",
|
||||||
|
"db:erd:watch": "chokidar \"prisma/schema.prisma\" -c \"npm run db:erd\""
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@base-ui/react": "^1.4.1",
|
"@base-ui/react": "^1.4.1",
|
||||||
|
|
@ -47,6 +49,7 @@
|
||||||
"*.{ts,tsx,mjs}": "eslint --fix"
|
"*.{ts,tsx,mjs}": "eslint --fix"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@mermaid-js/mermaid-cli": "^11.12.0",
|
||||||
"@tailwindcss/postcss": "^4",
|
"@tailwindcss/postcss": "^4",
|
||||||
"@types/bcryptjs": "^2.4.6",
|
"@types/bcryptjs": "^2.4.6",
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
|
|
@ -54,10 +57,13 @@
|
||||||
"@types/react": "^19",
|
"@types/react": "^19",
|
||||||
"@types/react-dom": "^19",
|
"@types/react-dom": "^19",
|
||||||
"@vitest/coverage-v8": "^4.1.5",
|
"@vitest/coverage-v8": "^4.1.5",
|
||||||
|
"chokidar-cli": "^3.0.0",
|
||||||
|
"concurrently": "^9.2.1",
|
||||||
"eslint": "^9",
|
"eslint": "^9",
|
||||||
"eslint-config-next": "16.2.4",
|
"eslint-config-next": "16.2.4",
|
||||||
"husky": "^9.1.7",
|
"husky": "^9.1.7",
|
||||||
"lint-staged": "^16.4.0",
|
"lint-staged": "^16.4.0",
|
||||||
|
"prisma-erd-generator": "^2.4.2",
|
||||||
"tailwindcss": "^4",
|
"tailwindcss": "^4",
|
||||||
"tsx": "^4.21.0",
|
"tsx": "^4.21.0",
|
||||||
"typescript": "^5",
|
"typescript": "^5",
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,11 @@ generator client {
|
||||||
provider = "prisma-client-js"
|
provider = "prisma-client-js"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
generator erd {
|
||||||
|
provider = "prisma-erd-generator"
|
||||||
|
output = "../docs/erd.svg"
|
||||||
|
}
|
||||||
|
|
||||||
datasource db {
|
datasource db {
|
||||||
provider = "postgresql"
|
provider = "postgresql"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue