diff --git a/apps/workspace-api/Doc.txt b/apps/workspace-api/Doc.txt index e69de29..f357263 100644 --- a/apps/workspace-api/Doc.txt +++ b/apps/workspace-api/Doc.txt @@ -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. \ No newline at end of file diff --git a/apps/workspace-api/ToDo's b/apps/workspace-api/ToDo's index e69de29..121840b 100644 --- a/apps/workspace-api/ToDo's +++ b/apps/workspace-api/ToDo's @@ -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 \ No newline at end of file diff --git a/apps/workspace-api/build.gradle b/apps/workspace-api/build.gradle index ec49d03..efcc765 100644 --- a/apps/workspace-api/build.gradle +++ b/apps/workspace-api/build.gradle @@ -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' @@ -47,4 +53,4 @@ generateJava { tasks.named('test') { useJUnitPlatform() -} +} \ No newline at end of file diff --git a/apps/workspace-api/src/main/resources/application.properties b/apps/workspace-api/src/main/resources/application.properties index 7611153..91deed2 100644 --- a/apps/workspace-api/src/main/resources/application.properties +++ b/apps/workspace-api/src/main/resources/application.properties @@ -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 \ No newline at end of file diff --git a/apps/workspace-api/src/todo.txt b/apps/workspace-api/src/todo.txt deleted file mode 100644 index e69de29..0000000