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>
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
# 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).
|
||||
Reference in New Issue
Block a user