git commit -m "feat(workspace): inventory overview, auth, persistent h2 db, users & roles - add inventory overview endpoint (aggregated stock per SKU) - implement inventory movements (production, sale, return, adjustment) - add session-based login with Spring Security (form login) - protect /api/** endpoints - add logout with session invalidation - introduce user roles (ADMIN, WORKER) and active flag - seed admin user in dev profile - switch from H2 in-memory to persistent H2 file database - enable H2 console for development - add Next.js workspace UI (inventory table, filters, movements) - support active/inactive products and users (soft disable)"
274 lines
6.6 KiB
Plaintext
274 lines
6.6 KiB
Plaintext
VOYAGE – Nächste Projektschritte (Workspace + Login + Webblog) – UPDATE 2026-01-21
|
||
===============================================================================
|
||
|
||
Ziel
|
||
----
|
||
Ein internes Workspace-System mit Login + Webinterface
|
||
und ein separates öffentliches Webblog für Content & Brand.
|
||
|
||
|
||
Aktueller Stand
|
||
---------------
|
||
Bereits implementiert:
|
||
- Products
|
||
- SKUs (Varianten)
|
||
- InventoryMovements (Bestandsbuchungen)
|
||
- Current Stock pro SKU (Aggregation)
|
||
- Inventory Overview Endpoint (GET /api/inventory/overview)
|
||
- Workspace UI (Next.js, minimal)
|
||
- Login-System (Spring Security, Form Login, Session)
|
||
- /api/** ist geschützt (nur eingeloggt)
|
||
- Login per Browser (/login) und per curl (Cookie/JSESSIONID) funktioniert
|
||
- Logout invalidiert Session + löscht JSESSIONID
|
||
|
||
Damit ist das Domain-Fundament + Zugriffsschutz + UI-taugliche API abgeschlossen.
|
||
|
||
|
||
Wichtiger Hinweis zur Datenbank (AKTUELLER ZUSTAND)
|
||
---------------------------------------------------
|
||
Die Anwendung verwendet NICHT MEHR eine In-Memory Datenbank.
|
||
|
||
Aktueller Stand:
|
||
- H2 File-basierte Datenbank (persistent)
|
||
- JDBC URL: jdbc:h2:file:./data/voyage-db;AUTO_SERVER=TRUE
|
||
- Daten liegen auf der Festplatte (data/voyage-db.mv.db)
|
||
- KEIN Datenverlust bei App-Restart
|
||
|
||
Wichtig:
|
||
- Die DB überlebt Neustarts
|
||
- IDs (productId, skuId, userId) bleiben stabil
|
||
- AUTO_SERVER erlaubt parallelen Zugriff (App + H2 Console)
|
||
|
||
SEHR WICHTIG:
|
||
- Das H2 Passwort wird beim ERSTEN Start festgelegt
|
||
- Danach MUSS es gleich bleiben
|
||
- Falsches Passwort → App startet NICHT (Error 28000)
|
||
|
||
Empfohlene Config:
|
||
- Username: sa
|
||
- Password: leer (oder exakt das beim ersten Start gesetzte)
|
||
|
||
H2 Console:
|
||
- URL: http://localhost:8080/h2-console
|
||
- JDBC URL: jdbc:h2:file:./data/voyage-db;AUTO_SERVER=TRUE
|
||
- User: sa
|
||
- Password: (leer oder wie initial gesetzt)
|
||
|
||
H2 Login ≠ Workspace Login (komplett getrennt)
|
||
|
||
|
||
Grundprinzip
|
||
------------
|
||
Workspace (intern) und Public Website (Blog) sind zwei verschiedene Welten
|
||
und sollten technisch getrennt sein.
|
||
|
||
- Workspace = interne Realität (Inventory, Orders, Drops)
|
||
- Public Web = Content, Blog, Brand (keine sensiblen Daten)
|
||
|
||
|
||
Empfohlene Architektur
|
||
----------------------
|
||
|
||
1) workspace-api (Spring Boot)
|
||
- Products / SKUs / Inventory
|
||
- Inventory Overview (aggregiert)
|
||
- Auth & Rollen
|
||
- persistente DB
|
||
- später Orders / Drops
|
||
|
||
2) workspace-ui (Webinterface)
|
||
- internes Dashboard (Next.js)
|
||
- spricht mit workspace-api
|
||
- nutzt Session-Cookies (Browser)
|
||
|
||
3) public-web (Blog / Brand)
|
||
- öffentlich zugänglich
|
||
- kein Login nötig
|
||
- getrennt vom Workspace
|
||
|
||
|
||
Repo-Struktur
|
||
-------------
|
||
voyage/
|
||
├─ apps/
|
||
│ ├─ workspace-api/ (Backend)
|
||
│ ├─ workspace-ui/ (internes UI)
|
||
│ └─ public-web/ (Blog / Brand)
|
||
└─ packages/
|
||
└─ shared/ (optional: DTOs / Types)
|
||
|
||
|
||
Empfohlene Reihenfolge (sehr wichtig)
|
||
-------------------------------------
|
||
|
||
SCHRITT 1: Login-System für Workspace
|
||
------------------------------------
|
||
Status: ERLEDIGT ✅
|
||
|
||
Ziel:
|
||
- Zugriff auf /api/** nur für eingeloggte Nutzer
|
||
- Workspace nicht öffentlich zugänglich
|
||
|
||
Implementiert:
|
||
- Spring Security
|
||
- Form Login
|
||
- Session-basiert (kein JWT)
|
||
- Logout mit Session-Invalidierung
|
||
- Redirect zurück ins Workspace UI
|
||
|
||
User-Modell:
|
||
- UserAccount in DB
|
||
- Rollen: ADMIN / WORKER
|
||
- active Flag (true / false)
|
||
|
||
Inactive User:
|
||
- kann sich NICHT einloggen
|
||
- bleibt für Historie erhalten
|
||
|
||
|
||
SCHRITT 2: Workspace-taugliche Endpoints
|
||
----------------------------------------
|
||
Status: ERLEDIGT ✅
|
||
|
||
Implementiert:
|
||
- GET /api/inventory/overview
|
||
|
||
Liefert pro SKU:
|
||
- Produktname
|
||
- Kategorie
|
||
- Größe / Farbe
|
||
- Preis
|
||
- Aktueller Bestand (SUM der InventoryMovements)
|
||
|
||
Bedeutung:
|
||
- Ein Request = komplette Inventory Tabelle
|
||
- Keine Aggregation im Frontend nötig
|
||
- Grundlage für UI, Low-Stock, Drops
|
||
|
||
|
||
SCHRITT 3: Workspace UI (minimal starten)
|
||
-----------------------------------------
|
||
Status: ERLEDIGT (MINIMAL) ✅
|
||
|
||
Implementiert:
|
||
- Inventory Übersicht
|
||
- Tabelle mit allen SKUs + currentStock
|
||
- Suche & Filter (Name, SKU, Kategorie)
|
||
- Inventory Movements (+ / -)
|
||
- SALE erzeugt negatives Delta
|
||
- PRODUCTION positives Delta
|
||
|
||
Ergebnis:
|
||
Ein echtes internes Tool, sofort nutzbar.
|
||
|
||
|
||
SCHRITT 4: Active / Inactive statt Löschen
|
||
------------------------------------------
|
||
Status: IMPLEMENTIERT / EMPFOHLEN ✅
|
||
|
||
Grundregel:
|
||
- NIEMALS löschen, wenn Historie existiert
|
||
|
||
Umsetzung:
|
||
- Products und SKUs haben active Flag
|
||
- active = false:
|
||
- wird im Workspace ausgeblendet
|
||
- bleibt in DB für Historie
|
||
|
||
Beispiel:
|
||
- Caps werden nicht mehr verkauft
|
||
- Product/SKUs auf inactive setzen
|
||
- Inventory bleibt korrekt nachvollziehbar
|
||
|
||
|
||
SCHRITT 5: Worker-User
|
||
---------------------
|
||
Status: IMPLEMENTIERT (Basis) ✅
|
||
|
||
User-Typen:
|
||
- ADMIN: volle Rechte, Userverwaltung
|
||
- WORKER: Inventory sehen & buchen
|
||
|
||
Worker anlegen:
|
||
- per Admin Endpoint oder DB
|
||
- Passwort wird BCrypt-gehasht
|
||
- active = true notwendig
|
||
|
||
Worker deaktivieren:
|
||
- active = false
|
||
- Login gesperrt
|
||
- Daten bleiben erhalten
|
||
|
||
|
||
SCHRITT 6: Public Webblog (parallel, aber getrennt)
|
||
---------------------------------------------------
|
||
Status: PARALLEL MÖGLICH ✅
|
||
|
||
Empfohlener Start:
|
||
- Eigenes Frontend (public-web)
|
||
- Content als Markdown im Repo
|
||
- Git als CMS
|
||
|
||
Vorteile:
|
||
- Kein Admin-UI nötig
|
||
- Keine Auth
|
||
- Sehr schneller Workflow
|
||
|
||
|
||
Warum diese Reihenfolge sinnvoll ist
|
||
------------------------------------
|
||
- Workspace erzeugt operativen Wert
|
||
- Login schützt eure Arbeit
|
||
- Inventory Overview macht das System sofort nutzbar
|
||
- UI basiert auf stabiler API
|
||
- Blog kann unabhängig wachsen
|
||
|
||
|
||
Langfristige Erweiterungen
|
||
--------------------------
|
||
- Orders → automatische SALE Movements
|
||
- Drops → Production → initialer Bestand
|
||
- Low-Stock Alerts
|
||
- Rollenfeingranularität
|
||
- Flyway Migrations
|
||
- Postgres als DB
|
||
- Public Shop (optional)
|
||
|
||
|
||
Merksätze
|
||
---------
|
||
- Workspace zuerst, Public später
|
||
- Login früh einbauen (erledigt)
|
||
- Inventory niemals direkt ändern
|
||
- SKUs sind die operative Wahrheit
|
||
- Löschen ist fast immer falsch → inactive ist richtig
|
||
- H2 Passwort niemals ändern ohne DB Reset
|
||
|
||
|
||
Nächster konkreter Schritt
|
||
--------------------------
|
||
- Admin UI für User + Active/Inactive
|
||
- Deactivate-Flow für Products & SKUs
|
||
- Orders mit automatischen InventoryMovements
|
||
|
||
Curls
|
||
-----------------
|
||
curl -X POST http://localhost:8080/api/admin/users \
|
||
-H "Content-Type: application/json" \
|
||
-b cookies.txt \
|
||
-d '{
|
||
"username": "admin2",
|
||
"password": "admin123!",
|
||
"role": "ADMIN",
|
||
"active": true
|
||
}'
|
||
|
||
curl -X POST http://localhost:8080/api/admin/users \
|
||
-H "Content-Type: application/json" \
|
||
-b cookies.txt \
|
||
-d '{
|
||
"username": "worker1",
|
||
"password": "worker123!",
|
||
"role": "WORKER",
|
||
"active": true
|
||
}' |