Wordt niet gebruikt. azure-pipelines.yml is weg, en de verwijzingen ernaar in README.md, BEHEER.md (sectie CI/CD), Changelog.md en .dockerignore zijn opgeruimd. De testsuite draait onveranderd lokaal via test.ps1 / test.sh. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
331 lines
10 KiB
Markdown
331 lines
10 KiB
Markdown
# VibeFinance — Beheer
|
|
|
|
De app draait in **2 containers**: `app` (Express API + gebouwde frontend) en
|
|
`postgres`. Eén image, één origin — geen aparte webserver en geen interne proxy.
|
|
|
|
---
|
|
|
|
## Ontwikkeling
|
|
|
|
```powershell
|
|
.\dev.ps1 # build + start (standaard)
|
|
.\dev.ps1 build # alleen bouwen
|
|
.\dev.ps1 up -Target app # alleen de app herbouwen + herstarten
|
|
.\dev.ps1 up -Target postgres # alleen de database herstarten
|
|
.\dev.ps1 logs # logs van de app volgen
|
|
.\dev.ps1 test # testsuite draaien
|
|
.\dev.ps1 down # stoppen én volumes wissen
|
|
.\dev.ps1 push # dev-image naar registry pushen
|
|
```
|
|
|
|
> Op macOS/Linux: gebruik `./dev.sh` met dezelfde argumenten.
|
|
|
|
In dev draait één container beide processen (zie `docker/dev-entrypoint.sh`):
|
|
|
|
| Adres | Wat |
|
|
|---|---|
|
|
| http://localhost | Vite dev-server met hot reload |
|
|
| http://localhost:3001/api/health | de API rechtstreeks |
|
|
|
|
Vite proxyt `/api` naar `localhost:3001` binnen dezelfde container.
|
|
|
|
> ⚠️ Alleen `.\dev.ps1 down` wist de development-database (`docker compose down -v`).
|
|
> `.\dev.ps1 up` doet een gewone `down` en laat het volume staan.
|
|
|
|
---
|
|
|
|
## Testen
|
|
|
|
```powershell
|
|
.\test.ps1 # dependency-check + backend-tests + build + smoketest
|
|
.\test.ps1 -Unit # dependency-check + backend-tests
|
|
.\test.ps1 -NoSmoke # zonder de stack te starten
|
|
.\test.ps1 -Strict # faal als een dependency achterloopt
|
|
.\test.ps1 -SkipDeps # dependency-check overslaan (bijv. offline)
|
|
```
|
|
|
|
Alles loopt in Docker; Node op de host is niet nodig.
|
|
|
|
| Stap | Wat er gebeurt |
|
|
|---|---|
|
|
| Dependency-check | `docker/check-updates.mjs` vergelijkt `package.json` met het npm-register |
|
|
| Backend-tests | `Dockerfile` target `test` → `node --test` in `backend/test/`, zonder database |
|
|
| Productiebuild | `Dockerfile` target `production` — faalt de Vite-build, faalt deze stap |
|
|
| Smoketest | app + postgres starten en `/api/health` en `/` opvragen |
|
|
|
|
De dependency-check draait standaard bij elke testronde, dus je ziet direct of
|
|
er updates open staan. Pakketten die bewust achterblijven zet je met een reden
|
|
in `docker/update-exceptions.json`; die worden als `[vast ]` gemeld en laten de
|
|
check niet falen. Zonder netwerk: `-SkipDeps`. In een CI-gate: `-Strict`.
|
|
|
|
De check los draaien:
|
|
|
|
```bash
|
|
docker run --rm -v ${PWD}:/repo -w /repo node:22-alpine node docker/check-updates.mjs
|
|
docker run --rm -v ${PWD}:/repo -w /repo node:22-alpine node docker/check-updates.mjs --strict
|
|
```
|
|
|
|
Losse backend-tests en linting in een lopende dev-container:
|
|
|
|
```bash
|
|
docker compose -f docker-compose.dev.yml exec app npm test
|
|
docker compose -f docker-compose.dev.yml exec app npm run lint
|
|
docker compose -f docker-compose.dev.yml exec -w /app/frontend app npm run lint
|
|
```
|
|
|
|
---
|
|
---
|
|
|
|
## Release workflow
|
|
|
|
```powershell
|
|
# 1. Versienummer in package.json van "x.x.x-dev" naar "x.x.x"
|
|
# 2. Changelog.md bijwerken — die sectie wordt de release-notes
|
|
# 3. Token met release-rechten zetten
|
|
$env:GITEA_TOKEN = "<token>"
|
|
|
|
.\release.ps1 # test, bouw (amd64+arm64), push, tag, Gitea-release
|
|
.\release.ps1 -DryRun # droogloop — toont alle stappen zonder uit te voeren
|
|
.\release.ps1 -NoBuild # sla docker build over, alleen tag + release
|
|
.\release.ps1 -SkipTests # sla de testsuite over (niet aanbevolen)
|
|
|
|
# 4. Versienummer in package.json naar "x.x.(x+1)-dev" voor volgende cyclus
|
|
```
|
|
|
|
Het script bouwt één image voor `linux/amd64` en `linux/arm64`, zodat dezelfde
|
|
tag op een Raspberry Pi en op een x86-server werkt.
|
|
|
|
---
|
|
|
|
## Docker
|
|
|
|
```bash
|
|
# Update via pre-built images
|
|
docker compose pull && docker compose up -d
|
|
|
|
# Reset inclusief database ⚠️ wist alle data
|
|
docker compose down -v && docker compose up -d
|
|
```
|
|
|
|
### PostgreSQL versie-upgrade
|
|
|
|
Bij een upgrade van PostgreSQL (bijv. 16 → 18) is de bestaande data niet compatibel. Stappen:
|
|
|
|
```bash
|
|
# 1. Backup maken
|
|
docker exec vibefinance_postgres pg_dump -U vibefinance vibefinance > backup-$(date +%F).sql
|
|
|
|
# 2. Oude containers en volumes verwijderen
|
|
docker compose down -v
|
|
|
|
# 3. Nieuwe versie starten
|
|
docker compose up -d
|
|
|
|
# 4. Backup terugzetten
|
|
docker exec -i vibefinance_postgres psql -U vibefinance -d vibefinance < backup-YYYY-MM-DD.sql
|
|
```
|
|
|
|
---
|
|
|
|
## Architectuur — één app-container
|
|
|
|
De Express-app serveert zowel de API als de gebouwde frontend:
|
|
|
|
| Verzoek | Wat de app doet |
|
|
|---|---|
|
|
| `/api/...` | REST API (rate limited) |
|
|
| `/assets/...` | statische build uit `STATIC_DIR`, 1 jaar `immutable` gecached |
|
|
| al het overige | `index.html` — fallback voor React-routing |
|
|
|
|
`STATIC_DIR` staat standaard op `/app/public`; daar zet de `Dockerfile` de
|
|
Vite-build neer. Bestaat die map niet (bijv. in dev), dan serveert de app
|
|
alleen de API en logt dat bij het starten.
|
|
|
|
> Ontbreekt de build in het image, dan krijg je op `/` een 404 en werkt alleen
|
|
> `/api/...`. Controleer dan de `frontend-build` stage in de `Dockerfile`.
|
|
|
|
---
|
|
|
|
## Logs en diagnose
|
|
|
|
```bash
|
|
# Live logs (dev) — beide processen van de app-container
|
|
docker compose -f docker-compose.dev.yml logs -f app
|
|
|
|
# Live logs (productie)
|
|
docker compose logs -f
|
|
|
|
# Shell in de app-container (dev)
|
|
docker compose -f docker-compose.dev.yml exec app sh
|
|
|
|
# Status containers
|
|
docker compose ps
|
|
|
|
# Database inspecteren (dev)
|
|
docker exec -it vibefinance-postgres-dev psql -U vibefinance -d vibefinance
|
|
|
|
# Database inspecteren (productie)
|
|
docker exec -it vibefinance_postgres psql -U vibefinance -d vibefinance
|
|
```
|
|
|
|
---
|
|
|
|
## Data persistentie
|
|
|
|
De backend slaat alle data op in **PostgreSQL**.
|
|
|
|
| Omgeving | Volume | Mount pad |
|
|
|---|---|---|
|
|
| Productie | `vibefinance_pgdata` | `/var/lib/postgresql` |
|
|
| Development | `postgres_dev_data` | `/var/lib/postgresql` |
|
|
|
|
> PostgreSQL 18 gebruikt `PGDATA=/var/lib/postgresql/18/docker`. Het volume is gemount op `/var/lib/postgresql` zodat data bewaard blijft na een container restart.
|
|
|
|
**Backup maken:**
|
|
|
|
```bash
|
|
# Dev
|
|
docker exec vibefinance-postgres-dev pg_dump -U vibefinance vibefinance > backup-$(date +%F).sql
|
|
|
|
# Productie
|
|
docker exec vibefinance_postgres pg_dump -U vibefinance vibefinance > backup-$(date +%F).sql
|
|
```
|
|
|
|
**Backup terugzetten:**
|
|
|
|
```bash
|
|
# Dev
|
|
docker exec -i vibefinance-postgres-dev psql -U vibefinance -d vibefinance < backup-2026-04-08.sql
|
|
|
|
# Productie
|
|
docker exec -i vibefinance_postgres psql -U vibefinance -d vibefinance < backup-2026-04-08.sql
|
|
```
|
|
|
|
---
|
|
|
|
## Gebruikersbeheer
|
|
|
|
De eerste geregistreerde gebruiker krijgt automatisch de **Admin**-rol. Verdere accounts kunnen via de app aangemaakt worden (Gebruikersbeheer, Admin vereist) of via de API.
|
|
|
|
Rollen:
|
|
| Rol | Rechten |
|
|
|---|---|
|
|
| `Admin` | Alles, inclusief gebruikersbeheer |
|
|
| `Bewerker` | Data lezen en bewerken |
|
|
| `Viewer` | Alleen lezen |
|
|
|
|
---
|
|
|
|
## Productie checklist
|
|
|
|
- [ ] `POSTGRES_PASSWORD` instellen op een sterk wachtwoord
|
|
- [ ] `JWT_SECRET` aanpassen (genereer met `openssl rand -hex 64`)
|
|
- [ ] `CORS_ORIGIN` instellen op je domeinnaam
|
|
- [ ] `APP_PORT` aanpassen indien poort 3400 al in gebruik is
|
|
- [ ] Testsuite groen (`test.ps1` / `./test.sh`)
|
|
- [ ] TLS afhandelen via een externe reverse proxy (bijv. Nginx Proxy Manager, Caddy, Traefik)
|
|
|
|
---
|
|
|
|
## Dependencies bijwerken
|
|
|
|
Node hoeft niet op de host te staan; de lockfiles zijn met een container bij te
|
|
werken. Per map (`frontend` en `backend`):
|
|
|
|
```bash
|
|
# Laatste versies opzoeken
|
|
docker run --rm -v ${PWD}/frontend:/w -w /w node:22-alpine npm outdated
|
|
|
|
# Versies in package.json aanpassen, daarna de lockfile herschrijven
|
|
docker run --rm -v ${PWD}/frontend:/w -w /w node:22-alpine npm install --package-lock-only
|
|
```
|
|
|
|
Daarna altijd de testsuite draaien — die bouwt ook het productie-image, dus een
|
|
kapotte upgrade valt meteen op:
|
|
|
|
```powershell
|
|
.\test.ps1
|
|
```
|
|
|
|
En de dev-stack herbouwen. `node_modules` staan in anonieme volumes; zonder
|
|
`--renew-anon-volumes` blijven de oude versies staan. `.\dev.ps1 up` doet dit
|
|
al automatisch:
|
|
|
|
```powershell
|
|
.\dev.ps1 up
|
|
```
|
|
|
|
> Let op bij majors: `eslint-plugin-react` loopt achter op ESLint (peer
|
|
> `<= ^9.7`), daarom staat de frontend op ESLint 9 en de backend op 10.
|
|
> Express 5 vereist benoemde wildcards in routes (`/api/*splat`); `server.js`
|
|
> gebruikt daarom pad-loze middleware in plaats van `app.get("*")`.
|
|
|
|
---
|
|
|
|
## Registry
|
|
|
|
```
|
|
vibehoogie.duckdns.org/vibe/vibefinance-app (frontend + backend in één image)
|
|
|
|
Tags:
|
|
latest productie — meest recente release
|
|
x.x.x productie — specifieke versie
|
|
latest-dev development — meest recente dev build
|
|
x.x.x-dev development — specifieke dev versie
|
|
```
|
|
|
|
Inloggen op registry:
|
|
```bash
|
|
docker login vibehoogie.duckdns.org
|
|
```
|
|
|
|
---
|
|
|
|
## Update-notificaties
|
|
|
|
De app vergelijkt de draaiende versie met de laatste **release** op Gitea en toont
|
|
dat op het belletje in de topbalk en onder "Over VibeFinance".
|
|
|
|
**Hoe de check loopt**
|
|
|
|
1. De frontend vraagt `/api/update-check` op de eigen backend — de Gitea API stuurt
|
|
geen CORS-headers, dus de browser mag die niet direct bevragen.
|
|
2. De backend haalt `releases/latest` bij Gitea op en cachet het antwoord 15 minuten.
|
|
3. De frontend kijkt bij het openen, daarna elk half uur en bij het terugkeren naar
|
|
het tabblad. Alleen een écht hoger versienummer geeft een melding.
|
|
|
|
Builds met een `-dev` suffix melden nooit (die lopen voor op de laatste release).
|
|
Wil je de melding tijdens ontwikkeling toch testen: open de app met `?updatecheck`
|
|
in de URL.
|
|
|
|
**Configuratie**
|
|
|
|
De bron staat in de root `package.json`:
|
|
|
|
```json
|
|
"repository": "https://vibehoogie.duckdns.org/vibe/VibeFinance",
|
|
"updateCheckUrl": "https://vibehoogie.duckdns.org/api/v1/repos/vibe/VibeFinance/releases/latest"
|
|
```
|
|
|
|
`dev.ps1` zet die URL als `UPDATE_CHECK_URL` in de omgeving; in productie komt hij
|
|
uit `.env` (of de default in `docker-compose.yml`). Beschikbare backend-variabelen:
|
|
|
|
| Variabele | Betekenis |
|
|
|---|---|
|
|
| `UPDATE_CHECK_URL` | Release-API die gepolld wordt. Leeg = melding uit. |
|
|
| `UPDATE_CHECK_TOKEN` | Alleen nodig als de repo in Gitea niet publiek leesbaar is. |
|
|
|
|
**Een release publiceren**
|
|
|
|
Een kale Git-tag is niet genoeg: `releases/latest` geeft alleen echte releases terug.
|
|
`release.ps1` maakt die aan (stap 4) met de changelog-sectie van die versie als
|
|
release-notes. Daarvoor is een Gitea-token met release-rechten nodig:
|
|
|
|
```powershell
|
|
$env:GITEA_TOKEN = "<token>"
|
|
.\release.ps1
|
|
```
|
|
|
|
Zonder token slaat het script die stap over met een waarschuwing — images en tag
|
|
staan dan wel klaar, maar gebruikers zien geen melding tot de release bestaat.
|