Commit Graph
6 Commits
Author SHA1 Message Date
Nick Szaunig 7b23862a41 feat: expand backup to all data and add automatic scheduled backups
Backend Image / build-and-push (push) Successful in 2m16s
Frontend Image / build-and-push (push) Successful in 1m56s
Backup export/import now covers Role, User, RolePermission,
Notification, AuditLog and Document (with actual file content), not
just business data - matching "wirklich alle Daten". Role/User use
natural keys (role.key, resource+action) so a bundle restores cleanly
into a different database.

Adds BackupSchedulerService (@nestjs/schedule) for cron-based automatic
backups to a local path (BACKUP_STORAGE_PATH), with retention pruning
and a file-mtime guard against duplicate runs across replicas. New
GET /backup/schedule and POST /backup/schedule/run-now endpoints, plus
a status card and manual trigger in the frontend Backup settings page.
2026-09-03 11:33:48 +02:00
Nick Szaunig 8432313fa9 feat: Profilseite, Etikettendruck mit QR-Code, mehr Automatisierungen und Entra-ID-SSO
Backend Image / build-and-push (push) Successful in 2m28s
Frontend Image / build-and-push (push) Successful in 2m10s
- Profilseite mit MFA-Einrichtung, Passwort/E-Mail/Name aendern, Konto deaktivieren
- Bearbeiten-Buttons fuer Bienenstaende/Voelker/Koeniginnen/Aufgaben-Datensaetze
- Restliche englische Enum-Werte durch deutsche Labels ersetzt (SelectValue-Fix)
- Sidebar-Eintraege fuer Ernten/Schleuderungen ergaenzt
- Automatisierungen von 3 auf 6 Regeln erweitert (Schwarmstimmung, kritischer Gesundheitsstatus, Lagerbestand)
- Responsive Grid-Layout fuer Volk-/Koeniginnen-/Honigchargen-/Bienenstand-Detailseiten
- Etikettenvorlagen mit Platzhaltern inkl. QR-Code (verweist auf Herkunftsseite) und PDF-Druck
- Entra-ID-SSO (Authorization Code + PKCE, kein Auto-Provisioning, Secrets nur ueber Environment-Variablen)
2026-08-31 18:56:08 +02:00
Nick Szaunig f1298eff08 fix: harden auth against brute force, add auth audit logging, fix cookie/TLS gaps
Security review findings (HIGH-1/2/3, MEDIUM):

- Rate limiting via @nestjs/throttler: global 100 req/min default, stricter
  10 req/min on login and refresh. Also closes the MEDIUM finding (public
  batch-lookup enumeration) since it now sits behind the global limit too.
  Trust the K8s ingress's single proxy hop so throttling keys off the real
  client IP, not the ingress pod's IP.
- Auth events (login success/failure, logout, token refresh) are now
  audit-logged via new AuditAction values, closing the gap where the
  project's own audit-log principle never actually covered the Auth module.
- Refresh-token cookie now defaults to Secure=true (opt out only via
  COOKIE_SECURE=false for local HTTP dev), instead of keying off NODE_ENV
  which was never set in the K8s deploy templates. Added a TLS block +
  cert-manager annotation to both the backend and frontend ingress
  templates, which previously had no HTTPS termination configured at all.
2026-08-25 10:49:25 +02:00
Nick Szaunig 4a9fdd5c71 feat(backend): Dokumente und Bilder mit lokalem Datei-Upload (Modul 29)
DocumentsModule (Document: entityType/entityId, Dateiname, MIME-Typ,
Groesse, Speicherpfad, Hochgeladen-von) fuer Bienenstand/Volk/Koenigin/
Durchsicht/Honigcharge. Upload als multipart/form-data (Multer, 10 MB
Limit, MIME-Allowlist jpeg/png/webp/pdf), Speicherung unter
DOCUMENTS_STORAGE_PATH (austauschbar). ARCHITECTURE.md Annahme 7
dokumentiert die Multi-Replica-Einschraenkung ohne geteiltes Volume.
2026-08-23 11:29:22 +02:00
Nick Szaunig 029484f9d5 feat(frontend): Login + Benutzerverwaltung (Modul 1)
/login: Formular gegen AuthProvider (Access-Token im Memory, Refresh
per httpOnly-Cookie), Fehlermeldung bei falschen Zugangsdaten.

(app)/layout.tsx: geschuetztes Layout, leitet ohne Session zu /login um,
Header mit Nutzer-E-Mail + Abmelden. settings/layout.tsx: zusaetzliches
Admin-Gate fuer /settings/users.

/settings/users: Liste, Anlegen-Dialog (shadcn/Base UI Dialog+Select),
Deaktivieren - alles ueber TanStack Query gegen die Users-API.

proxy.ts (Next 16 Nachfolger von middleware.ts): optimistische
Cookie-Praesenz-Pruefung fuer /login und /settings/*, echte
Autorisierung bleibt serverseitig (RolesGuard).

Backend-Fixes waehrend Browser-Verifikation gefunden und behoben:
- CORS fehlte komplett (app.enableCors, FRONTEND_ORIGIN) - jeder
  Cross-Origin-Request von :3000 nach :3001 wurde geblockt.
- React-StrictMode-Doppel-Effect liess zwei parallele Refresh-Aufrufe
  laufen; da Refresh-Tokens rotierend/einmalig sind, gewann einer und
  der andere bekam 401 -> Nutzer flog nach jedem Reload aus der Session.
  Fix: AbortController im Session-Restore-Effect.
- Manifest verwies auf nicht existente PNG-Icons (404); durch
  public/icon.svg ersetzt.

7 Vitest-Tests (Login-Formular, Users-Liste, JWT-Decode), Lint,
Typecheck und Build gruen. Kompletter Flow (Login, Reload-Persistenz,
Benutzer anlegen/deaktivieren, Abmelden, Redirect ohne Session) live
im Browser gegen den echten Server verifiziert.
2026-08-21 08:45:37 +02:00
Nick Szaunig eae3fea957 feat: Grundgeruest fertigstellen (Backend/Frontend/K8s)
Backend: Prisma-Client auf prisma-client-js + Driver-Adapter (@prisma/adapter-pg)
umgestellt (Prisma 7 verlangt Adapter, ESM-Client brach an Jest), erste Migration
erzeugt und angewendet, /api/v1 Versioning, Swagger unter /api/v1/docs, Helmet,
globale ValidationPipe, PrismaModule, HealthModule (/health, /health/ready mit
DB-Check), tsconfig.build.json Root-Dir-Fix (dist/main.js statt dist/src/main.js).

Frontend: Tailwind v4 + shadcn/ui initialisiert, TanStack Query Provider, PWA
Manifest (app/manifest.ts), Vitest + Testing Library Setup, next.config output
standalone.

deploy/k8s: Dockerfiles (Backend/Frontend, Multi-Stage) + Deployment/Service/
Ingress/ConfigMap/Secret-Vorlagen fuer beide Projekte.

Lokale Dev-/Test-Postgres-Instanz unter ApiCore-Backend/.devdb angelegt (eigene
Rolle, kein bestehendes Passwort noetig), .env/.env.test lokal befuellt.

Lint, Typecheck, Tests und Build sind fuer Backend und Frontend gruen; Server
wurde lokal gestartet und /health, /health/ready, /api/v1/docs manuell verifiziert.
2026-08-21 05:17:26 +02:00