Aus Zeitpunkt, Stundenfenster und Blöcken entsteht alles, was die Ansicht braucht: Spalten ab Montag, Zeilen im Viertelstundenraster und die Lage jedes Balkens darin. Reine Logik, 21 Tests. Drei Feinheiten, die ohne Test leicht falsch geraten: - Das Stundenfenster ist die Hülle über alle Arbeitsfenster, mit einer Stunde Luft. Ohne die Luft läge ein Block, der genau am Rand beginnt, an der Kante und ließe sich kaum greifen. - Balken werden am Fensterrand abgeschnitten. Ein Termin von 6 bis 23 Uhr würde sonst das Raster sprengen. - Sich überschneidende Termine bekommen Spuren nebeneinander, sonst läge einer unsichtbar hinter dem anderen. Eine Spur wird wieder frei, sobald sie zu Ende ist. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
105 lines
3.0 KiB
JSON
105 lines
3.0 KiB
JSON
{
|
|
"name": "planer",
|
|
"version": "0.3.0",
|
|
"private": true,
|
|
"description": "Aufgaben, Ideen, Projekte und Zeitblöcke mit Anbindung an Microsoft 365 und Google Kalender",
|
|
"type": "module",
|
|
"engines": {
|
|
"node": ">=22.12.0"
|
|
},
|
|
"scripts": {
|
|
"dev": "next dev",
|
|
"build": "prisma generate && next build",
|
|
"start": "next start",
|
|
"pruefen": "node scripts/pruefen.mjs",
|
|
"format": "prettier --write .",
|
|
"format:pruefen": "prettier --check .",
|
|
"lint": "eslint . --max-warnings 0",
|
|
"typen": "tsc --noEmit",
|
|
"test": "vitest run",
|
|
"test:beobachten": "vitest",
|
|
"test:integration": "tsx scripts/integrationstest.ts",
|
|
"test:migration": "tsx scripts/migrationstest.ts",
|
|
"test:e2e": "playwright test",
|
|
"screenshots": "tsx scripts/screenshots.ts",
|
|
"db:generieren": "prisma generate",
|
|
"db:migrieren": "prisma migrate dev",
|
|
"db:einspielen": "prisma migrate deploy",
|
|
"db:seed": "tsx prisma/seed.ts",
|
|
"db:studio": "prisma studio",
|
|
"db:demo-seed": "tsx prisma/demo-seed.ts"
|
|
},
|
|
"prisma": {
|
|
"seed": "tsx prisma/seed.ts"
|
|
},
|
|
"overrides": {
|
|
"@simplewebauthn/browser": "14.0.0",
|
|
"@simplewebauthn/server": "14.0.1",
|
|
"nodemailer": "10.0.3"
|
|
},
|
|
"dependencies": {
|
|
"@auth/prisma-adapter": "2.11.3",
|
|
"@date-fns/tz": "1.5.0",
|
|
"@dnd-kit/core": "6.3.1",
|
|
"@dnd-kit/utilities": "3.2.2",
|
|
"@prisma/adapter-pg": "7.10.0",
|
|
"@prisma/client": "7.10.0",
|
|
"@radix-ui/react-avatar": "1.2.6",
|
|
"@radix-ui/react-dialog": "1.1.23",
|
|
"@radix-ui/react-dropdown-menu": "2.1.24",
|
|
"@radix-ui/react-label": "2.1.15",
|
|
"@radix-ui/react-separator": "1.1.15",
|
|
"@radix-ui/react-slot": "1.3.3",
|
|
"@simplewebauthn/browser": "14.0.0",
|
|
"@simplewebauthn/server": "14.0.1",
|
|
"bcryptjs": "3.0.3",
|
|
"class-variance-authority": "0.7.1",
|
|
"clsx": "2.1.1",
|
|
"date-fns": "4.4.0",
|
|
"lucide-react": "1.44.0",
|
|
"next": "16.3.4",
|
|
"next-auth": "5.0.0-beta.32",
|
|
"next-themes": "0.4.6",
|
|
"node-cron": "4.6.0",
|
|
"nodemailer": "10.0.3",
|
|
"pg": "8.23.0",
|
|
"react": "19.3.0",
|
|
"react-dom": "19.3.0",
|
|
"server-only": "0.0.1",
|
|
"sonner": "2.0.8",
|
|
"tailwind-merge": "3.6.0",
|
|
"zod": "4.6.1"
|
|
},
|
|
"devDependencies": {
|
|
"@playwright/test": "1.63.0",
|
|
"@tailwindcss/postcss": "4.3.3",
|
|
"@testing-library/react": "16.3.3",
|
|
"@types/node": "24.13.4",
|
|
"@types/nodemailer": "8.0.1",
|
|
"@types/pg": "8.23.1",
|
|
"@types/react": "19.3.0",
|
|
"@types/react-dom": "19.3.0",
|
|
"@vitejs/plugin-react": "6.1.1",
|
|
"@vitest/coverage-v8": "5.0.0",
|
|
"dotenv": "17.4.2",
|
|
"eslint": "9.39.5",
|
|
"eslint-config-next": "16.3.4",
|
|
"jsdom": "30.0.1",
|
|
"prettier": "3.9.6",
|
|
"prettier-plugin-tailwindcss": "0.8.1",
|
|
"prisma": "7.10.0",
|
|
"tailwindcss": "4.3.3",
|
|
"tsx": "4.23.13",
|
|
"tw-animate-css": "1.4.0",
|
|
"typescript": "6.0.3",
|
|
"typescript-eslint": "8.70.0",
|
|
"vitest": "5.0.0"
|
|
},
|
|
"allowScripts": {
|
|
"prisma@7.10.0": true,
|
|
"@prisma/engines@7.10.0": true,
|
|
"esbuild@0.28.2": true,
|
|
"unrs-resolver@1.12.2": true
|
|
}
|
|
}
|