2026-09-04 09:19:14 +02:00
# Changelog
2026-09-11 14:05:55 +02:00
## [Niet vrijgegeven]
2026-09-17 16:23:39 +02:00
### Gewijzigd
- De x-as van beide grafieken toont korte maandlabels (`sep '26` ) in plaats van
een volledige datum bij elk punt, en ze staan rechtop in plaats van 45 graden
gedraaid. Tien tekens gedraaid kosten zo'n 45px en er passen er maar een stuk
of veertien op de tekenbreedte; bij een langere reeks liepen ze door elkaar
heen tot één grijze band. De grafiek rekent nu uit hoeveel labels er passen en
toont elke n-de, met het laatste punt er altijd bij — groeit je reeks, dan dunt
hij vanzelf verder uit
- Doordat de labels niet meer gedraaid zijn is de ruimte eronder kleiner: `pb`
van 52 naar 30 op het dashboard en van 62 naar 34 op Voortgang. Die hoogte gaat
naar de lijn zelf
- Nieuwe formatter `fmtMaand` in `utils/format.js` , naast `fmtDatum`
- De lijnen in de Voortgang-grafieken zijn vloeiend, net als op het dashboard.
Ze werden met `<polyline>` als rechte segmenten getekend; nu met dezelfde
Catmull-Rom afronding. De gradient eronder is daarmee ook een `<path>` in
plaats van een `<polygon>`
- `crPath` stond als lokale functie in `DashboardTab.jsx` en is verhuisd naar
`utils/grafiek.js` , samen met `vlakPad` voor de vulling onder een lijn. Twee
grafieken die dezelfde curve horen te tekenen moeten niet elk hun eigen kopie
hebben. In dat bestand staat ook waaróm de inleglijn bewust géén afronding
krijgt: een spline schiet tussen twee punten iets buiten hun bereik, en bij
een reeks die nooit terugloopt tekent dat een daling die er niet is
### Opgelost
- De tooltip van de Voortgang-grafiek toonde alleen een bedrag. Nu de x-as geen
dagen meer noemt was dat de enige plek waar de exacte datum nog te lezen was,
en die stond er niet in. De tooltip heeft er een datumregel bij
## [1.0.8] - 2026-09-15
2026-09-15 14:02:17 +02:00
### Toegevoegd
- **Kleurthema's.** Negen paletten in `frontend/src/constants/themas.js` , te kiezen
onder Instellingen naast de dark-mode schakelaar. Thema en licht/donker staan
los van elkaar: het thema levert het accent, de schakelaar de ondergrond. Dat
scheelt een compleet tweede palet per thema en laat de bestaande schakelaar
doen wat hij deed
- `useTheme(themaId, darkMode)` leidt randen, invoervelden en schaduwen af uit
het accent van het thema, dus die kleuren vanzelf mee. Nieuwe sleutels op `T` :
`accent` , `accentLicht` , `accentTekst` , `accentGradient` , `chartVan` ,
`chartTot` , `darkMode` , `themaId` en `themaNaam` . De bestaande sleutels houden
hun naam en betekenis, zodat er niets hoeft te wijzigen dat ze al gebruikt
- Het accent dat tekst draagt is per ondergrond een andere stap van dezelfde
kleur — de lichte op donker, de donkere op licht. Eén stap voor beide modi
haalt aan één kant altijd te weinig contrast
### Opgelost
- De weergavevoorkeuren overleven een herlaad. `darkMode` stond op
`useState(true)` en werd nergens bewaard: zette je de app op licht en laadde je
opnieuw, dan stond je weer in het donker. Thema en modus gaan nu naar
localStorage, net als de kolombreedtes. Ze staan los van je financiële data en
gaan dus niet mee in de backup-ZIP
- `VoortgangTab.jsx` bepaalde de modus met `T.bg === "#0f1117"` . Die kleur is de
achtergrond allang niet meer (dat is `#241A39` ), dus de grafiek gebruikte
altijd de lichte rasterlijnen — ook in het donker. Leest nu `T.darkMode` , wat
met instelbare thema's sowieso de enige werkbare manier is
- De kolomkoppen van de categorieën hebben een `title` , net als de
Opmerkingen-cellen al hadden: bij de standaardbreedte kapt "Crowdfunding" af
- De dark-mode schakelaar in `InstellingenModal.jsx` was een `<div>` met een
klik-handler en dus niet met het toetsenbord te bedienen. Nu een
`<button role="switch">` met `aria-checked`
### Gewijzigd
- De accenten door de hele app lopen via het thema. Ongeveer 80 verwijzingen in
negen bestanden: knoppen, badges, de actieve tab, de doelbalk, de avatar, het
logo in de navigatiebalk en de gradient van de vermogenslijn in de grafiek.
`PURPLE` en `PURPLE_LIGHT` werden in vijf bestanden uit `constants/index.js`
geïmporteerd; die blijven bestaan voor het loginscherm, maar de app leest nu
`T.accent` en `T.accentTekst`
- De knopstijlen `primaryBtn` , `editBtn` en `addBtn` in `EigenVermogenTab.jsx` en
`SchuldTab.jsx` zijn functies van `T` geworden, zoals `cancelBtn` al was — een
object op moduleniveau kan het thema niet volgen
- `VBadge` , `TabBtn` en `VProgressBar` in `components/ui/index.jsx` lezen hun
standaardkleur uit het thema in plaats van uit een geïmporteerde constante. Wie
een kleur meegeeft houdt die, dus de categorie- en schuldkleuren blijven staan
- Een paar plekken die in lichte modus nauwelijks werkten, lopen nu ook via het
thema: de doelbalk had `rgba(255,255,255,0.07)` als achtergrond (onzichtbaar op
wit) en de tooltips in beide grafieken hadden een vaste donkere vulling
### Bekend
- Het loginscherm blijft bewust op de huisstijl. Daar zit bijna de helft van alle
paarse accenten (32 van de 70) voor een scherm dat je enkele seconden ziet — en
bij opslag per account weet je daar nog niet welk thema je moet tonen
- De kleurenkiezer voor schuldblokken (`SchuldTab.jsx` ) en de categoriekleuren
houden hun vaste lijst. Dat is data van de gebruiker, geen thema
## [1.0.7] - 2026-09-11
2026-09-11 17:11:11 +02:00
### Opgelost
- De tooltip van de dashboardgrafiek viel buiten de tekening zodra vermogen en
inleg ver uit elkaar lagen. Hij werd boven het hoogste punt geplaatst en klapte
naar onderen als daar geen ruimte was — maar dat "onderen" rekende vanaf het
laagste punt, en met een kaart van 76px kwam hij dan onder het tekenvlak
terecht: over de datumlabels heen en half afgekapt. Precies in het midden van
de grafiek, waar je hem het meest gebruikt. De kaart staat nu náást de
hoverlijn (links of rechts, afhankelijk van waar de meeste ruimte is) en wordt
verticaal geklemd binnen het tekenvlak, dus hij past altijd
## [1.0.6] - 2026-09-11
2026-09-11 15:20:09 +02:00
### Toegevoegd
- De grafiek "Ontwikkeling van Eigen Vermogen" op het dashboard heeft een tweede
lijn: de **cumulatief geïnvesteerde fiat** . Die is opgebouwd uit dezelfde
gegevens als de KPI's erboven — het oudste voortgangsmoment telt als inleg,
elke latere rij telt zijn stortingen erbij op — zodat het laatste punt van de
lijn exact gelijk is aan "Totaal geïnvesteerde fiat". Het verschil tussen de
twee lijnen is je rendement, en dat staat nu ook in de tooltip: vermogen,
ingelegd en resultaat per datum
- Legenda boven de grafiek, nodig zodra er meer dan één lijn in staat
### Gewijzigd
- De inleglijn wordt met rechte segmenten getekend en niet met de
Catmull-Rom-afronding van de vermogenslijn. Cumulatieve inleg loopt nooit
terug, maar de bezier-afronding trekt tussen twee ongelijke stortingen een
doorbuiging onder het vorige punt — dan zou de grafiek een daling tonen die
in de data niet bestaat
- De y-as schaalt op beide reeksen. Op alleen de vermogenswaarden zou de
inleglijn buiten beeld lopen zodra je meer hebt ingelegd dan het vermogen
waard is
- De schermentabel in `README.md` beschreef het Dashboard als "totaal eigen
vermogen, schulden en netto vermogen". Dat klopte niet: `DashboardTab.jsx`
leest `totSchuld` helemaal niet en toont geen schuld en geen nettowaarde — dat
staat op het Voortgang-tabblad. De rij noemt nu wat er wél staat (KPI's over
inleg, vermogen, winst en ROI, de doelbalk en de grafiek), met een alinea
eronder over de twee lijnen
### Bekend
- De screenshot bovenaan `README.md` is van vóór deze wijziging en toont de
grafiek nog met één lijn
## [1.0.5] - 2026-09-11
2026-09-11 14:05:55 +02:00
### Gewijzigd
- De documentatie is gelijkgetrokken met de code. `README.md` : de bestandsboom
miste `backend/src/logger.js` , `docker/check-updates.mjs` ,
`frontend/public/` , `InstellingenModal.jsx` , `LoginBackground.jsx` en de
losse bestanden in `utils/` , en noemde de update-route `update-check` terwijl
het bestand `routes/update.js` heet. De schermentabel gebruikt nu de labels
zoals ze in `constants/index.js` staan ("Schuld", "Voortgang Schuld & EV") en
vermeldt **Instellingen** — thema plus backup/restore via ZIP, dat nergens in
de README stond
- De tabel "wat de app met een verzoek doet" (in beide bestanden) noemde alleen
`/assets/...` en de SPA-fallback. `server.js` kent vier gevallen: `no-store`
op de API en op HTML, een jaar `immutable` op de gehashte bundels,
`must-revalidate` op bestanden met een vaste naam (`favicon.svg` , `icons/*` )
en een echte 404 op een pad mét extensie waar geen bestand achter zit
- `BEHEER.md` beschreef `Bewerker` als "data lezen en bewerken" en `Viewer` als
"alleen lezen". Zo werkt het niet: `requireAdmin` is de enige rolcontrole in
de code en bewaakt alleen `/api/users` . Een `Viewer` mag daardoor gewoon zijn
eigen data schrijven — geen gat in de afscherming, want `/api/data` gaat altijd
over de rij van het eigen token, maar wél iets anders dan er stond. De sectie
zegt nu wat de code doet en wat er nodig is voor een echt read-only account
- `README.md` en `BEHEER.md` wijzen bij backup naar het juiste niveau: de ZIP
onder Instellingen bevat alleen de data van de ingelogde gebruiker, `pg_dump`
is de volledige servercopie
- `DATABASE_URL` staat in de variabelentabel van `README.md` . Hij wordt door
`docker-compose.yml` samengesteld uit de `POSTGRES_*` waarden, dus zelf zetten
is alleen nodig buiten Compose
2026-09-10 21:33:44 +02:00
## [1.0.4] - 2026-09-10
2026-09-10 15:40:27 +02:00
2026-09-10 16:51:06 +02:00
### Gewijzigd
- Git-tags krijgen weer een `v` -prefix (`v1.0.4` ), net als t/m `v1.0.0` . Sinds
1.0.1 was dat `1.0.1` , `1.0.2` , `1.0.3` — en omdat Gitea de tag op de
release-pagina toont, stond daar het kale nummer terwijl de release-naam wél
`v1.0.3` was. De image-tags in de registry houden bewust géén `v` ; dat is de
conventie voor container-tags. De update-check verdraagt beide: backend en
frontend strippen een leidende `v` voordat ze versies vergelijken
### Opgelost
- Het omzetten van de changelog-kop slokte de lege regel eronder op, waardoor
`## [x.x.x] - datum` direct tegen `### Toegevoegd` aan kwam te staan. Oorzaak
was `\s*$` in het zoekpatroon: `\s` matcht ook newlines. Het patroon eindigt nu
op `[ \t]*(?=\r?$)` — een lookahead, want dit bestand heeft CRLF en met alleen
`[ \t]*$` matchte de kop helemaal niet meer (de `\r` zit ertussen). Zo blijft
de match binnen één regel én blijft het regeleinde ongemoeid
## [1.0.3] - 2026-09-10
2026-09-10 16:24:30 +02:00
### Toegevoegd
- `release.ps1` zet de changelog-kop `## [Niet vrijgegeven]` nu zelf om naar
`## [x.x.x] - datum` , net zoals het al deed met `frontend/package.json` en de
README-badge. Handmatig omzetten hoeft dus niet meer
- Staat er ook na die omzetting niets over deze versie in `Changelog.md` , dan
breekt het script af **vóór** de build met de melding wat je moet toevoegen.
Eerder viel het stil terug op de tekst `"Release x.x.x"` en meldde het
"Gepubliceerd" — dat overkwam 0.1.9 en 1.0.2, en is achteraf alleen met een
`PATCH` op de release te herstellen. Nieuwe switch `-NoChangelog` om bewust
zonder release-notes te publiceren
- `release.ps1` zet na een geslaagde release de versie in de root
`package.json` op `x.x.(x+1)-dev` . Dat was voorheen de laatste handmatige stap
van de release-workflow. Het staat bewust ná het publiceren, zodat een
afgebroken release het nummer niet vooruit schuift
### Opgelost
- **`-DryRun` in combinatie met `-Force` verwijderde écht de Git-tag.** De twee
commando's in stap 4 (`git tag -d` en `git push origin :refs/tags/x.x.x` )
liepen niet via `Invoke-Cmd` en hadden dus geen droogloop-controle. Gitea
ruimt de release op zodra de tag verdwijnt, dus een droogloop kon een
gepubliceerde release wissen — zo is de release van 1.0.2 verloren gegaan en
opnieuw aangemaakt. Onder `-DryRun` worden beide nu alleen gemeld
### Gewijzigd
- De changelog-controle staat vóór de drie auto-updates, zodat een afgebroken
release geen gewijzigde bestanden achterlaat terwijl hij "er is niets
gepubliceerd" meldt
- Stap 5 leest de release-notes uit het geheugen in plaats van opnieuw van
schijf. Een droogloop schrijft de kop niet, en toonde daardoor de placeholder
in de payload — precies wat je met een droogloop wilt uitsluiten
- De Quick Start in `README.md` begint nu met het ophalen van
`docker-compose.yml` (clone, of alleen die twee bestanden via `raw` ). Zonder
dat bestand antwoordt `docker compose pull` met `no configuration file
provided: not found` , en die stap ontbrak. Beide foutmeldingen staan er nu bij
met hun oorzaak
## [1.0.2] - 2026-09-10
2026-09-10 15:40:27 +02:00
### Gewijzigd
- De update-melding op het belletje toont alleen nog de kop, de versieregel en de
link naar de release. De release-notes stonden er als ruwe Markdown in — in een
kaart van 280px leverde dat zichtbare `### ` -koppen en afgekapte regels op.
`/api/update-check` stuurt `notes` nog wel mee, zodat ze later ergens met meer
ruimte gebruikt kunnen worden
- `BEHEER.md` legt vast dat de release-link uit Gitea's `ROOT_URL` wordt
samengesteld en niet per release wordt opgeslagen: na een `ROOT_URL` -wijziging
plus herstart zijn álle releases in één keer goed, ook de oude. Verder staat er
nu hoe je aan het verschil tussen `401` en `403` ziet of een token nog leeft, en
hoe je anoniem over https fetcht als SSH niet meedoet
2026-09-10 14:16:09 +02:00
## [1.0.1] - 2026-09-10
2026-09-09 12:43:11 +02:00
2026-09-10 14:03:34 +02:00
### Toegevoegd
- Kolommen in de tabellen op Eigen Vermogen ("Geïnvesteerde Fiat") en Voortgang
zijn versleepbaar: pak de rechterrand van een kolomkop. De breedtes gaan per
tabel naar localStorage, dus ze overleven een tabwissel en een herlaad;
dubbelklik op de greep zet één kolom terug op zijn standaardbreedte. De logica
staat in de nieuwe hook `frontend/src/hooks/useKolomBreedtes.js` , de greep zelf
is `.kolom-grip` in `App.css`
2026-09-09 21:59:18 +02:00
### Gewijzigd
2026-09-10 14:03:34 +02:00
- De `Vibe` -organisatie in Gitea staat op **public** , dus lezen vereist geen
token meer: `git clone` , `docker compose pull` en de update-check werken
anoniem. `UPDATE_CHECK_TOKEN` in `.env` is daarmee optioneel — de code
ondersteunt hem nog als vangnet voor het geval de organisatie weer privé
wordt. Schrijven verandert niet: `docker push` en het aanmaken van een release
hebben nog steeds het werkstation-token nodig
2026-09-10 14:30:18 +02:00
- Het tweetoken-model in `BEHEER.md` is teruggebracht tot **één** Gitea-token op
het werkstation, met `write:package` en `write:repository` . Het host-token is
niet meer nodig (pull en update-check zijn anoniem), `git push` gaat over SSH,
en `REGISTRY_TOKEN` hoeft niet apart: `release.ps1` en `dev.ps1` vielen daar al
terug op `GITEA_TOKEN` . Geen code-wijziging, alleen minder te beheren
2026-09-10 14:03:34 +02:00
- De tabellen op Eigen Vermogen en Voortgang staan op `table-layout: fixed` ,
nodig om ingestelde kolombreedtes te respecteren. Gevolg: lange tekst rekt een
kolom niet meer op maar wordt afgekapt met een ellips. De Opmerkingen-cellen
hebben een `title` , dus hover geeft de volledige tekst
2026-09-09 21:59:18 +02:00
- Het label bij een beschikbare update in "Over VibeFinance" is "Nieuwe versie"
(was "Nieuwste versie" in 1.0.0)
### Opgelost
2026-09-10 14:03:34 +02:00
- De sticky kolomkop van die tabellen was in dark mode maar 30% dekkend: hij
gebruikte `T.card` (`rgba(22,23,27,0.30)` ), waardoor de rijen tijdens het
scrollen zichtbaar door de koptekst heen liepen. Nu `T.popupBg` , de
ondoorzichtige variant die al in het thema stond
- In dev bakte Vite de versie uit `frontend/package.json` in in plaats van de
versie uit de root `package.json` . `VITE_APP_VERSION` kwam alleen als
build-arg mee, maar de `development` -stage in de `Dockerfile` declareert die
`ARG` niet — en Vite bakt de constante in bij het *starten* van de dev-server,
niet bij het bouwen van het image. De variabele staat nu in de
runtime-omgeving van de dev-container; `vite.config.js` valt met `||` (was
`??` ) terug op `package.json` als hij leeg is
2026-09-09 21:59:18 +02:00
- API-antwoorden sturen nu `Cache-Control: no-store` . Ze hadden alleen een
`ETag` en geen cache-beleid, waardoor de browser zelf mocht bepalen hoe lang
hij ze hergebruikte — per browser en profiel verschillend. Gevolg: de
update-melding bleef in Brave op een oud antwoord hangen (nog van vóór het
werkende token) terwijl een verse Edge het goede kreeg
## [1.0.0] - 2026-09-09
2026-09-09 17:36:34 +02:00
### Gewijzigd
- `BEHEER.md` heeft één centrale `## Tokens` -sectie met het tweetoken-model
(werkstation `write:*` , Docker-host `read:*` ) plus de betekenis van een 401,
403 en 404 van Gitea; de Registry-, pull- en update-secties verwijzen daarnaar
in plaats van de scopes elk apart uit te leggen
- `.env.example` noemt bij `UPDATE_CHECK_TOKEN` de vereiste scope
(`read:repository` ) en wat je ziet als die ontbreekt
- "Over VibeFinance" noemt de beschikbare update nu "Nieuwste versie" in plaats
van "Nieuw beschikbaar"
- `README.md` bijgewerkt: de Quick Start noemt de `docker login` die een pull uit
de privé-registry vereist (die stap ontbrak), de release-sectie verwijst naar
`.env.release` en `write:repository` , en `UPDATE_CHECK_TOKEN` noemt zijn scope
- `release.ps1` werkt de versiebadge in `README.md` bij, net als de versie in
`frontend/package.json` — die badge stond drie releases achter. Een `-DryRun`
meldt de wijziging en schrijft niet
- `README.md` heeft ruimte voor een screenshot onder de badges
(`docs/screenshot-dashboard.png` ); `docs/` staat in `.dockerignore` en `.png`
en `.jpg` zijn in `.gitattributes` als binair vastgelegd
- Badges `React_18` → `React_19` (de app draait op React 19.2)
- `BEHEER.md` legt bij de release-workflow vast wat het script zelf bijwerkt
(`frontend/package.json` en de README-badge), en dat de changelog-kop exact
`## [x.x.x]` moet zijn — anders vallen de release-notes terug op
`"Release x.x.x"` , zoals bij 0.1.9 gebeurde
- Projectboom in `README.md` bevat `docs/` en `frontend/src/version.js`
## [0.1.9] - 2026-09-09
2026-09-09 12:43:11 +02:00
### Gewijzigd
- `release.ps1` leest een `.env.release` naast het script in (niet in git), zodat
`GITEA_TOKEN` en de registry-credentials niet elke shell opnieuw gezet hoeven
te worden; een variabele die al in de omgeving staat wint, en alleen de namen
worden gelogd
- `.gitignore` negeert nu alle `.env.*` op `.env.example` na — `.env.release`
zou anders door een `git add .` in git belanden
- `BEHEER.md` beschrijft welke token-scopes waarvoor nodig zijn
(`write:package` voor de registry, `write:repository` voor een release) en
hoe je een 404 in stap 5 nakijkt
- De draaiende versie komt uit de build in plaats van uit een bestand: de
frontend leest `__APP_VERSION__` via het nieuwe `src/version.js` , niet meer
rechtstreeks uit `frontend/package.json` . `vite.config.js` definieerde die
constante al, maar niets gebruikte hem — een productie-image gebouwd terwijl
er een `-dev` in `package.json` stond, sloeg de update-check stil helemaal
over
2026-09-09 11:04:26 +02:00
## [0.1.8] - 2026-09-09
### Gewijzigd
- `BEHEER.md` beschrijft de registry-login die een deploy-machine nodig heeft om
te kunnen pullen: het package is privé, dus ook `docker compose pull` vraagt
een token (`read:package` ) — anoniem geeft de registry `401 Unauthorized`
- Testsuite dekt nu het serveren van de favicon, de cache-headers daarop en de
404 op ontbrekende bestanden
2026-09-09 11:25:35 +02:00
- `release.ps1 -DryRun` schrijft de frontend-versie niet meer echt weg: een
droogloop meldde de sync wél en voerde hem óók uit, waardoor er na een
`-DryRun` een gewijzigde `frontend/package.json` bleef liggen
2026-09-09 11:04:26 +02:00
### Opgelost
- De favicon bleef weg in de browser: `favicon.svg` en `icons/*` hebben geen
hash in hun naam, maar kregen wel een jaar `immutable` mee — een eenmaal
verkeerd gecacht antwoord revalideerde daardoor nooit meer. Alleen de
gehashte bundels in `/assets` houden die cache; de rest revalideert
- `/favicon.ico` en `/apple-touch-icon.png` gaven via de SPA-fallback
`index.html` terug met status 200 en `text/html` — de browser kreeg HTML waar
hij een icoon verwachtte en toonde stil niets, zonder zichtbare fout. Paden
met een bestandsextensie geven nu een echte 404
2026-09-08 22:09:28 +02:00
## [0.1.7] - 2026-09-08
### Gewijzigd
- Versienummer opgehoogd naar 0.1.7
- Eerste release vanaf de opnieuw aangemaakte Gitea-repository, met `main`
als hoofdbranch
2026-09-04 11:51:29 +02:00
## [0.1.6] - 2026-09-04
### Gewijzigd
- **Migratie naar 2 containers**: de Express-app serveert nu zelf de gebouwde
frontend op `/` (met SPA-fallback naar `index.html` ); de aparte nginx-container
is vervallen. Eén image, één origin, geen interne proxy — bedoeld voor
self-hosting op een Raspberry Pi
- Nieuwe multi-stage `Dockerfile` in de root met targets `test` , `development`
en `production` ; `frontend/Dockerfile` , `frontend/nginx-spa.conf` en
`backend/Dockerfile` zijn verwijderd
- `docker-compose.yml` bevat alleen nog `app` en `postgres` ; de app publiceert
`APP_PORT` (standaard 3400) naar containerpoort 3001
- Dev-stack draait beide processen in één container (`docker/dev-entrypoint.sh` ):
API met `node --watch` en de Vite dev-server met hot reload
- Rate limiting geldt alleen nog voor `/api` — statische bestanden werden anders
na 200 requests geblokkeerd
- Content-Security-Policy via Helmet toegespitst op wat de frontend laadt
(Google Fonts, inline styles, base64-avatars)
- Assets met hash worden een jaar `immutable` gecached, `index.html` nooit
- Schema-initialisatie zit nu in `initDb()` in plaats van bij het importeren van
`db.js` , zodat de app zonder database te importeren is (tests)
- `dev.ps1` , `release.ps1` en de shell-wrappers werken met één app-image;
`dev.ps1 up` wist de dev-database niet langer (alleen `dev.ps1 down` )
- `release.ps1` draait de testsuite vóór het publiceren en bouwt voor
`linux/amd64` + `linux/arm64`
2026-09-04 12:21:06 +02:00
- Dependencies naar de nieuwste versies: React 19.2, Vite 8.2,
@vitejs/plugin -react 6.1, Express 5.2, Helmet 8.3, express-rate-limit 8.7,
pino 10.3 / pino-http 11, pg 8.23, dotenv 17.4, bcryptjs 3.0, ESLint 9.39
(frontend) / 10.9 (backend)
- Express 5 vereist benoemde wildcards in routes; `app.use("/api/*")` en
`app.get("*")` vervangen door een prefix-mount en pad-loze middleware
- `dev.ps1 up` gebruikt `--renew-anon-volumes` , anders blijven de oude
`node_modules` in de dev-container staan na een upgrade
- Vite 8 bundelt met Rolldown: `manualChunks` (object-vorm) vervangen door
`build.rollupOptions.output.advancedChunks`
2026-09-04 22:47:48 +02:00
- `release.ps1` controleert vóór de build of origin bereikbaar is en of je op de
registry bent ingelogd, in plaats van pas na een multi-arch build te stranden
op `401 Unauthorized` . Logt zelf in met `REGISTRY_USER` + `REGISTRY_TOKEN`
wanneer die gezet zijn; `dev.ps1 push` doet dezelfde controle
- Git-commando's in `release.ps1` draaien met `BatchMode=yes` , zodat het script
niet blijft hangen op een wachtwoordprompt van SSH
- `release.ps1` , `dev.ps1` en `test.ps1` eindigen expliciet met exitcode 0, en de
slotregel van een `-DryRun` zegt nu dat er niets is gepubliceerd
2026-09-04 22:56:19 +02:00
- Mislukte stappen in `release.ps1` geven geen PowerShell-stacktrace meer maar
een gerichte melding: bij een mislukte push wordt de registry-login opnieuw
getest en volgt de bijbehorende instructie, bij een mislukte tag-push het
https-alternatief
2026-09-04 11:51:29 +02:00
### Toegevoegd
- Testsuite: `backend/test/app.test.js` (11 tests met `node --test` ) voor de
API-routes, SPA-fallback, cache-headers en security-headers
- `test.ps1` / `test.sh` : backend-tests, productiebuild en smoketest op de
echte 2-container stack
- `.env.example` , `.dockerignore` en `.gitignore`
- `STATIC_DIR` als omgevingsvariabele (map met de frontend-build)
2026-09-04 12:21:06 +02:00
- Dependency-check als eerste stap van de testsuite: `docker/check-updates.mjs`
vergelijkt beide `package.json` 's met het npm-register, met bewuste
uitzonderingen in `docker/update-exceptions.json` (`-Strict` om te falen,
2026-09-04 12:24:22 +02:00
`-SkipDeps` om over te slaan)
2026-09-04 12:21:06 +02:00
- ESLint flat configs (`frontend/eslint.config.js` , `backend/eslint.config.js` ) —
`npm run lint` werkte voorheen niet, er was geen configuratie
- Lockfiles voor beide packages (`backend/package-lock.json` was er niet)
- `.gitattributes` : shell-scripts en Docker-bestanden altijd met LF, anders
faalt het shebang in de container
2026-09-04 11:51:29 +02:00
---
2026-09-04 09:19:23 +02:00
## [0.1.5] - 2026-09-04
### Toegevoegd
- Donut-grafieken: hover per categorie toont naam, bedrag en percentage
### Gewijzigd
- Update-check loopt nu via de eigen backend (`/api/update-check` ) in plaats van
rechtstreeks naar de Gitea API — de browser blokkeerde die call (geen CORS-headers)
- Versievergelijking is semver-based: alleen een hoger versienummer meldt, `-dev`
builds melden niets meer
- Update-check herhaalt zich elk half uur en bij terugkeer naar het tabblad
(was: eenmalig bij laden)
- `release.ps1` maakt de Gitea-release aan met de changelog-sectie als release-notes
(een kale Git-tag komt niet in `releases/latest` en gaf dus geen melding)
- Middenwaarde in de donut schaalt mee met de beschikbare ruimte
### Opgelost
- Donkere spleten tussen de donut-segmenten (de tussenruimte liet de achtergrondbaan zien)
- De update-melding op het belletje bleef altijd leeg door de geblokkeerde API-call
---
2026-09-04 09:19:14 +02:00
## [0.1.3] - 2026-04-16
### Toegevoegd
- Versienummer met logo zichtbaar boven de logout-knop in de sidebar
### Gewijzigd
- Registry verplaatst van intern IP (`10.0.3.108:3000` ) naar publieke DuckDNS-hostnaam (`vibehoogie.duckdns.org` ) — toegankelijk via Nginx Proxy Manager
- PostgreSQL productie geüpgraded van versie 16 naar 18 (volume mount aangepast naar `/var/lib/postgresql` )
- Witte rand rondom de app verwijderd (globale CSS reset toegevoegd, `App.css` gekoppeld aan `App.jsx` )
### Opgelost
- Login gaf "Kan geen verbinding maken met de server": `nginx-spa.conf` miste een `/api/` proxy-blok naar de backend-container — alle API-calls kwamen niet aan
---
## [0.0.4] - 2026-04-08
### Toegevoegd
- _Nog in ontwikkeling_
---
## [0.0.3] - 2026-04-08
### Toegevoegd
- Gebruikersbeheer haalt accounts op uit de backend API (was: localStorage)
- Gebruikers bewerken: naam, e-mailadres en wachtwoord aanpassen via ✏️ knop
- Nieuwe gebruiker aanmaken vereist nu ook een wachtwoord
- Eerste geregistreerde gebruiker krijgt automatisch de Admin-rol
- `aangemaakt` kolom toegevoegd aan de `users` tabel (zichtbaar in gebruikersbeheer)
- Custom dropdown component voor rolselectie (past donker thema)
- Voortgang overzicht gebruikt eigen `evVoortgangHistory` — los van geïnvesteerde fiat
### Opgelost
- Data ging verloren na container restart: PostgreSQL 18 gebruikt een ander `PGDATA` pad (`/var/lib/postgresql/18/docker` ). Volume nu gemount op `/var/lib/postgresql`
- Geïnvesteerde fiat invullen vulde automatisch ook het voortgangsoverzicht in
---
## [0.0.2] - 2026-04-01
### Toegevoegd
- PostgreSQL als persistente database (vervangt in-memory opslag)
- JWT authenticatie met instelbare vervaltijd
- Backup en restore via ZIP-bestand
- Rate limiting op auth-endpoints
- Helmet security headers
- Docker multi-stage builds (dev / productie)
- Dev script (`dev.ps1` / `dev.sh` ) voor bouwen, starten en pushen
### Gewijzigd
- Gebruikersdata per account opgeslagen (niet meer gedeeld)
---
## [0.0.1] - 2026-03-01
### Toegevoegd
- Initiële release van VibeFinance
- Dashboard met overzicht van eigen vermogen, schulden en netto vermogen
- Eigen vermogen beheer met categorieën en historiek
- Schulden beheer met blokken en afbetalingsoverzicht
- Voortgangspagina met grafieken (EV en schuld over tijd)
- Gebruikersbeheer en authenticatie
- Dark mode ondersteuning