• v1.0.13 Stable

    jhoogie released this 2026-10-01 17:00:42 +02:00 | 13 commits to main since this release

    Opgelost

    • De kaart "Rendement Eigen Vermogen" op Voortgang stond leeg. Bedrag en
      percentage waren sinds de eerste commit hardcoded als — in de JSX; er zat
      geen berekening achter en evRows werd niet eens uit de context gehaald. Het
      oogde als een datafout — lege database, mislukte API-call — maar de kaart was
      nooit afgebouwd. Hij rekent nu met dezelfde formule als het blok "Rendement"
      op Eigen vermogen: huidige waarde min geïnvesteerde fiat, gedeeld door die
      inleg. Groen bij winst, rood bij verlies, en — zolang er niets is ingelegd,
      zodat er niet door nul wordt gedeeld
    • Beide kaarten tonen daarmee hetzelfde totaal. Dat is bewust: twee plekken die
      "rendement" noemen horen niet twee verschillende getallen te geven

    Gewijzigd

    • De achtergrond achter een popup is lichter: rgba(0,0,0,0.75) naar 0.45 in
      de gedeelde Overlay. Op 0.75 was van het scherm eronder vrijwel niets meer
      te zien, terwijl je bij het invullen van een modal juist wilt kunnen nakijken
      waar je vandaan kwam. Gedimd genoeg om de modal de aandacht te laten houden
    • De popups van NavBar, Instellingen en Gebruikersbeheer gebruiken de gedeelde
      Overlay niet maar hadden hun eigen backdrop op rgba(0,0,0,0.55) met
      backdropFilter: blur(4px). Alle drie staan nu op dezelfde 0.45, en de blur
      is eruit: die maakte de achtergrond onscherp in plaats van zichtbaar, en
      zonder dat weg te halen bleven ze alsnog afwijken van de rest. Vier
      popup-backdrops, één waarde
    Downloads
  • v1.0.12 Stable

    jhoogie released this 2026-09-18 15:21:20 +02:00 | 14 commits to main since this release

    Beveiliging

    • De postgres-container draait niet meer als root. Beide compose-bestanden
      starten hem met user: "postgres". Alle 46 bevindingen op postgres:18-alpine
      zitten in één bestand — /usr/local/bin/gosu, dat upstream met Go 1.24.6
      compileert — en het entrypoint roept gosu alleen aan als het als root start.
      Non-root starten slaat die tak over, dus de binary draait nooit meer. De
      Alpine-pakketten in dat image zijn zelf schoon
    • Getest op een bestaande database die ooit als root was aangemaakt: die start
      als non-root en de data blijft intact. Ook een verse database initialiseert
      gewoon
    • Bewust géén eigen postgres-image gebouwd om die binary te verwijderen. Dat zou
      de scan op nul zetten maar je verplichten het image zelf te herbouwen bij elke
      postgres-patch — precies de achterstand die het image vier maanden op 18.4 met
      143 bevindingen hield. De afweging staat in BEHEER.md, zodat de volgende
      scan niet opnieuw tot dezelfde vraag leidt
    • test.ps1 waarschuwt bij stap 4 wanneer postgres:18-alpine in de registry
      nieuwer is dan wat er lokaal staat. Die achterstand is het werkelijke risico;
      het getal in de scan is dat niet
    Downloads
  • v1.0.11 Stable

    jhoogie released this 2026-09-18 13:40:28 +02:00 | 15 commits to main since this release

    Beveiliging

    • PostgreSQL 18.4 → 18.6. Het postgres:18-alpine image dat in gebruik was
      dateerde van vier maanden geleden. Dat is een patch binnen dezelfde major, dus
      de data-directory blijft geldig en er komt geen dump/restore aan te pas — het
      volume blijft gewoon staan. De kwetsbaarhedenscan op het image gaat van 143
      naar 45 bevindingen, het grootste deel in de Alpine-pakketten eronder. Wat
      overblijft (1 kritiek, 21 hoog) zit allemaal in Go's stdlib v1.24.6 in een
      meegecompileerde binary; dat kan alleen upstream oplossen
    • BEHEER.md beschreef alleen de major-upgrade, met een docker compose down -v erin. Wie dat bij een patch-upgrade zou volgen, wist zijn database zonder
      dat het nodig is. De twee gevallen staan nu apart beschreven
    • De imagescan staat op nul. De scan van 1.0.10 gaf 39 bevindingen
      (1 kritiek, 12 hoog, 15 middel, 11 laag). Geen enkele kwam uit deze
      applicatie: twintig zaten in libssl3 en libcrypto3 (Alpine in het
      node-image liep achter op 3.5.8-r0) en negentien in de dependencies die npm
      zelf meelevert — tar, pacote, sigstore, brace-expansion, picomatch,
      ip-address. De eigen ip-address van de app stond al op 10.7.0 en was dus
      nooit het probleem
    • Het productie-image doet nu een apk upgrade aan het eind van de build. Het
      node-image wordt minder vaak herbouwd dan Alpine patches uitbrengt, dus
      OpenSSL loopt er structureel op achter
    • npm, npx, corepack en yarn gaan uit het productie-image. De container start
      met node src/server.js en gebruikt nooit een pakketbeheerder; ze zaten er
      alleen in omdat het base-image ze meelevert. Weg met de tool is weg met die
      hele categorie, ook bij de volgende ronde — npm's dependencies zijn een
      terugkerende bron van meldingen
    • Nieuwe teststap [4/5] Imagescan met Trivy, die het gebouwde image scant en
      faalt op CRITICAL of HIGH waarvoor een fix bestaat (--ignore-unfixed, want
      een CVE zonder patch hoort je release niet te blokkeren). -Strict trekt de
      lat naar MEDIUM en LOW, -SkipScan slaat hem over. Stap 1 kijkt naar de
      package.json's en had geen van deze 39 gezien; deze kijkt naar wat er
      werkelijk in het image zit. release.ps1 draait dezelfde scan vóór het
      pushen, dus een image met openstaande CVE's komt de registry niet meer in

    Toegevoegd

    • Export naar HTML. Onder Instellingen staat naast backup en restore nu
      "Exporteren naar HTML": één zelfdragend bestand met al je gegevens, bedoeld
      als laatste vangnet. Draait de app niet meer, is de database weg en ligt er
      geen backup, dan is dit bestand nog steeds te openen — in elke browser, op een
      computer zonder internet. Er zit niets van buiten in: opmaak staat inline,
      geen lettertypen, geen afbeeldingen, geen scripts
    • De pagina toont een samenvatting met de KPI's, en daaronder eigen vermogen en
      schulden per categorie met subtotalen en een eindtotaal, de voortgangstabel
      met verschil per moment, en de historie van EV en schuld. Bedragen staan met
      twee decimalen — anders dan het scherm, want dit is een archiefstuk waar de
      exacte waarde in hoort — rechts uitgelijnd met cijfers van gelijke breedte
    • Het bestand is tegelijk een backup. Onderin staat de complete ruwe data in
      een <script type="application/json">-blok dat de browser niet uitvoert en
      niet toont. "Backup herstellen" accepteert daarom nu naast de ZIP ook zo'n
      HTML-bestand. Eén bestand dat je zowel kunt lezen als kunt terugzetten
    • Uitvoer wordt zowel als HTML als binnen het JSON-blok ge-escaped. Een post die
      Fonds <A> & co heet, of een </script> in de gegevens, sloopt de pagina
      niet en breekt de ingebakken backup niet open
    • Nieuwe utils/htmlExport.js, met leesHtmlBackup voor de weg terug. Die
      gebruikt DOMParser en geen reguliere expressie: de gegevens kunnen van alles
      bevatten, en een parser die HTML echt begrijpt trapt daar niet in. Geen nieuwe
      dependency
    • De voortgangstabel is Datum plus één kolom per categorie plus vier vaste
      kolommen — bij zes categorieën twaalf stuks, en die passen op geen enkel
      scherm. De tabellen scrollen daarom horizontaal in plaats van kolommen buiten
      beeld te laten vallen. De datumkolom blijft daarbij staan, want zonder die
      kolom weet je niet meer naar welk moment je kijkt, en een schaduwrandje
      verschijnt aan de kant waar nog inhoud zit. Dat laatste is een CSS-truc met
      meeschuivende achtergronden: de pagina mag geen scripts bevatten, maar zonder
      hint ziet niemand dat er rechts meer staat. Op print vervalt het allemaal en
      wordt de tabel kleiner gezet, zodat alle kolommen op papier alsnog meekomen
    • De initiële schuld stond wel in de gegevens maar niet op de pagina. Hij
      hoort niet bij een schuldblok, dus zonder eigen regel viel hij buiten de
      export. Staat er nu onder de schuldentabel, met "afgelost sinds start" erbij
    • Stortingen op een verwijderde categorie blijven in oude voortgangsrijen
      staan, maar de app toont alleen kolommen van bestaande categorieën — die
      bedragen waren dus nergens meer te zien. De export geeft ze alsnog een kolom,
      gemerkt als Verwijderd (c9). Voor een bestand dat alles moet bewaren wat je
      ooit hebt ingevoerd is stil weglaten het verkeerde gedrag
    Downloads
  • v1.0.10 Stable

    jhoogie released this 2026-09-17 17:27:26 +02:00 | 16 commits to main since this release

    Opgelost

    • Het laatste label op de x-as viel over zijn buurman heen (mei '26 en 26
      over elkaar). De stap werd vanaf het begin van de reeks geteld en het laatste
      punt werd daar los bovenop geforceerd, zodat het op willekeurige afstand van
      zijn voorganger landde — bij een reeks die niet toevallig op een veelvoud
      uitkwam, pal ernaast. De stap telt nu terug vanaf het laatste punt: dat valt
      daarmee per definitie op een stap en houdt volle tussenruimte, zonder dat er
      nog een uitzondering voor nodig is
    • De breedte waarop de grafiek rekent ging van 46 naar 54px per label, zodat er
      lucht tussen staat in plaats van kop-aan-kop. Over reekslengtes van 13 tot 120
      punten blijft de tussenruimte nu minimaal 57px
    Downloads
  • v1.0.9 ad45e372e6

    v1.0.9 Stable

    jhoogie released this 2026-09-17 16:28:52 +02:00 | 17 commits to main since this release

    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
    Downloads
  • v1.0.8 0b67f346e1

    v1.0.8 Stable

    jhoogie released this 2026-09-15 14:06:24 +02:00 | 18 commits to main since this release

    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
    Downloads
  • v1.0.7 750dc69e56

    v1.0.7 Stable

    jhoogie released this 2026-09-11 17:12:49 +02:00 | 19 commits to main since this release

    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
    Downloads
  • v1.0.6 b4d1e25e50

    v1.0.6 Stable

    jhoogie released this 2026-09-11 15:21:48 +02:00 | 20 commits to main since this release

    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
    Downloads
  • v1.0.5 e315039c35

    v1.0.5 Stable

    jhoogie released this 2026-09-11 14:07:21 +02:00 | 21 commits to main since this release

    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
    Downloads
  • v1.0.4 04e70208bd

    v1.0.4 Stable

    jhoogie released this 2026-09-10 21:25:54 +02:00 | 23 commits to main since this release

    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
    Downloads