- Java 43.6%
- TypeScript 32.7%
- HTML 16.3%
- SCSS 4.5%
- PLpgSQL 1.5%
- Other 1.4%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .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
Mitgliedsdaten speichert die App lokal beim Login (Name, E-Mail, Gruppen aus Authentik).
Benachrichtigungen gehen über die Management-App:
MANAGEMENT_API_BASE_URL
MANAGEMENT_NOTIFICATION_SECRET
MANAGEMENT_NOTIFICATION_APP_SLUG=inventory
POST /api/internal/notifications/apps/{slug}/events mit dem App-Secret
(MANAGEMENT_NOTIFICATION_SECRET, Admin → Externe Benachrichtigungen). Katalog und Setup:
docs/external-notifications.md.
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 und Bootstrap-Brücke kommen aus den Forgejo-Packages
@node-k/tokens, @node-k/styles, @node-k/assets, @node-k/ui (je 0.2.8).
Scope-Registry: frontend/.npmrc. Optional Auth: NODE_AUTH_TOKEN
(siehe .env.example und frontend/.npmrc.example).
Inventar-only und Namens-Aliase: frontend/src/styles/_variables.scss.
Details: docs/design-tokens-migration.md.
Import-Reihenfolge in styles.scss:
@node-k/tokensSCSSvariables(Aliase, App-only, Status/Layout)bootstrap-overrides(Modal/Dropdown/…)@node-k/styles/scss/bootstrap(Brücke + Bootstrap + bs-vars/components)utilities
Fonts und :root-Tokens zusätzlich über angular.json (nodek-fonts.css, nodek-tokens.css).
Theme: Default dunkel; Umschalter schreibt localStorage.nk-theme und setzt data-theme / data-bs-theme.
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