From f9b17e996482e0ceb10940706af4e56877480929 Mon Sep 17 00:00:00 2001 From: Jan Date: Wed, 8 Apr 2026 16:30:44 +0200 Subject: [PATCH] Initial commit --- .dockerignore | 6 + .env.example | 6 + .gitignore | 10 + Dockerfile | 19 + README.md | 65 + docker-compose.yml | 32 + docker/entrypoint.sh | 14 + next-env.d.ts | 5 + next.config.mjs | 4 + package.json | 38 + .../202604070001_init/migration.sql | 81 + .../migration.sql | 84 + .../migration.sql | 60 + .../202604081930_audit_logs/migration.sql | 20 + prisma/schema.prisma | 146 ++ prisma/seed.ts | 250 +++ public/apple-touch-icon.png | Bin 0 -> 34412 bytes public/favicon.ico | Bin 0 -> 651 bytes public/icon-192.png | Bin 0 -> 34979 bytes public/icon-512.png | Bin 0 -> 154005 bytes public/icon.png | Bin 0 -> 154005 bytes public/icon.svg | 9 + public/sw.js | 45 + src/app/api/audit-logs/[id]/restore/route.ts | 516 +++++ src/app/api/auth/[...nextauth]/route.ts | 8 + src/app/api/budgets/[id]/route.ts | 147 ++ src/app/api/budgets/route.ts | 115 ++ src/app/api/expenses/[id]/approve/route.ts | 124 ++ src/app/api/expenses/[id]/documented/route.ts | 84 + src/app/api/expenses/[id]/paid/route.ts | 62 + src/app/api/expenses/[id]/route.ts | 63 + src/app/api/expenses/route.ts | 86 + src/app/api/export/csv/route.ts | 518 +++++ src/app/api/import/csv/route.ts | 239 +++ src/app/api/periods/[id]/route.ts | 73 + src/app/api/periods/current/route.ts | 80 + src/app/api/periods/route.ts | 96 + src/app/api/users/[id]/password/route.ts | 74 + src/app/api/users/[id]/route.ts | 83 + src/app/api/users/route.ts | 118 ++ src/app/api/working-groups/[id]/route.ts | 148 ++ src/app/api/working-groups/route.ts | 67 + src/app/globals.css | 44 + src/app/layout.tsx | 50 + src/app/login/page.tsx | 34 + src/app/manifest.ts | 32 + src/app/page.tsx | 239 +++ src/components/dashboard/budget-column.tsx | 743 +++++++ .../dashboard/color-picker-field.tsx | 46 + src/components/dashboard/dashboard-shell.tsx | 1835 +++++++++++++++++ src/components/login-form.tsx | 109 + src/components/providers/app-providers.tsx | 46 + .../service-worker-registration.tsx | 18 + src/lib/accounting-periods.ts | 22 + src/lib/audit-log.ts | 62 + src/lib/audit-snapshots.ts | 98 + src/lib/auth.ts | 87 + src/lib/backup-csv.ts | 61 + src/lib/dashboard-types.ts | 99 + src/lib/domain.ts | 122 ++ src/lib/prisma.ts | 17 + src/lib/session.ts | 19 + src/theme.ts | 136 ++ src/types/next-auth.d.ts | 32 + tsconfig.json | 28 + 65 files changed, 7574 insertions(+) create mode 100644 .dockerignore create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 docker-compose.yml create mode 100644 docker/entrypoint.sh create mode 100644 next-env.d.ts create mode 100644 next.config.mjs create mode 100644 package.json create mode 100644 prisma/migrations/202604070001_init/migration.sql create mode 100644 prisma/migrations/202604071700_budget_accounts/migration.sql create mode 100644 prisma/migrations/202604081200_accounting_periods/migration.sql create mode 100644 prisma/migrations/202604081930_audit_logs/migration.sql create mode 100644 prisma/schema.prisma create mode 100644 prisma/seed.ts create mode 100644 public/apple-touch-icon.png create mode 100644 public/favicon.ico create mode 100644 public/icon-192.png create mode 100644 public/icon-512.png create mode 100644 public/icon.png create mode 100644 public/icon.svg create mode 100644 public/sw.js create mode 100644 src/app/api/audit-logs/[id]/restore/route.ts create mode 100644 src/app/api/auth/[...nextauth]/route.ts create mode 100644 src/app/api/budgets/[id]/route.ts create mode 100644 src/app/api/budgets/route.ts create mode 100644 src/app/api/expenses/[id]/approve/route.ts create mode 100644 src/app/api/expenses/[id]/documented/route.ts create mode 100644 src/app/api/expenses/[id]/paid/route.ts create mode 100644 src/app/api/expenses/[id]/route.ts create mode 100644 src/app/api/expenses/route.ts create mode 100644 src/app/api/export/csv/route.ts create mode 100644 src/app/api/import/csv/route.ts create mode 100644 src/app/api/periods/[id]/route.ts create mode 100644 src/app/api/periods/current/route.ts create mode 100644 src/app/api/periods/route.ts create mode 100644 src/app/api/users/[id]/password/route.ts create mode 100644 src/app/api/users/[id]/route.ts create mode 100644 src/app/api/users/route.ts create mode 100644 src/app/api/working-groups/[id]/route.ts create mode 100644 src/app/api/working-groups/route.ts create mode 100644 src/app/globals.css create mode 100644 src/app/layout.tsx create mode 100644 src/app/login/page.tsx create mode 100644 src/app/manifest.ts create mode 100644 src/app/page.tsx create mode 100644 src/components/dashboard/budget-column.tsx create mode 100644 src/components/dashboard/color-picker-field.tsx create mode 100644 src/components/dashboard/dashboard-shell.tsx create mode 100644 src/components/login-form.tsx create mode 100644 src/components/providers/app-providers.tsx create mode 100644 src/components/service-worker-registration.tsx create mode 100644 src/lib/accounting-periods.ts create mode 100644 src/lib/audit-log.ts create mode 100644 src/lib/audit-snapshots.ts create mode 100644 src/lib/auth.ts create mode 100644 src/lib/backup-csv.ts create mode 100644 src/lib/dashboard-types.ts create mode 100644 src/lib/domain.ts create mode 100644 src/lib/prisma.ts create mode 100644 src/lib/session.ts create mode 100644 src/theme.ts create mode 100644 src/types/next-auth.d.ts create mode 100644 tsconfig.json diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..37ee38f --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +node_modules +.next +.git +.env +npm-debug.log + diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..997a2b3 --- /dev/null +++ b/.env.example @@ -0,0 +1,6 @@ +POSTGRES_DB="rave_budget_control" +POSTGRES_USER="postgres" +POSTGRES_PASSWORD="change-this-db-password" +DATABASE_URL="postgresql://postgres:postgres@db:5432/rave_budget_control?schema=public" +NEXTAUTH_URL="http://localhost:3000" +NEXTAUTH_SECRET="replace-this-with-a-long-random-secret" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..582b5dc --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +node_modules +.next +dist +coverage +.env +.env.local +uploads +public/uploads +prisma/dev.db + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..69a71cd --- /dev/null +++ b/Dockerfile @@ -0,0 +1,19 @@ +FROM node:20-bookworm-slim + +WORKDIR /app + +ENV NEXT_TELEMETRY_DISABLED=1 + +RUN apt-get update && apt-get install -y openssl && rm -rf /var/lib/apt/lists/* + +COPY package.json ./ +RUN npm install + +COPY . . + +RUN npx prisma generate +RUN npm run build + +EXPOSE 3000 + +CMD ["sh", "./docker/entrypoint.sh"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..255592e --- /dev/null +++ b/README.md @@ -0,0 +1,65 @@ +# RFP Finanzübersicht + +Material-3-orientierter MVP fuer die Budgetsteuerung von Vereins-AGs mit rollenbasierter Freigabelogik, PWA-Grundlage und Docker-Setup. + +## Stack + +- Next.js 14 mit App Router und TypeScript +- MUI 6 fuer Material Design 3 +- Prisma + PostgreSQL +- NextAuth Credentials Login +- Docker Compose fuer lokalen Start + +## Enthalten im MVP + +- Horizontale Budget-Dashboard-Ansicht pro AG +- Budget-Fuellstand mit blasser/gefaerbter Visualisierung +- Automatische Freigabe fuer Ausgaben unter 50 EUR +- Drei digitale Freigaben fuer Ausgaben ab 50 EUR +- Rollen `Admin`, `Finanz-AG`, `AG-Mitglied` +- Admin-Formulare fuer Budgets und Nutzeranlage +- Statusaktionen `Freigegeben`, `Bezahlt`, `Dokumentiert` +- Demo-Accounts und Seed-Daten +- PWA-Manifest und Service-Worker-Basis fuer Offline-Shell + +## Lokaler Start + +1. Optional `.env.example` nach `.env` kopieren und Werte anpassen. +2. Projekt starten: + +```bash +docker-compose up --build +``` + +3. App oeffnen unter `http://localhost:3000` + +## Demo-Accounts + +- `admin.a@raveforpeace.org` / `demo123!` +- `admin.b@raveforpeace.org` / `demo123!` +- `finance@raveforpeace.org` / `demo123!` +- `deko@raveforpeace.org` / `demo123!` +- `technik@raveforpeace.org` / `demo123!` + +## Abnahmekriterien durchspielen + +1. Als `admin.a@raveforpeace.org` anmelden und bei `AG Deko` ein Budget setzen, zum Beispiel `1200`. +2. Als `deko@raveforpeace.org` anmelden und eine Ausgabe ueber `60` EUR erfassen. +3. Als `admin.a@raveforpeace.org` wieder anmelden und `Freigeben als Vorstand A` klicken. +4. Als `admin.b@raveforpeace.org` anmelden und `Freigeben als Vorstand B` klicken. +5. Als `finance@raveforpeace.org` anmelden und die Finanzfreigabe setzen. +6. Nach der dritten Freigabe wird der Posten kraeftig dargestellt. +7. Danach `Bezahlt setzen` klicken, um den blauen Haken zu erhalten. + +## Datenmodell + +- `users`: Nutzer mit Rolle, Login und optionaler AG-Zuordnung +- `working_groups`: AG-Name, Budget, Farbe +- `expenses`: Betrag, Status, Bezahlt-/Dokumentiert-Zeitstempel, optionaler Beleg-Link +- `approvals`: Wer hat welche Signatur fuer welchen Posten gesetzt + +## Hinweise + +- Die Dokumentation eines Belegs ist im MVP als Beleg-URL umgesetzt. +- Web-Push ist architektonisch vorbereitet ueber PWA-Grundlage, aber die eigentliche Push-Auslieferung ist noch nicht implementiert. +- Fuer Produktion sollten `NEXTAUTH_SECRET`, Datenbank-Zugangsdaten und Reverse-Proxy/SSL sauber gesetzt werden. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..27f5b38 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,32 @@ +services: + db: + image: postgres:16-alpine + restart: unless-stopped + environment: + POSTGRES_DB: ${POSTGRES_DB:-rave_budget_control} + POSTGRES_USER: ${POSTGRES_USER:-postgres} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres} + volumes: + - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres -d rave_budget_control"] + interval: 10s + timeout: 5s + retries: 10 + + app: + build: + context: . + restart: unless-stopped + depends_on: + db: + condition: service_healthy + environment: + DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@db:5432/${POSTGRES_DB:-rave_budget_control}?schema=public + NEXTAUTH_URL: ${NEXTAUTH_URL:-http://localhost:3000} + NEXTAUTH_SECRET: ${NEXTAUTH_SECRET} + ports: + - "3000:3000" + +volumes: + postgres_data: diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh new file mode 100644 index 0000000..bbc64c9 --- /dev/null +++ b/docker/entrypoint.sh @@ -0,0 +1,14 @@ +#!/bin/sh +set -e + +mkdir -p public/uploads + +echo "Applying database migrations..." +npx prisma migrate deploy + +echo "Seeding demo data..." +npx prisma db seed + +echo "Starting Next.js..." +exec npm run start + diff --git a/next-env.d.ts b/next-env.d.ts new file mode 100644 index 0000000..adeaa6c --- /dev/null +++ b/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// This file is auto-generated by Next.js. + diff --git a/next.config.mjs b/next.config.mjs new file mode 100644 index 0000000..4678774 --- /dev/null +++ b/next.config.mjs @@ -0,0 +1,4 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = {}; + +export default nextConfig; diff --git a/package.json b/package.json new file mode 100644 index 0000000..944d9fe --- /dev/null +++ b/package.json @@ -0,0 +1,38 @@ +{ + "name": "rave-budget-control", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "prisma:generate": "prisma generate", + "prisma:migrate": "prisma migrate deploy", + "seed": "tsx prisma/seed.ts" + }, + "prisma": { + "seed": "tsx prisma/seed.ts" + }, + "dependencies": { + "@emotion/react": "^11.13.3", + "@emotion/styled": "^11.13.0", + "@mui/icons-material": "^6.1.3", + "@mui/material": "^6.1.3", + "@prisma/client": "^5.20.0", + "bcryptjs": "^2.4.3", + "next": "^14.2.14", + "next-auth": "^4.24.8", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "zod": "^3.23.8" + }, + "devDependencies": { + "@types/bcryptjs": "^2.4.6", + "@types/node": "^22.7.4", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "prisma": "^5.20.0", + "tsx": "^4.19.1", + "typescript": "^5.6.2" + } +} diff --git a/prisma/migrations/202604070001_init/migration.sql b/prisma/migrations/202604070001_init/migration.sql new file mode 100644 index 0000000..6207574 --- /dev/null +++ b/prisma/migrations/202604070001_init/migration.sql @@ -0,0 +1,81 @@ +CREATE TYPE "Role" AS ENUM ('ADMIN', 'FINANCE', 'MEMBER'); +CREATE TYPE "ApprovalType" AS ENUM ('CHAIR_A', 'CHAIR_B', 'FINANCE'); +CREATE TYPE "ApprovalStatus" AS ENUM ('PENDING', 'APPROVED'); + +CREATE TABLE "working_groups" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "total_budget" DECIMAL(10,2) NOT NULL, + "color_code" TEXT NOT NULL, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + CONSTRAINT "working_groups_pkey" PRIMARY KEY ("id") +); + +CREATE TABLE "users" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "email" TEXT NOT NULL, + "password_hash" TEXT NOT NULL, + "role" "Role" NOT NULL, + "approval_preference" "ApprovalType", + "working_group_id" TEXT, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + CONSTRAINT "users_pkey" PRIMARY KEY ("id") +); + +CREATE TABLE "expenses" ( + "id" TEXT NOT NULL, + "title" TEXT NOT NULL, + "amount" DECIMAL(10,2) NOT NULL, + "creator_id" TEXT NOT NULL, + "ag_id" TEXT NOT NULL, + "approval_status" "ApprovalStatus" NOT NULL DEFAULT 'PENDING', + "paid_at" TIMESTAMP(3), + "documented_at" TIMESTAMP(3), + "proof_url" TEXT, + "notes" TEXT, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + CONSTRAINT "expenses_pkey" PRIMARY KEY ("id") +); + +CREATE TABLE "approvals" ( + "id" TEXT NOT NULL, + "expense_id" TEXT NOT NULL, + "user_id" TEXT NOT NULL, + "approval_type" "ApprovalType" NOT NULL, + "timestamp" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT "approvals_pkey" PRIMARY KEY ("id") +); + +CREATE UNIQUE INDEX "working_groups_name_key" ON "working_groups"("name"); +CREATE UNIQUE INDEX "users_email_key" ON "users"("email"); +CREATE UNIQUE INDEX "approvals_expense_id_approval_type_key" ON "approvals"("expense_id", "approval_type"); + +ALTER TABLE "users" + ADD CONSTRAINT "users_working_group_id_fkey" + FOREIGN KEY ("working_group_id") REFERENCES "working_groups"("id") + ON DELETE SET NULL ON UPDATE CASCADE; + +ALTER TABLE "expenses" + ADD CONSTRAINT "expenses_creator_id_fkey" + FOREIGN KEY ("creator_id") REFERENCES "users"("id") + ON DELETE RESTRICT ON UPDATE CASCADE; + +ALTER TABLE "expenses" + ADD CONSTRAINT "expenses_ag_id_fkey" + FOREIGN KEY ("ag_id") REFERENCES "working_groups"("id") + ON DELETE CASCADE ON UPDATE CASCADE; + +ALTER TABLE "approvals" + ADD CONSTRAINT "approvals_expense_id_fkey" + FOREIGN KEY ("expense_id") REFERENCES "expenses"("id") + ON DELETE CASCADE ON UPDATE CASCADE; + +ALTER TABLE "approvals" + ADD CONSTRAINT "approvals_user_id_fkey" + FOREIGN KEY ("user_id") REFERENCES "users"("id") + ON DELETE CASCADE ON UPDATE CASCADE; + diff --git a/prisma/migrations/202604071700_budget_accounts/migration.sql b/prisma/migrations/202604071700_budget_accounts/migration.sql new file mode 100644 index 0000000..de36bd9 --- /dev/null +++ b/prisma/migrations/202604071700_budget_accounts/migration.sql @@ -0,0 +1,84 @@ +ALTER TABLE "users" ADD COLUMN "username" TEXT; + +WITH ranked AS ( + SELECT + id, + CASE + WHEN lower(regexp_replace(split_part(email, '@', 1), '[^a-zA-Z0-9_-]', '-', 'g')) = '' + THEN CONCAT('user-', substring(id from 1 for 6)) + ELSE lower(regexp_replace(split_part(email, '@', 1), '[^a-zA-Z0-9_-]', '-', 'g')) + END AS base, + ROW_NUMBER() OVER ( + PARTITION BY CASE + WHEN lower(regexp_replace(split_part(email, '@', 1), '[^a-zA-Z0-9_-]', '-', 'g')) = '' + THEN CONCAT('user-', substring(id from 1 for 6)) + ELSE lower(regexp_replace(split_part(email, '@', 1), '[^a-zA-Z0-9_-]', '-', 'g')) + END + ORDER BY created_at, id + ) AS rn + FROM "users" +) +UPDATE "users" AS u +SET "username" = CASE + WHEN ranked.rn = 1 THEN ranked.base + ELSE CONCAT(ranked.base, '-', ranked.rn) +END +FROM ranked +WHERE u.id = ranked.id; + +ALTER TABLE "users" ALTER COLUMN "username" SET NOT NULL; +ALTER TABLE "users" ALTER COLUMN "email" DROP NOT NULL; +CREATE UNIQUE INDEX "users_username_key" ON "users"("username"); + +CREATE TABLE "budgets" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "total_budget" DECIMAL(10,2) NOT NULL, + "color_code" TEXT NOT NULL, + "working_group_id" TEXT NOT NULL, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + CONSTRAINT "budgets_pkey" PRIMARY KEY ("id") +); + +INSERT INTO "budgets" ( + "id", + "name", + "total_budget", + "color_code", + "working_group_id", + "created_at", + "updated_at" +) +SELECT + CONCAT('budget_', "id"), + 'Hauptbudget', + "total_budget", + "color_code", + "id", + "created_at", + "updated_at" +FROM "working_groups"; + +CREATE UNIQUE INDEX "budgets_working_group_id_name_key" ON "budgets"("working_group_id", "name"); + +ALTER TABLE "budgets" + ADD CONSTRAINT "budgets_working_group_id_fkey" + FOREIGN KEY ("working_group_id") REFERENCES "working_groups"("id") + ON DELETE CASCADE ON UPDATE CASCADE; + +ALTER TABLE "expenses" RENAME COLUMN "notes" TO "description"; +ALTER TABLE "expenses" ADD COLUMN "budget_id" TEXT; + +UPDATE "expenses" +SET "budget_id" = CONCAT('budget_', "ag_id"); + +ALTER TABLE "expenses" ALTER COLUMN "budget_id" SET NOT NULL; + +ALTER TABLE "expenses" + ADD CONSTRAINT "expenses_budget_id_fkey" + FOREIGN KEY ("budget_id") REFERENCES "budgets"("id") + ON DELETE RESTRICT ON UPDATE CASCADE; + +ALTER TABLE "working_groups" DROP COLUMN "total_budget"; +ALTER TABLE "working_groups" DROP COLUMN "color_code"; diff --git a/prisma/migrations/202604081200_accounting_periods/migration.sql b/prisma/migrations/202604081200_accounting_periods/migration.sql new file mode 100644 index 0000000..a1d6b68 --- /dev/null +++ b/prisma/migrations/202604081200_accounting_periods/migration.sql @@ -0,0 +1,60 @@ +CREATE TYPE "ExpenseRecurrence" AS ENUM ('NONE', 'MONTHLY'); + +CREATE TABLE "accounting_periods" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "starts_at" TIMESTAMP(3) NOT NULL, + "ends_at" TIMESTAMP(3) NOT NULL, + "is_current" BOOLEAN NOT NULL DEFAULT false, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + CONSTRAINT "accounting_periods_pkey" PRIMARY KEY ("id") +); + +CREATE UNIQUE INDEX "accounting_periods_name_key" ON "accounting_periods"("name"); +CREATE UNIQUE INDEX "accounting_periods_is_current_key" ON "accounting_periods"("is_current") WHERE "is_current" = true; + +INSERT INTO "accounting_periods" ( + "id", + "name", + "starts_at", + "ends_at", + "is_current", + "created_at", + "updated_at" +) +VALUES ( + 'period_current', + CONCAT('Haushalt ', EXTRACT(YEAR FROM CURRENT_DATE)::text), + date_trunc('year', CURRENT_DATE)::timestamp(3), + (date_trunc('year', CURRENT_DATE) + interval '1 year' - interval '1 day')::timestamp(3), + true, + CURRENT_TIMESTAMP, + CURRENT_TIMESTAMP +); + +ALTER TABLE "budgets" ADD COLUMN "period_id" TEXT; +ALTER TABLE "expenses" ADD COLUMN "period_id" TEXT; +ALTER TABLE "expenses" ADD COLUMN "recurrence" "ExpenseRecurrence" NOT NULL DEFAULT 'NONE'; + +UPDATE "budgets" +SET "period_id" = 'period_current'; + +UPDATE "expenses" +SET "period_id" = 'period_current'; + +ALTER TABLE "budgets" ALTER COLUMN "period_id" SET NOT NULL; +ALTER TABLE "expenses" ALTER COLUMN "period_id" SET NOT NULL; + +DROP INDEX "budgets_working_group_id_name_key"; +CREATE UNIQUE INDEX "budgets_working_group_id_period_id_name_key" ON "budgets"("working_group_id", "period_id", "name"); + +ALTER TABLE "budgets" + ADD CONSTRAINT "budgets_period_id_fkey" + FOREIGN KEY ("period_id") REFERENCES "accounting_periods"("id") + ON DELETE RESTRICT ON UPDATE CASCADE; + +ALTER TABLE "expenses" + ADD CONSTRAINT "expenses_period_id_fkey" + FOREIGN KEY ("period_id") REFERENCES "accounting_periods"("id") + ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/202604081930_audit_logs/migration.sql b/prisma/migrations/202604081930_audit_logs/migration.sql new file mode 100644 index 0000000..88b116a --- /dev/null +++ b/prisma/migrations/202604081930_audit_logs/migration.sql @@ -0,0 +1,20 @@ +CREATE TABLE "audit_logs" ( + "id" TEXT NOT NULL, + "actor_id" TEXT, + "action" TEXT NOT NULL, + "entity_type" TEXT NOT NULL, + "entity_id" TEXT, + "entity_label" TEXT, + "summary" TEXT NOT NULL, + "metadata" JSONB, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "audit_logs_pkey" PRIMARY KEY ("id") +); + +CREATE INDEX "audit_logs_created_at_idx" ON "audit_logs"("created_at"); + +ALTER TABLE "audit_logs" +ADD CONSTRAINT "audit_logs_actor_id_fkey" +FOREIGN KEY ("actor_id") REFERENCES "users"("id") +ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma new file mode 100644 index 0000000..472e7c6 --- /dev/null +++ b/prisma/schema.prisma @@ -0,0 +1,146 @@ +generator client { + provider = "prisma-client-js" +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +enum Role { + ADMIN + FINANCE + MEMBER +} + +enum ApprovalType { + CHAIR_A + CHAIR_B + FINANCE +} + +enum ApprovalStatus { + PENDING + APPROVED +} + +enum ExpenseRecurrence { + NONE + MONTHLY +} + +model User { + id String @id @default(cuid()) + name String + username String @unique + email String? @unique + passwordHash String @map("password_hash") + role Role + approvalPreference ApprovalType? @map("approval_preference") + workingGroupId String? @map("working_group_id") + workingGroup WorkingGroup? @relation(fields: [workingGroupId], references: [id], onDelete: SetNull) + createdExpenses Expense[] @relation("ExpenseCreator") + approvals Approval[] + auditLogs AuditLog[] + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + + @@map("users") +} + +model AccountingPeriod { + id String @id @default(cuid()) + name String @unique + startsAt DateTime @map("starts_at") + endsAt DateTime @map("ends_at") + isCurrent Boolean @default(false) @map("is_current") + budgets Budget[] + expenses Expense[] + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + + @@map("accounting_periods") +} + +model WorkingGroup { + id String @id @default(cuid()) + name String @unique + members User[] + budgets Budget[] + expenses Expense[] + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + + @@map("working_groups") +} + +model Budget { + id String @id @default(cuid()) + name String + totalBudget Decimal @db.Decimal(10, 2) @map("total_budget") + colorCode String @map("color_code") + workingGroupId String @map("working_group_id") + periodId String @map("period_id") + workingGroup WorkingGroup @relation(fields: [workingGroupId], references: [id], onDelete: Cascade) + period AccountingPeriod @relation(fields: [periodId], references: [id], onDelete: Restrict) + expenses Expense[] + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + + @@unique([workingGroupId, periodId, name]) + @@map("budgets") +} + +model Expense { + id String @id @default(cuid()) + title String + description String? + amount Decimal @db.Decimal(10, 2) + creatorId String @map("creator_id") + agId String @map("ag_id") + budgetId String @map("budget_id") + periodId String @map("period_id") + approvalStatus ApprovalStatus @default(PENDING) @map("approval_status") + recurrence ExpenseRecurrence @default(NONE) + paidAt DateTime? @map("paid_at") + documentedAt DateTime? @map("documented_at") + proofUrl String? @map("proof_url") + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + creator User @relation("ExpenseCreator", fields: [creatorId], references: [id], onDelete: Restrict) + workingGroup WorkingGroup @relation(fields: [agId], references: [id], onDelete: Cascade) + budget Budget @relation(fields: [budgetId], references: [id], onDelete: Restrict) + period AccountingPeriod @relation(fields: [periodId], references: [id], onDelete: Restrict) + approvals Approval[] + + @@map("expenses") +} + +model Approval { + id String @id @default(cuid()) + expenseId String @map("expense_id") + userId String @map("user_id") + approvalType ApprovalType @map("approval_type") + timestamp DateTime @default(now()) + expense Expense @relation(fields: [expenseId], references: [id], onDelete: Cascade) + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + + @@unique([expenseId, approvalType]) + @@map("approvals") +} + +model AuditLog { + id String @id @default(cuid()) + actorId String? @map("actor_id") + actor User? @relation(fields: [actorId], references: [id], onDelete: SetNull) + action String + entityType String @map("entity_type") + entityId String? @map("entity_id") + entityLabel String? @map("entity_label") + summary String + metadata Json? + createdAt DateTime @default(now()) @map("created_at") + + @@index([createdAt]) + @@map("audit_logs") +} diff --git a/prisma/seed.ts b/prisma/seed.ts new file mode 100644 index 0000000..b651b62 --- /dev/null +++ b/prisma/seed.ts @@ -0,0 +1,250 @@ +import { ApprovalStatus, ApprovalType, ExpenseRecurrence, PrismaClient, Role } from "@prisma/client"; +import bcrypt from "bcryptjs"; + +const prisma = new PrismaClient(); + +async function upsertCurrentPeriod() { + const year = new Date().getFullYear(); + const startsAt = new Date(Date.UTC(year, 0, 1)); + const endsAt = new Date(Date.UTC(year, 11, 31, 23, 59, 59)); + + await prisma.accountingPeriod.updateMany({ + data: { + isCurrent: false + } + }); + + return prisma.accountingPeriod.upsert({ + where: { + name: `Haushalt ${year}` + }, + update: { + startsAt, + endsAt, + isCurrent: true + }, + create: { + name: `Haushalt ${year}`, + startsAt, + endsAt, + isCurrent: true + } + }); +} + +async function upsertWorkingGroup(name: string) { + return prisma.workingGroup.upsert({ + where: { name }, + update: {}, + create: { + name + } + }); +} + +async function upsertBudget( + workingGroupId: string, + periodId: string, + name: string, + totalBudget: number, + colorCode: string +) { + return prisma.budget.upsert({ + where: { + workingGroupId_periodId_name: { + workingGroupId, + periodId, + name + } + }, + update: { + totalBudget, + colorCode + }, + create: { + name, + totalBudget, + colorCode, + workingGroupId, + periodId + } + }); +} + +async function main() { + const passwordHash = await bcrypt.hash("demo123!", 12); + const currentPeriod = await upsertCurrentPeriod(); + + const deko = await upsertWorkingGroup("AG Deko"); + const awareness = await upsertWorkingGroup("AG Awareness"); + const technik = await upsertWorkingGroup("AG Technik"); + + await upsertBudget(deko.id, currentPeriod.id, "Deko Hauptbudget", 0, "#FFB94A"); + await upsertBudget(awareness.id, currentPeriod.id, "Awareness Hauptbudget", 800, "#68A35D"); + const technikBudget = await upsertBudget(technik.id, currentPeriod.id, "Technik Infrastruktur", 1500, "#5677F6"); + + await prisma.user.upsert({ + where: { username: "vorstand-a" }, + update: { + name: "Admin 1", + username: "vorstand-a", + email: null, + passwordHash, + role: Role.ADMIN, + approvalPreference: ApprovalType.CHAIR_A, + workingGroupId: null + }, + create: { + name: "Admin 1", + username: "vorstand-a", + email: null, + passwordHash, + role: Role.ADMIN, + approvalPreference: ApprovalType.CHAIR_A + } + }); + + await prisma.user.upsert({ + where: { username: "vorstand-b" }, + update: { + name: "Admin 2", + username: "vorstand-b", + email: null, + passwordHash, + role: Role.ADMIN, + approvalPreference: ApprovalType.CHAIR_B, + workingGroupId: null + }, + create: { + name: "Admin 2", + username: "vorstand-b", + email: null, + passwordHash, + role: Role.ADMIN, + approvalPreference: ApprovalType.CHAIR_B + } + }); + + await prisma.user.upsert({ + where: { username: "finanzen" }, + update: { + name: "Finanz-AG", + username: "finanzen", + email: null, + passwordHash, + role: Role.FINANCE, + approvalPreference: ApprovalType.FINANCE, + workingGroupId: null + }, + create: { + name: "Finanz-AG", + username: "finanzen", + email: null, + passwordHash, + role: Role.FINANCE, + approvalPreference: ApprovalType.FINANCE + } + }); + + await prisma.user.upsert({ + where: { username: "deko" }, + update: { + name: "Deko Mitglied", + username: "deko", + email: null, + passwordHash, + role: Role.MEMBER, + approvalPreference: null, + workingGroupId: deko.id + }, + create: { + name: "Deko Mitglied", + username: "deko", + email: null, + passwordHash, + role: Role.MEMBER, + workingGroupId: deko.id + } + }); + + await prisma.user.upsert({ + where: { username: "technik" }, + update: { + name: "Technik Mitglied", + username: "technik", + email: null, + passwordHash, + role: Role.MEMBER, + approvalPreference: null, + workingGroupId: technik.id + }, + create: { + name: "Technik Mitglied", + username: "technik", + email: null, + passwordHash, + role: Role.MEMBER, + workingGroupId: technik.id + } + }); + + const existingExpense = await prisma.expense.findFirst({ + where: { title: "Muster: Kabelbinder" } + }); + + if (!existingExpense) { + const technikUser = await prisma.user.findUniqueOrThrow({ + where: { username: "technik" } + }); + + await prisma.expense.create({ + data: { + title: "Muster: Kabelbinder", + description: "Beispiel fuer einen automatisch freigegebenen Infrastrukturposten.", + amount: 24.5, + creatorId: technikUser.id, + agId: technik.id, + budgetId: technikBudget.id, + periodId: currentPeriod.id, + approvalStatus: ApprovalStatus.APPROVED, + proofUrl: null, + recurrence: ExpenseRecurrence.NONE + } + }); + } + + const existingSubscription = await prisma.expense.findFirst({ + where: { title: "Muster: Vereinssoftware Abo" } + }); + + if (!existingSubscription) { + const financeUser = await prisma.user.findUniqueOrThrow({ + where: { username: "finanzen" } + }); + + await prisma.expense.create({ + data: { + title: "Muster: Vereinssoftware Abo", + description: "Monatlich wiederkehrendes Beispielabo fuer die Uebersicht.", + amount: 19, + creatorId: financeUser.id, + agId: technik.id, + budgetId: technikBudget.id, + periodId: currentPeriod.id, + approvalStatus: ApprovalStatus.APPROVED, + proofUrl: null, + recurrence: ExpenseRecurrence.MONTHLY + } + }); + } +} + +main() + .then(async () => { + await prisma.$disconnect(); + }) + .catch(async (error) => { + console.error(error); + await prisma.$disconnect(); + process.exit(1); + }); diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..555530d2ba4912ece695bd198924a35054538405 GIT binary patch literal 34412 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 x3Kyhrxv$C literal 0 HcmV?d00001 diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..bddd2f37d5e7bd7ae1c0eb31420248b49bc55cfd GIT binary patch literal 651 zcmV;60(AWV0096201yxW0000W0CfTY02TlM0EtjeM-2)Z3IG5A4M|8uQUCw|5C8xG z5C{eU001BJ|6u?C0z64XK~#90rISr>5>XU}pSc4JAEl)fDASs1{cJ+Ss8MTbqb6=$ zbmb3m?cZ?YzcA^>H2wjb7>#k!)(BLfQ0PF*z%b0c*G07iO?1(doZWffJm<@ZCT-0* zA_OpRUt=`#k->;WBFahc1f>*G1}G`<`~gx)!lBSuDTA>=C~UG|+xY$v%L!!R($ z+A)FSbSV_BQmq{z0LzLHk6SEXTtI0}A{L|BY%z2_qEqn+0|5|;gmGOL8Axge4NB#G z9H+yBdv~Z*YGku%?mjK@;?)MJ>@g;RCM(x3Q{Jyp+A9%HO{1imyhNqs zFCGJ}6}5VU>|6@dOry1?RIU=pfN&y)R_gCN;5U*2tqrR624BAJ&}uo1Mgh5O2B|bC l4S&3zao%qf|1bG>`~=w>5!}gWYX<-T002ovPDHLkV1oT!9H{^R literal 0 HcmV?d00001 diff --git a/public/icon-192.png b/public/icon-192.png new file mode 100644 index 0000000000000000000000000000000000000000..051cb1e04571d5a1fac4ce9210405e39cfa0f59c GIT binary patch literal 34979 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 RiXH|a@O1TaS?83{1OOyJ^M(Kb literal 0 HcmV?d00001 diff --git a/public/icon-512.png b/public/icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..60bf8a46a58cc59869da91bb5f0a16b9f0d5ef84 GIT binary patch literal 154005 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 literal 0 HcmV?d00001 diff --git a/public/icon.png b/public/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..60bf8a46a58cc59869da91bb5f0a16b9f0d5ef84 GIT binary patch literal 154005 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 literal 0 HcmV?d00001 diff --git a/public/icon.svg b/public/icon.svg new file mode 100644 index 0000000..f604063 --- /dev/null +++ b/public/icon.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/sw.js b/public/sw.js new file mode 100644 index 0000000..93e4f29 --- /dev/null +++ b/public/sw.js @@ -0,0 +1,45 @@ +const CACHE_NAME = "rave-budget-control-v1"; +const APP_SHELL = ["/", "/login", "/icon.svg", "/manifest.webmanifest"]; + +self.addEventListener("install", (event) => { + event.waitUntil( + caches + .open(CACHE_NAME) + .then((cache) => cache.addAll(APP_SHELL)) + .then(() => self.skipWaiting()) + ); +}); + +self.addEventListener("activate", (event) => { + event.waitUntil( + caches.keys().then((cacheNames) => + Promise.all(cacheNames.filter((cacheName) => cacheName !== CACHE_NAME).map((cacheName) => caches.delete(cacheName))) + ) + ); +}); + +self.addEventListener("fetch", (event) => { + const { request } = event; + const url = new URL(request.url); + + if (request.method !== "GET" || url.pathname.startsWith("/api")) { + return; + } + + event.respondWith( + fetch(request) + .then((response) => { + const responseClone = response.clone(); + + caches.open(CACHE_NAME).then((cache) => { + cache.put(request, responseClone); + }); + + return response; + }) + .catch(async () => { + const cached = await caches.match(request); + return cached ?? caches.match("/"); + }) + ); +}); diff --git a/src/app/api/audit-logs/[id]/restore/route.ts b/src/app/api/audit-logs/[id]/restore/route.ts new file mode 100644 index 0000000..7fc6cd5 --- /dev/null +++ b/src/app/api/audit-logs/[id]/restore/route.ts @@ -0,0 +1,516 @@ +import { NextResponse } from "next/server"; + +import { createAuditLog, getRollbackMetadata } from "@/lib/audit-log"; +import { APPROVAL_FLOW, canManageUsers } from "@/lib/domain"; +import prisma from "@/lib/prisma"; +import { getCurrentViewer } from "@/lib/session"; + +type Context = { + params: { + id: string; + }; +}; + +function asRecord(value: unknown, label: string) { + if (!value || typeof value !== "object" || Array.isArray(value)) { + throw new Error(`${label} ist im Änderungsverlauf nicht vollständig hinterlegt.`); + } + + return value as Record; +} + +function asString(value: unknown, label: string) { + if (typeof value !== "string" || value.length === 0) { + throw new Error(`${label} fehlt im Änderungsverlauf.`); + } + + return value; +} + +function asNullableString(value: unknown) { + return typeof value === "string" && value.length > 0 ? value : null; +} + +function asDate(value: unknown, label: string) { + if (value === null || value === undefined || value === "") { + return null; + } + + const parsed = new Date(asString(value, label)); + + if (Number.isNaN(parsed.getTime())) { + throw new Error(`${label} ist ungültig.`); + } + + return parsed; +} + +function asNumber(value: unknown, label: string) { + if (typeof value !== "number" || Number.isNaN(value)) { + throw new Error(`${label} ist ungültig.`); + } + + return value; +} + +export async function POST(_: Request, { params }: Context) { + const viewer = await getCurrentViewer(); + + if (!viewer) { + return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); + } + + if (!canManageUsers(viewer.role)) { + return NextResponse.json({ error: "Nur Vorstand oder Finanz-AG dürfen Zustände zurücksetzen." }, { status: 403 }); + } + + const auditLog = await prisma.auditLog.findUnique({ + where: { + id: params.id + } + }); + + if (!auditLog) { + return NextResponse.json({ error: "Log-Eintrag nicht gefunden." }, { status: 404 }); + } + + const rollback = getRollbackMetadata(auditLog.metadata); + + if (!rollback) { + return NextResponse.json({ error: "Dieser Log-Eintrag enthält noch keinen wiederherstellbaren Zustand." }, { status: 400 }); + } + + try { + await prisma.$transaction(async (tx) => { + switch (rollback.kind) { + case "budget.create": { + const created = asRecord(rollback.created, "Budget"); + const budgetId = asString(created.id, "Budget-ID"); + const budget = await tx.budget.findUnique({ + where: { id: budgetId }, + include: { + _count: { + select: { + expenses: true + } + } + } + }); + + if (!budget) { + throw new Error("Das angelegte Budget existiert nicht mehr."); + } + + if (budget._count.expenses > 0) { + throw new Error("Das Budget hat bereits Ausgaben und kann nicht automatisch entfernt werden."); + } + + await tx.budget.delete({ + where: { id: budgetId } + }); + + if (rollback.createdWorkingGroup) { + const createdWorkingGroup = asRecord(rollback.createdWorkingGroup, "Arbeitsgruppe"); + const workingGroupId = asString(createdWorkingGroup.id, "AG-ID"); + const workingGroup = await tx.workingGroup.findUnique({ + where: { id: workingGroupId }, + include: { + _count: { + select: { + members: true, + budgets: true, + expenses: true + } + } + } + }); + + if ( + workingGroup && + workingGroup._count.members === 0 && + workingGroup._count.budgets === 0 && + workingGroup._count.expenses === 0 + ) { + await tx.workingGroup.delete({ + where: { id: workingGroup.id } + }); + } + } + break; + } + + case "budget.update": { + const previous = asRecord(rollback.previous, "Budget"); + const budgetId = asString(previous.id, "Budget-ID"); + + await tx.budget.update({ + where: { id: budgetId }, + data: { + name: asString(previous.name, "Budgetname"), + totalBudget: asNumber(previous.totalBudget, "Budgetbetrag"), + colorCode: asString(previous.colorCode, "Budgetfarbe") + } + }); + break; + } + + case "budget.delete": { + const deleted = asRecord(rollback.deleted, "Budget"); + + await tx.budget.create({ + data: { + id: asString(deleted.id, "Budget-ID"), + name: asString(deleted.name, "Budgetname"), + totalBudget: asNumber(deleted.totalBudget, "Budgetbetrag"), + colorCode: asString(deleted.colorCode, "Budgetfarbe"), + workingGroupId: asString(deleted.workingGroupId, "AG-ID"), + periodId: asString(deleted.periodId, "Zeitraum-ID"), + createdAt: asDate(deleted.createdAt, "Budget erstellt am") ?? new Date() + } + }); + break; + } + + case "workingGroup.delete": { + const deleted = asRecord(rollback.deleted, "Arbeitsgruppe"); + + await tx.workingGroup.create({ + data: { + id: asString(deleted.id, "AG-ID"), + name: asString(deleted.name, "AG-Name"), + createdAt: asDate(deleted.createdAt, "AG erstellt am") ?? new Date() + } + }); + break; + } + + case "workingGroup.create": { + const created = asRecord(rollback.created, "Arbeitsgruppe"); + const workingGroupId = asString(created.id, "AG-ID"); + const workingGroup = await tx.workingGroup.findUnique({ + where: { id: workingGroupId }, + include: { + _count: { + select: { + members: true, + budgets: true, + expenses: true + } + } + } + }); + + if (!workingGroup) { + throw new Error("Die angelegte AG existiert nicht mehr."); + } + + if (workingGroup._count.members > 0 || workingGroup._count.budgets > 0 || workingGroup._count.expenses > 0) { + throw new Error("Die AG wird bereits verwendet und kann nicht automatisch entfernt werden."); + } + + await tx.workingGroup.delete({ + where: { id: workingGroupId } + }); + break; + } + + case "workingGroup.update": { + const previous = asRecord(rollback.previous, "Arbeitsgruppe"); + const workingGroupId = asString(previous.id, "AG-ID"); + + await tx.workingGroup.update({ + where: { id: workingGroupId }, + data: { + name: asString(previous.name, "AG-Name") + } + }); + break; + } + + case "period.create": { + const created = asRecord(rollback.created, "Zeitraum"); + const periodId = asString(created.id, "Zeitraum-ID"); + const period = await tx.accountingPeriod.findUnique({ + where: { id: periodId }, + include: { + _count: { + select: { + budgets: true, + expenses: true + } + } + } + }); + + if (!period) { + throw new Error("Der angelegte Zeitraum existiert nicht mehr."); + } + + if (period.isCurrent) { + throw new Error("Der aktuell aktive Zeitraum kann nicht automatisch entfernt werden."); + } + + if (period._count.expenses > 0) { + throw new Error("Der Zeitraum enthält bereits Ausgaben und kann nicht automatisch entfernt werden."); + } + + await tx.budget.deleteMany({ + where: { + periodId + } + }); + + await tx.accountingPeriod.delete({ + where: { + id: periodId + } + }); + break; + } + + case "period.delete": { + const deleted = asRecord(rollback.deleted, "Zeitraum"); + + await tx.accountingPeriod.create({ + data: { + id: asString(deleted.id, "Zeitraum-ID"), + name: asString(deleted.name, "Zeitraumname"), + startsAt: asDate(deleted.startsAt, "Zeitraumstart") ?? new Date(), + endsAt: asDate(deleted.endsAt, "Zeitraumende") ?? new Date(), + isCurrent: Boolean(deleted.isCurrent), + createdAt: asDate(deleted.createdAt, "Zeitraum erstellt am") ?? new Date() + } + }); + break; + } + + case "period.setCurrent": { + const previousCurrentPeriodId = asNullableString(rollback.previousCurrentPeriodId); + + await tx.accountingPeriod.updateMany({ + data: { + isCurrent: false + } + }); + + if (previousCurrentPeriodId) { + await tx.accountingPeriod.update({ + where: { + id: previousCurrentPeriodId + }, + data: { + isCurrent: true + } + }); + } + break; + } + + case "user.create": { + const created = asRecord(rollback.created, "Nutzer"); + const userId = asString(created.id, "Nutzer-ID"); + + if (viewer.id === userId) { + throw new Error("Dein eigenes aktives Konto kann nicht über den Änderungsverlauf entfernt werden."); + } + + const user = await tx.user.findUnique({ + where: { id: userId }, + include: { + _count: { + select: { + approvals: true, + createdExpenses: true + } + } + } + }); + + if (!user) { + throw new Error("Der angelegte Nutzer existiert nicht mehr."); + } + + if (user._count.approvals > 0 || user._count.createdExpenses > 0) { + throw new Error("Der Nutzer hat bereits Ausgaben oder Freigaben und kann nicht automatisch entfernt werden."); + } + + if (user.role === "ADMIN") { + const adminCount = await tx.user.count({ + where: { + role: "ADMIN" + } + }); + + if (adminCount <= 1) { + throw new Error("Mindestens ein Vorstandskonto muss erhalten bleiben."); + } + } + + await tx.user.delete({ + where: { id: userId } + }); + break; + } + + case "user.delete": { + const deleted = asRecord(rollback.deleted, "Nutzer"); + + await tx.user.create({ + data: { + id: asString(deleted.id, "Nutzer-ID"), + name: asString(deleted.name, "Anzeigename"), + username: asString(deleted.username, "Login-Name"), + email: asNullableString(deleted.email), + passwordHash: asString(deleted.passwordHash, "Passworthash"), + role: asString(deleted.role, "Rolle") as "ADMIN" | "FINANCE" | "MEMBER", + approvalPreference: asNullableString(deleted.approvalPreference) as "CHAIR_A" | "CHAIR_B" | "FINANCE" | null, + workingGroupId: asNullableString(deleted.workingGroupId), + createdAt: asDate(deleted.createdAt, "Nutzer erstellt am") ?? new Date() + } + }); + break; + } + + case "user.passwordReset": { + await tx.user.update({ + where: { + id: asString(rollback.userId, "Nutzer-ID") + }, + data: { + passwordHash: asString(rollback.previousPasswordHash, "Altes Passwort") + } + }); + break; + } + + case "expense.create": { + const created = asRecord(rollback.created, "Ausgabe"); + const expenseId = asString(created.id, "Ausgabe-ID"); + const expense = await tx.expense.findUnique({ + where: { id: expenseId }, + include: { + _count: { + select: { + approvals: true + } + } + } + }); + + if (!expense) { + throw new Error("Die angelegte Ausgabe existiert nicht mehr."); + } + + if (expense._count.approvals > 0 || expense.paidAt || expense.documentedAt) { + throw new Error("Die Ausgabe wurde bereits weiterverarbeitet und kann nicht automatisch entfernt werden."); + } + + await tx.expense.delete({ + where: { id: expenseId } + }); + break; + } + + case "expense.delete": { + const deleted = asRecord(rollback.deleted, "Ausgabe"); + + await tx.expense.create({ + data: { + id: asString(deleted.id, "Ausgabe-ID"), + title: asString(deleted.title, "Titel"), + description: asNullableString(deleted.description), + amount: asNumber(deleted.amount, "Betrag"), + creatorId: asString(deleted.creatorId, "Ersteller-ID"), + agId: asString(deleted.agId, "AG-ID"), + budgetId: asString(deleted.budgetId, "Budget-ID"), + periodId: asString(deleted.periodId, "Zeitraum-ID"), + approvalStatus: asString(deleted.approvalStatus, "Freigabestatus") as "PENDING" | "APPROVED", + recurrence: asString(deleted.recurrence, "Wiederholung") as "NONE" | "MONTHLY", + proofUrl: asNullableString(deleted.proofUrl), + createdAt: asDate(deleted.createdAt, "Ausgabe erstellt am") ?? new Date(), + paidAt: asDate(deleted.paidAt, "Bezahlt am"), + documentedAt: asDate(deleted.documentedAt, "Dokumentiert am") + } + }); + break; + } + + case "expense.approve": { + const approval = asRecord(rollback.approval, "Freigabe"); + const expenseId = asString(approval.expenseId, "Ausgabe-ID"); + + await tx.approval.delete({ + where: { + id: asString(approval.id, "Freigabe-ID") + } + }); + + const remainingApprovals = await tx.approval.findMany({ + where: { + expenseId + } + }); + + const approvalTypes = remainingApprovals.map((entry) => entry.approvalType); + const approvalStatus = APPROVAL_FLOW.every((approvalType) => approvalTypes.includes(approvalType)) + ? "APPROVED" + : "PENDING"; + + await tx.expense.update({ + where: { id: expenseId }, + data: { + approvalStatus + } + }); + break; + } + + case "expense.markPaid": { + await tx.expense.update({ + where: { + id: asString(rollback.expenseId, "Ausgabe-ID") + }, + data: { + paidAt: asDate(rollback.previousPaidAt, "Vorheriger Bezahlt-Zeitpunkt") + } + }); + break; + } + + case "expense.document": { + await tx.expense.update({ + where: { + id: asString(rollback.expenseId, "Ausgabe-ID") + }, + data: { + proofUrl: asNullableString(rollback.previousProofUrl), + documentedAt: asDate(rollback.previousDocumentedAt, "Vorheriger Dokumentationszeitpunkt") + } + }); + break; + } + + default: + throw new Error("Dieser Änderungstyp kann aktuell noch nicht automatisch zurückgesetzt werden."); + } + }); + + await createAuditLog(prisma, { + actorId: viewer.id, + action: "audit.restore", + entityType: auditLog.entityType, + entityId: auditLog.entityId, + entityLabel: auditLog.entityLabel, + summary: `Änderung "${auditLog.summary}" wurde zurückgesetzt.`, + metadata: { + restoredAuditLogId: auditLog.id, + restoredAction: auditLog.action + } + }); + + return NextResponse.json({ ok: true }); + } catch (error) { + const message = error instanceof Error ? error.message : "Der Zustand konnte nicht zurückgesetzt werden."; + return NextResponse.json({ error: message }, { status: 400 }); + } +} diff --git a/src/app/api/auth/[...nextauth]/route.ts b/src/app/api/auth/[...nextauth]/route.ts new file mode 100644 index 0000000..587c804 --- /dev/null +++ b/src/app/api/auth/[...nextauth]/route.ts @@ -0,0 +1,8 @@ +import NextAuth from "next-auth"; + +import { authOptions } from "@/lib/auth"; + +const handler = NextAuth(authOptions); + +export { handler as GET, handler as POST }; + diff --git a/src/app/api/budgets/[id]/route.ts b/src/app/api/budgets/[id]/route.ts new file mode 100644 index 0000000..a61ff53 --- /dev/null +++ b/src/app/api/budgets/[id]/route.ts @@ -0,0 +1,147 @@ +import { Prisma } from "@prisma/client"; +import { NextResponse } from "next/server"; +import { z } from "zod"; + +import { snapshotBudget } from "@/lib/audit-snapshots"; +import { createAuditLog } from "@/lib/audit-log"; +import { canManageBudgets } from "@/lib/domain"; +import prisma from "@/lib/prisma"; +import { getCurrentViewer } from "@/lib/session"; + +const updateBudgetSchema = z.object({ + name: z.string().trim().min(2).max(80), + totalBudget: z.coerce.number().min(0), + colorCode: z.string().regex(/^#([0-9a-fA-F]{6})$/) +}); + +type Context = { + params: { + id: string; + }; +}; + +export async function PATCH(request: Request, { params }: Context) { + const viewer = await getCurrentViewer(); + + if (!viewer) { + return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); + } + + if (!canManageBudgets(viewer.role)) { + return NextResponse.json({ error: "Nur Vorstand oder Finanz-AG duerfen Budgets aendern." }, { status: 403 }); + } + + const budget = await prisma.budget.findUnique({ + where: { id: params.id } + }); + + if (!budget) { + return NextResponse.json({ error: "Budget nicht gefunden." }, { status: 404 }); + } + + const body = await request.json().catch(() => null); + const parsed = updateBudgetSchema.safeParse(body); + + if (!parsed.success) { + return NextResponse.json({ error: "Budgetname, Betrag oder Farbe sind ungueltig." }, { status: 400 }); + } + + try { + const previousBudget = budget; + const updatedBudget = await prisma.budget.update({ + where: { id: params.id }, + data: { + name: parsed.data.name, + totalBudget: parsed.data.totalBudget, + colorCode: parsed.data.colorCode + } + }); + + await createAuditLog(prisma, { + actorId: viewer.id, + action: "budget.update", + entityType: "budget", + entityId: updatedBudget.id, + entityLabel: updatedBudget.name, + summary: `Budget ${updatedBudget.name} wurde aktualisiert.`, + metadata: { + totalBudget: parsed.data.totalBudget, + colorCode: parsed.data.colorCode, + rollback: { + kind: "budget.update", + previous: snapshotBudget(previousBudget), + next: snapshotBudget(updatedBudget) + } + } + }); + + return NextResponse.json({ budget: updatedBudget }); + } catch (error) { + if ( + error instanceof Prisma.PrismaClientKnownRequestError && + error.code === "P2002" + ) { + return NextResponse.json( + { error: "In dieser AG gibt es bereits ein Budget mit diesem Namen." }, + { status: 409 } + ); + } + + throw error; + } +} + +export async function DELETE(_: Request, { params }: Context) { + const viewer = await getCurrentViewer(); + + if (!viewer) { + return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); + } + + if (!canManageBudgets(viewer.role)) { + return NextResponse.json({ error: "Nur Vorstand oder Finanz-AG duerfen Budgets loeschen." }, { status: 403 }); + } + + const budget = await prisma.budget.findUnique({ + where: { id: params.id }, + include: { + _count: { + select: { + expenses: true + } + } + } + }); + + if (!budget) { + return NextResponse.json({ error: "Budget nicht gefunden." }, { status: 404 }); + } + + if (budget._count.expenses > 0) { + return NextResponse.json( + { error: "Dieses Budget enthaelt noch Ausgaben. Bitte loesche oder verschiebe erst die Posten." }, + { status: 400 } + ); + } + + await prisma.budget.delete({ + where: { id: params.id } + }); + + await createAuditLog(prisma, { + actorId: viewer.id, + action: "budget.delete", + entityType: "budget", + entityId: budget.id, + entityLabel: budget.name, + summary: `Budget ${budget.name} wurde geloescht.`, + metadata: { + rollback: { + kind: "budget.delete", + deleted: snapshotBudget(budget) + } + } + }); + + return NextResponse.json({ ok: true }); +} diff --git a/src/app/api/budgets/route.ts b/src/app/api/budgets/route.ts new file mode 100644 index 0000000..c79240e --- /dev/null +++ b/src/app/api/budgets/route.ts @@ -0,0 +1,115 @@ +import { NextResponse } from "next/server"; +import { z } from "zod"; + +import { snapshotBudget } from "@/lib/audit-snapshots"; +import { createAuditLog } from "@/lib/audit-log"; +import { canManageBudgets } from "@/lib/domain"; +import prisma from "@/lib/prisma"; +import { getCurrentViewer } from "@/lib/session"; + +const budgetSchema = z.object({ + workingGroupId: z.string().trim().min(1), + periodId: z.string().trim().min(1), + name: z.string().trim().min(2).max(80), + totalBudget: z.coerce.number().min(0), + colorCode: z.string().regex(/^#([0-9a-fA-F]{6})$/) +}); + +export async function POST(request: Request) { + const viewer = await getCurrentViewer(); + + if (!viewer) { + return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); + } + + if (!canManageBudgets(viewer.role)) { + return NextResponse.json({ error: "Nur Vorstand oder Finanz-AG duerfen Budgets verwalten." }, { status: 403 }); + } + + const body = await request.json().catch(() => null); + const parsed = budgetSchema.safeParse(body); + + if (!parsed.success) { + return NextResponse.json({ error: "Bitte AG, Budgetname, Betrag und Farbe korrekt angeben." }, { status: 400 }); + } + + const workingGroup = await prisma.workingGroup.findUnique({ + where: { + id: parsed.data.workingGroupId + } + }); + + if (!workingGroup) { + return NextResponse.json({ error: "Die ausgewaehlte AG wurde nicht gefunden." }, { status: 404 }); + } + + const accountingPeriod = await prisma.accountingPeriod.findUnique({ + where: { + id: parsed.data.periodId + } + }); + + if (!accountingPeriod) { + return NextResponse.json({ error: "Der ausgewaehlte Abrechnungszeitraum wurde nicht gefunden." }, { status: 404 }); + } + + const existingBudget = await prisma.budget.findUnique({ + where: { + workingGroupId_periodId_name: { + workingGroupId: workingGroup.id, + periodId: accountingPeriod.id, + name: parsed.data.name + } + } + }); + + const budget = existingBudget + ? await prisma.budget.update({ + where: { + id: existingBudget.id + }, + data: { + totalBudget: parsed.data.totalBudget, + colorCode: parsed.data.colorCode + } + }) + : await prisma.budget.create({ + data: { + workingGroupId: workingGroup.id, + periodId: accountingPeriod.id, + name: parsed.data.name, + totalBudget: parsed.data.totalBudget, + colorCode: parsed.data.colorCode + } + }); + + await createAuditLog(prisma, { + actorId: viewer.id, + action: existingBudget ? "budget.update" : "budget.create", + entityType: "budget", + entityId: budget.id, + entityLabel: budget.name, + summary: existingBudget + ? `Budget ${budget.name} in ${workingGroup.name} gespeichert.` + : `Budget ${budget.name} in ${workingGroup.name} angelegt.`, + metadata: { + workingGroupId: workingGroup.id, + workingGroupName: workingGroup.name, + periodId: accountingPeriod.id, + periodName: accountingPeriod.name, + totalBudget: parsed.data.totalBudget, + rollback: existingBudget + ? { + kind: "budget.update", + previous: snapshotBudget(existingBudget), + next: snapshotBudget(budget) + } + : { + kind: "budget.create", + created: snapshotBudget(budget) + } + } + }); + + return NextResponse.json({ budget }); +} diff --git a/src/app/api/expenses/[id]/approve/route.ts b/src/app/api/expenses/[id]/approve/route.ts new file mode 100644 index 0000000..13e33fb --- /dev/null +++ b/src/app/api/expenses/[id]/approve/route.ts @@ -0,0 +1,124 @@ +import { NextResponse } from "next/server"; +import { z } from "zod"; + +import { snapshotApproval } from "@/lib/audit-snapshots"; +import { createAuditLog } from "@/lib/audit-log"; +import { APPROVAL_FLOW, getAvailableApprovalTypes, requiresManualApproval } from "@/lib/domain"; +import prisma from "@/lib/prisma"; +import { getCurrentViewer } from "@/lib/session"; + +const approvalSchema = z.object({ + approvalType: z.enum(APPROVAL_FLOW) +}); + +type Context = { + params: { + id: string; + }; +}; + +export async function POST(request: Request, { params }: Context) { + const viewer = await getCurrentViewer(); + + if (!viewer) { + return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); + } + + const expense = await prisma.expense.findUnique({ + where: { id: params.id }, + include: { + approvals: true + } + }); + + if (!expense) { + return NextResponse.json({ error: "Ausgabe nicht gefunden." }, { status: 404 }); + } + + if (!requiresManualApproval(Number(expense.amount))) { + return NextResponse.json({ error: "Diese Ausgabe ist bereits automatisch freigegeben." }, { status: 400 }); + } + + const body = await request.json().catch(() => null); + const parsed = approvalSchema.safeParse(body); + + if (!parsed.success) { + return NextResponse.json({ error: "Freigabetyp ungueltig." }, { status: 400 }); + } + + const existingApprovals = expense.approvals.map((approval) => approval.approvalType); + const availableApprovals = getAvailableApprovalTypes( + viewer.role, + viewer.approvalPreference, + existingApprovals + ); + + if (!availableApprovals.includes(parsed.data.approvalType)) { + return NextResponse.json({ error: "Du darfst diese Freigabe nicht setzen." }, { status: 403 }); + } + + const transactionResult = await prisma.$transaction(async (tx) => { + const existingApproval = await tx.approval.findUnique({ + where: { + expenseId_approvalType: { + expenseId: expense.id, + approvalType: parsed.data.approvalType + } + } + }); + + const createdApproval = + existingApproval ?? + (await tx.approval.create({ + data: { + expenseId: expense.id, + userId: viewer.id, + approvalType: parsed.data.approvalType + } + })); + + const approvals = await tx.approval.findMany({ + where: { + expenseId: expense.id + } + }); + + const approvalTypes = approvals.map((approval) => approval.approvalType); + const approvalStatus = APPROVAL_FLOW.every((approvalType) => approvalTypes.includes(approvalType)) + ? "APPROVED" + : "PENDING"; + + await tx.expense.update({ + where: { id: expense.id }, + data: { + approvalStatus + } + }); + + return { + approval: createdApproval, + previousStatus: expense.approvalStatus, + nextStatus: approvalStatus + }; + }); + + await createAuditLog(prisma, { + actorId: viewer.id, + action: "expense.approve", + entityType: "expense", + entityId: expense.id, + entityLabel: expense.title, + summary: `${parsed.data.approvalType} fuer ${expense.title} wurde gesetzt.`, + metadata: { + approvalType: parsed.data.approvalType, + rollback: { + kind: "expense.approve", + approval: snapshotApproval(transactionResult.approval), + previousStatus: transactionResult.previousStatus, + nextStatus: transactionResult.nextStatus + } + } + }); + + return NextResponse.json({ ok: true }); +} diff --git a/src/app/api/expenses/[id]/documented/route.ts b/src/app/api/expenses/[id]/documented/route.ts new file mode 100644 index 0000000..44f1043 --- /dev/null +++ b/src/app/api/expenses/[id]/documented/route.ts @@ -0,0 +1,84 @@ +import { NextResponse } from "next/server"; +import { z } from "zod"; + +import { createAuditLog } from "@/lib/audit-log"; +import { canDocumentExpense } from "@/lib/domain"; +import prisma from "@/lib/prisma"; +import { getCurrentViewer } from "@/lib/session"; + +const documentedSchema = z.object({ + proofUrl: z + .union([z.string().trim().url(), z.literal(""), z.null(), z.undefined()]) + .transform((value) => (typeof value === "string" && value.length > 0 ? value : undefined)) +}); + +type Context = { + params: { + id: string; + }; +}; + +export async function POST(request: Request, { params }: Context) { + const viewer = await getCurrentViewer(); + + if (!viewer) { + return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); + } + + if (!canDocumentExpense(viewer.role)) { + return NextResponse.json({ error: "Nur Vorstand oder Finanz-AG duerfen dokumentieren." }, { status: 403 }); + } + + const expense = await prisma.expense.findUnique({ + where: { id: params.id } + }); + + if (!expense) { + return NextResponse.json({ error: "Ausgabe nicht gefunden." }, { status: 404 }); + } + + if (expense.approvalStatus !== "APPROVED") { + return NextResponse.json({ error: "Dokumentation ist erst nach Freigabe moeglich." }, { status: 400 }); + } + + if (!expense.paidAt) { + return NextResponse.json({ error: "Bitte zuerst Bezahlt setzen." }, { status: 400 }); + } + + const body = await request.json().catch(() => ({})); + const parsed = documentedSchema.safeParse(body); + + if (!parsed.success) { + return NextResponse.json({ error: "Beleg-URL ist ungueltig." }, { status: 400 }); + } + + const updatedExpense = await prisma.expense.update({ + where: { id: params.id }, + data: { + proofUrl: parsed.data.proofUrl ?? expense.proofUrl, + documentedAt: expense.documentedAt ?? new Date() + } + }); + + await createAuditLog(prisma, { + actorId: viewer.id, + action: "expense.document", + entityType: "expense", + entityId: updatedExpense.id, + entityLabel: updatedExpense.title, + summary: `Ausgabe ${updatedExpense.title} wurde dokumentiert.`, + metadata: { + proofUrl: parsed.data.proofUrl ?? updatedExpense.proofUrl, + rollback: { + kind: "expense.document", + expenseId: updatedExpense.id, + previousProofUrl: expense.proofUrl, + previousDocumentedAt: expense.documentedAt?.toISOString() ?? null, + nextProofUrl: updatedExpense.proofUrl, + nextDocumentedAt: updatedExpense.documentedAt?.toISOString() ?? null + } + } + }); + + return NextResponse.json({ expense: updatedExpense }); +} diff --git a/src/app/api/expenses/[id]/paid/route.ts b/src/app/api/expenses/[id]/paid/route.ts new file mode 100644 index 0000000..73e0ba3 --- /dev/null +++ b/src/app/api/expenses/[id]/paid/route.ts @@ -0,0 +1,62 @@ +import { NextResponse } from "next/server"; + +import { createAuditLog } from "@/lib/audit-log"; +import { canMarkPaid } from "@/lib/domain"; +import prisma from "@/lib/prisma"; +import { getCurrentViewer } from "@/lib/session"; + +type Context = { + params: { + id: string; + }; +}; + +export async function POST(_: Request, { params }: Context) { + const viewer = await getCurrentViewer(); + + if (!viewer) { + return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); + } + + if (!canMarkPaid(viewer.role)) { + return NextResponse.json({ error: "Nur Vorstand oder Finanz-AG duerfen Bezahlt setzen." }, { status: 403 }); + } + + const expense = await prisma.expense.findUnique({ + where: { id: params.id } + }); + + if (!expense) { + return NextResponse.json({ error: "Ausgabe nicht gefunden." }, { status: 404 }); + } + + if (expense.approvalStatus !== "APPROVED") { + return NextResponse.json({ error: "Bezahlt ist erst nach Freigabe moeglich." }, { status: 400 }); + } + + const updatedExpense = await prisma.expense.update({ + where: { id: params.id }, + data: { + paidAt: expense.paidAt ?? new Date() + } + }); + + await createAuditLog(prisma, { + actorId: viewer.id, + action: "expense.markPaid", + entityType: "expense", + entityId: updatedExpense.id, + entityLabel: updatedExpense.title, + summary: `Ausgabe ${updatedExpense.title} wurde als bezahlt markiert.`, + metadata: { + rollback: { + kind: "expense.markPaid", + expenseId: updatedExpense.id, + previousPaidAt: expense.paidAt?.toISOString() ?? null, + nextPaidAt: updatedExpense.paidAt?.toISOString() ?? null + } + } + }); + + return NextResponse.json({ expense: updatedExpense }); +} diff --git a/src/app/api/expenses/[id]/route.ts b/src/app/api/expenses/[id]/route.ts new file mode 100644 index 0000000..7de6a5b --- /dev/null +++ b/src/app/api/expenses/[id]/route.ts @@ -0,0 +1,63 @@ +import { NextResponse } from "next/server"; + +import { snapshotExpense } from "@/lib/audit-snapshots"; +import { createAuditLog } from "@/lib/audit-log"; +import prisma from "@/lib/prisma"; +import { getCurrentViewer } from "@/lib/session"; + +type Context = { + params: { + id: string; + }; +}; + +export async function DELETE(_: Request, { params }: Context) { + const viewer = await getCurrentViewer(); + + if (!viewer) { + return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); + } + + const expense = await prisma.expense.findUnique({ + where: { id: params.id } + }); + + if (!expense) { + return NextResponse.json({ error: "Ausgabe nicht gefunden." }, { status: 404 }); + } + + const isAdminDelete = viewer.role === "ADMIN" || viewer.role === "FINANCE"; + const isOwnPendingExpense = + viewer.id === expense.creatorId && + expense.approvalStatus === "PENDING" && + !expense.paidAt && + !expense.documentedAt; + + if (!isAdminDelete && !isOwnPendingExpense) { + return NextResponse.json( + { error: "Du darfst nur eigene ungepruefte Ausgaben loeschen." }, + { status: 403 } + ); + } + + await prisma.expense.delete({ + where: { id: params.id } + }); + + await createAuditLog(prisma, { + actorId: viewer.id, + action: "expense.delete", + entityType: "expense", + entityId: expense.id, + entityLabel: expense.title, + summary: `Ausgabe ${expense.title} wurde geloescht.`, + metadata: { + rollback: { + kind: "expense.delete", + deleted: snapshotExpense(expense) + } + } + }); + + return NextResponse.json({ ok: true }); +} diff --git a/src/app/api/expenses/route.ts b/src/app/api/expenses/route.ts new file mode 100644 index 0000000..f9d77fe --- /dev/null +++ b/src/app/api/expenses/route.ts @@ -0,0 +1,86 @@ +import { NextResponse } from "next/server"; +import { z } from "zod"; + +import { snapshotExpense } from "@/lib/audit-snapshots"; +import { createAuditLog } from "@/lib/audit-log"; +import { canCreateExpenseForGroup, requiresManualApproval } from "@/lib/domain"; +import prisma from "@/lib/prisma"; +import { getCurrentViewer } from "@/lib/session"; + +const expenseSchema = z.object({ + title: z.string().trim().min(2).max(120), + description: z + .union([z.string().trim().max(1000), z.literal(""), z.null(), z.undefined()]) + .transform((value) => (typeof value === "string" && value.length > 0 ? value : undefined)), + amount: z.coerce.number().positive(), + agId: z.string().trim().min(1), + budgetId: z.string().trim().min(1), + recurrence: z.enum(["NONE", "MONTHLY"]).default("NONE"), + proofUrl: z + .union([z.string().trim().url(), z.literal(""), z.null(), z.undefined()]) + .transform((value) => (typeof value === "string" && value.length > 0 ? value : undefined)), +}); + +export async function POST(request: Request) { + const viewer = await getCurrentViewer(); + + if (!viewer) { + return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); + } + + const body = await request.json().catch(() => null); + const parsed = expenseSchema.safeParse(body); + + if (!parsed.success) { + return NextResponse.json({ error: "Bitte Titel, Betrag und AG korrekt ausfuellen." }, { status: 400 }); + } + + if (!canCreateExpenseForGroup(viewer.role, viewer.workingGroupId, parsed.data.agId)) { + return NextResponse.json({ error: "Du kannst nur in deiner eigenen AG Ausgaben erfassen." }, { status: 403 }); + } + + const budget = await prisma.budget.findUnique({ + where: { id: parsed.data.budgetId } + }); + + if (!budget || budget.workingGroupId !== parsed.data.agId) { + return NextResponse.json({ error: "Das ausgewaehlte Budget passt nicht zur AG." }, { status: 404 }); + } + + const expense = await prisma.expense.create({ + data: { + title: parsed.data.title, + description: parsed.data.description, + amount: parsed.data.amount, + agId: parsed.data.agId, + budgetId: parsed.data.budgetId, + periodId: budget.periodId, + creatorId: viewer.id, + proofUrl: parsed.data.proofUrl, + recurrence: parsed.data.recurrence, + approvalStatus: requiresManualApproval(parsed.data.amount) ? "PENDING" : "APPROVED" + } + }); + + await createAuditLog(prisma, { + actorId: viewer.id, + action: "expense.create", + entityType: "expense", + entityId: expense.id, + entityLabel: expense.title, + summary: `Ausgabe ${expense.title} wurde angelegt.`, + metadata: { + amount: parsed.data.amount, + budgetId: parsed.data.budgetId, + workingGroupId: parsed.data.agId, + recurrence: parsed.data.recurrence, + approvalStatus: expense.approvalStatus, + rollback: { + kind: "expense.create", + created: snapshotExpense(expense) + } + } + }); + + return NextResponse.json({ expense }); +} diff --git a/src/app/api/export/csv/route.ts b/src/app/api/export/csv/route.ts new file mode 100644 index 0000000..0a9febd --- /dev/null +++ b/src/app/api/export/csv/route.ts @@ -0,0 +1,518 @@ +import { NextResponse } from "next/server"; + +import { toCsvCell } from "@/lib/backup-csv"; +import { canManageUsers } from "@/lib/domain"; +import prisma from "@/lib/prisma"; +import { getCurrentViewer } from "@/lib/session"; + +const CSV_HEADERS = [ + "recordType", + "id", + "parentId", + "parentType", + "workingGroupId", + "workingGroupName", + "periodId", + "periodName", + "periodStartsAt", + "periodEndsAt", + "periodIsCurrent", + "budgetId", + "budgetName", + "userId", + "userName", + "username", + "passwordHash", + "email", + "role", + "approvalPreference", + "title", + "description", + "amount", + "totalBudget", + "colorCode", + "approvalStatus", + "approvalType", + "recurrence", + "proofUrl", + "createdAt", + "paidAt", + "documentedAt", + "memberUsernames", + "creatorName", + "creatorUsername", + "approverName", + "approverUsername", + "auditActorId", + "auditAction", + "auditEntityType", + "auditEntityId", + "auditEntityLabel", + "auditSummary", + "auditMetadata" +] as const; + +type CsvRow = Record<(typeof CSV_HEADERS)[number], string | number | null | undefined>; + +export async function GET() { + const viewer = await getCurrentViewer(); + + if (!viewer) { + return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); + } + + if (!canManageUsers(viewer.role)) { + return NextResponse.json({ error: "Nur Vorstand oder Finanz-AG duerfen CSV-Backups herunterladen." }, { status: 403 }); + } + + const [users, accountingPeriods, workingGroups, auditLogs] = await Promise.all([ + prisma.user.findMany({ + include: { + workingGroup: { + select: { + name: true + } + } + }, + orderBy: [ + { role: "asc" }, + { username: "asc" } + ] + }), + prisma.accountingPeriod.findMany({ + orderBy: { + startsAt: "asc" + } + }), + prisma.workingGroup.findMany({ + orderBy: { + name: "asc" + }, + include: { + members: { + select: { + id: true, + name: true, + username: true, + email: true, + role: true, + approvalPreference: true + }, + orderBy: { + username: "asc" + } + }, + budgets: { + orderBy: { + name: "asc" + }, + include: { + period: { + select: { + id: true, + name: true, + startsAt: true, + endsAt: true, + isCurrent: true + } + }, + expenses: { + orderBy: { + createdAt: "asc" + }, + include: { + creator: { + select: { + id: true, + name: true, + username: true + } + }, + approvals: { + orderBy: { + timestamp: "asc" + }, + include: { + user: { + select: { + id: true, + name: true, + username: true + } + } + } + } + } + } + } + } + } + }), + prisma.auditLog.findMany({ + orderBy: { + createdAt: "asc" + } + }) + ]); + + const rows: CsvRow[] = []; + + for (const user of users) { + rows.push({ + recordType: "user", + id: user.id, + parentId: user.workingGroupId, + parentType: user.workingGroupId ? "workingGroup" : "", + workingGroupId: user.workingGroupId, + workingGroupName: user.workingGroup?.name ?? "", + periodId: "", + periodName: "", + periodStartsAt: "", + periodEndsAt: "", + periodIsCurrent: "", + budgetId: "", + budgetName: "", + userId: user.id, + userName: user.name, + username: user.username, + passwordHash: user.passwordHash, + email: user.email, + role: user.role, + approvalPreference: user.approvalPreference ?? "", + title: "", + description: "", + amount: "", + totalBudget: "", + colorCode: "", + approvalStatus: "", + approvalType: "", + recurrence: "", + proofUrl: "", + createdAt: user.createdAt.toISOString(), + paidAt: "", + documentedAt: "", + memberUsernames: "", + creatorName: "", + creatorUsername: "", + approverName: "", + approverUsername: "", + auditActorId: "", + auditAction: "", + auditEntityType: "", + auditEntityId: "", + auditEntityLabel: "", + auditSummary: "", + auditMetadata: "" + }); + } + + for (const period of accountingPeriods) { + rows.push({ + recordType: "period", + id: period.id, + parentId: "", + parentType: "", + workingGroupId: "", + workingGroupName: "", + periodId: period.id, + periodName: period.name, + periodStartsAt: period.startsAt.toISOString(), + periodEndsAt: period.endsAt.toISOString(), + periodIsCurrent: period.isCurrent ? "true" : "false", + budgetId: "", + budgetName: "", + userId: "", + userName: "", + username: "", + passwordHash: "", + email: "", + role: "", + approvalPreference: "", + title: "", + description: "", + amount: "", + totalBudget: "", + colorCode: "", + approvalStatus: "", + approvalType: "", + recurrence: "", + proofUrl: "", + createdAt: period.createdAt.toISOString(), + paidAt: "", + documentedAt: "", + memberUsernames: "", + creatorName: "", + creatorUsername: "", + approverName: "", + approverUsername: "", + auditActorId: "", + auditAction: "", + auditEntityType: "", + auditEntityId: "", + auditEntityLabel: "", + auditSummary: "", + auditMetadata: "" + }); + } + + for (const group of workingGroups) { + rows.push({ + recordType: "workingGroup", + id: group.id, + parentId: "", + parentType: "", + workingGroupId: group.id, + workingGroupName: group.name, + periodId: "", + periodName: "", + periodStartsAt: "", + periodEndsAt: "", + periodIsCurrent: "", + budgetId: "", + budgetName: "", + userId: "", + userName: "", + username: "", + passwordHash: "", + email: "", + role: "", + approvalPreference: "", + title: "", + description: "", + amount: "", + totalBudget: group.budgets.reduce((sum, budget) => sum + Number(budget.totalBudget), 0).toFixed(2), + colorCode: "", + approvalStatus: "", + approvalType: "", + recurrence: "", + proofUrl: "", + createdAt: group.createdAt.toISOString(), + paidAt: "", + documentedAt: "", + memberUsernames: group.members.map((member) => member.username).join(" | "), + creatorName: "", + creatorUsername: "", + approverName: "", + approverUsername: "", + auditActorId: "", + auditAction: "", + auditEntityType: "", + auditEntityId: "", + auditEntityLabel: "", + auditSummary: "", + auditMetadata: "" + }); + + for (const budget of group.budgets) { + rows.push({ + recordType: "budget", + id: budget.id, + parentId: group.id, + parentType: "workingGroup", + workingGroupId: group.id, + workingGroupName: group.name, + periodId: budget.period.id, + periodName: budget.period.name, + periodStartsAt: budget.period.startsAt.toISOString(), + periodEndsAt: budget.period.endsAt.toISOString(), + periodIsCurrent: budget.period.isCurrent ? "true" : "false", + budgetId: budget.id, + budgetName: budget.name, + userId: "", + userName: "", + username: "", + passwordHash: "", + email: "", + role: "", + approvalPreference: "", + title: "", + description: "", + amount: "", + totalBudget: Number(budget.totalBudget).toFixed(2), + colorCode: budget.colorCode, + approvalStatus: "", + approvalType: "", + recurrence: "", + proofUrl: "", + createdAt: budget.createdAt.toISOString(), + paidAt: "", + documentedAt: "", + memberUsernames: "", + creatorName: "", + creatorUsername: "", + approverName: "", + approverUsername: "", + auditActorId: "", + auditAction: "", + auditEntityType: "", + auditEntityId: "", + auditEntityLabel: "", + auditSummary: "", + auditMetadata: "" + }); + + for (const expense of budget.expenses) { + rows.push({ + recordType: "expense", + id: expense.id, + parentId: budget.id, + parentType: "budget", + workingGroupId: group.id, + workingGroupName: group.name, + periodId: budget.period.id, + periodName: budget.period.name, + periodStartsAt: budget.period.startsAt.toISOString(), + periodEndsAt: budget.period.endsAt.toISOString(), + periodIsCurrent: budget.period.isCurrent ? "true" : "false", + budgetId: budget.id, + budgetName: budget.name, + userId: expense.creator.id, + userName: expense.creator.name, + username: expense.creator.username, + passwordHash: "", + email: "", + role: "", + approvalPreference: "", + title: expense.title, + description: expense.description ?? "", + amount: Number(expense.amount).toFixed(2), + totalBudget: "", + colorCode: "", + approvalStatus: expense.approvalStatus, + approvalType: "", + recurrence: expense.recurrence, + proofUrl: expense.proofUrl ?? "", + createdAt: expense.createdAt.toISOString(), + paidAt: expense.paidAt?.toISOString() ?? "", + documentedAt: expense.documentedAt?.toISOString() ?? "", + memberUsernames: "", + creatorName: expense.creator.name, + creatorUsername: expense.creator.username, + approverName: "", + approverUsername: "", + auditActorId: "", + auditAction: "", + auditEntityType: "", + auditEntityId: "", + auditEntityLabel: "", + auditSummary: "", + auditMetadata: "" + }); + + for (const approval of expense.approvals) { + rows.push({ + recordType: "approval", + id: approval.id, + parentId: expense.id, + parentType: "expense", + workingGroupId: group.id, + workingGroupName: group.name, + periodId: budget.period.id, + periodName: budget.period.name, + periodStartsAt: budget.period.startsAt.toISOString(), + periodEndsAt: budget.period.endsAt.toISOString(), + periodIsCurrent: budget.period.isCurrent ? "true" : "false", + budgetId: budget.id, + budgetName: budget.name, + userId: approval.user.id, + userName: approval.user.name, + username: approval.user.username, + passwordHash: "", + email: "", + role: "", + approvalPreference: "", + title: expense.title, + description: "", + amount: Number(expense.amount).toFixed(2), + totalBudget: "", + colorCode: "", + approvalStatus: expense.approvalStatus, + approvalType: approval.approvalType, + recurrence: expense.recurrence, + proofUrl: "", + createdAt: approval.timestamp.toISOString(), + paidAt: "", + documentedAt: "", + memberUsernames: "", + creatorName: expense.creator.name, + creatorUsername: expense.creator.username, + approverName: approval.user.name, + approverUsername: approval.user.username, + auditActorId: "", + auditAction: "", + auditEntityType: "", + auditEntityId: "", + auditEntityLabel: "", + auditSummary: "", + auditMetadata: "" + }); + } + } + } + } + + for (const auditLog of auditLogs) { + rows.push({ + recordType: "auditLog", + id: auditLog.id, + parentId: "", + parentType: "", + workingGroupId: "", + workingGroupName: "", + periodId: "", + periodName: "", + periodStartsAt: "", + periodEndsAt: "", + periodIsCurrent: "", + budgetId: "", + budgetName: "", + userId: "", + userName: "", + username: "", + passwordHash: "", + email: "", + role: "", + approvalPreference: "", + title: "", + description: "", + amount: "", + totalBudget: "", + colorCode: "", + approvalStatus: "", + approvalType: "", + recurrence: "", + proofUrl: "", + createdAt: auditLog.createdAt.toISOString(), + paidAt: "", + documentedAt: "", + memberUsernames: "", + creatorName: "", + creatorUsername: "", + approverName: "", + approverUsername: "", + auditActorId: auditLog.actorId ?? "", + auditAction: auditLog.action, + auditEntityType: auditLog.entityType, + auditEntityId: auditLog.entityId ?? "", + auditEntityLabel: auditLog.entityLabel ?? "", + auditSummary: auditLog.summary, + auditMetadata: auditLog.metadata ? JSON.stringify(auditLog.metadata) : "" + }); + } + + const csvLines = [ + CSV_HEADERS.join(","), + ...rows.map((row) => CSV_HEADERS.map((header) => toCsvCell(row[header])).join(",")) + ]; + + const timestamp = new Date().toISOString().slice(0, 10); + const csv = `\uFEFF${csvLines.join("\n")}`; + + return new NextResponse(csv, { + headers: { + "Content-Type": "text/csv; charset=utf-8", + "Content-Disposition": `attachment; filename="rfp-finanzuebersicht-backup-${timestamp}.csv"`, + "Cache-Control": "no-store" + } + }); +} diff --git a/src/app/api/import/csv/route.ts b/src/app/api/import/csv/route.ts new file mode 100644 index 0000000..634a996 --- /dev/null +++ b/src/app/api/import/csv/route.ts @@ -0,0 +1,239 @@ +import { NextResponse } from "next/server"; + +import { createAuditLog } from "@/lib/audit-log"; +import { parseCsv } from "@/lib/backup-csv"; +import { canManageUsers } from "@/lib/domain"; +import prisma from "@/lib/prisma"; +import { getCurrentViewer } from "@/lib/session"; + +function toNullable(value: string | undefined) { + return value && value.length > 0 ? value : null; +} + +function toDate(value: string | undefined) { + if (!value) { + return null; + } + + const parsed = new Date(value); + return Number.isNaN(parsed.getTime()) ? null : parsed; +} + +function toNumber(value: string | undefined) { + if (!value || value.length === 0) { + return null; + } + + const parsed = Number(value); + return Number.isFinite(parsed) ? parsed : null; +} + +export async function POST(request: Request) { + const viewer = await getCurrentViewer(); + + if (!viewer) { + return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); + } + + if (!canManageUsers(viewer.role)) { + return NextResponse.json({ error: "Nur Vorstand oder Finanz-AG duerfen Backups einspielen." }, { status: 403 }); + } + + const formData = await request.formData().catch(() => null); + const uploadedFile = formData?.get("file"); + + if (!(uploadedFile instanceof File)) { + return NextResponse.json({ error: "Bitte eine CSV-Datei auswaehlen." }, { status: 400 }); + } + + const content = await uploadedFile.text(); + const rows = parseCsv(content); + + if (rows.length < 2) { + return NextResponse.json({ error: "Die CSV-Datei enthaelt keine Daten." }, { status: 400 }); + } + + const headers = rows[0]; + const rawEntries = rows + .slice(1) + .filter((row) => row.some((cell) => cell.trim().length > 0)) + .map((row) => { + const entry = Object.fromEntries(headers.map((header, index) => [header, row[index] ?? ""])); + return entry as Record; + }); + + const userRows = rawEntries.filter((entry) => entry.recordType === "user"); + + if (userRows.some((entry) => !entry.passwordHash)) { + return NextResponse.json( + { error: "Dieses Backup stammt aus einem alten Format ohne Passwort-Hashes und kann nicht vollstaendig eingespielt werden." }, + { status: 400 } + ); + } + + const periodRows = rawEntries.filter((entry) => entry.recordType === "period"); + const groupRows = rawEntries.filter((entry) => entry.recordType === "workingGroup"); + const budgetRows = rawEntries.filter((entry) => entry.recordType === "budget"); + const expenseRows = rawEntries.filter((entry) => entry.recordType === "expense"); + const approvalRows = rawEntries.filter((entry) => entry.recordType === "approval"); + const auditRows = rawEntries.filter((entry) => entry.recordType === "auditLog"); + + try { + await prisma.$transaction(async (tx) => { + await tx.approval.deleteMany(); + await tx.expense.deleteMany(); + await tx.budget.deleteMany(); + await tx.auditLog.deleteMany(); + await tx.user.deleteMany(); + await tx.workingGroup.deleteMany(); + await tx.accountingPeriod.deleteMany(); + + for (const row of periodRows) { + const startsAt = toDate(row.periodStartsAt); + const endsAt = toDate(row.periodEndsAt); + + if (!startsAt || !endsAt) { + throw new Error(`Zeitraum ${row.periodName || row.id} enthaelt kein gueltiges Datum.`); + } + + await tx.accountingPeriod.create({ + data: { + id: row.id, + name: row.periodName, + startsAt, + endsAt, + isCurrent: row.periodIsCurrent === "true", + createdAt: toDate(row.createdAt) ?? new Date() + } + }); + } + + for (const row of groupRows) { + await tx.workingGroup.create({ + data: { + id: row.id, + name: row.workingGroupName, + createdAt: toDate(row.createdAt) ?? new Date() + } + }); + } + + for (const row of userRows) { + await tx.user.create({ + data: { + id: row.id, + name: row.userName, + username: row.username, + email: toNullable(row.email), + passwordHash: row.passwordHash, + role: row.role as "ADMIN" | "FINANCE" | "MEMBER", + approvalPreference: toNullable(row.approvalPreference) as "CHAIR_A" | "CHAIR_B" | "FINANCE" | null, + workingGroupId: toNullable(row.workingGroupId), + createdAt: toDate(row.createdAt) ?? new Date() + } + }); + } + + for (const row of budgetRows) { + const totalBudget = toNumber(row.totalBudget); + + if (totalBudget === null) { + throw new Error(`Budget ${row.budgetName || row.id} enthaelt keinen gueltigen Betrag.`); + } + + await tx.budget.create({ + data: { + id: row.id, + name: row.budgetName, + totalBudget, + colorCode: row.colorCode, + workingGroupId: row.workingGroupId, + periodId: row.periodId, + createdAt: toDate(row.createdAt) ?? new Date() + } + }); + } + + for (const row of expenseRows) { + const amount = toNumber(row.amount); + + if (amount === null) { + throw new Error(`Ausgabe ${row.title || row.id} enthaelt keinen gueltigen Betrag.`); + } + + await tx.expense.create({ + data: { + id: row.id, + title: row.title, + description: toNullable(row.description), + amount, + creatorId: row.userId, + agId: row.workingGroupId, + budgetId: row.budgetId, + periodId: row.periodId, + approvalStatus: row.approvalStatus === "APPROVED" ? "APPROVED" : "PENDING", + recurrence: row.recurrence === "MONTHLY" ? "MONTHLY" : "NONE", + proofUrl: toNullable(row.proofUrl), + createdAt: toDate(row.createdAt) ?? new Date(), + paidAt: toDate(row.paidAt), + documentedAt: toDate(row.documentedAt) + } + }); + } + + for (const row of approvalRows) { + const timestamp = toDate(row.createdAt); + + if (!timestamp) { + throw new Error(`Freigabe ${row.id} enthaelt keinen gueltigen Zeitstempel.`); + } + + await tx.approval.create({ + data: { + id: row.id, + expenseId: row.parentId, + userId: row.userId, + approvalType: row.approvalType as "CHAIR_A" | "CHAIR_B" | "FINANCE", + timestamp + } + }); + } + + for (const row of auditRows) { + await tx.auditLog.create({ + data: { + id: row.id, + actorId: toNullable(row.auditActorId), + action: row.auditAction, + entityType: row.auditEntityType, + entityId: toNullable(row.auditEntityId), + entityLabel: toNullable(row.auditEntityLabel), + summary: row.auditSummary, + metadata: row.auditMetadata ? JSON.parse(row.auditMetadata) : null, + createdAt: toDate(row.createdAt) ?? new Date() + } + }); + } + }); + + await createAuditLog(prisma, { + actorId: userRows.some((row) => row.id === viewer.id) ? viewer.id : null, + action: "backup.import", + entityType: "system", + entityLabel: uploadedFile.name, + summary: `CSV-Backup ${uploadedFile.name} wurde eingespielt.`, + metadata: { + fileName: uploadedFile.name, + rowCount: rawEntries.length + } + }); + + return NextResponse.json({ + ok: true, + importedRows: rawEntries.length + }); + } catch (error) { + const message = error instanceof Error ? error.message : "Das Backup konnte nicht eingespielt werden."; + return NextResponse.json({ error: message }, { status: 400 }); + } +} diff --git a/src/app/api/periods/[id]/route.ts b/src/app/api/periods/[id]/route.ts new file mode 100644 index 0000000..00e5eab --- /dev/null +++ b/src/app/api/periods/[id]/route.ts @@ -0,0 +1,73 @@ +import { NextResponse } from "next/server"; + +import { snapshotPeriod } from "@/lib/audit-snapshots"; +import { createAuditLog } from "@/lib/audit-log"; +import { canManageBudgets } from "@/lib/domain"; +import prisma from "@/lib/prisma"; +import { getCurrentViewer } from "@/lib/session"; + +type Context = { + params: { + id: string; + }; +}; + +export async function DELETE(_: Request, { params }: Context) { + const viewer = await getCurrentViewer(); + + if (!viewer) { + return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); + } + + if (!canManageBudgets(viewer.role)) { + return NextResponse.json({ error: "Nur Vorstand oder Finanz-AG duerfen Zeitraeume loeschen." }, { status: 403 }); + } + + const period = await prisma.accountingPeriod.findUnique({ + where: { id: params.id }, + include: { + _count: { + select: { + budgets: true, + expenses: true + } + } + } + }); + + if (!period) { + return NextResponse.json({ error: "Zeitraum nicht gefunden." }, { status: 404 }); + } + + if (period.isCurrent) { + return NextResponse.json({ error: "Der aktuell aktive Zeitraum kann nicht geloescht werden." }, { status: 400 }); + } + + if (period._count.budgets > 0 || period._count.expenses > 0) { + return NextResponse.json( + { error: "Dieser Zeitraum enthaelt noch Budgets oder Ausgaben und kann deshalb nicht geloescht werden." }, + { status: 400 } + ); + } + + await prisma.accountingPeriod.delete({ + where: { id: params.id } + }); + + await createAuditLog(prisma, { + actorId: viewer.id, + action: "period.delete", + entityType: "period", + entityId: period.id, + entityLabel: period.name, + summary: `Zeitraum ${period.name} wurde geloescht.`, + metadata: { + rollback: { + kind: "period.delete", + deleted: snapshotPeriod(period) + } + } + }); + + return NextResponse.json({ ok: true }); +} diff --git a/src/app/api/periods/current/route.ts b/src/app/api/periods/current/route.ts new file mode 100644 index 0000000..6a45248 --- /dev/null +++ b/src/app/api/periods/current/route.ts @@ -0,0 +1,80 @@ +import { NextResponse } from "next/server"; +import { z } from "zod"; + +import { createAuditLog } from "@/lib/audit-log"; +import { canManageBudgets } from "@/lib/domain"; +import prisma from "@/lib/prisma"; +import { getCurrentViewer } from "@/lib/session"; + +const currentPeriodSchema = z.object({ + periodId: z.string().trim().min(1) +}); + +export async function PATCH(request: Request) { + const viewer = await getCurrentViewer(); + + if (!viewer) { + return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); + } + + if (!canManageBudgets(viewer.role)) { + return NextResponse.json({ error: "Nur Vorstand oder Finanz-AG duerfen den aktuellen Zeitraum wechseln." }, { status: 403 }); + } + + const body = await request.json().catch(() => null); + const parsed = currentPeriodSchema.safeParse(body); + + if (!parsed.success) { + return NextResponse.json({ error: "Bitte einen gueltigen Zeitraum auswaehlen." }, { status: 400 }); + } + + const period = await prisma.accountingPeriod.findUnique({ + where: { + id: parsed.data.periodId + } + }); + + if (!period) { + return NextResponse.json({ error: "Zeitraum nicht gefunden." }, { status: 404 }); + } + + const previousCurrentPeriod = await prisma.accountingPeriod.findFirst({ + where: { + isCurrent: true + } + }); + + await prisma.$transaction([ + prisma.accountingPeriod.updateMany({ + data: { + isCurrent: false + } + }), + prisma.accountingPeriod.update({ + where: { + id: period.id + }, + data: { + isCurrent: true + } + }) + ]); + + await createAuditLog(prisma, { + actorId: viewer.id, + action: "period.setCurrent", + entityType: "period", + entityId: period.id, + entityLabel: period.name, + summary: `Aktiver Zeitraum wurde auf ${period.name} gesetzt.`, + metadata: { + rollback: { + kind: "period.setCurrent", + previousCurrentPeriodId: previousCurrentPeriod?.id ?? null, + nextCurrentPeriodId: period.id + } + } + }); + + return NextResponse.json({ ok: true }); +} diff --git a/src/app/api/periods/route.ts b/src/app/api/periods/route.ts new file mode 100644 index 0000000..d26daa1 --- /dev/null +++ b/src/app/api/periods/route.ts @@ -0,0 +1,96 @@ +import { NextResponse } from "next/server"; +import { z } from "zod"; + +import { snapshotPeriod } from "@/lib/audit-snapshots"; +import { createAuditLog } from "@/lib/audit-log"; +import { canManageBudgets } from "@/lib/domain"; +import prisma from "@/lib/prisma"; +import { getCurrentViewer } from "@/lib/session"; + +const periodSchema = z.object({ + name: z.string().trim().min(2).max(80), + startsAt: z.coerce.date(), + endsAt: z.coerce.date(), + copyBudgetsFromPeriodId: z.union([z.string().trim().min(1), z.literal(""), z.null(), z.undefined()]) +}); + +export async function POST(request: Request) { + const viewer = await getCurrentViewer(); + + if (!viewer) { + return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); + } + + if (!canManageBudgets(viewer.role)) { + return NextResponse.json({ error: "Nur Vorstand oder Finanz-AG duerfen Zeitraeume verwalten." }, { status: 403 }); + } + + const body = await request.json().catch(() => null); + const parsed = periodSchema.safeParse(body); + + if (!parsed.success) { + return NextResponse.json({ error: "Bitte Zeitraumname sowie Start- und Enddatum korrekt angeben." }, { status: 400 }); + } + + if (parsed.data.endsAt < parsed.data.startsAt) { + return NextResponse.json({ error: "Das Enddatum muss nach dem Startdatum liegen." }, { status: 400 }); + } + + const copyBudgetsFromPeriodId = + typeof parsed.data.copyBudgetsFromPeriodId === "string" && parsed.data.copyBudgetsFromPeriodId.length > 0 + ? parsed.data.copyBudgetsFromPeriodId + : null; + + const period = await prisma.$transaction(async (tx) => { + const createdPeriod = await tx.accountingPeriod.create({ + data: { + name: parsed.data.name, + startsAt: parsed.data.startsAt, + endsAt: parsed.data.endsAt, + isCurrent: false + } + }); + + if (copyBudgetsFromPeriodId) { + const sourceBudgets = await tx.budget.findMany({ + where: { + periodId: copyBudgetsFromPeriodId + } + }); + + if (sourceBudgets.length > 0) { + await tx.budget.createMany({ + data: sourceBudgets.map((budget) => ({ + name: budget.name, + totalBudget: budget.totalBudget, + colorCode: budget.colorCode, + workingGroupId: budget.workingGroupId, + periodId: createdPeriod.id + })) + }); + } + } + + return createdPeriod; + }); + + await createAuditLog(prisma, { + actorId: viewer.id, + action: "period.create", + entityType: "period", + entityId: period.id, + entityLabel: period.name, + summary: `Zeitraum ${period.name} wurde angelegt.`, + metadata: { + startsAt: period.startsAt.toISOString(), + endsAt: period.endsAt.toISOString(), + copiedFromPeriodId: copyBudgetsFromPeriodId, + rollback: { + kind: "period.create", + created: snapshotPeriod(period) + } + } + }); + + return NextResponse.json({ period }); +} diff --git a/src/app/api/users/[id]/password/route.ts b/src/app/api/users/[id]/password/route.ts new file mode 100644 index 0000000..fad5beb --- /dev/null +++ b/src/app/api/users/[id]/password/route.ts @@ -0,0 +1,74 @@ +import bcrypt from "bcryptjs"; +import { NextResponse } from "next/server"; +import { z } from "zod"; + +import { createAuditLog } from "@/lib/audit-log"; +import { canManageUsers } from "@/lib/domain"; +import prisma from "@/lib/prisma"; +import { getCurrentViewer } from "@/lib/session"; + +const passwordSchema = z.object({ + password: z.string().min(8).max(128) +}); + +type Context = { + params: { + id: string; + }; +}; + +export async function POST(request: Request, { params }: Context) { + const viewer = await getCurrentViewer(); + + if (!viewer) { + return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); + } + + if (!canManageUsers(viewer.role)) { + return NextResponse.json({ error: "Nur Vorstand oder Finanz-AG duerfen Passwoerter neu setzen." }, { status: 403 }); + } + + const body = await request.json().catch(() => null); + const parsed = passwordSchema.safeParse(body); + + if (!parsed.success) { + return NextResponse.json({ error: "Bitte ein Passwort mit mindestens 8 Zeichen angeben." }, { status: 400 }); + } + + const user = await prisma.user.findUnique({ + where: { id: params.id }, + select: { id: true, username: true, passwordHash: true } + }); + + if (!user) { + return NextResponse.json({ error: "Nutzer nicht gefunden." }, { status: 404 }); + } + + const passwordHash = await bcrypt.hash(parsed.data.password, 12); + + await prisma.user.update({ + where: { id: params.id }, + data: { + passwordHash + } + }); + + await createAuditLog(prisma, { + actorId: viewer.id, + action: "user.passwordReset", + entityType: "user", + entityId: user.id, + entityLabel: user.username, + summary: "Ein Nutzerpasswort wurde neu gesetzt.", + metadata: { + rollback: { + kind: "user.passwordReset", + userId: user.id, + previousPasswordHash: user.passwordHash, + nextPasswordHash: passwordHash + } + } + }); + + return NextResponse.json({ ok: true }); +} diff --git a/src/app/api/users/[id]/route.ts b/src/app/api/users/[id]/route.ts new file mode 100644 index 0000000..2b35d95 --- /dev/null +++ b/src/app/api/users/[id]/route.ts @@ -0,0 +1,83 @@ +import { NextResponse } from "next/server"; + +import { snapshotUser } from "@/lib/audit-snapshots"; +import { createAuditLog } from "@/lib/audit-log"; +import { canManageUsers } from "@/lib/domain"; +import prisma from "@/lib/prisma"; +import { getCurrentViewer } from "@/lib/session"; + +type Context = { + params: { + id: string; + }; +}; + +export async function DELETE(_: Request, { params }: Context) { + const viewer = await getCurrentViewer(); + + if (!viewer) { + return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); + } + + if (!canManageUsers(viewer.role)) { + return NextResponse.json({ error: "Nur Vorstand oder Finanz-AG duerfen Nutzer loeschen." }, { status: 403 }); + } + + if (viewer.id === params.id) { + return NextResponse.json({ error: "Du kannst dein eigenes Konto hier nicht loeschen." }, { status: 400 }); + } + + const user = await prisma.user.findUnique({ + where: { id: params.id }, + include: { + _count: { + select: { + approvals: true, + createdExpenses: true + } + } + } + }); + + if (!user) { + return NextResponse.json({ error: "Nutzer nicht gefunden." }, { status: 404 }); + } + + if (user._count.approvals > 0 || user._count.createdExpenses > 0) { + return NextResponse.json( + { error: "Nutzer mit Freigaben oder Ausgaben koennen nicht geloescht werden." }, + { status: 400 } + ); + } + + if (user.role === "ADMIN") { + const adminCount = await prisma.user.count({ + where: { role: "ADMIN" } + }); + + if (adminCount <= 1) { + return NextResponse.json({ error: "Mindestens ein Admin muss erhalten bleiben." }, { status: 400 }); + } + } + + await prisma.user.delete({ + where: { id: params.id } + }); + + await createAuditLog(prisma, { + actorId: viewer.id, + action: "user.delete", + entityType: "user", + entityId: user.id, + entityLabel: user.username, + summary: `Nutzer ${user.username} wurde geloescht.`, + metadata: { + rollback: { + kind: "user.delete", + deleted: snapshotUser(user) + } + } + }); + + return NextResponse.json({ ok: true }); +} diff --git a/src/app/api/users/route.ts b/src/app/api/users/route.ts new file mode 100644 index 0000000..90a48ef --- /dev/null +++ b/src/app/api/users/route.ts @@ -0,0 +1,118 @@ +import bcrypt from "bcryptjs"; +import { NextResponse } from "next/server"; +import { z } from "zod"; + +import { snapshotUser } from "@/lib/audit-snapshots"; +import { createAuditLog } from "@/lib/audit-log"; +import { canManageUsers } from "@/lib/domain"; +import prisma from "@/lib/prisma"; +import { getCurrentViewer } from "@/lib/session"; + +const userRoleSchema = z.enum(["ADMIN", "FINANCE", "MEMBER"]); +const approvalPreferenceSchema = z.enum(["CHAIR_A", "CHAIR_B", "FINANCE"]); + +const createUserSchema = z.object({ + username: z.string().trim().min(2).max(40), + password: z.string().min(8).max(128), + role: userRoleSchema, + workingGroupId: z.union([z.string().trim().min(1), z.literal(""), z.null(), z.undefined()]), + approvalPreference: z.union([approvalPreferenceSchema, z.literal(""), z.null(), z.undefined()]) +}); + +export async function POST(request: Request) { + const viewer = await getCurrentViewer(); + + if (!viewer) { + return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); + } + + if (!canManageUsers(viewer.role)) { + return NextResponse.json({ error: "Nur Vorstand oder Finanz-AG duerfen Nutzer anlegen." }, { status: 403 }); + } + + const body = await request.json().catch(() => null); + const parsed = createUserSchema.safeParse(body); + + if (!parsed.success) { + return NextResponse.json({ error: "Bitte Login-Name, Passwort und Rolle korrekt angeben." }, { status: 400 }); + } + + const username = parsed.data.username.toLowerCase(); + const workingGroupId = typeof parsed.data.workingGroupId === "string" && parsed.data.workingGroupId.length > 0 + ? parsed.data.workingGroupId + : null; + const requestedApprovalPreference = + parsed.data.approvalPreference === "CHAIR_A" || + parsed.data.approvalPreference === "CHAIR_B" || + parsed.data.approvalPreference === "FINANCE" + ? parsed.data.approvalPreference + : null; + + if (parsed.data.role === "MEMBER" && !workingGroupId) { + return NextResponse.json({ error: "AG-Mitglieder brauchen eine AG-Zuordnung." }, { status: 400 }); + } + + if (workingGroupId) { + const workingGroup = await prisma.workingGroup.findUnique({ + where: { id: workingGroupId } + }); + + if (!workingGroup) { + return NextResponse.json({ error: "Die ausgewaehlte AG wurde nicht gefunden." }, { status: 404 }); + } + } + + const existingUserByUsername = await prisma.user.findUnique({ + where: { username } + }); + + if (existingUserByUsername) { + return NextResponse.json({ error: "Dieser Login-Name ist bereits vergeben." }, { status: 409 }); + } + + const passwordHash = await bcrypt.hash(parsed.data.password, 12); + const approvalPreference = + parsed.data.role === "FINANCE" + ? "FINANCE" + : parsed.data.role === "ADMIN" + ? requestedApprovalPreference + : null; + + const user = await prisma.user.create({ + data: { + name: username, + username, + email: null, + passwordHash, + role: parsed.data.role, + workingGroupId: parsed.data.role === "MEMBER" ? workingGroupId : null, + approvalPreference + } + }); + + await createAuditLog(prisma, { + actorId: viewer.id, + action: "user.create", + entityType: "user", + entityId: user.id, + entityLabel: user.username, + summary: `Nutzer ${user.username} wurde angelegt.`, + metadata: { + role: user.role, + workingGroupId: user.workingGroupId, + rollback: { + kind: "user.create", + created: snapshotUser(user) + } + } + }); + + return NextResponse.json({ + user: { + id: user.id, + name: user.name, + username: user.username, + role: user.role + } + }); +} diff --git a/src/app/api/working-groups/[id]/route.ts b/src/app/api/working-groups/[id]/route.ts new file mode 100644 index 0000000..84d2ad9 --- /dev/null +++ b/src/app/api/working-groups/[id]/route.ts @@ -0,0 +1,148 @@ +import { NextResponse } from "next/server"; +import { z } from "zod"; + +import { snapshotWorkingGroup } from "@/lib/audit-snapshots"; +import { createAuditLog } from "@/lib/audit-log"; +import { canManageBudgets } from "@/lib/domain"; +import prisma from "@/lib/prisma"; +import { getCurrentViewer } from "@/lib/session"; + +type Context = { + params: { + id: string; + }; +}; + +const workingGroupSchema = z.object({ + name: z.string().trim().min(2).max(80) +}); + +export async function PATCH(request: Request, { params }: Context) { + const viewer = await getCurrentViewer(); + + if (!viewer) { + return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); + } + + if (!canManageBudgets(viewer.role)) { + return NextResponse.json({ error: "Nur Vorstand oder Finanz-AG duerfen AGs bearbeiten." }, { status: 403 }); + } + + const body = await request.json().catch(() => null); + const parsed = workingGroupSchema.safeParse(body); + + if (!parsed.success) { + return NextResponse.json({ error: "Bitte einen gueltigen AG-Namen angeben." }, { status: 400 }); + } + + const workingGroup = await prisma.workingGroup.findUnique({ + where: { id: params.id } + }); + + if (!workingGroup) { + return NextResponse.json({ error: "AG nicht gefunden." }, { status: 404 }); + } + + const existingWorkingGroup = await prisma.workingGroup.findFirst({ + where: { + id: { + not: params.id + }, + name: { + equals: parsed.data.name, + mode: "insensitive" + } + } + }); + + if (existingWorkingGroup) { + return NextResponse.json({ error: "Diese AG gibt es bereits." }, { status: 409 }); + } + + const updatedWorkingGroup = await prisma.workingGroup.update({ + where: { + id: params.id + }, + data: { + name: parsed.data.name + } + }); + + await createAuditLog(prisma, { + actorId: viewer.id, + action: "workingGroup.update", + entityType: "workingGroup", + entityId: updatedWorkingGroup.id, + entityLabel: updatedWorkingGroup.name, + summary: `AG ${workingGroup.name} wurde auf ${updatedWorkingGroup.name} umbenannt.`, + metadata: { + rollback: { + kind: "workingGroup.update", + previous: snapshotWorkingGroup(workingGroup), + next: snapshotWorkingGroup(updatedWorkingGroup) + } + } + }); + + return NextResponse.json({ workingGroup: updatedWorkingGroup }); +} + +export async function DELETE(_: Request, { params }: Context) { + const viewer = await getCurrentViewer(); + + if (!viewer) { + return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); + } + + if (!canManageBudgets(viewer.role)) { + return NextResponse.json({ error: "Nur Vorstand oder Finanz-AG duerfen AGs loeschen." }, { status: 403 }); + } + + const workingGroup = await prisma.workingGroup.findUnique({ + where: { id: params.id }, + include: { + _count: { + select: { + members: true, + budgets: true, + expenses: true + } + } + } + }); + + if (!workingGroup) { + return NextResponse.json({ error: "AG nicht gefunden." }, { status: 404 }); + } + + if (workingGroup._count.members > 0 || workingGroup._count.budgets > 0 || workingGroup._count.expenses > 0) { + return NextResponse.json( + { + error: + "Diese AG wird noch verwendet. Bitte zuerst Mitglieder, Budgets und eventuelle Ausgaben entfernen." + }, + { status: 400 } + ); + } + + await prisma.workingGroup.delete({ + where: { id: params.id } + }); + + await createAuditLog(prisma, { + actorId: viewer.id, + action: "workingGroup.delete", + entityType: "workingGroup", + entityId: workingGroup.id, + entityLabel: workingGroup.name, + summary: `AG ${workingGroup.name} wurde geloescht.`, + metadata: { + rollback: { + kind: "workingGroup.delete", + deleted: snapshotWorkingGroup(workingGroup) + } + } + }); + + return NextResponse.json({ ok: true }); +} diff --git a/src/app/api/working-groups/route.ts b/src/app/api/working-groups/route.ts new file mode 100644 index 0000000..4242837 --- /dev/null +++ b/src/app/api/working-groups/route.ts @@ -0,0 +1,67 @@ +import { NextResponse } from "next/server"; +import { z } from "zod"; + +import { snapshotWorkingGroup } from "@/lib/audit-snapshots"; +import { createAuditLog } from "@/lib/audit-log"; +import { canManageBudgets } from "@/lib/domain"; +import prisma from "@/lib/prisma"; +import { getCurrentViewer } from "@/lib/session"; + +const workingGroupSchema = z.object({ + name: z.string().trim().min(2).max(80) +}); + +export async function POST(request: Request) { + const viewer = await getCurrentViewer(); + + if (!viewer) { + return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); + } + + if (!canManageBudgets(viewer.role)) { + return NextResponse.json({ error: "Nur Vorstand oder Finanz-AG duerfen AGs verwalten." }, { status: 403 }); + } + + const body = await request.json().catch(() => null); + const parsed = workingGroupSchema.safeParse(body); + + if (!parsed.success) { + return NextResponse.json({ error: "Bitte einen gueltigen AG-Namen angeben." }, { status: 400 }); + } + + const existingWorkingGroup = await prisma.workingGroup.findFirst({ + where: { + name: { + equals: parsed.data.name, + mode: "insensitive" + } + } + }); + + if (existingWorkingGroup) { + return NextResponse.json({ error: "Diese AG gibt es bereits." }, { status: 409 }); + } + + const workingGroup = await prisma.workingGroup.create({ + data: { + name: parsed.data.name + } + }); + + await createAuditLog(prisma, { + actorId: viewer.id, + action: "workingGroup.create", + entityType: "workingGroup", + entityId: workingGroup.id, + entityLabel: workingGroup.name, + summary: `AG ${workingGroup.name} wurde angelegt.`, + metadata: { + rollback: { + kind: "workingGroup.create", + created: snapshotWorkingGroup(workingGroup) + } + } + }); + + return NextResponse.json({ workingGroup }); +} diff --git a/src/app/globals.css b/src/app/globals.css new file mode 100644 index 0000000..ad7bd54 --- /dev/null +++ b/src/app/globals.css @@ -0,0 +1,44 @@ +:root { + color-scheme: light dark; +} + +html, +body { + margin: 0; + min-height: 100%; +} + +html { + background: #f5f1e8; +} + +body { + background: + radial-gradient(circle at top left, rgba(242, 139, 75, 0.22), transparent 34%), + radial-gradient(circle at right 20%, rgba(59, 90, 224, 0.2), transparent 28%), + linear-gradient(180deg, #faf6ef 0%, #f3eee4 100%); + color: #17203a; +} + +@media (prefers-color-scheme: dark) { + html { + background: #0b1020; + } + + body { + background: + radial-gradient(circle at top left, rgba(255, 179, 107, 0.16), transparent 30%), + radial-gradient(circle at right 18%, rgba(140, 164, 255, 0.2), transparent 26%), + linear-gradient(180deg, #0b1020 0%, #111a2b 100%); + color: #e9eef9; + } +} + +a { + color: inherit; + text-decoration: none; +} + +* { + box-sizing: border-box; +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx new file mode 100644 index 0000000..9ae1b41 --- /dev/null +++ b/src/app/layout.tsx @@ -0,0 +1,50 @@ +import type { Metadata } from "next"; +import { Space_Grotesk, Source_Sans_3 } from "next/font/google"; +import type { ReactNode } from "react"; + +import { AppProviders } from "@/components/providers/app-providers"; +import { ServiceWorkerRegistration } from "@/components/service-worker-registration"; + +import "./globals.css"; + +const displayFont = Space_Grotesk({ + subsets: ["latin"], + variable: "--font-display" +}); + +const bodyFont = Source_Sans_3({ + subsets: ["latin"], + variable: "--font-body" +}); + +export const metadata: Metadata = { + title: "RFP Finanz\u00fcbersicht", + description: "Budgetkontrolle und Freigaben f\u00fcr Rave for Peace.", + applicationName: "RFP Finanz\u00fcbersicht", + icons: { + icon: [ + { url: "/favicon.ico", sizes: "any" }, + { url: "/icon-192.png", type: "image/png", sizes: "192x192" }, + { url: "/icon-512.png", type: "image/png", sizes: "512x512" } + ], + apple: [{ url: "/apple-touch-icon.png", sizes: "180x180", type: "image/png" }], + shortcut: ["/favicon.ico"] + } +}; + +type RootLayoutProps = { + children: ReactNode; +}; + +export default function RootLayout({ children }: RootLayoutProps) { + return ( + + + + + {children} + + + + ); +} diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx new file mode 100644 index 0000000..28df0b5 --- /dev/null +++ b/src/app/login/page.tsx @@ -0,0 +1,34 @@ +import { Box, Container, Stack, Typography } from "@mui/material"; +import { getServerSession } from "next-auth"; +import { redirect } from "next/navigation"; + +import { LoginForm } from "@/components/login-form"; +import { authOptions } from "@/lib/auth"; + +export const dynamic = "force-dynamic"; + +export default async function LoginPage() { + const session = await getServerSession(authOptions); + + if (session?.user?.id) { + redirect("/"); + } + + return ( + + + + + + {"RFP Finanz\u00fcbersicht"} + + + {"Material-3-orientierter MVP f\u00fcr Budget\u00fcbersicht, Freigaben und Dokumentation im Verein."} + + + + + + + ); +} diff --git a/src/app/manifest.ts b/src/app/manifest.ts new file mode 100644 index 0000000..61720fd --- /dev/null +++ b/src/app/manifest.ts @@ -0,0 +1,32 @@ +import type { MetadataRoute } from "next"; + +export default function manifest(): MetadataRoute.Manifest { + return { + name: "RFP Finanz\u00fcbersicht", + short_name: "RFP Finanzen", + description: "Budgetfreigaben und Finanzstatus f\u00fcr Vereins-AGs.", + start_url: "/", + display: "standalone", + background_color: "#F5F1E8", + theme_color: "#3B5AE0", + icons: [ + { + src: "/icon-192.png", + sizes: "192x192", + type: "image/png", + purpose: "maskable" + }, + { + src: "/icon-512.png", + sizes: "512x512", + type: "image/png", + purpose: "maskable" + }, + { + src: "/apple-touch-icon.png", + sizes: "180x180", + type: "image/png" + } + ] + }; +} diff --git a/src/app/page.tsx b/src/app/page.tsx new file mode 100644 index 0000000..cff0e4c --- /dev/null +++ b/src/app/page.tsx @@ -0,0 +1,239 @@ +import { redirect } from "next/navigation"; + +import { DashboardShell } from "@/components/dashboard/dashboard-shell"; +import { getCurrentAccountingPeriod } from "@/lib/accounting-periods"; +import { getRollbackMetadata } from "@/lib/audit-log"; +import type { + DashboardAccountingPeriod, + DashboardAuditLog, + DashboardManagedUser, + DashboardViewer, + DashboardWorkingGroup +} from "@/lib/dashboard-types"; +import { canManageUsers } from "@/lib/domain"; +import prisma from "@/lib/prisma"; +import { getCurrentViewer } from "@/lib/session"; + +export const dynamic = "force-dynamic"; + +export default async function DashboardPage() { + const viewer = await getCurrentViewer(); + + if (!viewer) { + redirect("/login"); + } + + const currentPeriod = await getCurrentAccountingPeriod(); + + if (!currentPeriod) { + throw new Error("Kein Abrechnungszeitraum gefunden."); + } + + const accountingPeriods = await prisma.accountingPeriod.findMany({ + orderBy: { + startsAt: "desc" + } + }); + + const workingGroups = await prisma.workingGroup.findMany({ + include: { + members: { + select: { + id: true, + name: true, + username: true, + role: true + } + }, + budgets: { + where: { + periodId: currentPeriod.id + }, + orderBy: { + name: "asc" + }, + include: { + expenses: { + orderBy: { + createdAt: "desc" + }, + include: { + creator: { + select: { + id: true, + username: true + } + }, + approvals: { + orderBy: { + timestamp: "asc" + }, + include: { + user: { + select: { + id: true, + username: true + } + } + } + } + } + } + } + } + }, + orderBy: { + name: "asc" + } + }); + + const managedUsers = canManageUsers(viewer.role) + ? await prisma.user.findMany({ + include: { + workingGroup: { + select: { + name: true + } + }, + _count: { + select: { + approvals: true, + createdExpenses: true + } + } + }, + orderBy: [ + { + role: "asc" + }, + { + username: "asc" + } + ] + }) + : []; + + const auditLogs = canManageUsers(viewer.role) + ? await prisma.auditLog.findMany({ + orderBy: { + createdAt: "desc" + }, + take: 120, + include: { + actor: { + select: { + id: true, + name: true, + username: true, + role: true + } + } + } + }) + : []; + + const serializedViewer: DashboardViewer = { + id: viewer.id, + name: viewer.username, + username: viewer.username, + role: viewer.role, + workingGroupId: viewer.workingGroupId, + approvalPreference: viewer.approvalPreference + }; + + const serializedGroups: DashboardWorkingGroup[] = workingGroups.map((workingGroup) => ({ + id: workingGroup.id, + name: workingGroup.name, + totalBudget: workingGroup.budgets.reduce((sum, budget) => sum + Number(budget.totalBudget), 0), + members: workingGroup.members.map((member) => ({ + id: member.id, + name: member.username, + username: member.username, + role: member.role + })), + budgets: workingGroup.budgets.map((budget) => ({ + id: budget.id, + name: budget.name, + totalBudget: Number(budget.totalBudget), + colorCode: budget.colorCode, + periodId: budget.periodId, + expenses: budget.expenses.map((expense) => ({ + id: expense.id, + title: expense.title, + description: expense.description, + amount: Number(expense.amount), + budgetId: expense.budgetId, + periodId: expense.periodId, + approvalStatus: expense.approvalStatus, + recurrence: expense.recurrence, + paidAt: expense.paidAt?.toISOString() ?? null, + documentedAt: expense.documentedAt?.toISOString() ?? null, + proofUrl: expense.proofUrl, + createdAt: expense.createdAt.toISOString(), + creator: { + id: expense.creator.id, + name: expense.creator.username + }, + approvals: expense.approvals.map((approval) => ({ + id: approval.id, + approvalType: approval.approvalType, + timestamp: approval.timestamp.toISOString(), + user: { + id: approval.user.id, + name: approval.user.username + } + })) + })) + })) + })); + + const serializedUsers: DashboardManagedUser[] = managedUsers.map((user) => ({ + id: user.id, + name: user.username, + username: user.username, + role: user.role, + workingGroupId: user.workingGroupId, + workingGroupName: user.workingGroup?.name ?? null, + approvalPreference: user.approvalPreference, + createdExpensesCount: user._count.createdExpenses, + approvalsCount: user._count.approvals + })); + + const serializedPeriods: DashboardAccountingPeriod[] = accountingPeriods.map((period) => ({ + id: period.id, + name: period.name, + startsAt: period.startsAt.toISOString(), + endsAt: period.endsAt.toISOString(), + isCurrent: period.isCurrent + })); + + const serializedAuditLogs: DashboardAuditLog[] = auditLogs.map((entry) => ({ + id: entry.id, + action: entry.action, + entityType: entry.entityType, + entityId: entry.entityId, + entityLabel: entry.entityLabel, + summary: entry.summary, + canRestore: Boolean(getRollbackMetadata(entry.metadata)), + createdAt: entry.createdAt.toISOString(), + actor: entry.actor + ? { + id: entry.actor.id, + name: entry.actor.username, + username: entry.actor.username, + role: entry.actor.role + } + : null + })); + + return ( + + ); +} diff --git a/src/components/dashboard/budget-column.tsx b/src/components/dashboard/budget-column.tsx new file mode 100644 index 0000000..a90dcdc --- /dev/null +++ b/src/components/dashboard/budget-column.tsx @@ -0,0 +1,743 @@ +"use client"; + +import CheckCircleRoundedIcon from "@mui/icons-material/CheckCircleRounded"; +import CloseRoundedIcon from "@mui/icons-material/CloseRounded"; +import DeleteOutlineRoundedIcon from "@mui/icons-material/DeleteOutlineRounded"; +import DoneAllRoundedIcon from "@mui/icons-material/DoneAllRounded"; +import EditRoundedIcon from "@mui/icons-material/EditRounded"; +import EuroRoundedIcon from "@mui/icons-material/EuroRounded"; +import ReceiptLongRoundedIcon from "@mui/icons-material/ReceiptLongRounded"; +import TaskAltRoundedIcon from "@mui/icons-material/TaskAltRounded"; +import { + Box, + Button, + Card, + CardContent, + Chip, + Divider, + IconButton, + Link, + Stack, + TextField, + Typography +} from "@mui/material"; +import { alpha, useTheme } from "@mui/material/styles"; +import { useEffect, useMemo, useState } from "react"; + +import { ColorPickerField } from "@/components/dashboard/color-picker-field"; +import type { DashboardBudget, DashboardExpense, DashboardViewer, DashboardWorkingGroup } from "@/lib/dashboard-types"; +import { + APPROVAL_FLOW, + approvalLabel, + canDeleteExpense, + canDocumentExpense, + canManageBudgets, + canMarkPaid, + getAvailableApprovalTypes, + recurrenceLabel, + requiresManualApproval +} from "@/lib/domain"; + +type BudgetColumnProps = { + group: DashboardWorkingGroup; + viewer: DashboardViewer; + busy: boolean; + onApprove: (expenseId: string, approvalType: "CHAIR_A" | "CHAIR_B" | "FINANCE") => Promise; + onMarkPaid: (expenseId: string) => Promise; + onDocument: (expenseId: string, proofUrl?: string) => Promise; + onSaveWorkingGroup: (groupId: string, name: string) => Promise; + onDeleteWorkingGroup: (groupId: string, groupName: string) => Promise; + onSaveBudget: (budgetId: string, name: string, totalBudget: string, colorCode: string) => Promise; + onDeleteBudget: (budgetId: string) => Promise; + onDeleteExpense: (expenseId: string) => Promise; +}; + +type BudgetDraft = { + name: string; + totalBudget: string; + colorCode: string; +}; + +const currencyFormatter = new Intl.NumberFormat("de-DE", { + style: "currency", + currency: "EUR" +}); + +const wrappingChipSx = { + height: "auto", + "& .MuiChip-label": { + display: "block", + whiteSpace: "normal", + py: 0.5 + } +} as const; + +function formatCurrency(value: number) { + return currencyFormatter.format(value); +} + +function createDraft(budget: DashboardBudget): BudgetDraft { + return { + name: budget.name, + totalBudget: budget.totalBudget.toFixed(2), + colorCode: budget.colorCode + }; +} + +function StatusChips({ expense }: { expense: DashboardExpense }) { + return ( + + + {expense.paidAt ? ( + } sx={wrappingChipSx} /> + ) : null} + {expense.documentedAt ? ( + } sx={wrappingChipSx} /> + ) : null} + {expense.recurrence === "MONTHLY" ? ( + + ) : null} + + ); +} + +function getApprovedSpend(expenses: DashboardExpense[]) { + return expenses.reduce((sum, expense) => sum + (expense.approvalStatus === "APPROVED" ? expense.amount : 0), 0); +} + +function getPendingSpend(expenses: DashboardExpense[]) { + return expenses.reduce((sum, expense) => sum + (expense.approvalStatus === "PENDING" ? expense.amount : 0), 0); +} + +export function BudgetColumn({ + group, + viewer, + busy, + onApprove, + onMarkPaid, + onDocument, + onSaveWorkingGroup, + onDeleteWorkingGroup, + onSaveBudget, + onDeleteBudget, + onDeleteExpense +}: BudgetColumnProps) { + const theme = useTheme(); + const isDark = theme.palette.mode === "dark"; + const [budgetDrafts, setBudgetDrafts] = useState>({}); + const [editingBudgetId, setEditingBudgetId] = useState(null); + const [isEditingGroup, setIsEditingGroup] = useState(false); + const [groupDraftName, setGroupDraftName] = useState(group.name); + const [proofUrlDrafts, setProofUrlDrafts] = useState>({}); + + const budgetCardWidth = 352; + const groupCardWidth = Math.min( + Math.max(group.budgets.length * budgetCardWidth + Math.max(group.budgets.length - 1, 0) * 16 + 48, 440), + 1160 + ); + const canEditBudgets = canManageBudgets(viewer.role); + + useEffect(() => { + setBudgetDrafts( + Object.fromEntries(group.budgets.map((budget) => [budget.id, createDraft(budget)])) + ); + }, [group.budgets]); + + useEffect(() => { + if (editingBudgetId && !group.budgets.some((budget) => budget.id === editingBudgetId)) { + setEditingBudgetId(null); + } + }, [editingBudgetId, group.budgets]); + + useEffect(() => { + setGroupDraftName(group.name); + }, [group.name]); + + const approvedSpend = useMemo( + () => group.budgets.reduce((sum, budget) => sum + getApprovedSpend(budget.expenses), 0), + [group.budgets] + ); + const pendingSpend = useMemo( + () => group.budgets.reduce((sum, budget) => sum + getPendingSpend(budget.expenses), 0), + [group.budgets] + ); + const totalCommitted = approvedSpend + pendingSpend; + const remainingBudget = group.totalBudget - totalCommitted; + + function getDraft(budget: DashboardBudget) { + return budgetDrafts[budget.id] ?? createDraft(budget); + } + + function updateDraft(budget: DashboardBudget, patch: Partial) { + setBudgetDrafts((current) => ({ + ...current, + [budget.id]: { + ...getDraft(budget), + ...patch + } + })); + } + + function resetDraft(budget: DashboardBudget) { + setBudgetDrafts((current) => ({ + ...current, + [budget.id]: createDraft(budget) + })); + } + + return ( + + + + + + + {group.name} + + + Gesamtbudgets: {formatCurrency(group.totalBudget)} + + + + {totalCommitted > group.totalBudget ? : null} + {canEditBudgets ? ( + { + if (isEditingGroup) { + setGroupDraftName(group.name); + setIsEditingGroup(false); + return; + } + + setIsEditingGroup(true); + }} + sx={{ + border: `1px solid ${alpha(theme.palette.text.primary, 0.12)}`, + bgcolor: alpha(theme.palette.background.default, isDark ? 0.72 : 0.65) + }} + > + {isEditingGroup ? : } + + ) : null} + + + + {isEditingGroup ? ( + { + event.preventDefault(); + await onSaveWorkingGroup(group.id, groupDraftName); + setIsEditingGroup(false); + }} + sx={{ + p: 2, + borderRadius: "18px", + border: `1px solid ${alpha(theme.palette.text.primary, isDark ? 0.12 : 0.08)}`, + background: `linear-gradient(180deg, ${alpha(theme.palette.background.paper, isDark ? 0.86 : 0.94)} 0%, ${alpha(theme.palette.text.primary, isDark ? 0.05 : 0.02)} 100%)` + }} + > + + setGroupDraftName(event.target.value)} + fullWidth + /> + + AGs lassen sich nur loeschen, wenn keine Mitglieder, Budgets oder Ausgaben mehr daran haengen. + + + + + + + + + ) : null} + + + } + label={`Freigegeben: ${formatCurrency(approvedSpend)}`} + sx={{ ...wrappingChipSx, width: "fit-content" }} + /> + } + label={`Geplant: ${formatCurrency(pendingSpend)}`} + variant="outlined" + sx={{ ...wrappingChipSx, width: "fit-content" }} + /> + } + label={`Rest: ${formatCurrency(remainingBudget)}`} + color={remainingBudget < 0 ? "error" : "default"} + sx={{ ...wrappingChipSx, width: "fit-content" }} + /> + + + {group.budgets.length === 0 ? ( + + In dieser AG gibt es noch keine Budgets. + + ) : null} + + + {group.budgets.map((budget) => { + const draft = getDraft(budget); + const isEditing = editingBudgetId === budget.id; + const budgetApproved = getApprovedSpend(budget.expenses); + const budgetPending = getPendingSpend(budget.expenses); + const budgetCommitted = budgetApproved + budgetPending; + const budgetRemaining = budget.totalBudget - budgetCommitted; + const approvedPercent = budget.totalBudget > 0 ? Math.min((budgetApproved / budget.totalBudget) * 100, 100) : 0; + const cumulativePercent = + budget.totalBudget > 0 ? Math.min((budgetCommitted / budget.totalBudget) * 100, 100) : 0; + + return ( + + + + + + + + + {budget.name} + + + Budget: {formatCurrency(budget.totalBudget)} + + {canEditBudgets ? ( + { + if (isEditing) { + resetDraft(budget); + setEditingBudgetId(null); + return; + } + + setEditingBudgetId(budget.id); + }} + sx={{ + border: `1px solid ${alpha(theme.palette.text.primary, 0.12)}`, + bgcolor: alpha(theme.palette.background.default, isDark ? 0.72 : 0.65) + }} + > + {isEditing ? : } + + ) : null} + + + + + + + + + + + + } + label={`Freigegeben: ${formatCurrency(budgetApproved)}`} + sx={{ ...wrappingChipSx, width: "fit-content", bgcolor: alpha(budget.colorCode, 0.14) }} + /> + } + label={`Geplant: ${formatCurrency(budgetPending)}`} + variant="outlined" + sx={{ ...wrappingChipSx, width: "fit-content" }} + /> + } + label={`Rest: ${formatCurrency(budgetRemaining)}`} + color={budgetRemaining < 0 ? "error" : "default"} + sx={{ ...wrappingChipSx, width: "fit-content" }} + /> + + {"Unter 50 EUR werden sofort freigegeben. Gr\u00f6\u00dfere Ausgaben bleiben blass, bis alle drei Signaturen vorliegen."} + + + + + {isEditing ? ( + { + event.preventDefault(); + await onSaveBudget(budget.id, draft.name, draft.totalBudget, draft.colorCode); + setEditingBudgetId(null); + }} + > + + updateDraft(budget, { name: event.target.value })} + fullWidth + /> + updateDraft(budget, { totalBudget: event.target.value })} + fullWidth + /> + updateDraft(budget, { colorCode: value })} + /> + + + + + + + + ) : null} + + + + + {budget.expenses.length === 0 ? ( + + + Noch keine Ausgaben in diesem Budget. + + + ) : null} + + {budget.expenses.map((expense) => { + const doneApprovalTypes = expense.approvals.map((approval) => approval.approvalType); + const availableApprovals = requiresManualApproval(expense.amount) + ? getAvailableApprovalTypes(viewer.role, viewer.approvalPreference, doneApprovalTypes) + : []; + + return ( + + + + + + {expense.title} + + + {formatCurrency(expense.amount)} von {expense.creator.name} + + + + + + {expense.description ? ( + + {expense.description} + + ) : null} + + {requiresManualApproval(expense.amount) ? ( + + {APPROVAL_FLOW.map((approvalType) => { + const matchingApproval = expense.approvals.find( + (approval) => approval.approvalType === approvalType + ); + + return ( + + ); + })} + + ) : null} + + {expense.proofUrl ? ( + + {"Beleg \u00f6ffnen"} + + ) : null} + + + {availableApprovals.map((approvalType) => ( + + ))} + + {!expense.paidAt && expense.approvalStatus === "APPROVED" && canMarkPaid(viewer.role) ? ( + + ) : null} + + {canDeleteExpense( + viewer.role, + viewer.id, + expense.creator.id, + expense.approvalStatus, + expense.paidAt, + expense.documentedAt + ) ? ( + + ) : null} + + + {expense.paidAt && !expense.documentedAt && canDocumentExpense(viewer.role) ? ( + + + setProofUrlDrafts((current) => ({ + ...current, + [expense.id]: event.target.value + })) + } + size="small" + fullWidth + /> + + + ) : null} + + + Angelegt am{" "} + {new Intl.DateTimeFormat("de-DE", { dateStyle: "medium", timeStyle: "short" }).format( + new Date(expense.createdAt) + )} + + + + ); + })} + + + + + ); + })} + + + + + ); +} diff --git a/src/components/dashboard/color-picker-field.tsx b/src/components/dashboard/color-picker-field.tsx new file mode 100644 index 0000000..55d83b5 --- /dev/null +++ b/src/components/dashboard/color-picker-field.tsx @@ -0,0 +1,46 @@ +"use client"; + +import { Box, Stack, Typography } from "@mui/material"; +import { alpha, useTheme } from "@mui/material/styles"; + +import { COLOR_PRESETS } from "@/lib/domain"; + +type ColorPickerFieldProps = { + label: string; + value: string; + onChange: (value: string) => void; +}; + +export function ColorPickerField({ label, value, onChange }: ColorPickerFieldProps) { + const theme = useTheme(); + + return ( + + + {label} + + + {COLOR_PRESETS.map((preset) => ( + onChange(preset)} + sx={{ + width: 28, + height: 28, + borderRadius: "50%", + border: + value === preset + ? `3px solid ${theme.palette.text.primary}` + : `2px solid ${alpha(theme.palette.text.primary, 0.14)}`, + bgcolor: preset, + cursor: "pointer" + }} + /> + ))} + + + ); +} diff --git a/src/components/dashboard/dashboard-shell.tsx b/src/components/dashboard/dashboard-shell.tsx new file mode 100644 index 0000000..45dda9e --- /dev/null +++ b/src/components/dashboard/dashboard-shell.tsx @@ -0,0 +1,1835 @@ +"use client"; + +import AddRoundedIcon from "@mui/icons-material/AddRounded"; +import DeleteOutlineRoundedIcon from "@mui/icons-material/DeleteOutlineRounded"; +import DownloadRoundedIcon from "@mui/icons-material/DownloadRounded"; +import KeyRoundedIcon from "@mui/icons-material/KeyRounded"; +import LogoutRoundedIcon from "@mui/icons-material/LogoutRounded"; +import SavingsRoundedIcon from "@mui/icons-material/SavingsRounded"; +import VerifiedRoundedIcon from "@mui/icons-material/VerifiedRounded"; +import WalletRoundedIcon from "@mui/icons-material/WalletRounded"; +import { + Alert, + Box, + Button, + Card, + CardContent, + Chip, + Container, + MenuItem, + Stack, + Tab, + Tabs, + TextField, + Typography, + useMediaQuery +} from "@mui/material"; +import { alpha, useTheme } from "@mui/material/styles"; +import { signOut } from "next-auth/react"; +import { useRouter } from "next/navigation"; +import type { FormEvent } from "react"; +import { startTransition, useEffect, useMemo, useState } from "react"; + +import { BudgetColumn } from "@/components/dashboard/budget-column"; +import { ColorPickerField } from "@/components/dashboard/color-picker-field"; +import type { + DashboardAccountingPeriod, + DashboardAuditLog, + DashboardManagedUser, + DashboardViewer, + DashboardWorkingGroup +} from "@/lib/dashboard-types"; +import { + AUTO_APPROVAL_THRESHOLD, + canManageBudgets, + canManageUsers, + roleLabel +} from "@/lib/domain"; + +type DashboardShellProps = { + viewer: DashboardViewer; + workingGroups: DashboardWorkingGroup[]; + managedUsers: DashboardManagedUser[]; + auditLogs: DashboardAuditLog[]; + accountingPeriods: DashboardAccountingPeriod[]; + currentPeriodId: string; +}; + +type ExpenseFormState = { + title: string; + description: string; + amount: string; + agId: string; + budgetId: string; + recurrence: "NONE" | "MONTHLY"; + proofUrl: string; +}; + +type BudgetFormState = { + workingGroupId: string; + name: string; + totalBudget: string; + colorCode: string; +}; + +type WorkingGroupFormState = { + name: string; +}; + +type UserFormState = { + username: string; + password: string; + role: "ADMIN" | "FINANCE" | "MEMBER"; + workingGroupId: string; + approvalPreference: "" | "CHAIR_A" | "CHAIR_B"; +}; + +type PeriodFormState = { + name: string; + startsAt: string; + endsAt: string; + copyBudgetsFromPeriodId: string; +}; + +type DashboardMessage = { + type: "success" | "error"; + text: string; +}; + +type MobileSection = "overview" | "actions"; +type DesktopSection = "overview" | "budgetGroups" | "periods" | "users" | "logs"; + +const currencyFormatter = new Intl.NumberFormat("de-DE", { + style: "currency", + currency: "EUR" +}); + +const dateTimeFormatter = new Intl.DateTimeFormat("de-DE", { + dateStyle: "medium", + timeStyle: "short" +}); + +function toDateInputValue(value: string) { + return value.slice(0, 10); +} + +function formatPeriodRange(startsAt: string, endsAt: string) { + const formatter = new Intl.DateTimeFormat("de-DE", { dateStyle: "medium" }); + return `${formatter.format(new Date(startsAt))} bis ${formatter.format(new Date(endsAt))}`; +} + +function getSuggestedPeriodDraft(currentPeriod: DashboardAccountingPeriod | undefined): PeriodFormState { + if (!currentPeriod) { + const year = new Date().getFullYear(); + return { + name: `Haushalt ${year}`, + startsAt: toDateInputValue(new Date(Date.UTC(year, 0, 1)).toISOString()), + endsAt: toDateInputValue(new Date(Date.UTC(year, 11, 31)).toISOString()), + copyBudgetsFromPeriodId: "" + }; + } + + const startsAt = new Date(currentPeriod.startsAt); + const endsAt = new Date(currentPeriod.endsAt); + const duration = Math.max(endsAt.getTime() - startsAt.getTime(), 24 * 60 * 60 * 1000); + const nextStart = new Date(endsAt.getTime() + 24 * 60 * 60 * 1000); + const nextEnd = new Date(nextStart.getTime() + duration); + + return { + name: `${currentPeriod.name} Folgezeitraum`, + startsAt: toDateInputValue(nextStart.toISOString()), + endsAt: toDateInputValue(nextEnd.toISOString()), + copyBudgetsFromPeriodId: currentPeriod.id + }; +} + +function generatePassword(length = 14) { + const alphabet = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789!@$%"; + const cryptoSource = globalThis.crypto; + + if (!cryptoSource?.getRandomValues) { + return "RFP2026!Start"; + } + + const values = cryptoSource.getRandomValues(new Uint32Array(length)); + return Array.from(values, (value) => alphabet[value % alphabet.length]).join(""); +} + +async function parseResponse(response: Response) { + const payload = await response.json().catch(() => null); + + if (!response.ok) { + throw new Error(payload?.error ?? "Die Anfrage konnte nicht verarbeitet werden."); + } + + return payload; +} + +export function DashboardShell({ + viewer, + workingGroups, + managedUsers, + auditLogs, + accountingPeriods, + currentPeriodId +}: DashboardShellProps) { + const theme = useTheme(); + const isDark = theme.palette.mode === "dark"; + const isCompactLayout = useMediaQuery(theme.breakpoints.down("lg")); + const router = useRouter(); + + const visibleGroups = workingGroups; + const editableExpenseGroups = + viewer.role === "MEMBER" + ? workingGroups.filter((group) => group.id === viewer.workingGroupId) + : workingGroups; + const canManageAccounts = canManageUsers(viewer.role); + const canManagePeriods = canManageBudgets(viewer.role); + const currentPeriod = accountingPeriods.find((period) => period.id === currentPeriodId) ?? accountingPeriods[0]; + const desktopSections = [ + { value: "overview" as const, label: "\u00dcbersicht" }, + ...(canManagePeriods ? [{ value: "budgetGroups" as const, label: "Budget / AGs" }] : []), + ...(canManagePeriods ? [{ value: "periods" as const, label: "Zeitraum" }] : []), + ...(canManageAccounts ? [{ value: "users" as const, label: "Nutzerverwaltung" }] : []), + ...(canManageAccounts ? [{ value: "logs" as const, label: "Backup & Log" }] : []) + ]; + const showDesktopSectionTabs = !isCompactLayout && desktopSections.length > 1; + + const defaultEditableGroup = + editableExpenseGroups.find((group) => group.id === viewer.workingGroupId) ?? + editableExpenseGroups[0] ?? + visibleGroups[0]; + const defaultBudget = defaultEditableGroup?.budgets[0]; + + const [expenseForm, setExpenseForm] = useState({ + title: "", + description: "", + amount: "", + agId: defaultEditableGroup?.id ?? "", + budgetId: defaultBudget?.id ?? "", + recurrence: "NONE", + proofUrl: "" + }); + const [budgetForm, setBudgetForm] = useState({ + workingGroupId: visibleGroups[0]?.id ?? "", + name: "Hauptbudget", + totalBudget: "1200", + colorCode: "#FFB94A" + }); + const [workingGroupForm, setWorkingGroupForm] = useState({ + name: "" + }); + const [userForm, setUserForm] = useState({ + username: "", + password: "", + role: "MEMBER", + workingGroupId: visibleGroups[0]?.id ?? "", + approvalPreference: "" + }); + const [message, setMessage] = useState(null); + const [busy, setBusy] = useState(false); + const [mobileSection, setMobileSection] = useState("overview"); + const [desktopSection, setDesktopSection] = useState("overview"); + const [selectedCurrentPeriodId, setSelectedCurrentPeriodId] = useState(currentPeriodId); + const [selectedMobileGroupId, setSelectedMobileGroupId] = useState( + viewer.workingGroupId ?? visibleGroups[0]?.id ?? "" + ); + const [backupFile, setBackupFile] = useState(null); + const [editingPasswordUserId, setEditingPasswordUserId] = useState(null); + const [passwordDrafts, setPasswordDrafts] = useState>({}); + const [periodForm, setPeriodForm] = useState(getSuggestedPeriodDraft(currentPeriod)); + + useEffect(() => { + if (visibleGroups.length === 0) { + setSelectedMobileGroupId(""); + return; + } + + const hasSelectedGroup = visibleGroups.some((group) => group.id === selectedMobileGroupId); + if (!hasSelectedGroup) { + setSelectedMobileGroupId(viewer.workingGroupId ?? visibleGroups[0]?.id ?? ""); + } + }, [selectedMobileGroupId, viewer.workingGroupId, visibleGroups]); + + useEffect(() => { + setSelectedCurrentPeriodId(currentPeriodId); + setPeriodForm(getSuggestedPeriodDraft(currentPeriod)); + }, [currentPeriod, currentPeriodId]); + + useEffect(() => { + if (!desktopSections.some((section) => section.value === desktopSection)) { + setDesktopSection("overview"); + } + }, [desktopSection, desktopSections]); + + useEffect(() => { + if (visibleGroups.length === 0) { + setBudgetForm((current) => ({ + ...current, + workingGroupId: "" + })); + return; + } + + const groupStillExists = visibleGroups.some((group) => group.id === budgetForm.workingGroupId); + + if (!groupStillExists) { + setBudgetForm((current) => ({ + ...current, + workingGroupId: visibleGroups[0]?.id ?? "" + })); + } + }, [budgetForm.workingGroupId, visibleGroups]); + + useEffect(() => { + if (!message || message.type !== "success") { + return; + } + + const timeoutId = window.setTimeout(() => { + setMessage((current) => (current?.type === "success" ? null : current)); + }, 10000); + + return () => { + window.clearTimeout(timeoutId); + }; + }, [message]); + + useEffect(() => { + const hasEditableGroup = editableExpenseGroups.some((group) => group.id === expenseForm.agId); + + if (!hasEditableGroup) { + setExpenseForm((current) => ({ + ...current, + agId: defaultEditableGroup?.id ?? "", + budgetId: defaultEditableGroup?.budgets[0]?.id ?? "" + })); + } + }, [defaultEditableGroup, editableExpenseGroups, expenseForm.agId]); + + useEffect(() => { + const selectedGroup = + editableExpenseGroups.find((group) => group.id === expenseForm.agId) ?? defaultEditableGroup; + const hasBudget = selectedGroup?.budgets.some((budget) => budget.id === expenseForm.budgetId) ?? false; + + if (!hasBudget) { + setExpenseForm((current) => ({ + ...current, + budgetId: selectedGroup?.budgets[0]?.id ?? "" + })); + } + }, [defaultEditableGroup, editableExpenseGroups, expenseForm.agId, expenseForm.budgetId]); + + useEffect(() => { + if (userForm.role !== "MEMBER") { + return; + } + + const groupStillExists = visibleGroups.some((group) => group.id === userForm.workingGroupId); + + if (!groupStillExists) { + setUserForm((current) => ({ + ...current, + workingGroupId: visibleGroups[0]?.id ?? "" + })); + } + }, [userForm.role, userForm.workingGroupId, visibleGroups]); + + const selectedExpenseGroup = + editableExpenseGroups.find((group) => group.id === expenseForm.agId) ?? defaultEditableGroup; + const selectedBudgetOptions = selectedExpenseGroup?.budgets ?? []; + const mobileSelectedGroup = visibleGroups.find((group) => group.id === selectedMobileGroupId) ?? visibleGroups[0]; + const selectedBudgetWorkingGroup = + visibleGroups.find((group) => group.id === budgetForm.workingGroupId) ?? null; + const selectedPeriodForManagement = + accountingPeriods.find((period) => period.id === selectedCurrentPeriodId) ?? currentPeriod ?? null; + + const totals = useMemo(() => { + return visibleGroups.reduce( + (summary, group) => { + const approved = group.budgets.reduce( + (groupSum, budget) => + groupSum + + budget.expenses.reduce( + (sum, expense) => sum + (expense.approvalStatus === "APPROVED" ? expense.amount : 0), + 0 + ), + 0 + ); + const pending = group.budgets.reduce( + (groupSum, budget) => + groupSum + + budget.expenses.reduce( + (sum, expense) => sum + (expense.approvalStatus === "PENDING" ? expense.amount : 0), + 0 + ), + 0 + ); + const subscriptions = group.budgets.reduce( + (groupSum, budget) => + groupSum + + budget.expenses.reduce( + (sum, expense) => sum + (expense.recurrence === "MONTHLY" ? expense.amount : 0), + 0 + ), + 0 + ); + const subscriptionCount = group.budgets.reduce( + (groupSum, budget) => + groupSum + budget.expenses.filter((expense) => expense.recurrence === "MONTHLY").length, + 0 + ); + + summary.budget += group.totalBudget; + summary.approved += approved; + summary.pending += pending; + summary.subscriptions += subscriptions; + summary.subscriptionCount += subscriptionCount; + + return summary; + }, + { budget: 0, approved: 0, pending: 0, subscriptions: 0, subscriptionCount: 0 } + ); + }, [visibleGroups]); + + async function runAction( + task: () => Promise, + successMessage: string | ((result: T) => string) + ) { + setBusy(true); + setMessage(null); + + try { + const result = await task(); + setMessage({ + type: "success", + text: typeof successMessage === "function" ? successMessage(result) : successMessage + }); + startTransition(() => { + router.refresh(); + }); + } catch (error) { + const text = error instanceof Error ? error.message : "Unerwarteter Fehler."; + setMessage({ type: "error", text }); + } finally { + setBusy(false); + } + } + + async function handleCreateExpense(event: FormEvent) { + event.preventDefault(); + + if (!expenseForm.agId) { + setMessage({ type: "error", text: "Bitte zuerst eine bearbeitbare AG ausw\u00e4hlen." }); + return; + } + + if (!expenseForm.budgetId) { + setMessage({ type: "error", text: "Bitte zuerst ein Budget f\u00fcr diese AG anlegen oder ausw\u00e4hlen." }); + return; + } + + await runAction(async () => { + await parseResponse( + await fetch("/api/expenses", { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + title: expenseForm.title, + description: expenseForm.description, + amount: expenseForm.amount, + agId: expenseForm.agId, + budgetId: expenseForm.budgetId, + recurrence: expenseForm.recurrence, + proofUrl: expenseForm.proofUrl + }) + }) + ); + + const resetGroup = defaultEditableGroup?.id ?? ""; + const resetBudget = defaultEditableGroup?.budgets[0]?.id ?? ""; + + setExpenseForm({ + title: "", + description: "", + amount: "", + agId: resetGroup, + budgetId: resetBudget, + recurrence: "NONE", + proofUrl: "" + }); + }, "Ausgabe wurde gespeichert."); + } + + async function handleUpsertBudget(event: FormEvent) { + event.preventDefault(); + + if (!budgetForm.workingGroupId) { + setMessage({ + type: "error", + text: "Bitte zuerst eine AG auswaehlen oder neu anlegen." + }); + return; + } + + await runAction(async () => { + await parseResponse( + await fetch("/api/budgets", { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + ...budgetForm, + periodId: currentPeriodId + }) + }) + ); + }, "Budget wurde gespeichert."); + } + + async function handleCreateWorkingGroup(event: FormEvent) { + event.preventDefault(); + + await runAction( + async () => { + const result = (await parseResponse( + await fetch("/api/working-groups", { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify(workingGroupForm) + }) + )) as { workingGroup?: { id: string; name: string } }; + + setWorkingGroupForm({ name: "" }); + + if (result.workingGroup?.id) { + setBudgetForm((current) => ({ + ...current, + workingGroupId: result.workingGroup?.id ?? current.workingGroupId + })); + } + + return result; + }, + (result) => `AG ${result.workingGroup?.name ?? "wurde"} wurde angelegt.` + ); + } + + async function handleApprove(expenseId: string, approvalType: "CHAIR_A" | "CHAIR_B" | "FINANCE") { + await runAction(async () => { + await parseResponse( + await fetch(`/api/expenses/${expenseId}/approve`, { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ approvalType }) + }) + ); + }, `Freigabe ${approvalType} wurde erfasst.`); + } + + async function handleMarkPaid(expenseId: string) { + await runAction(async () => { + await parseResponse( + await fetch(`/api/expenses/${expenseId}/paid`, { + method: "POST" + }) + ); + }, "Ausgabe ist jetzt als bezahlt markiert."); + } + + async function handleDocument(expenseId: string, proofUrl?: string) { + await runAction(async () => { + await parseResponse( + await fetch(`/api/expenses/${expenseId}/documented`, { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ proofUrl }) + }) + ); + }, "Ausgabe wurde dokumentiert."); + } + + async function handleSaveBudget(budgetId: string, name: string, totalBudget: string, colorCode: string) { + await runAction(async () => { + await parseResponse( + await fetch(`/api/budgets/${budgetId}`, { + method: "PATCH", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + name, + totalBudget, + colorCode + }) + }) + ); + }, "Budget wurde aktualisiert."); + } + + async function handleDeleteBudget(budgetId: string) { + await runAction(async () => { + await parseResponse( + await fetch(`/api/budgets/${budgetId}`, { + method: "DELETE" + }) + ); + }, "Budget wurde gel\u00f6scht."); + } + + async function handleDeleteExpense(expenseId: string) { + await runAction(async () => { + await parseResponse( + await fetch(`/api/expenses/${expenseId}`, { + method: "DELETE" + }) + ); + }, "Ausgabe wurde gel\u00f6scht."); + } + + async function handleCreatePeriod(event: FormEvent) { + event.preventDefault(); + + await runAction(async () => { + await parseResponse( + await fetch("/api/periods", { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify(periodForm) + }) + ); + }, "Neuer Abrechnungszeitraum wurde angelegt."); + } + + async function handleDeletePeriod(periodId: string, periodName: string) { + await runAction(async () => { + await parseResponse( + await fetch(`/api/periods/${periodId}`, { + method: "DELETE" + }) + ); + }, `Zeitraum ${periodName} wurde geloescht.`); + } + + async function handleSetCurrentPeriod() { + await runAction(async () => { + await parseResponse( + await fetch("/api/periods/current", { + method: "PATCH", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + periodId: selectedCurrentPeriodId + }) + }) + ); + }, "Aktuelle \u00dcbersicht wurde auf den gew\u00e4hlten Zeitraum umgestellt."); + } + + async function handleSaveWorkingGroup(groupId: string, name: string) { + await runAction(async () => { + await parseResponse( + await fetch(`/api/working-groups/${groupId}`, { + method: "PATCH", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ name }) + }) + ); + }, "AG wurde aktualisiert."); + } + + async function handleDeleteWorkingGroup(groupId: string, groupName: string) { + await runAction(async () => { + await parseResponse( + await fetch(`/api/working-groups/${groupId}`, { + method: "DELETE" + }) + ); + + const nextGroup = visibleGroups.find((group) => group.id !== groupId) ?? null; + + setBudgetForm((current) => ({ + ...current, + workingGroupId: nextGroup?.id ?? "" + })); + + setExpenseForm((current) => ({ + ...current, + agId: current.agId === groupId ? nextGroup?.id ?? "" : current.agId, + budgetId: current.agId === groupId ? nextGroup?.budgets[0]?.id ?? "" : current.budgetId + })); + }, `AG ${groupName} wurde geloescht.`); + } + + async function handleCreateUser(event: FormEvent) { + event.preventDefault(); + + await runAction( + async () => { + const createdPassword = userForm.password; + const createdUsername = userForm.username.trim().toLowerCase(); + + await parseResponse( + await fetch("/api/users", { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + username: createdUsername, + password: userForm.password, + role: userForm.role, + workingGroupId: userForm.role === "MEMBER" ? userForm.workingGroupId : "", + approvalPreference: userForm.role === "ADMIN" ? userForm.approvalPreference : "" + }) + }) + ); + + setUserForm({ + username: "", + password: "", + role: "MEMBER", + workingGroupId: visibleGroups[0]?.id ?? "", + approvalPreference: "" + }); + + return { + createdUsername, + createdPassword + }; + }, + ({ createdUsername, createdPassword }) => + `Nutzer wurde angelegt. Startpasswort f\u00fcr ${createdUsername}: ${createdPassword}` + ); + } + + async function handleDeleteUser(userId: string) { + await runAction(async () => { + await parseResponse( + await fetch(`/api/users/${userId}`, { + method: "DELETE" + }) + ); + }, "Nutzer wurde gel\u00f6scht."); + } + + async function handleResetPassword(userId: string, userName: string) { + const nextPassword = passwordDrafts[userId]?.trim() ?? ""; + + if (nextPassword.length < 8) { + setMessage({ + type: "error", + text: "Bitte ein neues Passwort mit mindestens 8 Zeichen eingeben." + }); + return; + } + + await runAction( + async () => { + await parseResponse( + await fetch(`/api/users/${userId}/password`, { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + password: nextPassword + }) + }) + ); + + setEditingPasswordUserId(null); + + return { + userName, + nextPassword + }; + }, + ({ userName: changedUserName, nextPassword: changedPassword }) => + `Neues Passwort f\u00fcr ${changedUserName}: ${changedPassword}` + ); + } + + async function handleImportBackup() { + if (!backupFile) { + setMessage({ + type: "error", + text: "Bitte zuerst eine CSV-Datei auswählen." + }); + return; + } + + await runAction( + async () => { + const formData = new FormData(); + formData.set("file", backupFile); + + const result = await parseResponse( + await fetch("/api/import/csv", { + method: "POST", + body: formData + }) + ); + + setBackupFile(null); + return result as { importedRows?: number }; + }, + (result) => + `Backup wurde eingespielt.${typeof result.importedRows === "number" ? ` Importierte Zeilen: ${result.importedRows}.` : ""}` + ); + } + + async function handleRestoreAuditLog(entryId: string, summary: string) { + if (!window.confirm(`Diesen Zustand wirklich zurücksetzen?\n\n${summary}`)) { + return; + } + + await runAction(async () => { + await parseResponse( + await fetch(`/api/audit-logs/${entryId}/restore`, { + method: "POST" + }) + ); + }, "Änderung wurde zurückgesetzt."); + } + + function openPasswordReset(userId: string) { + setEditingPasswordUserId(userId); + setPasswordDrafts((current) => ({ + ...current, + [userId]: current[userId] && current[userId].length >= 8 ? current[userId] : generatePassword() + })); + } + + const islandCardSx = { + borderRadius: { xs: "24px", md: "30px" }, + border: `1px solid ${alpha(theme.palette.text.primary, isDark ? 0.12 : 0.08)}`, + background: `linear-gradient(180deg, ${alpha(theme.palette.background.paper, isDark ? 0.82 : 0.96)} 0%, ${alpha(theme.palette.text.primary, isDark ? 0.04 : 0.02)} 100%)`, + overflow: "hidden", + boxShadow: isDark ? `0 20px 48px ${alpha("#02040A", 0.34)}` : `0 18px 44px ${alpha("#B86E2B", 0.08)}` + }; + + const nestedPanelSx = { + p: 2, + borderRadius: "20px", + border: `1px solid ${alpha(theme.palette.text.primary, isDark ? 0.12 : 0.08)}`, + background: `linear-gradient(180deg, ${alpha(theme.palette.background.paper, isDark ? 0.78 : 0.9)} 0%, ${alpha(theme.palette.text.primary, isDark ? 0.05 : 0.02)} 100%)`, + overflow: "hidden" + }; + + const periodManagementPanel = canManagePeriods ? ( + + + + Zeitraum wechseln + + + {"Nur Vorstand und Finanz-AG k\u00f6nnen die aktuelle \u00dcbersicht global umstellen."} + + + + setSelectedCurrentPeriodId(event.target.value)} + fullWidth + sx={{ minWidth: 0 }} + > + {accountingPeriods.map((period) => ( + + {period.name} + + ))} + + + + + + {selectedPeriodForManagement?.isCurrent + ? "Der aktuell aktive Zeitraum kann nicht gel\u00f6scht werden." + : "Leere, nicht aktive Zeitr\u00e4ume lassen sich hier wieder entfernen."} + + + + + + Neuen Zeitraum anlegen + + setPeriodForm((current) => ({ ...current, name: event.target.value }))} + required + fullWidth + /> + + setPeriodForm((current) => ({ ...current, startsAt: event.target.value }))} + InputLabelProps={{ shrink: true }} + required + fullWidth + /> + setPeriodForm((current) => ({ ...current, endsAt: event.target.value }))} + InputLabelProps={{ shrink: true }} + required + fullWidth + /> + + + setPeriodForm((current) => ({ + ...current, + copyBudgetsFromPeriodId: event.target.value + })) + } + fullWidth + helperText={"Optional kopiert die vorhandenen Budgett\u00f6pfe direkt in den neuen Zeitraum."} + > + {`Ohne Budget\u00fcbernahme`} + {accountingPeriods.map((period) => ( + + {period.name} + + ))} + + + + + + ) : null; + + const actionCards = ( + + {isCompactLayout || desktopSection === "overview" ? ( + + + + + + Neue Ausgabe + + + {"Alle sehen alle AGs. AG-Mitglieder buchen aber nur in ihrer eigenen AG. Unter "} + {AUTO_APPROVAL_THRESHOLD} + {" EUR wird automatisch freigegeben."} + + + + + + setExpenseForm((current) => ({ ...current, title: event.target.value }))} + required + fullWidth + /> + + setExpenseForm((current) => ({ ...current, description: event.target.value })) + } + fullWidth + multiline + minRows={3} + /> + setExpenseForm((current) => ({ ...current, amount: event.target.value }))} + required + fullWidth + /> + + setExpenseForm((current) => ({ + ...current, + recurrence: event.target.value as ExpenseFormState["recurrence"] + })) + } + fullWidth + helperText={"Monatliche Abos erscheinen oben gesammelt im \u00dcberblick."} + > + Einmalig + Monatliches Abo + + setExpenseForm((current) => ({ ...current, agId: event.target.value }))} + required + fullWidth + disabled={viewer.role === "MEMBER" || editableExpenseGroups.length === 0} + helperText={ + viewer.role === "MEMBER" + ? "Du kannst nur in deiner eigenen AG buchen." + : "W\u00e4hle die AG, in der die Ausgabe erfasst werden soll." + } + > + {editableExpenseGroups.map((group) => ( + + {group.name} + + ))} + + setExpenseForm((current) => ({ ...current, budgetId: event.target.value }))} + required + fullWidth + disabled={selectedBudgetOptions.length === 0} + helperText={ + selectedBudgetOptions.length === 0 + ? "In dieser AG gibt es noch kein Budget." + : "Bitte den passenden Budgettopf w\u00e4hlen." + } + > + {selectedBudgetOptions.map((budget) => ( + + {budget.name} + + ))} + + setExpenseForm((current) => ({ ...current, proofUrl: event.target.value }))} + fullWidth + /> + + + + + + + ) : null} + + {canManageBudgets(viewer.role) && (isCompactLayout || desktopSection === "budgetGroups") ? ( + + + + + + AG anlegen + + + {"Lege Arbeitsgruppen separat an. Bearbeiten oder loeschen geht danach direkt in der Uebersicht per Stift."} + + + + + + setWorkingGroupForm((current) => ({ ...current, name: event.target.value })) + } + required + fullWidth + /> + + + + + + + ) : null} + + {canManageBudgets(viewer.role) && (isCompactLayout || desktopSection === "budgetGroups") ? ( + + + + + + Budget anlegen + + + {"Neue Budgett\u00f6pfe werden immer f\u00fcr den aktuell ausgew\u00e4hlten Abrechnungszeitraum angelegt."} + + + {currentPeriod ? ( + + ) : null} + + + + setBudgetForm((current) => ({ ...current, workingGroupId: event.target.value })) + } + required + fullWidth + disabled={visibleGroups.length === 0} + helperText={ + visibleGroups.length === 0 + ? "Lege zuerst eine AG an." + : "Das Budget wird in der ausgewaehlten AG angelegt." + } + > + {visibleGroups.map((group) => ( + + {group.name} + + ))} + + + {selectedBudgetWorkingGroup + ? `Neue Budgettoepfe landen in ${selectedBudgetWorkingGroup.name}.` + : "Waehle zuerst eine bestehende AG aus."} + + setBudgetForm((current) => ({ ...current, name: event.target.value }))} + required + /> + + setBudgetForm((current) => ({ ...current, totalBudget: event.target.value })) + } + required + /> + setBudgetForm((current) => ({ ...current, colorCode: value }))} + /> + + + + + + + + + ) : null} + + {canManagePeriods && isCompactLayout ? ( + + {periodManagementPanel} + + ) : null} + + {canManageAccounts && (isCompactLayout || desktopSection === "logs") ? ( + + + + + + CSV-Backup + + + {"Exportiert Nutzer, AGs, Budgets, Ausgaben, Freigaben und den Änderungsverlauf in eine gemeinsame CSV-Datei."} + + + + + + + + + {backupFile + ? `Ausgewählt: ${backupFile.name}` + : "Der Import ersetzt den aktuellen Datenbestand vollständig durch den Stand aus der CSV."} + + + + + ) : null} + + {canManageAccounts && (isCompactLayout || desktopSection === "users") ? ( + + + + + + Nutzer anlegen + + + {"Konten werden direkt mit Login-Name und Passwort angelegt. Der Login-Name ist gleichzeitig der Anzeigename."} + + + + + setUserForm((current) => ({ ...current, username: event.target.value }))} + required + /> + + + setUserForm((current) => ({ ...current, password: event.target.value })) + } + required + fullWidth + helperText={"Dieses Passwort wird nach dem Anlegen oben als Best\u00e4tigung angezeigt."} + /> + + + + setUserForm((current) => ({ + ...current, + role: event.target.value as UserFormState["role"], + approvalPreference: event.target.value === "ADMIN" ? current.approvalPreference : "", + workingGroupId: event.target.value === "MEMBER" ? current.workingGroupId : "" + })) + } + required + > + Vorstand + Finanz-AG + AG-Mitglied + + + {userForm.role === "MEMBER" ? ( + + setUserForm((current) => ({ ...current, workingGroupId: event.target.value })) + } + required + > + {visibleGroups.map((group) => ( + + {group.name} + + ))} + + ) : null} + + {userForm.role === "ADMIN" ? ( + + setUserForm((current) => ({ + ...current, + approvalPreference: event.target.value as UserFormState["approvalPreference"] + })) + } + > + Keine Voreinstellung + Vorstand A + Vorstand B + + ) : null} + + + + + + + + ) : null} + + {canManageAccounts && (isCompactLayout || desktopSection === "users") ? ( + + + + + + Nutzer verwalten + + + {"Bestehende Passw\u00f6rter bleiben sicher gehasht und sind nicht auslesbar. Hier kannst du neue setzen und direkt sehen."} + + + + {managedUsers.map((user) => { + const canDelete = user.id !== viewer.id && user.createdExpensesCount === 0 && user.approvalsCount === 0; + const isResetOpen = editingPasswordUserId === user.id; + + return ( + + + + + {user.username} + + {roleLabel(user.role)} + + + + + + + + + + + + + + {isResetOpen ? ( + + + + setPasswordDrafts((current) => ({ + ...current, + [user.id]: event.target.value + })) + } + fullWidth + helperText={ + "Nur neu gesetzte Passw\u00f6rter sind sichtbar. Das alte Passwort bleibt absichtlich verborgen." + } + /> + + + + + + + + ) : null} + + + ); + })} + + + + + ) : null} + + {canManagePeriods && isCompactLayout ? ( + + {periodManagementPanel} + + ) : null} + + {canManageAccounts && (isCompactLayout || desktopSection === "logs") ? ( + + + + + + {"\u00c4nderungsverlauf"} + + + {"Zeigt die letzten \u00c4nderungen an Nutzern, Ausgaben, Budgets, AGs und Zeitr\u00e4umen."} + + + {auditLogs.length > 0 ? ( + + {auditLogs.map((entry) => ( + + + + {entry.summary} + + + + + {entry.entityLabel ? : null} + + + + {entry.actor + ? `${entry.actor.username} - ${roleLabel(entry.actor.role)}` + : "Systemeintrag"} + + {entry.canRestore ? ( + + ) : null} + + + ))} + + ) : ( + {"Noch keine \u00c4nderungen protokolliert."} + )} + + + + ) : null} + + ); + + const periodOverviewCard = isCompactLayout ? null : showDesktopSectionTabs ? ( + + + setDesktopSection(nextValue)} + variant="fullWidth" + sx={{ + minHeight: 0, + ".MuiTabs-indicator": { + display: "none" + }, + ".MuiTab-root": { + minHeight: 48, + px: 1.5, + py: 1, + m: 0.35, + borderRadius: "16px", + textTransform: "none", + fontWeight: 700, + border: `1px solid ${alpha(theme.palette.text.primary, isDark ? 0.12 : 0.1)}`, + color: theme.palette.text.secondary, + backgroundColor: alpha(theme.palette.background.paper, isDark ? 0.42 : 0.9) + }, + ".Mui-selected": { + color: theme.palette.primary.main, + borderColor: alpha(theme.palette.primary.main, 0.35), + backgroundColor: alpha(theme.palette.primary.main, isDark ? 0.22 : 0.12) + } + }} + > + {desktopSections.map((section) => ( + + ))} + + + + ) : null; + + const overviewContent = ( + + {isCompactLayout && visibleGroups.length > 1 ? ( + + + + + + {"AG ausw\u00e4hlen"} + + + {"Mobil zeigen wir jeweils eine AG auf einmal, damit die Budgetkarten sauber lesbar bleiben."} + + + setSelectedMobileGroupId(event.target.value)} + fullWidth + > + {visibleGroups.map((group) => ( + + {group.name} + + ))} + + + + + ) : null} + + + {(isCompactLayout ? (mobileSelectedGroup ? [mobileSelectedGroup] : []) : visibleGroups).map((group) => ( + + ))} + + + ); + + const desktopSectionContent = + desktopSection === "overview" ? ( + + {actionCards} + {overviewContent} + + ) : desktopSection === "periods" ? ( + + {canManagePeriods ? ( + + {periodManagementPanel} + + ) : null} + + ) : ( + {actionCards} + ); + + return ( + + + + + + + + + + Rave for Peace + + + {"RFP Finanz\u00fcbersicht"} + + + {`Aktuelle \u00dcbersicht: ${currentPeriod?.name ?? "Zeitraum fehlt"}. Alle AGs sind sichtbar, Mitglieder bearbeiten nur ihre eigene AG.`} + + + + + + + + + + } + label={`Freigegeben: ${currencyFormatter.format(totals.approved)}`} + sx={{ bgcolor: alpha("#FFFFFF", 0.12), color: "white" }} + /> + } + label={`Geplant: ${currencyFormatter.format(totals.pending)}`} + sx={{ bgcolor: alpha("#FFFFFF", 0.12), color: "white" }} + /> + } + label={`Budgets sichtbar: ${currencyFormatter.format(totals.budget)}`} + sx={{ bgcolor: alpha("#FFFFFF", 0.12), color: "white" }} + /> + + {isCompactLayout && currentPeriod ? ( + + ) : null} + {isCompactLayout && currentPeriod ? ( + + ) : null} + + + + + + + + + + {message ? {message.text} : null} + {periodOverviewCard} + + {isCompactLayout ? ( + + + setMobileSection(nextValue)} + variant="fullWidth" + > + + + + + {mobileSection === "overview" ? overviewContent : actionCards} + + ) : ( + {desktopSectionContent} + )} + + + + ); +} + + diff --git a/src/components/login-form.tsx b/src/components/login-form.tsx new file mode 100644 index 0000000..baab7dd --- /dev/null +++ b/src/components/login-form.tsx @@ -0,0 +1,109 @@ +"use client"; + +import { Alert, Box, Button, Card, CardContent, Chip, Stack, TextField, Typography } from "@mui/material"; +import { signIn } from "next-auth/react"; +import { useRouter } from "next/navigation"; +import type { FormEvent } from "react"; +import { useState } from "react"; + +const demoAccounts = [ + { label: "Vorstand A", username: "vorstand-a" }, + { label: "Vorstand B", username: "vorstand-b" }, + { label: "Finanz-AG", username: "finanzen" }, + { label: "Deko Mitglied", username: "deko" } +]; + +export function LoginForm() { + const router = useRouter(); + const [identifier, setIdentifier] = useState("vorstand-a"); + const [password, setPassword] = useState("demo123!"); + const [error, setError] = useState(null); + const [isLoading, setIsLoading] = useState(false); + + async function handleSubmit(event: FormEvent) { + event.preventDefault(); + setError(null); + setIsLoading(true); + + const result = await signIn("credentials", { + identifier, + password, + redirect: false + }); + + setIsLoading(false); + + if (result?.error) { + setError("Anmeldung fehlgeschlagen. Bitte Zugangsdaten pr\u00fcfen."); + return; + } + + router.push("/"); + router.refresh(); + } + + return ( + + + + + + Anmeldung + + + Melde dich mit deinem Login-Namen und Passwort an. + + + + + {demoAccounts.map((account) => ( + { + setIdentifier(account.username); + setPassword("demo123!"); + }} + variant="outlined" + /> + ))} + + + {"Demo-Passwort f\u00fcr alle Konten: demo123!"} + + {error ? {error} : null} + + + + setIdentifier(event.target.value)} + fullWidth + required + /> + setPassword(event.target.value)} + fullWidth + required + /> + + + + + + + ); +} diff --git a/src/components/providers/app-providers.tsx b/src/components/providers/app-providers.tsx new file mode 100644 index 0000000..72d1f2d --- /dev/null +++ b/src/components/providers/app-providers.tsx @@ -0,0 +1,46 @@ +"use client"; + +import type { PaletteMode } from "@mui/material"; +import { Box, CssBaseline, ThemeProvider } from "@mui/material"; +import { SessionProvider } from "next-auth/react"; +import type { ReactNode } from "react"; +import { useEffect, useMemo, useState } from "react"; + +import { getAppTheme } from "@/theme"; + +type AppProvidersProps = { + children: ReactNode; +}; + +export function AppProviders({ children }: AppProvidersProps) { + const [mode, setMode] = useState(null); + + useEffect(() => { + const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); + + const applyMode = () => { + setMode(mediaQuery.matches ? "dark" : "light"); + }; + + applyMode(); + + if (typeof mediaQuery.addEventListener === "function") { + mediaQuery.addEventListener("change", applyMode); + return () => mediaQuery.removeEventListener("change", applyMode); + } + + mediaQuery.addListener(applyMode); + return () => mediaQuery.removeListener(applyMode); + }, []); + + const theme = useMemo(() => getAppTheme(mode ?? "dark"), [mode]); + + return ( + + + + {mode ? children : } + + + ); +} diff --git a/src/components/service-worker-registration.tsx b/src/components/service-worker-registration.tsx new file mode 100644 index 0000000..8f77ab5 --- /dev/null +++ b/src/components/service-worker-registration.tsx @@ -0,0 +1,18 @@ +"use client"; + +import { useEffect } from "react"; + +export function ServiceWorkerRegistration() { + useEffect(() => { + if (!("serviceWorker" in navigator)) { + return; + } + + navigator.serviceWorker.register("/sw.js").catch(() => { + // Registrierung darf die App nicht blockieren. + }); + }, []); + + return null; +} + diff --git a/src/lib/accounting-periods.ts b/src/lib/accounting-periods.ts new file mode 100644 index 0000000..eb06daf --- /dev/null +++ b/src/lib/accounting-periods.ts @@ -0,0 +1,22 @@ +import prisma from "@/lib/prisma"; + +export async function getCurrentAccountingPeriod() { + const current = await prisma.accountingPeriod.findFirst({ + where: { + isCurrent: true + }, + orderBy: { + startsAt: "desc" + } + }); + + if (current) { + return current; + } + + return prisma.accountingPeriod.findFirst({ + orderBy: { + startsAt: "desc" + } + }); +} diff --git a/src/lib/audit-log.ts b/src/lib/audit-log.ts new file mode 100644 index 0000000..c79c6d4 --- /dev/null +++ b/src/lib/audit-log.ts @@ -0,0 +1,62 @@ +import type { Prisma, PrismaClient } from "@prisma/client"; + +type AuditClient = PrismaClient | Prisma.TransactionClient; + +export type AuditRollbackPayload = { + kind: string; + [key: string]: Prisma.JsonValue | null | undefined; +}; + +type CreateAuditLogInput = { + actorId?: string | null; + action: string; + entityType: string; + entityId?: string | null; + entityLabel?: string | null; + summary: string; + metadata?: Prisma.InputJsonValue; +}; + +export function withRollbackMetadata( + details: Record = {}, + rollback?: AuditRollbackPayload | null +) { + return { + ...details, + rollback: rollback ?? null + } satisfies Prisma.InputJsonObject; +} + +export function getRollbackMetadata(metadata: Prisma.JsonValue | null | undefined) { + if (!metadata || typeof metadata !== "object" || Array.isArray(metadata)) { + return null; + } + + const rollback = (metadata as Record).rollback; + + if (!rollback || typeof rollback !== "object" || Array.isArray(rollback)) { + return null; + } + + const kind = (rollback as Record).kind; + + if (typeof kind !== "string" || kind.length === 0) { + return null; + } + + return rollback as Record & { kind: string }; +} + +export async function createAuditLog(client: AuditClient, input: CreateAuditLogInput) { + await client.auditLog.create({ + data: { + actorId: input.actorId ?? null, + action: input.action, + entityType: input.entityType, + entityId: input.entityId ?? null, + entityLabel: input.entityLabel ?? null, + summary: input.summary, + metadata: input.metadata + } + }); +} diff --git a/src/lib/audit-snapshots.ts b/src/lib/audit-snapshots.ts new file mode 100644 index 0000000..e2c84f6 --- /dev/null +++ b/src/lib/audit-snapshots.ts @@ -0,0 +1,98 @@ +import type { Approval, AccountingPeriod, Budget, Expense, User, WorkingGroup } from "@prisma/client"; + +export function snapshotWorkingGroup(workingGroup: Pick) { + return { + id: workingGroup.id, + name: workingGroup.name, + createdAt: workingGroup.createdAt.toISOString() + }; +} + +export function snapshotPeriod(period: Pick) { + return { + id: period.id, + name: period.name, + startsAt: period.startsAt.toISOString(), + endsAt: period.endsAt.toISOString(), + isCurrent: period.isCurrent, + createdAt: period.createdAt.toISOString() + }; +} + +export function snapshotBudget(budget: Pick) { + return { + id: budget.id, + name: budget.name, + totalBudget: Number(budget.totalBudget), + colorCode: budget.colorCode, + workingGroupId: budget.workingGroupId, + periodId: budget.periodId, + createdAt: budget.createdAt.toISOString() + }; +} + +export function snapshotExpense( + expense: Pick< + Expense, + | "id" + | "title" + | "description" + | "amount" + | "creatorId" + | "agId" + | "budgetId" + | "periodId" + | "approvalStatus" + | "recurrence" + | "proofUrl" + | "createdAt" + | "paidAt" + | "documentedAt" + > +) { + return { + id: expense.id, + title: expense.title, + description: expense.description, + amount: Number(expense.amount), + creatorId: expense.creatorId, + agId: expense.agId, + budgetId: expense.budgetId, + periodId: expense.periodId, + approvalStatus: expense.approvalStatus, + recurrence: expense.recurrence, + proofUrl: expense.proofUrl, + createdAt: expense.createdAt.toISOString(), + paidAt: expense.paidAt?.toISOString() ?? null, + documentedAt: expense.documentedAt?.toISOString() ?? null + }; +} + +export function snapshotApproval(approval: Pick) { + return { + id: approval.id, + expenseId: approval.expenseId, + userId: approval.userId, + approvalType: approval.approvalType, + timestamp: approval.timestamp.toISOString() + }; +} + +export function snapshotUser( + user: Pick< + User, + "id" | "name" | "username" | "email" | "passwordHash" | "role" | "approvalPreference" | "workingGroupId" | "createdAt" + > +) { + return { + id: user.id, + name: user.name, + username: user.username, + email: user.email, + passwordHash: user.passwordHash, + role: user.role, + approvalPreference: user.approvalPreference, + workingGroupId: user.workingGroupId, + createdAt: user.createdAt.toISOString() + }; +} diff --git a/src/lib/auth.ts b/src/lib/auth.ts new file mode 100644 index 0000000..574c578 --- /dev/null +++ b/src/lib/auth.ts @@ -0,0 +1,87 @@ +import type { NextAuthOptions } from "next-auth"; +import CredentialsProvider from "next-auth/providers/credentials"; +import bcrypt from "bcryptjs"; +import { z } from "zod"; + +import prisma from "@/lib/prisma"; + +const credentialsSchema = z.object({ + identifier: z.string().trim().min(2), + password: z.string().min(6) +}); + +export const authOptions: NextAuthOptions = { + session: { + strategy: "jwt" + }, + pages: { + signIn: "/login" + }, + providers: [ + CredentialsProvider({ + name: "Login und Passwort", + credentials: { + identifier: { label: "Login-Name", type: "text" }, + password: { label: "Passwort", type: "password" } + }, + async authorize(rawCredentials) { + const parsedCredentials = credentialsSchema.safeParse(rawCredentials); + + if (!parsedCredentials.success) { + return null; + } + + const normalizedIdentifier = parsedCredentials.data.identifier.toLowerCase(); + const matchedUser = await prisma.user.findUnique({ + where: { + username: normalizedIdentifier + } + }); + + if (!matchedUser) { + return null; + } + + const isPasswordValid = await bcrypt.compare(parsedCredentials.data.password, matchedUser.passwordHash); + + if (!isPasswordValid) { + return null; + } + + return { + id: matchedUser.id, + name: matchedUser.username, + username: matchedUser.username, + email: matchedUser.email, + role: matchedUser.role, + workingGroupId: matchedUser.workingGroupId, + approvalPreference: matchedUser.approvalPreference + }; + } + }) + ], + callbacks: { + async jwt({ token, user }) { + if (user) { + token.id = user.id; + token.username = user.username; + token.role = user.role; + token.workingGroupId = user.workingGroupId; + token.approvalPreference = user.approvalPreference; + } + + return token; + }, + async session({ session, token }) { + if (session.user) { + session.user.id = token.id ?? ""; + session.user.username = token.username ?? ""; + session.user.role = token.role ?? "MEMBER"; + session.user.workingGroupId = token.workingGroupId ?? null; + session.user.approvalPreference = token.approvalPreference ?? null; + } + + return session; + } + } +}; diff --git a/src/lib/backup-csv.ts b/src/lib/backup-csv.ts new file mode 100644 index 0000000..e894c5a --- /dev/null +++ b/src/lib/backup-csv.ts @@ -0,0 +1,61 @@ +export function toCsvCell(value: string | number | null | undefined) { + if (value === null || value === undefined) { + return "\"\""; + } + + const normalized = String(value).replace(/"/g, "\"\""); + return `"${normalized}"`; +} + +export function parseCsv(content: string) { + const rows: string[][] = []; + let currentRow: string[] = []; + let currentCell = ""; + let inQuotes = false; + + for (let index = 0; index < content.length; index += 1) { + const char = content[index]; + const nextChar = content[index + 1]; + + if (char === "\"") { + if (inQuotes && nextChar === "\"") { + currentCell += "\""; + index += 1; + } else { + inQuotes = !inQuotes; + } + continue; + } + + if (char === "," && !inQuotes) { + currentRow.push(currentCell); + currentCell = ""; + continue; + } + + if ((char === "\n" || char === "\r") && !inQuotes) { + if (char === "\r" && nextChar === "\n") { + index += 1; + } + + currentRow.push(currentCell); + rows.push(currentRow); + currentRow = []; + currentCell = ""; + continue; + } + + currentCell += char; + } + + if (currentCell.length > 0 || currentRow.length > 0) { + currentRow.push(currentCell); + rows.push(currentRow); + } + + if (rows[0]?.[0]?.charCodeAt(0) === 0xfeff) { + rows[0][0] = rows[0][0].slice(1); + } + + return rows; +} diff --git a/src/lib/dashboard-types.ts b/src/lib/dashboard-types.ts new file mode 100644 index 0000000..e0d3a46 --- /dev/null +++ b/src/lib/dashboard-types.ts @@ -0,0 +1,99 @@ +import type { AppRole, ApprovalStatusValue, ApprovalTypeValue, ExpenseRecurrenceValue } from "@/lib/domain"; + +export type DashboardAccountingPeriod = { + id: string; + name: string; + startsAt: string; + endsAt: string; + isCurrent: boolean; +}; + +export type DashboardViewer = { + id: string; + name: string; + username: string; + role: AppRole; + workingGroupId: string | null; + approvalPreference: ApprovalTypeValue | null; +}; + +export type DashboardApproval = { + id: string; + approvalType: ApprovalTypeValue; + timestamp: string; + user: { + id: string; + name: string; + }; +}; + +export type DashboardExpense = { + id: string; + title: string; + description: string | null; + amount: number; + budgetId: string; + periodId: string; + approvalStatus: ApprovalStatusValue; + recurrence: ExpenseRecurrenceValue; + paidAt: string | null; + documentedAt: string | null; + proofUrl: string | null; + createdAt: string; + creator: { + id: string; + name: string; + }; + approvals: DashboardApproval[]; +}; + +export type DashboardBudget = { + id: string; + name: string; + totalBudget: number; + colorCode: string; + periodId: string; + expenses: DashboardExpense[]; +}; + +export type DashboardWorkingGroup = { + id: string; + name: string; + totalBudget: number; + members: { + id: string; + name: string; + username: string; + role: AppRole; + }[]; + budgets: DashboardBudget[]; +}; + +export type DashboardManagedUser = { + id: string; + name: string; + username: string; + role: AppRole; + workingGroupId: string | null; + workingGroupName: string | null; + approvalPreference: ApprovalTypeValue | null; + createdExpensesCount: number; + approvalsCount: number; +}; + +export type DashboardAuditLog = { + id: string; + action: string; + entityType: string; + entityId: string | null; + entityLabel: string | null; + summary: string; + canRestore: boolean; + createdAt: string; + actor: { + id: string; + name: string; + username: string; + role: AppRole; + } | null; +}; diff --git a/src/lib/domain.ts b/src/lib/domain.ts new file mode 100644 index 0000000..9679a11 --- /dev/null +++ b/src/lib/domain.ts @@ -0,0 +1,122 @@ +export const AUTO_APPROVAL_THRESHOLD = 50; + +export const APPROVAL_FLOW = ["CHAIR_A", "CHAIR_B", "FINANCE"] as const; +export const COLOR_PRESETS = [ + "#FFB94A", + "#68A35D", + "#5677F6", + "#FF8C69", + "#D567C8", + "#17A2B8", + "#A47A5B", + "#8E6CE7", + "#E05A73", + "#3FAF88" +] as const; + +export type AppRole = "ADMIN" | "FINANCE" | "MEMBER"; +export type ApprovalTypeValue = (typeof APPROVAL_FLOW)[number]; +export type ApprovalStatusValue = "PENDING" | "APPROVED"; +export type ExpenseRecurrenceValue = "NONE" | "MONTHLY"; + +export function requiresManualApproval(amount: number) { + return amount >= AUTO_APPROVAL_THRESHOLD; +} + +export function roleLabel(role: AppRole) { + switch (role) { + case "ADMIN": + return "Vorstand"; + case "FINANCE": + return "Finanz-AG"; + case "MEMBER": + return "AG-Mitglied"; + } +} + +export function approvalLabel(approvalType: ApprovalTypeValue) { + switch (approvalType) { + case "CHAIR_A": + return "Vorstand A"; + case "CHAIR_B": + return "Vorstand B"; + case "FINANCE": + return "Finanz-AG"; + } +} + +export function recurrenceLabel(recurrence: ExpenseRecurrenceValue) { + switch (recurrence) { + case "MONTHLY": + return "Monatliches Abo"; + case "NONE": + return "Einmalig"; + } +} + +export function hasAdministrativeAccess(role: AppRole) { + return role === "ADMIN" || role === "FINANCE"; +} + +export function canManageBudgets(role: AppRole) { + return hasAdministrativeAccess(role); +} + +export function canManageUsers(role: AppRole) { + return hasAdministrativeAccess(role); +} + +export function canMarkPaid(role: AppRole) { + return hasAdministrativeAccess(role); +} + +export function canDocumentExpense(role: AppRole) { + return hasAdministrativeAccess(role); +} + +export function canCreateExpenseForGroup(role: AppRole, viewerGroupId: string | null, targetGroupId: string) { + if (hasAdministrativeAccess(role)) { + return true; + } + + return viewerGroupId === targetGroupId; +} + +export function canDeleteExpense( + role: AppRole, + viewerId: string, + creatorId: string, + approvalStatus: ApprovalStatusValue, + paidAt: string | null, + documentedAt: string | null +) { + if (role === "ADMIN" || role === "FINANCE") { + return true; + } + + return viewerId === creatorId && approvalStatus === "PENDING" && !paidAt && !documentedAt; +} + +export function getAvailableApprovalTypes( + role: AppRole, + approvalPreference: ApprovalTypeValue | null | undefined, + existingApprovals: ApprovalTypeValue[] +): ApprovalTypeValue[] { + const missingApprovals = APPROVAL_FLOW.filter( + (approvalType) => !existingApprovals.includes(approvalType) + ) as ApprovalTypeValue[]; + + if (role === "ADMIN") { + if (approvalPreference && missingApprovals.includes(approvalPreference)) { + return [approvalPreference, ...missingApprovals.filter((approvalType) => approvalType !== approvalPreference)]; + } + + return missingApprovals; + } + + if (role === "FINANCE") { + return missingApprovals.includes("FINANCE") ? ["FINANCE"] : []; + } + + return []; +} diff --git a/src/lib/prisma.ts b/src/lib/prisma.ts new file mode 100644 index 0000000..c9dcacc --- /dev/null +++ b/src/lib/prisma.ts @@ -0,0 +1,17 @@ +import { PrismaClient } from "@prisma/client"; + +const globalForPrisma = globalThis as unknown as { + prisma?: PrismaClient; +}; + +const prisma = + globalForPrisma.prisma ?? + new PrismaClient({ + log: process.env.NODE_ENV === "development" ? ["error", "warn"] : ["error"] + }); + +if (process.env.NODE_ENV !== "production") { + globalForPrisma.prisma = prisma; +} + +export default prisma; diff --git a/src/lib/session.ts b/src/lib/session.ts new file mode 100644 index 0000000..9614536 --- /dev/null +++ b/src/lib/session.ts @@ -0,0 +1,19 @@ +import { getServerSession } from "next-auth"; + +import { authOptions } from "@/lib/auth"; +import prisma from "@/lib/prisma"; + +export async function getCurrentViewer() { + const session = await getServerSession(authOptions); + + if (!session?.user?.id) { + return null; + } + + return prisma.user.findUnique({ + where: { id: session.user.id }, + include: { + workingGroup: true + } + }); +} diff --git a/src/theme.ts b/src/theme.ts new file mode 100644 index 0000000..8058432 --- /dev/null +++ b/src/theme.ts @@ -0,0 +1,136 @@ +import type { PaletteMode } from "@mui/material"; +import { alpha, createTheme } from "@mui/material/styles"; + +const primaryLight = "#3B5AE0"; +const primaryDark = "#8CA4FF"; +const secondaryLight = "#F28B4B"; +const secondaryDark = "#FFB36B"; +const successLight = "#2F8F64"; +const successDark = "#57C089"; +const deepLight = "#17203A"; +const deepDark = "#E9EEF9"; +const surfaceLight = "#F5F1E8"; +const paperLight = "#FFFDF9"; +const surfaceDark = "#0B1020"; +const paperDark = "#121A2B"; + +export function getAppTheme(mode: PaletteMode) { + const isDark = mode === "dark"; + const primary = isDark ? primaryDark : primaryLight; + const secondary = isDark ? secondaryDark : secondaryLight; + const success = isDark ? successDark : successLight; + const textPrimary = isDark ? deepDark : deepLight; + const textSecondary = alpha(textPrimary, isDark ? 0.76 : 0.7); + const backgroundDefault = isDark ? surfaceDark : surfaceLight; + const backgroundPaper = isDark ? paperDark : paperLight; + + return createTheme({ + palette: { + mode, + primary: { + main: primary + }, + secondary: { + main: secondary + }, + background: { + default: backgroundDefault, + paper: backgroundPaper + }, + text: { + primary: textPrimary, + secondary: textSecondary + }, + success: { + main: success + }, + divider: alpha(textPrimary, isDark ? 0.12 : 0.08) + }, + shape: { + borderRadius: 24 + }, + typography: { + fontFamily: "var(--font-body)", + h1: { + fontFamily: "var(--font-display)", + fontSize: "clamp(2.4rem, 5vw, 4.5rem)", + fontWeight: 700, + letterSpacing: "-0.04em" + }, + h2: { + fontFamily: "var(--font-display)", + fontWeight: 700, + letterSpacing: "-0.03em" + }, + h3: { + fontFamily: "var(--font-display)", + fontWeight: 700 + }, + button: { + fontWeight: 700, + textTransform: "none" + } + }, + components: { + MuiCssBaseline: { + styleOverrides: { + ":root": { + colorScheme: mode + }, + body: { + background: isDark + ? [ + `radial-gradient(circle at top left, ${alpha(secondary, 0.16)}, transparent 30%)`, + `radial-gradient(circle at right 18%, ${alpha(primary, 0.2)}, transparent 26%)`, + "linear-gradient(180deg, #0b1020 0%, #111a2b 100%)" + ].join(", ") + : [ + `radial-gradient(circle at top left, ${alpha(secondary, 0.22)}, transparent 34%)`, + `radial-gradient(circle at right 20%, ${alpha(primary, 0.2)}, transparent 28%)`, + "linear-gradient(180deg, #faf6ef 0%, #f3eee4 100%)" + ].join(", "), + color: textPrimary + } + } + }, + MuiCard: { + styleOverrides: { + root: { + borderRadius: 28, + border: `1px solid ${alpha(textPrimary, isDark ? 0.12 : 0.08)}`, + boxShadow: isDark + ? `0 24px 64px ${alpha("#000000", 0.34)}` + : `0 18px 48px ${alpha(primary, 0.12)}` + } + } + }, + MuiButton: { + defaultProps: { + disableElevation: true + }, + styleOverrides: { + root: { + borderRadius: 999, + paddingInline: 18 + } + } + }, + MuiChip: { + styleOverrides: { + root: { + borderRadius: 999 + } + } + }, + MuiPaper: { + styleOverrides: { + root: { + backgroundImage: "none" + } + } + } + } + }); +} + +export const appTheme = getAppTheme("light"); diff --git a/src/types/next-auth.d.ts b/src/types/next-auth.d.ts new file mode 100644 index 0000000..908a6f6 --- /dev/null +++ b/src/types/next-auth.d.ts @@ -0,0 +1,32 @@ +import type { ApprovalType, Role } from "@prisma/client"; +import type { DefaultSession } from "next-auth"; + +declare module "next-auth" { + interface Session { + user: { + id: string; + username: string; + role: Role; + workingGroupId: string | null; + approvalPreference: ApprovalType | null; + } & DefaultSession["user"]; + } + + interface User { + id: string; + username: string; + role: Role; + workingGroupId: string | null; + approvalPreference: ApprovalType | null; + } +} + +declare module "next-auth/jwt" { + interface JWT { + id?: string; + username?: string; + role?: Role; + workingGroupId?: string | null; + approvalPreference?: ApprovalType | null; + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..3ce8e47 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "ES2017", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": false, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} +