Implementiert:
- GET /api/inventory/overview Liefert pro SKU: - Produktname - Kategorie - Größe / Farbe - Preis - Aktueller Bestand (SUM der InventoryMovements) Bedeutung: - Ein einzelner Request ist ausreichend für das gesamte Inventory-Dashboard - Backend liefert UI-fertige Daten (keine Aggregation im Frontend nötig) Grundlage für: - Inventory Tabelle - Low-Stock Checks - Drop-Planung - Workspace UI
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
VOYAGE – SKUs & InventoryMovements
|
||||
=================================
|
||||
|
||||
1. Product vs. SKU
|
||||
------------------
|
||||
|
||||
Ein Product beschreibt das Modell / die Idee.
|
||||
Beispiel:
|
||||
- "Voyage Tee"
|
||||
|
||||
Eine SKU (Stock Keeping Unit) ist die kleinste verkaufbare Einheit.
|
||||
Sie beschreibt eine konkrete Variante eines Produkts.
|
||||
|
||||
Beispiel-SKUs für "Voyage Tee":
|
||||
- VOY-TEE-BLK-M (Schwarz, Größe M)
|
||||
- VOY-TEE-BLK-L (Schwarz, Größe L)
|
||||
- VOY-TEE-WHT-M (Weiß, Größe M)
|
||||
|
||||
Wichtige Regel:
|
||||
- Produkte werden NICHT gelagert oder verkauft
|
||||
- NUR SKUs werden gelagert, verkauft und gezählt
|
||||
|
||||
|
||||
2. Warum SKUs notwendig sind
|
||||
----------------------------
|
||||
|
||||
- Bestand unterscheidet sich pro Größe/Farbe
|
||||
- Preis kann pro Variante unterschiedlich sein
|
||||
- Orders referenzieren SKUs
|
||||
- Inventory bezieht sich IMMER auf SKUs
|
||||
|
||||
Kurz:
|
||||
Alles Operative hängt an der SKU, nicht am Product.
|
||||
|
||||
|
||||
3. InventoryMovement – Grundidee
|
||||
--------------------------------
|
||||
|
||||
InventoryMovement speichert JEDE Veränderung am Bestand.
|
||||
|
||||
Es gibt KEIN Feld wie:
|
||||
- stock = 49
|
||||
|
||||
Stattdessen gibt es Buchungen (Movements):
|
||||
- +50 PRODUCTION
|
||||
- -1 SALE
|
||||
- +1 RETURN
|
||||
- -3 ADJUSTMENT
|
||||
|
||||
|
||||
4. Inventory als Buchhaltung
|
||||
----------------------------
|
||||
|
||||
Inventory funktioniert wie ein Konto:
|
||||
|
||||
- Jede Bewegung ist eine Buchung
|
||||
- Der aktuelle Bestand ist die Summe aller Buchungen
|
||||
|
||||
Beispiel für eine SKU:
|
||||
|
||||
+50 (PRODUCTION)
|
||||
-1 (SALE)
|
||||
+1 (RETURN)
|
||||
|
||||
Current Stock = 50
|
||||
|
||||
|
||||
5. Vorteile dieses Modells
|
||||
--------------------------
|
||||
|
||||
- Vollständige Historie
|
||||
- Jeder Bestand ist erklärbar
|
||||
- Fehler lassen sich nachvollziehen
|
||||
- Perfekt für:
|
||||
- Drops
|
||||
- Reporting
|
||||
- Automationen
|
||||
- Forecasting
|
||||
|
||||
|
||||
6. Beziehung zwischen Product, SKU und Inventory
|
||||
------------------------------------------------
|
||||
|
||||
Product
|
||||
└─ SKU
|
||||
└─ InventoryMovements
|
||||
├─ +50 (PRODUCTION)
|
||||
├─ -1 (SALE)
|
||||
└─ -3 (ADJUSTMENT)
|
||||
|
||||
|
||||
7. Goldene Regeln
|
||||
-----------------
|
||||
|
||||
1. Bestand niemals direkt speichern
|
||||
2. Inventory immer über Movements ändern
|
||||
3. Orders erzeugen InventoryMovements
|
||||
4. Drops erzeugen initiale Production-Movements
|
||||
|
||||
|
||||
8. Was darauf aufbaut
|
||||
---------------------
|
||||
|
||||
- Inventory Overview (Stock pro SKU)
|
||||
- Order-Fulfillment (automatische Abbuchung)
|
||||
- Drop-Planung (geplant vs. real)
|
||||
- Low-Stock Alerts
|
||||
|
||||
Dieses Modell ist bewusst einfach, aber skalierbar.
|
||||
@@ -0,0 +1,200 @@
|
||||
VOYAGE – Nächste Projektschritte (Workspace + Login + Webblog) – UPDATE 2026-01-20
|
||||
===============================================================================
|
||||
|
||||
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
|
||||
- Inventory Overview Endpoint (aggregierte Bestandsübersicht)
|
||||
- Login-System (Spring Security, Form Login, Session)
|
||||
- /api/** ist geschützt (nur eingeloggt)
|
||||
- Login per Browser (/login) und per curl (Cookie/JSESSIONID) funktioniert
|
||||
|
||||
Damit ist das Domain-Fundament + Zugriffsschutz + UI-taugliche API abgeschlossen.
|
||||
|
||||
|
||||
Wichtiger Hinweis zur Datenbank (AKTUELLER ZUSTAND)
|
||||
---------------------------------------------------
|
||||
Die Anwendung verwendet derzeit eine H2 In-Memory Datenbank:
|
||||
|
||||
- JDBC URL: jdbc:h2:mem:...
|
||||
- Die Datenbank liegt ausschließlich im RAM
|
||||
- BEI JEDEM APP-RESTART WERDEN ALLE DATEN GELÖSCHT
|
||||
|
||||
Dieser Zustand ist bewusst gewählt und sinnvoll für:
|
||||
- frühe Entwicklung
|
||||
- schnelles Testen
|
||||
- Debugging
|
||||
- Fokus auf Domain-Logik statt Persistenz
|
||||
|
||||
Wichtig:
|
||||
- Products, SKUs und InventoryMovements müssen nach jedem Neustart neu angelegt werden
|
||||
- IDs (productId, skuId) ändern sich nach jedem Restart
|
||||
|
||||
Geplanter späterer Schritt:
|
||||
- Umstellung auf persistente DB (z. B. H2 file, Postgres)
|
||||
- Einführung von Migrations (Flyway)
|
||||
|
||||
|
||||
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 (besteht)
|
||||
- Aggregierte Inventory-Übersicht (besteht)
|
||||
- Auth (besteht)
|
||||
- später Orders / Drops
|
||||
|
||||
2) workspace-ui (Webinterface)
|
||||
- internes Dashboard
|
||||
- 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)
|
||||
|
||||
Offene Endpoints:
|
||||
- /health (öffentlich)
|
||||
- /h2-console (nur Development)
|
||||
|
||||
|
||||
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 einzelner Request ist ausreichend für das gesamte Inventory-Dashboard
|
||||
- Backend liefert UI-fertige Daten (keine Aggregation im Frontend nötig)
|
||||
|
||||
Grundlage für:
|
||||
- Inventory Tabelle
|
||||
- Low-Stock Checks
|
||||
- Drop-Planung
|
||||
- Workspace UI
|
||||
|
||||
|
||||
SCHRITT 3: Workspace UI (minimal starten)
|
||||
-----------------------------------------
|
||||
Status: ALS NÄCHSTES ✅
|
||||
|
||||
Nicht zu groß denken. Start mit EINER Seite:
|
||||
|
||||
- Inventory Übersicht
|
||||
- Tabelle mit allen SKUs + currentStock
|
||||
- Suche & Filter (Name, SKU, Kategorie)
|
||||
- Button für Inventory Movements (+ / -)
|
||||
|
||||
Ergebnis:
|
||||
Ein echtes internes Tool, das täglich nutzbar ist.
|
||||
|
||||
|
||||
SCHRITT 4: Public Webblog (parallel, aber getrennt)
|
||||
---------------------------------------------------
|
||||
Status: PARALLEL MÖGLICH ✅
|
||||
|
||||
Empfohlener Start:
|
||||
- Eigenes Frontend (public-web)
|
||||
- Content als Markdown-Dateien im Repo
|
||||
- Git als CMS
|
||||
|
||||
Vorteile:
|
||||
- Kein Admin-UI nötig
|
||||
- Keine Auth
|
||||
- Sehr schneller Content-Workflow
|
||||
|
||||
|
||||
Warum diese Reihenfolge sinnvoll ist
|
||||
------------------------------------
|
||||
- Workspace erzeugt operativen Wert
|
||||
- Login schützt eure Arbeit
|
||||
- Inventory Overview macht das System direkt benutzbar
|
||||
- UI kann ohne weitere Backend-Arbeit gebaut werden
|
||||
- Blog kann unabhängig wachsen
|
||||
- Keine unnötige Komplexität zu früh
|
||||
|
||||
|
||||
Langfristige Erweiterungen
|
||||
--------------------------
|
||||
- Orders → automatische InventoryMovements
|
||||
- Drops → Production → initialer Bestand
|
||||
- Automations (Low-Stock Alerts)
|
||||
- Rollen (Admin / Viewer)
|
||||
- Persistente Datenbank + Migrations
|
||||
- Public Shop (optional)
|
||||
|
||||
|
||||
Merksätze
|
||||
---------
|
||||
- Workspace zuerst, Public später
|
||||
- Login früh einbauen (erledigt)
|
||||
- Inventory niemals direkt ändern
|
||||
- SKUs sind die operative Wahrheit
|
||||
- In-Memory DB = flüchtig, aber perfekt für den Start
|
||||
|
||||
|
||||
Nächster konkreter Schritt
|
||||
--------------------------
|
||||
Start von:
|
||||
- workspace-ui (Inventory Tabelle auf Basis von /api/inventory/overview)
|
||||
|
||||
Danach:
|
||||
- Orders + automatische Inventory-Abbuchung
|
||||
- Umstellung auf persistente DB, sobald Stabilität erreicht ist
|
||||
@@ -37,8 +37,14 @@ dependencies {
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-validation-test'
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-webmvc-test'
|
||||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-security'
|
||||
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
}
|
||||
|
||||
|
||||
generateJava {
|
||||
schemaPaths = ["${projectDir}/src/main/resources/graphql-client"]
|
||||
packageName = 'com.voyage.workspace_api.codegen'
|
||||
|
||||
@@ -1 +1,6 @@
|
||||
spring.application.name=workspace-api
|
||||
|
||||
spring.h2.console.enabled=true
|
||||
spring.datasource.url=jdbc:h2:mem:voyage;DB_CLOSE_DELAY=-1
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.profiles.active=dev
|
||||
Reference in New Issue
Block a user