- Java 43.1%
- TypeScript 32.5%
- HTML 15.2%
- SCSS 5.9%
- PLpgSQL 1.9%
- Other 1.4%
| .cursor | ||
| .vscode | ||
| backend | ||
| docker | ||
| docs | ||
| frontend | ||
| scripts | ||
| .dockerignore | ||
| .env.example | ||
| .gitattributes | ||
| .gitignore | ||
| AGENTS.md | ||
| authentik-setup.md | ||
| CHANGELOG.md | ||
| docker-compose.dev.yml | ||
| docker-compose.yml | ||
| README.md | ||
node-K Inventar
Standalone Inventar-, Lager-, Ausleih- und Quellen-App für den Verein node-K.
Die Backend-Grundlage (Authentik-Login, Session, CSRF, WebSockets, Docker, Fehlerformat)
ist von der Management-App hledger übernommen — ohne Buchhaltungs-Domäne.
Was die App kann
- Gegenstände mit Inventarnummer, QR, Foto, Standort, Verantwortung
- Mengenartikel (Verbrauch/Kleinteile) mit Bestand, Mindestbestand und Buchungen
- Ausleihen mit Vier-Augen-Freigabe und Überfälligkeits-Mail (einmalig)
- Inventuren mit QR-Erfassung und Abschlussprotokoll
- Wunschliste, Sets/Beziehungen, Meta-Inventar (Quellen)
Tech-Stack
| Bereich | Technik |
|---|---|
| Backend | Java 25, Spring Boot 4.1.0, PostgreSQL, Flyway |
| Frontend | Angular 21 (standalone, zoneless, signals), Bootstrap 5 Dark |
| Auth | authentik OIDC — gleicher Ablauf wie Management: Authorization Code + Session-Cookie + CSRF |
| Deploy | Docker Compose, Multi-Stage-Build |
Schnellstart
Voraussetzungen: Java 25, Maven 3.9+, Node.js 22+, Docker.
cp .env.example .env
# Secrets in .env setzen, keine Credentials committen
# Postgres auf :5433 (passt zu Profil dev / application-dev.yml)
docker compose -f docker-compose.yml -f docker-compose.dev.yml --env-file .env up -d postgres
cd backend && mvn spring-boot:run
cd frontend && npm install && npm start
- Frontend: http://localhost:4200 (proxyt
/api,/oauth2,/wsnach :8080) - OpenAPI nur im Profil
dev: http://localhost:8080/swagger-ui.html
docker-compose.dev.yml mappt Postgres auf 5433, weil application-dev.yml so konfiguriert ist
(und Port 5432 auf Windows oft schon belegt ist). Nur Postgres braucht das Override; der volle
Stack (docker compose up) nutzt Postgres intern auf 5432.
Nach Änderungen an Flyway-Migrationen: cd backend && mvn clean (entfernt alte SQL aus target/)
und die DB neu aufsetzen (docker compose … down -v, dann Postgres wieder starten).
Lokal ohne Authentik: Profil dev mit app.dev.mock-user.enabled=true
(Standard in application-dev.yml). Niemals in Docker/Prod aktivieren.
Demo-Daten: DEV_SEED_DEMO=true (Leinwand-Set, HDMI, Filament, M3 12mm,
Retro-Hardware Klagenfurt).
AI-Agents: Start mit AGENTS.md. Authentik Schritt-für-Schritt: docs/authentik-setup.md (Kurzverweis: authentik-setup.md). Rollen: docs/roles-and-auth.md. Changelog: CHANGELOG.md.
Authentik
Session-OIDC wie die Management-App (kein SPA-PKCE). Einrichtung: docs/authentik-setup.md.
Wie in der Management-App:
- OAuth2/OIDC-Provider anlegen, Redirect
…/login/oauth2/code/authentik - Scopes:
openid,profile,email,groups - Gruppen (Claims → Spring-Rollen):
| authentik-Gruppe | Rolle |
|---|---|
| Inventory View | ROLE_INVENTORY_VIEW |
| Inventory Edit | ROLE_INVENTORY_EDIT |
| Inventory Inventory | ROLE_INVENTORY_INVENTORY |
| Inventory Loan Approve | ROLE_INVENTORY_LOAN_APPROVE |
| Inventory Sources | ROLE_INVENTORY_SOURCES |
| Inventory Wishlist | ROLE_INVENTORY_WISHLIST |
| Inventory Admin | alle Inventar-Rechte |
| Club Member | ROLE_MEMBER |
INVENTORY_ADMIN erhält automatisch alle Inventar-Rollen.
Env-Variablen (identisch zur Management-App plus Slug):
AUTHENTIK_ISSUER_URI
AUTHENTIK_AUTHORIZE_URI
AUTHENTIK_BASE_URL
AUTHENTIK_CLIENT_ID
AUTHENTIK_CLIENT_SECRET
AUTHENTIK_APP_SLUG=inventory
Docker: AUTHENTIK_ISSUER_URI / AUTHENTIK_BASE_URL oft host.docker.internal,
AUTHENTIK_AUTHORIZE_URI muss vom Browser erreichbar sein (localhost).
Management-API
Die App speichert ein Mitglieds-Snapshot (Anzeige-Name + externe ID). E-Mail für Benachrichtigungen wird nach Möglichkeit frisch geladen.
MANAGEMENT_API_BASE_URL
MANAGEMENT_API_TOKEN
Erwartete Endpunkte der Management-App (hledger), Bearer-Token:
GET /api/internal/members/by-sub/{sub}GET /api/internal/members/{id}
Felder wie MemberResponse: id, authentikSub, preferredCallName, firstName,
lastName, status, authentikEmail. Ist die Management-App down, gilt der Snapshot.
Docker Compose
docker compose --env-file .env up --build
Services: App + PostgreSQL. Volumes: postgres-data, inventory-uploads. Healthchecks aktiv.
Keine Secrets im Repo — nur .env.example.
Produktion (wie die Management-App): App hängt am externen Traefik-Netz proxy,
Host loot.node-k.at, TLS über leresolver. App-Port 8080 und Postgres 5432
sind nicht auf den Host gelegt — Erreichbarkeit nur über Traefik bzw. das Compose-Netz.
Das Netz proxy muss auf dem Host existieren (Traefik-Stack).
Lokal mit veröffentlichten Ports: docker-compose.dev.yml (App :8080, Postgres :5433).
Backup
Ein Volume allein ist kein vollständiges Backup.
- Konsistentes
pg_dumpder Datenbank (idealerweise während kurzer Schreibpause oder mit--format=custom) - Zusätzlich das Upload-Volume (
inventory-uploads) sichern - Regelmäßig, getrennt vom Host-Volume-Snapshot
Beispiel:
docker compose exec postgres pg_dump -U inventory -d inventory > backup-$(date +%F).sql
Tests
cd backend && mvn test
cd frontend && npm run build
cd frontend && npm run changelog:build
Abgedeckt:
- Mockito-Unit-Tests für Status, Ausleihe, Bestand, Inventur, Beziehungen, Rollen
@SpringBootTest+ Testcontainers PostgreSQL (org.testcontainers:testcontainers-postgresql) für Statuswechsel, Ausleihfreigabe (keine Selbstfreigabe;AUSGELIEHENerst nach Freigabe+Ausgabe), Überfälligkeits-Mail einmal, Bestandshistorie, Inventurabschluss, Rechte, Beziehungen, Set-Rückgabe, Quellen-PII
Voraussetzung für die Integrationstests: laufendes Docker Desktop. Ohne Docker
werden die IT-Tests per Assumption übersprungen (Testcontainers PostgreSQL is not running).
Sass / Design-Tokens
Geteilte Markenwerte kommen aus @node-k/tokens (heute file:./vendor/node-k-tokens,
später das published Paket). Inventar-only und Namens-Aliase stehen in
frontend/src/styles/_variables.scss. Umstellung: docs/design-tokens-migration.md.
Import-Reihenfolge in styles.scss:
- Font-Bridge (temporär)
@node-k/tokensSCSSvariables(Aliase, App-only, Bootstrap-Farben)bootstrap-overrides- Bootstrap
utilities
Bootstrap 5.3 thematisiert weiterhin über globale Variablen vor @import.
Ein Umstieg auf @use/@forward würde diese Overrides isolieren — deshalb bleiben @imports hier
bewusst, trotz Sass-Deprecation-Warnung.
Repo-Layout
backend/ Spring Boot
frontend/ Angular PWA
docker/ Multi-Stage Dockerfile + Entrypoint
docker-compose.yml
.env.example