Files
Materialschein/README.md
T
Fidelis HuberandClaude Sonnet 5 13cef3c96d
Build and Deploy / version (push) Successful in 1s
Build and Deploy / build (push) Failing after 1s
Build and Deploy / deploy (push) Skipped
Initial scaffold: React/Vite/TS PWA + Express/Prisma/Postgres backend
Materialschein & Kabelrechner für BergVOLT Elektrotechnik, portiert von der
vorherigen Single-File-HTML-Version. Microsoft-Entra-ID-Login (MSAL), Projekt-
Dashboard statt einer Datei pro Kunde, Retour-Buchen-Zusammenführung, 111
Kabeltypen aus den offiziellen Meinhart-Datenblättern. gitops/ nach
PROX/deploy-standard: git-backed Portainer-Stack, versionierte Docker-Images,
CI-Commit-back auf gitops/stack.yml.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 17:24:38 +02:00

97 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# BergVOLT Materialschein
Materialschein & Kabelrechner für BergVOLT Elektrotechnik. React + Vite + TypeScript
(PWA) im Client, Express + TypeScript + Prisma im Server, Postgres als Datenbank.
Anmeldung über Microsoft Entra ID (gleiche App-Registrierung wie das Zeiterfassungs-Tool).
## Lokale Entwicklung
```bash
# 1. Postgres lokal starten
docker compose -f docker-compose.dev.yml up -d
# 2. Server
cd server
npm install
echo 'DATABASE_URL="postgresql://materialschein:dev@localhost:5433/materialschein"' > .env
echo 'MSAL_CLIENT_ID="b1cd974c-77ce-4d93-b6e8-00e41a31adc8"' >> .env
echo 'MSAL_TENANT_ID="d9adeaaf-853b-4c4e-a822-8f1bedbb84f6"' >> .env
echo 'PORT=8787' >> .env
npx prisma migrate deploy
npm run dev # läuft auf :8787
# 3. Client (neues Terminal)
cd client
npm install
npm run dev # läuft auf :5173, proxied /api auf :8787
```
## Architektur
- `client/` React 18 + Vite + TypeScript, `vite-plugin-pwa` für Manifest/Service Worker.
MSAL.js (`@azure/msal-browser` + `@azure/msal-react`) für den Microsoft-Login.
- `server/` Express + TypeScript, validiert das MSAL-ID-Token serverseitig (JWKS von
`login.microsoftonline.com`) und liefert zusätzlich die gebaute Client-App aus
(`public/` = `client/dist`, SPA-Fallback für React-Router).
- `server/prisma/schema.prisma` zwei Tabellen: `projekte` (Baustellen) und
`material` (Positionen je Projekt, per `projektId` verknüpft).
- Ein Docker-Image (`Dockerfile`, Multi-Stage) enthält Client-Build + Server, Port 80.
## Deploy (git.prox.ws → Portainer)
Folgt [deploy-standard](https://git.prox.ws/PROX/deploy-standard) 1:1 `gitops/stack.yml`
und `.gitea/workflows/build.yml` sind bereits fertig im Repo. Zum Scharfschalten:
### 1. Azure AD zweite Redirect-URI eintragen
Bestehende App-Registrierung "BergVolt Zeiterfassung" im Azure Portal öffnen →
Authentifizierung → bei "Single-Page-Anwendung" ergänzen:
`https://materialschein.bergvolt.at` (oder die tatsächlich vorgesehene Domain/Pfad).
**Redirect-URI in `client/src/lib/authConfig.ts` steht auf `window.location.origin`
d.h. die exakte Domain, unter der die App später erreichbar ist, muss hier eingetragen werden.**
### 2. Gitea Repo-Secrets setzen
Repo → Settings → Actions → Secrets:
| Secret | Wert |
|---|---|
| `GITEAUSER` | Gitea-Username des Package-Namespace-Owners (siehe deploy-standard: Package-Push geht nur als Namespace-Owner) |
| `GITEAPASSWORD` | PAT dieses Users, Scope **nur `write:package`** (Settings → Applications → Generate New Token) |
| `PORTAINER_WEBHOOK_URL` | kommt aus Schritt 4 |
Repo → Settings → Actions: Default-Permission auf **Read and Write**, damit der
Commit-back (`gitops/stack.yml` auf `:<version>` pinnen) funktioniert.
### 3. Erster Push
```bash
git push origin main
```
`build` wird grün, `deploy` schlägt fehl (Webhook-Secret fehlt noch) erwartet.
### 4. Portainer Stack anlegen
Auf `https://10.1.10.111:9443` (Zugang laut deploy-standard bei "dominic"):
- Stacks → Add stack → **Repository**
- Repository URL: `https://git.prox.ws/BERGVOLT/Materialschein`
- Reference: `refs/heads/main`
- Compose path: `gitops/stack.yml`
- Authentication: `portainer-deploy` + dessen PAT (Org-Repos sind über das
`deploy-read`-Team bereits abgedeckt, nichts zusätzlich einzutragen)
- Environment-Variable setzen: `POSTGRES_PASSWORD` = ein zufälliges, sicheres Passwort
- **Webhook aktivieren**, **ForceUpdate an**, `ForcePullImage` bleibt aus
- Die angezeigte Webhook-URL (`.../api/stacks/webhooks/<uuid>`) als Gitea-Secret
`PORTAINER_WEBHOOK_URL` eintragen (Schritt 2).
- nginx-proxy-manager: Proxy Host auf Container `materialschein`, Port `80`.
### 5. Verifizieren
- Webhook von Hand feuern (`curl -sk -X POST <url>`) → `204`, Container laufen
(`db` + `web`).
- Push oder „Run workflow" auslösen → beide Jobs grün, `gitops/stack.yml` zeigt danach
`image: …:1.0.<N>` (kein `:latest` mehr), Commit `deploy: v1.0.<N> [skip ci]` im Log.
- Cleanup-Rule für den Package-Owner einmalig setzen (Org/User → Settings → Packages →
Cleanup Rules): keep most recent 10 + keep matching `^latest$`.
### Danach: zum Homescreen hinzufügen
Seite im Handy-Browser öffnen, anmelden, "Zum Home-Bildschirm hinzufügen" (iOS Safari)
bzw. "App installieren" (Android Chrome) die App ist als PWA installierbar
(`vite-plugin-pwa` generiert Manifest + Service Worker automatisch beim Build).