Go to file
Weapie e7d8d1a856
All checks were successful
check / verify (push) Successful in 3m30s
check / publish (push) Successful in 3m4s
Release 1.0.1
2026-10-08 15:41:59 +02:00
.claude Init commit 2025-11-12 17:16:01 +01:00
.github/workflows Fail early when Gitea advertises an insecure registry token endpoint 2026-10-08 08:45:52 +02:00
deploy Implement scoped RBAC, harden security and add verified Docker demo 2026-10-06 08:02:56 +02:00
prisma feat: separate checklist editing permission from task updates 2026-10-08 15:36:54 +02:00
public Implement scoped RBAC, harden security and add verified Docker demo 2026-10-06 08:02:56 +02:00
scripts Clarify forwarded protocol precedence in Gitea registry diagnostics 2026-10-08 09:00:49 +02:00
src feat: separate checklist editing permission from task updates 2026-10-08 15:36:54 +02:00
tests feat: separate checklist editing permission from task updates 2026-10-08 15:36:54 +02:00
.dockerignore Implement scoped RBAC, harden security and add verified Docker demo 2026-10-06 08:02:56 +02:00
.env.example Document production rollout and verify complete legacy data migration 2026-10-06 16:03:50 +02:00
.env.production.example Release 1.0.1 2026-10-08 15:41:59 +02:00
.gitignore Implement scoped RBAC, harden security and add verified Docker demo 2026-10-06 08:02:56 +02:00
API_DOCUMENTATION.md Implement scoped RBAC, harden security and add verified Docker demo 2026-10-06 08:02:56 +02:00
audit-review.json Implement scoped RBAC, harden security and add verified Docker demo 2026-10-06 08:02:56 +02:00
components.json Init commit 2025-11-12 17:16:01 +01:00
docker-compose.demo.yml Implement scoped RBAC, harden security and add verified Docker demo 2026-10-06 08:02:56 +02:00
docker-compose.production.direct.yml deploy: run administrator seed after access and upload migrations 2026-10-08 14:48:49 +02:00
docker-compose.production.yml deploy: run administrator seed after access and upload migrations 2026-10-08 14:48:49 +02:00
docker-compose.registry.yml Publish versioned Docker images to Gitea after container-network CI checks 2026-10-07 10:44:34 +02:00
docker-compose.yml deploy: run administrator seed after access and upload migrations 2026-10-08 14:48:49 +02:00
Dockerfile Implement scoped RBAC, harden security and add verified Docker demo 2026-10-06 08:02:56 +02:00
eslint.config.mjs Implement scoped RBAC, harden security and add verified Docker demo 2026-10-06 08:02:56 +02:00
IMPLEMENTATION.md Document production rollout and verify complete legacy data migration 2026-10-06 16:03:50 +02:00
next.config.ts Implement scoped RBAC, harden security and add verified Docker demo 2026-10-06 08:02:56 +02:00
package-lock.json Release 1.0.1 2026-10-08 15:41:59 +02:00
package.json Release 1.0.1 2026-10-08 15:41:59 +02:00
playwright.config.ts Implement scoped RBAC, harden security and add verified Docker demo 2026-10-06 08:02:56 +02:00
postcss.config.mjs Init commit 2025-11-12 17:16:01 +01:00
prisma.config.ts Implement scoped RBAC, harden security and add verified Docker demo 2026-10-06 08:02:56 +02:00
PRODUCTION.md Release 1.0.1 2026-10-08 15:41:59 +02:00
README.Docker.md Document production rollout and verify complete legacy data migration 2026-10-06 16:03:50 +02:00
README.md Release 1.0.1 2026-10-08 15:41:59 +02:00
REGISTRY.md deploy: run administrator seed after access and upload migrations 2026-10-08 14:48:49 +02:00
REVIEW.md Implement scoped RBAC, harden security and add verified Docker demo 2026-10-06 08:02:56 +02:00
SECURITY.md Implement scoped RBAC, harden security and add verified Docker demo 2026-10-06 08:02:56 +02:00
start.sh Implement scoped RBAC, harden security and add verified Docker demo 2026-10-06 08:02:56 +02:00
startup.sh Implement scoped RBAC, harden security and add verified Docker demo 2026-10-06 08:02:56 +02:00
tailwind.config.ts Implement scoped RBAC, harden security and add verified Docker demo 2026-10-06 08:02:56 +02:00
TESTBETRIEB.md Implement scoped RBAC, harden security and add verified Docker demo 2026-10-06 08:02:56 +02:00
tsconfig.json Init commit 2025-11-12 17:16:01 +01:00
typecheck-review.txt Implement scoped RBAC, harden security and add verified Docker demo 2026-10-06 08:02:56 +02:00
UPGRADE.md Release 1.0.1 2026-10-08 15:41:59 +02:00
UX-ABNAHME.md Redesign workspace with shadcn workflows and complete group management 2026-10-06 13:43:01 +02:00

Aufgabenplaner – Installation, Produktivbetrieb und Upgrade

Aufgabenverwaltung mit Next.js, PostgreSQL, privaten Anhängen und RBAC aus Benutzern, Gruppen, Rollen und einzelnen Berechtigungen. Die Oberfläche nutzt shadcn/Radix und Lucide; Aufgaben sind als Liste, Kanban oder Monatsagenda verfügbar.

Eine bestehende Installation wird aktualisiert, nicht neu initialisiert. Benutzer, Passwort-Hashes, Aufgaben, Status, Zuweisungen, Beauftragungsdaten, Kommentare und Anhänge werden übernommen. Die neue Version darf erst nach erfolgreicher Migration und Abnahme öffentlich erreichbar sein. Für den Umstieg einer produktiven Altinstallation zuerst die vollständige Upgrade-Anleitung lesen.

Inhalt

Funktionen

Aufgaben mit Suche, Filtern, Prioritäten, Tags, Projekten, Standorten, Checklisten, Kommentaren, Unteraufgaben, Abhängigkeiten und Wiederholungen. Zuweisung an Personen oder Teampool, Archiv/Wiederherstellung, Stapelaktionen, Vorlagen und gespeicherte Ansichten. CSV-/XLSX-Import mit Vorschau, CSV-/XLSX-/ICS-Export, widerrufbare Kalenderlinks, API-Tokens, signierte Webhooks, Audit und Erinnerungen. Benutzer und Gruppen lassen sich verwalten; Löschungen erfordern Bestätigung und unterliegen serverseitigen Schutzregeln.

Voraussetzungen

  • Linux-Server mit Docker Engine und Docker Compose v2; ausreichend Speicher für PostgreSQL, Anhänge, Builds und mindestens eine vollständige Sicherung. Kapazität mit dem eigenen Datenbestand prüfen.
  • PostgreSQL 16 (im Compose enthalten). Kein gleichzeitiger PostgreSQL-Major-Versionswechsel beim Anwendungsupgrade.
  • Öffentlich erreichbare HTTPS-Domain und Reverse Proxy. Beispiel: deploy/nginx.conf.example.
  • Repository-Zugriff und administrativer Zugriff auf die eigenen Docker-Volumes/Backups.
  • Für lokale Entwicklung: Node.js 22+, npm und PostgreSQL 16. Docker nutzt Node 22.

Die folgenden Serverbefehle verwenden Bash. Alle Befehle im Checkout ausführen. .env, Backups und Produktivdaten gehören nicht ins Git. Das öffentliche TLS-Zertifikat und die Proxy-Konfiguration sind betreiberspezifisch.

Neuinstallation

Nur für eine leere Installation. Bei vorhandenen Daten stattdessen UPGRADE.md verwenden.

git clone https://git.jfritzsche.de/jf/taskmanager.git
cd taskmanager
git switch main
cp .env.example .env
chmod 600 .env
openssl rand -hex 32  # als NEXTAUTH_SECRET eintragen
openssl rand -hex 24  # als Datenbankpasswort verwenden

.env bearbeiten, mindestens:

POSTGRES_PASSWORD=HIER_ZUFAELLIGES_DATENBANKPASSWORT
DATABASE_URL=postgresql://taskmanager:HIER_ZUFAELLIGES_DATENBANKPASSWORT@db:5432/taskmanager
NEXTAUTH_URL=https://aufgaben.example.org
NEXTAUTH_SECRET=HIER_ZUFAELLIGES_SECRET_MIT_MINDESTENS_32_ZEICHEN
ALLOW_LOCAL_HTTP=false
APP_TIMEZONE=Europe/Berlin
ARCHIVE_RETENTION_DAYS=0
BOOTSTRAP_EMAIL=admin@example.org
BOOTSTRAP_PASSWORD=HIER_EINMALPASSWORT_MIT_MINDESTENS_12_ZEICHEN

Passwörter in DATABASE_URL müssen URL-kodiert sein; die oben generierten Hexwerte benötigen keine Sonderbehandlung. POSTGRES_PASSWORD ist der unveränderte Passwortwert. Variablen mit $ in .env passend einfach quotieren, um Compose-Interpolation zu verhindern.

docker compose -p taskmanager build
docker compose -p taskmanager up -d --wait db
docker compose -p taskmanager run --rm migrate

Der Migrationsdienst führt auch die Seeds aus: RBAC über migrate-access.ts, danach Administrator-Bootstrap über prisma/seed.ts. Bootstrap-Werte danach aus .env entfernen. Seed legt ausschließlich bei fehlendem Administrator einen neuen an; keine Standardzugänge. Das Startpasswort muss bei der ersten Anmeldung geändert werden.

docker compose -p taskmanager up -d --wait app worker
curl --fail http://127.0.0.1:3000/api/health

Proxy auf 127.0.0.1:3000 richten, Domain/Zertifikate einrichten, /uploads/ sperren, HTTPS erzwingen. Wenn der Proxy selbst in Docker läuft, sein Netz und Upstream ausdrücklich anpassen: dessen 127.0.0.1 ist nicht der Host. Erst nach der Abnahme unten freigeben.

Konfiguration

Variable Bedeutung / Produktionswert
DATABASE_URL PostgreSQL-Verbindung; in Compose db:5432, außerhalb die tatsächliche Adresse.
POSTGRES_PASSWORD Passwort des Compose-DB-Benutzers taskmanager. Bei vorhandenem Volume muss es zum tatsächlich gesetzten DB-Passwort passen. Eine Änderung der Variable allein ändert das DB-Passwort nicht.
POSTGRES_DB Optional, Standard taskmanager; auch DATABASE_URL anpassen.
NEXTAUTH_URL Externe HTTPS-Adresse, keine interne Containeradresse.
NEXTAUTH_SECRET Zufällig, mindestens 32 Zeichen; sichern. Wechsel meldet Sitzungen ab.
APP_TIMEZONE Gültige Zeitzone, Standard Europe/Berlin.
UPLOAD_DIR Compose setzt /app/private-uploads. Bei Betrieb ohne Docker absoluten privaten Pfad verwenden.
LEGACY_UPLOAD_DIR Nur Migration. Compose verwendet dasselbe private Volume als Wurzel der übernommenen alten Upload-Verzeichnisstruktur. Ohne Compose explizit auf das alte public/uploads setzen.
GROUP_UPLOAD_QUOTA_MB Upload-Quota pro Gruppe; Standard 1024 MB. An Bestandsvolumen anpassen.
TRUST_PROXY Nur true, wenn der vertrauenswürdige Proxy x-real-ip ersetzt und direkter externer Zugriff ausgeschlossen ist.
ALLOW_LOCAL_HTTP Produktion false; nur lokale Tests dürfen Loopback-HTTP freischalten.
ARCHIVE_RETENTION_DAYS 0 bewahrt Archive unbegrenzt. Ab 30 werden archivierte erledigte Aufgaben nach Frist endgültig gelöscht.
SMTP_URL, MAIL_FROM Gemeinsam setzen, um Einladung, Passwort-Reset und Benachrichtigungen zu aktivieren. Ohne SMTP Konten mit Einmalpasswort anlegen.
OIDC_ISSUER, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET Optional gemeinsam konfigurieren. Callback: https://DOMAIN/api/auth/callback/oidc.
OIDC_REQUIRED_ACR Optional erwarteter ACR-Wert; MFA zusätzlich im Identity Provider erzwingen.
WEBHOOK_ALLOWED_HOSTS Kommagetrennte exakte öffentliche HTTPS-Hosts; keine Wildcards.
BOOTSTRAP_EMAIL, BOOTSTRAP_PASSWORD Ausschließlich einmalig bei Neuinstallation. Passwort 12 Zeichen bis 72 UTF-8-Bytes.
TASKMANAGER_ENV_FILE Optional anderer Pfad statt .env für die Container. Für Compose-Variablen zusätzlich --env-file PFAD verwenden.

Die alte Role-Spalte bleibt als Migrationsinformation erhalten; sie steuert keine Berechtigungen mehr. OIDC-Konten werden ausdrücklich über den Provider-Subject verknüpft, nicht automatisch über gleiche E-Mail-Adressen. Danach ist ihre lokale Passwortanmeldung gesperrt.

Berechtigungen

  • ASSIGNED: Zugriff auf dem Benutzer zugewiesene Aufgaben.
  • GROUP: Zugriff auf Aufgaben der jeweiligen Gruppe; direkte Gruppenrollen benötigen eine aktive Mitgliedschaft.
  • GLOBAL: Zugriff unabhängig von der Gruppe. Verwaltungsrechte sind ausschließlich global zulässig.

Rollen bündeln Permissions; Benutzer erhalten sie direkt oder über Gruppen. Fehlende Rechte werden serverseitig abgewiesen, auch bei Dateien und Exporten. Systemadministrator wird ausschließlich direkt vergeben; mindestens ein aktiver Administrator muss erhalten bleiben. Benutzerpflege verleiht nicht automatisch Rechteverwaltung.

Für den Teampool einer Gruppe „Teampool lesen und übernehmen“ mit GROUP und „Bearbeiter“ mit ASSIGNED zuweisen. Koordinatoren erhalten für die Bearbeitung eigener Aufgaben zusätzlich „Bearbeiter“. Gruppen mit bestehenden Aufgaben lassen sich nicht löschen; Aufgaben vorher umordnen oder die Gruppe deaktivieren.

Die genaue Zuordnung alter Rollen und die erforderliche organisatorische Nachprüfung stehen in UPGRADE.md.

Betrieb und Datensicherung

Dienste

  • db: persistentes PostgreSQL-Volume postgres_data.
  • migrate: Schema-, Rollen- und Anhangsmigration; beendet sich bei Erfolg mit Exitcode 0. Bei Fehler startet app nicht.
  • app: Next.js, UID/GID 1001, schreibgeschütztes Root-Dateisystem, privates uploads-Volume; Port nur am Host-Loopback.
  • worker: genau eine Instanz für Erinnerungen, Wiederholungen, Zustellung und Bereinigung. Gleiches privates Upload-Volume wie app und migrate.
docker compose -p taskmanager ps -a
docker compose -p taskmanager logs --tail=100 migrate app worker

/api/health prüft die DB-Verbindung. Worker-Heartbeat prüft, ob Durchläufe stattfinden. unhealthy extern alarmieren: Docker startet allein aufgrund dieses Status nicht neu. Auf freien Speicher, PostgreSQL-Backups, Zustellfehler und Backup-Alter überwachen. Genau eine Migration gleichzeitig ausführen; bei Updates App und Worker vorher stoppen.

Konsistentes Backup (Bash)

Projektname an die tatsächliche Installation anpassen; vorab docker compose ... ps kontrollieren. Der kurze Stopp verhindert auseinanderlaufende Datenbank-/Dateisicherungen. Folgender Ablauf setzt normalerweise laufende App und Worker voraus:

mkdir -p backups
BACKUP_DIR="$(pwd)/backups/$(date -u +%Y%m%dT%H%M%SZ)"
mkdir -m 700 "$BACKUP_DIR"
docker compose -p taskmanager stop -t 60 app worker
# Bei JEDEM Fehler hier angehalten lassen, Fehler prüfen und Dienste bewusst wieder starten.
docker compose -p taskmanager exec -T db sh -c 'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Fc' > "$BACKUP_DIR/database.dump"
docker compose -p taskmanager run --rm --no-deps --user 0:0 \
  -v "$BACKUP_DIR:/backup" worker tar -czf /backup/uploads.tar.gz -C /app/private-uploads .
cp .env "$BACKUP_DIR/environment.env"
(cd "$BACKUP_DIR" && sha256sum database.dump uploads.tar.gz environment.env > SHA256SUMS)
docker compose -p taskmanager start app worker

Jeden Exitcode prüfen, insbesondere vor Neustart; Skripte mit set -euo pipefail ausführen. PowerShell-Alternative: scripts/backup.ps1 -Project taskmanager -EnvFile .env; diese startet vorher laufende Dienste auch bei Fehlern wieder. .env zusätzlich geschützt sichern. Backups verschlüsselt außerhalb des Servers lagern, Zugriffsrechte begrenzen und regelmäßig in einer separaten Instanz wiederherstellen. SHA-256 prüft Integrität, ersetzt keine Verschlüsselung.

Updates und Wiederherstellung

Den getesteten Commit festhalten, Images bauen, Wartungsfenster aktivieren, konsistentes Backup erstellen, Dienste stoppen, docker compose ... run --rm migrate, anschließend up -d --wait app worker. Niemals prisma migrate reset, db push --accept-data-loss oder docker compose down -v auf Bestandsdaten verwenden.

Restore und Rollback stehen mit konkreten Befehlen in UPGRADE.md. Schemaänderungen werden nicht durch Start eines älteren Images rückgängig gemacht. Nach Freigabe entstandene Änderungen beim Rollback gesondert berücksichtigen.

Abnahme und Fehlerbehebung

Vor Freigabe prüfen:

  1. Migration Exitcode 0, db, app, worker healthy; HTTPS und richtige externe URL.
  2. Anzahl Benutzer/Aufgaben/Kommentare/Dateien mit dem Backup vergleichen; alte Beauftragungsdaten und Anhänge stichprobenartig prüfen.
  3. Bestehender Administrator und Bearbeiter können sich nach erneuter Anmeldung anmelden. Rollen und Gruppenzugriff prüfen.
  4. Fremde Aufgaben/Dateien sind ohne Berechtigung gesperrt; Rechteentzug greift sofort.
  5. Aufgabe erstellen, bearbeiten, zuweisen, erledigen, archivieren und wiederherstellen; Kommentar sowie Upload/Download prüfen.
  6. /uploads/... liefert keine Altdateien; Proxy bedient das Verzeichnis ebenfalls nicht statisch.
  7. SMTP, OIDC/MFA und Webhooks bei Verwendung mit echten Zielsystemen separat prüfen. Restore erfolgreich üben.
Problem Vorgehen
P3005 / vorhandene DB ohne Migrationshistorie Baseline nur nach Schemaabgleich, siehe Upgrade-Anleitung. Nicht zurücksetzen.
Doppelte normalisierte E-Mails Beide Konten erhalten und eindeutige echte Adressen festlegen; kein automatisches Zusammenführen. Danach Migration erneut starten.
ENOENT, Größen-/Inhaltsprüfung eines Anhangs Volume/Verzeichnisstruktur und Originalbackup prüfen. Fehlende Bytes können nicht rekonstruiert werden. Keine File-Zeilen löschen, um die Prüfung zu umgehen.
EACCES Eigentümer/Rechte des privaten Volumes für UID/GID 1001 prüfen. Nicht pauschal 777 vergeben.
Leere Daten nach Umstieg Projekt-/Volume-Namen und DATABASE_URL vergleichen; häufig wurde ein neues leeres Volume eingebunden. Nicht seeden, bevor die Quelle geklärt ist.
Login-Schleife / Cookie fehlt NEXTAUTH_URL, HTTPS und Proxy prüfen; nach Migration alte Sitzung abmelden.
Worker unhealthy Logs, DB-Erreichbarkeit, Platz, Konfiguration und Heartbeat prüfen.

Grenzen

Anhänge: PDF/JPEG/PNG/DOCX/XLSX, maximal 10 MB, tatsächlicher Inhalt wird geprüft. Nicht erkannte oder früher fälschlich akzeptierte Bestandsdateien bleiben erhalten und stoppen die Übernahme bis zur Klärung. Nicht referenzierte Altdateien bleiben im privaten Volume und werden nicht als Aufgabenanhang erfunden.

CSV/XLSX: 100 Zeilen/100 KB, keine Formeln; Batch: 50 Aufgaben mit möglichen Teilerfolgen; Export: 5000 Aufgaben. Kalenderseite ist eine Monatsagenda. Keine Offline-Datenkopien und keine native lokale MFA. E-Mail/Webhooks können nach einem Absturz doppelt zugestellt werden; Empfänger müssen deduplizieren. Audit ist kein externes manipulationssicheres Archiv. Malware-Scanning, TLS, externe Sicherung und Monitoring sind Betreiberaufgaben. Aktuelle Abhängigkeitsbefunde: SECURITY.md.

Entwicklung und Tests

npm ci
npx prisma generate
npx prisma migrate deploy
npx tsx scripts/migrate-access.ts
npx tsx scripts/migrate-uploads.ts
npm run dev
# separat:
npm run worker

Bei einer leeren Entwicklungsdatenbank einmalig Bootstrap-Werte setzen und npm run prisma:seed ausführen. Für Checks:

npm run typecheck
npm run lint
npm test
npm run build

Integration und Playwright nur gegen dedizierte taskmanager_review-DB, niemals Produktion: npm run test:integration, npx playwright install chromium, npx playwright test. Playwright nutzt Port 3107. Bei Proxy NO_PROXY=localhost,127.0.0.1 setzen.

Der reproduzierbare Altversions-Upgrade-Test verwendet ausschließlich eine leere Datenbank taskmanager_upgrade_test: DATABASE_URL=... npx tsx --test tests/upgrade.test.ts. Er legt das ursprüngliche Schema und Bestandsdaten an, prüft alle alten Aufgabenfelder, Konten, Kommentare, Anhangsbytes, Rollen und Wiederholbarkeit. Er lässt die Testdatenbank zur Kontrolle stehen; ein weiterer Lauf benötigt erneut eine leere Testdatenbank.

Lokale Vorführung: TESTBETRIEB.md. API: API_DOCUMENTATION.md. Oberfläche und Abnahme: UX-ABNAHME.md. Technischer Prüfstand: IMPLEMENTATION.md.