• v2026.7.20 0ff03ce8df

    v2026.7.20
    All checks were successful
    CI / frontend-test (push) Successful in 4m50s
    publish-main / build (backend) (push) Successful in 2m18s
    CI / backend-test (push) Successful in 8m49s
    release-and-deploy / deploy (push) Successful in 2m9s
    CI / backend-test-postgres (push) Successful in 9m34s
    CI / e2e (push) Successful in 8m47s
    publish-main / build (frontend) (push) Successful in 2m28s
    security-scan / Python SCA (pip-audit) (push) Successful in 57s
    publish-main / build (push) Successful in 0s
    security-scan / SBOM (trivy) (push) Successful in 18s
    release-and-deploy / pre-commit (push) Successful in 51s
    security-scan / Python SAST (bandit) (push) Successful in 39s
    security-scan / Filesystem scan (trivy fs) (push) Successful in 25s
    security-scan / JS SCA (npm audit) (push) Successful in 38s
    release-and-deploy / release (push) Successful in 33s
    release-and-deploy / build (backend) (push) Successful in 2m16s
    release-and-deploy / build (frontend) (push) Successful in 2m28s
    release-and-deploy / build (push) Successful in 0s
    release-and-deploy / frontend-test (push) Successful in 4m56s
    release-and-deploy / release-scripts (push) Successful in 11s
    release-and-deploy / backend-test (push) Successful in 8m53s
    CI / pre-commit (pull_request) Successful in 53s
    release-and-deploy / backend-test-postgres (push) Successful in 9m43s
    CI / frontend-test (pull_request) Successful in 5m23s
    release-and-deploy / e2e (push) Successful in 8m34s
    release-and-deploy / ci (push) Successful in 0s
    CI / release-scripts (pull_request) Successful in 11s
    security-scan / Python SCA (pip-audit) (pull_request) Successful in 58s
    security-scan / Python SAST (bandit) (pull_request) Successful in 34s
    CI / backend-test (pull_request) Successful in 9m5s
    security-scan / JS SCA (npm audit) (pull_request) Successful in 41s
    security-scan / SBOM (trivy) (pull_request) Successful in 17s
    security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 23s
    CI / backend-test-postgres (pull_request) Successful in 10m1s
    CI / e2e (pull_request) Successful in 8m38s
    test-build / build (backend) (pull_request) Successful in 1m46s
    test-build / build (frontend) (pull_request) Successful in 2m1s
    test-build / build (pull_request) Successful in 0s
    CI / pre-commit (push) Successful in 54s
    CI / release-scripts (push) Successful in 11s
    Stable

    robbertbos released this 2026-07-20 07:37:36 +00:00 | 12 commits to main since this release

    Bijlagen: previews van bestanden en grotere kaartjes

    • Niet-afbeelding-bijlagen zijn nu grotere kaartjes in een grid (met type-icoon,
      naam op leesbare grootte, bestandsgrootte en een aparte download-knop) in
      plaats van kleine chips.
    • Video's speel je direct op de pagina af in een modal-speler (met download);
      de file-proxy ondersteunt nu HTTP Range zodat je vlot kunt scrubben.
    • PDF's open je in-page in een preview-modal (met download + open-in-tabblad).
    • HTML-bijlagen (bv. rapporten) open je standaard in een veilige, afgeschermde
      sandbox-preview (scripts/grafieken werken, maar het bestand kan niet bij je
      sessie). Los te downloaden, of - met waarschuwing - buiten de sandbox in een
      nieuw tabblad te openen.

    Onboarding

    • Onboarding-hints: token-hint op het token-veld en een 8-staps
      inbox-rondleiding (menu, secties, snelle acties, kaart openen, thread,
      antwoorden, status en acties, verzenden).
    • De rondleiding komt met een voorbeeldbericht zodat er altijd iets is om
      naar te wijzen - ook met een lege "Doe nu". Het verdwijnt zodra je
      de rondleiding afrondt of overslaat.
    • Bestaande gebruikers met een gekoppelde server krijgen de rondleiding niet
      alsnog te zien (datamigratie).

    Verbeterd

    • Sectie-iconen zeggen nu wat ze bedoelen: "Doe nu" is een vlag (was een oog,
      dat in NLDD "tonen" betekent), "Voltooid" en "Gelezen" zijn een archiefdoos
      en de leeslijst een boek - overal hetzelfde icoon voor hetzelfde begrip.
    • De status- en actie-knoppen in de kaart-modal hebben dezelfde iconen als de
      secties waar ze de kaart heen sturen, en de statusrij staat nu in dezelfde
      volgorde als die secties: Doe nu, Nieuw, Backlog, Bubble up, Voltooid.
    • De toggle "Toon/verberg (concept) antwoord" is weg; de antwoord-composer
      staat altijd open. Scheelt een klik en een knop.
    • De notities-editor kreeg links (met Cmd/Ctrl+K) en emoji, plus een
      takenlijst-knop. De takenlijst is nu ook in de thread-composer beschikbaar
      (Mattermost rendert - [ ] als checklist).
    • Opmaak-werkbalk: de lijst-soorten (opsomming, genummerd, takenlijst) staan
      nu gegroepeerd, gescheiden van citaat en codeblok.
    • Het snooze-icoon (bubble-up) is nu een timer in plaats van een maan; past
      logischer bij "laat deze kaart later terugkomen".
    • Doorhalen, markeren en codeblok in de opmaak-werkbalk gebruiken nu native
      NLDD-iconen (strikethrough / highlighter / code-block) in plaats van
      eigen inline-SVG's, met uniforme icoongrootte.

    Opgelost

    • De beeld-lightbox lag onder de bovenbalk: linksboven klikken raakte de
      navigatie in plaats van de lightbox te sluiten. Hij wordt nu naar body
      geteleporteerd, net als de andere modals.
    • In een codeblok sprong het eerste teken in (inline <code>-padding); nu
      staat elke regel vlak, in zowel de composer als de notities-editor.
    • De tekst-inspringing van de notities-editor is gelijkgetrokken met de
      thread-composer.
    • Een link met een dubbele punt in de URL (bv. een LinkedIn-permalink) werd als
      platte tekst getoond; emoji-shortcodes binnen URLs worden nu met rust gelaten.
    • In de reageerders-hover staat de naam weer netjes uitgelijnd met de avatar.

    Onder de motorkap

    • De uitgaande wachtrij kan geen bericht meer versturen met het Mattermost-token
      van een andere gebruiker. outgoing_posts heeft nu composite foreign keys naar
      de kaart en het account van de eigenaar, en de runner leest de afzender van de
      rij in plaats van van de kaart. Niet exploiteerbaar, maar de garantie zat in een
      gewoonte in plaats van in het schema.
    • Uitloggen beëindigt nu ook de centrale Keycloak-sessie: de app navigeert
      top-level naar het end-session-endpoint (RP-initiated logout) i.p.v. via een
      fetch-redirect, zodat de volgende inlog niet stil via SSO doorgaat.
    • Backchannel-logout heeft nu een rate-limit (60/min in productie).
    • OIDC-inloggen blijft werken tijdens Keycloak-sleutelrotatie: de JWKS wordt
      bij een onbekende sleutel-id direct herophaald i.p.v. tot een uur te falen.
    • OIDC-tokenvalidatie gehard: asymmetrische-algoritme-allowlist, sub en exp
      verplicht, en malformed tokens worden netjes geweigerd i.p.v. een
      onafgehandelde 500.
    • Productie weigert te starten zonder WAGGLE_PUBLIC_HOST als OIDC aan staat:
      de redirect- en post-logout-URL mogen niet van de (spoofbare) Host-header
      afhangen. Op ZAD staat deze variabele al automatisch goed.
    • De dev-only endpoints (wachtwoordloze login, gebruiker wisselen, onboarding
      resetten) bestaan in productie niet meer: ze worden alleen geregistreerd als
      de dev-vlag aanstaat.
    • Alembic-migraties worden voortaan getest: upgrade, downgrade en opnieuw
      upgrade op zowel SQLite als Postgres, met een controle dat het gemigreerde
      schema overeenkomt met de modellen. De testsuite bouwde haar schema rechtstreeks
      uit de modellen, dus een kapotte of ontbrekende revisie bleef groen.
    • click naar 8.4.2: 8.3.2 had een advisory (PYSEC-2026-2132), waardoor de
      pip-audit-gate op elke PR afging. Transitief via typer.
    • Renovate biedt linkify-it 6 niet meer aan: die major laat de default-export
      vallen die markdown-it importeert, waardoor de build en alle composer-tests
      breken. Geblokkeerd tot markdown-it meegaat.
    • Renovate biedt TypeScript 7 niet meer aan: vue-tsc crasht erop
      (typescript/lib/tsc bestaat niet meer) en typescript-eslint eist <6.1.0.
      Geblokkeerd tot beide tools 7 ondersteunen.
    • De frontend-container-build faalde op npm ci (Missing: emojibase@17.0.0 from lock file): de Containerfile kopieerde frontend/.npmrc niet mee, waardoor npm
      daar zonder legacy-peer-deps draaide en de lockfile afkeurde die juist mét die
      vlag is gegenereerd.
    • De file-proxy serveert HTML-previews met een strikte CSP (sandbox allow-scripts + geen netwerk) en X-Frame-Options: SAMEORIGIN, zodat een
      rapport rendert maar niet bij je sessie kan of gegevens kan exfiltreren.
    • NLDD design-system naar 0.8.69: popovers en menu's flitsen niet meer kort op
      een default-positie voordat ze geplaatst worden, en de pagina blijft verborgen
      tot de web-components geladen zijn (geen flash of unstyled content).
    • npm >= 11 vastgelegd (engines in package.json + Renovate constraints)
      zodat de lockfile niet opnieuw scheef raakt: npm < 11 gooit emojibase uit
      package-lock.json, wat Renovate's lockfile-onderhoud liet afbreken
      (lockfile-error) en zo de dependency-PR's blokkeerde.
    • De e2e-CI-job wacht niet meer op frontend-test; hij bouwt zijn eigen
      frontend en deelt er niets mee. De jobs draaien nu parallel, wat de langste
      CI-stap eerder laat starten.
    • Renovate-config opgeschoond: forgejo-platform, Python-groep op pep621 (de
      uv-manager bestaat niet) en de dubbele regex-manager voor zad-actions weg.
    • Afhankelijkheids- en digest-bumps: TipTap 3.27.1 -> 3.28.0, linkify-it 5.0.2 +
      markdown-it 14.3.0 (npm-overrides), uv -> 0.11.29, renovate-image -> 43.259.2,
      dev-Keycloak 26.6 -> 26.7, nginx-unprivileged 1.31.2 -> 1.31.3 en verse
      digest-pins voor Postgres 17 en Python 3.14.6.

    Container images

  • v2026.6.30 dcc5a9f635

    v2026.6.30
    All checks were successful
    CI / pre-commit (pull_request) Successful in 1m5s
    CI / release-scripts (pull_request) Successful in 10s
    security-scan / Python SCA (pip-audit) (pull_request) Successful in 1m0s
    security-scan / Python SAST (bandit) (pull_request) Successful in 42s
    security-scan / JS SCA (npm audit) (pull_request) Successful in 47s
    CI / frontend-test (pull_request) Successful in 4m46s
    security-scan / SBOM (trivy) (pull_request) Successful in 18s
    security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 28s
    CI / backend-test (pull_request) Successful in 7m54s
    test-build / build (backend) (pull_request) Successful in 1m58s
    test-build / build (frontend) (pull_request) Successful in 2m17s
    test-build / build (pull_request) Successful in 0s
    CI / pre-commit (push) Successful in 1m10s
    CI / backend-test-postgres (pull_request) Successful in 9m6s
    CI / release-scripts (push) Successful in 11s
    publish-main / build (backend) (push) Successful in 2m21s
    CI / frontend-test (push) Successful in 4m47s
    publish-main / build (frontend) (push) Successful in 2m45s
    publish-main / build (push) Successful in 0s
    security-scan / Python SCA (pip-audit) (push) Successful in 1m3s
    security-scan / Python SAST (bandit) (push) Successful in 41s
    security-scan / JS SCA (npm audit) (push) Successful in 44s
    security-scan / Filesystem scan (trivy fs) (push) Successful in 23s
    security-scan / SBOM (trivy) (push) Successful in 16s
    CI / backend-test (push) Successful in 7m44s
    release-and-deploy / release (push) Successful in 33s
    CI / backend-test-postgres (push) Successful in 8m54s
    release-and-deploy / pre-commit (push) Successful in 1m8s
    release-and-deploy / build (backend) (push) Successful in 2m10s
    release-and-deploy / build (frontend) (push) Successful in 2m24s
    release-and-deploy / build (push) Successful in 0s
    release-and-deploy / release-scripts (push) Successful in 10s
    release-and-deploy / frontend-test (push) Successful in 4m42s
    release-and-deploy / backend-test (push) Successful in 8m0s
    CI / e2e (pull_request) Successful in 7m47s
    release-and-deploy / backend-test-postgres (push) Successful in 8m56s
    CI / e2e (push) Successful in 5m50s
    release-and-deploy / e2e (push) Successful in 4m45s
    release-and-deploy / ci (push) Successful in 0s
    release-and-deploy / deploy (push) Successful in 2m9s
    Stable

    robbertbos released this 2026-06-30 16:48:20 +00:00 | 75 commits to main since this release

    Verbeterd

    • Een kaart op Voltooid (of Gelezen) zetten in de modal sluit de modal nu
      meteen, in plaats van markeren-en-dan-zelf-sluiten.
    • Scheduled-send biedt 's ochtends vóór 08:00 nu ook "Vandaag 08:00" als
      snelkeuze, naast "Morgen 08:00".
    • De scheduled-send-popover klapt naar boven (of scrollt intern) wanneer er
      onderaan het scherm te weinig ruimte is, zodat hij niet meer buiten beeld
      valt.

    Opgelost

    • De profielkaart van een @-mention toont nu de avatar (de proxy-URL miste het
      vereiste account_id); zonder avatar blijven de initialen staan. Dezelfde
      fix geldt voor de @-mention-autocomplete tijdens het opstellen van een
      antwoord.
    • De sluit-knop op die profielkaart sluit alleen de kaart zelf, niet ook de
      onderliggende kaart-modal.
    • De thread-toon/verberg-knop in de kaart-modal toont weer een icoon (de oude
      icoonnaam bestond niet meer in de NLDD-set).
    • Een >-citaat (en losse </&) in een antwoord kwam als HTML-entiteit
      (&gt;) in Mattermost aan, waardoor de blockquote-opmaak wegviel; de
      markdown wordt nu letterlijk verstuurd.

    Container images

  • v2026.6.28 3a1de067aa

    v2026.6.28
    All checks were successful
    CI / pre-commit (pull_request) Successful in 1m19s
    CI / release-scripts (pull_request) Successful in 11s
    security-scan / Python SCA (pip-audit) (pull_request) Successful in 1m2s
    security-scan / Python SAST (bandit) (pull_request) Successful in 42s
    security-scan / JS SCA (npm audit) (pull_request) Successful in 48s
    security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 25s
    CI / frontend-test (pull_request) Successful in 4m39s
    security-scan / SBOM (trivy) (pull_request) Successful in 20s
    test-build / build (backend) (pull_request) Successful in 2m12s
    test-build / build (pull_request) Successful in 0s
    test-build / build (frontend) (pull_request) Successful in 2m36s
    CI / backend-test (pull_request) Successful in 8m14s
    CI / backend-test-postgres (pull_request) Successful in 9m17s
    CI / pre-commit (push) Successful in 1m17s
    CI / e2e (pull_request) Successful in 5m55s
    CI / release-scripts (push) Successful in 11s
    publish-main / build (backend) (push) Successful in 2m24s
    CI / frontend-test (push) Successful in 4m52s
    security-scan / Python SCA (pip-audit) (push) Successful in 1m3s
    security-scan / SBOM (trivy) (push) Successful in 17s
    CI / backend-test-postgres (push) Successful in 9m27s
    publish-main / build (frontend) (push) Successful in 2m45s
    publish-main / build (push) Successful in 0s
    security-scan / Python SAST (bandit) (push) Successful in 42s
    security-scan / Filesystem scan (trivy fs) (push) Successful in 25s
    security-scan / JS SCA (npm audit) (push) Successful in 43s
    CI / backend-test (push) Successful in 8m31s
    release-and-deploy / release (push) Successful in 35s
    release-and-deploy / pre-commit (push) Successful in 1m19s
    release-and-deploy / build (backend) (push) Successful in 2m28s
    release-and-deploy / build (frontend) (push) Successful in 2m40s
    release-and-deploy / build (push) Successful in 0s
    release-and-deploy / release-scripts (push) Successful in 11s
    release-and-deploy / frontend-test (push) Successful in 5m23s
    release-and-deploy / backend-test (push) Successful in 9m32s
    CI / e2e (push) Successful in 8m28s
    release-and-deploy / backend-test-postgres (push) Successful in 9m54s
    release-and-deploy / e2e (push) Successful in 5m42s
    release-and-deploy / ci (push) Successful in 0s
    release-and-deploy / deploy (push) Successful in 2m4s
    Stable

    robbertbos released this 2026-06-28 21:39:44 +00:00 | 86 commits to main since this release

    Verbeteringen aan de editor

    • De antwoord-composer en notities-editor heeft nu een opmaak-werkbalk. De basis
      bestaat uit een Paragraaf/Kop 1-6-dropdown, vet, cursief, doorhalen, code,
      opsomming, genummerde lijst, citaat en codeblok en links.
      Voor de antwoord-composer aanvullend nog een bijlage- en emoji-knop. Voor de
      notities-editor een onderstrepen, takenlijst en highlight opties.
    • Ctrl/Cmd+K opent een inline link-balk: typ of plak een URL voor de selectie,
      of pas een bestaande link aan / verwijder 'm. Geen window.prompt meer; de
      sneltoets-hint toont platform-bewust (Cmd op Mac, Ctrl elders).
    • Strakkere horizontale marges zodat de editor de beschikbare breedte beter
      benut.

    Reacties en custom emojis

    • Hover of focus op een emoji-reactie toont nu wie er reageerden (avatar +
      naam), met "Jij" bovenaan voor je eigen reactie.
    • Eigen Mattermost-emoji (custom emoticons) worden nu als afbeelding getoond, zowel
      in reacties als in berichttekst; onbekende codes vallen terug op :naam:.

    Verbeterd

    • Importeren: het bestand kies je nu via een gestylede sleepzone (slepen of
      klikken) die de gekozen bestandsnaam toont en een ongeldig bestand duidelijk
      als fout markeert, in plaats van de kale native bestand-knop.
    • Home/End springen nu naar de eerste/laatste kaart binnen een sectie (Focus en
      leeslijst), als aanvulling op de pijltjestoetsen.

    Opgelost

    • Een geopende kaart-modal (en de afbeelding-lightbox) vergrendelt nu de
      achtergrond-scroll, zodat de pagina eronder niet meer wegscrolt.
    • Verzonden/getoonde berichten gebruiken nu dezelfde rustige koppen-schaal als de
      editor (Kop 1 bescheiden, Kop 5/6 niet kleiner dan bodytekst) i.p.v. de grote
      browser-default.
    • Een getypte markdown-link [tekst](url) werd ontsnapt verstuurd
      (\[tekst\](url)) en kwam in Mattermost als platte tekst aan; nu wordt het
      bij het typen een echte link en als schone markdown verstuurd.
    • Afbeelding-previews in de Inbox- en leeslijst-stream worden weer getoond.
    • De bubble-up-popover opende buiten beeld bij een gescrolde pagina (o.a. een
      lange kaart in de modal); staat nu correct boven de knop.

    Design-system opfrissing

    • De reageerders- en mention-profiel-popovers zijn herbouwd op het
      NLDD-popover-component (consistente styling, top-layer-positionering en
      light-dismiss); de reageerders-lijst opent links onder de badge.
    • Statuslabels (concept/ingepland, de "Wacht op verzending"-telling, "Bubbled
      up", "Verschijnt over ...") gebruiken nu de design-system-tag: beter leesbaar,
      AA-contrast in licht en donker, geen HOOFDLETTERS meer.
    • Im-/export tonen een laad-indicator over het paneel bij acties langer dan een
      seconde; de invoer is dan vergrendeld. Korte acties tonen niets.
    • Een thread laden toont nu een laad-animatie naast de tekst.
    • De "/"-zoeksneltoets staat als toetsenbord-hint in het menu (verborgen op
      apparaten zonder toetsenbord).
    • Op smalle schermen klapt de bron-breadcrumb op een kaart in tot … > kanaal;
      de opent server + team in een dropdown. Lange kanaalnamen kappen af met
      een ellipsis, zodat de kaart-acties niet meer buiten de kaart vallen.
    • De geplande/mislukte-berichten-lijst stapelt op smalle schermen in één kolom
      (tijd, bericht, acties onder elkaar) i.p.v. een vaste 3-koloms-grid die de
      inhoud buiten de kaart duwde.

    Onder de motorkap

    • ZAD-productie wordt automatisch (her)deployed bij een CalVer-tag via
      release-and-deploy.yaml (build -> release -> deploy; deploy draait alleen na
      een geslaagde release). PR's draaien test-build (build + scan, geen push),
      main pusht :latest via publish-main; de container-build zelf is een
      herbruikbare workflow (_container-build). De ZAD-deploymentnaam is
      configureerbaar via ZAD_DEPLOYMENT_NAME i.p.v. vast in de workflow, en de
      ZAD-deploy-action staat op v4.0.6.
    • package-lock.json opnieuw gegenereerd met npm 11 (de versie in de
      CI-container) zodat verplichte peer-packages - emojibase en
      vue-eslint-parser - weer in de lockfile staan. Een eerdere herberekening
      onder oudere npm liet ze vallen, waardoor npm ci in de frontend-image en
      de ESLint-stap braken. vue-eslint-parser is bovendien expliciet als
      devDependency vastgelegd.
    • NLDD design-system 0.8.56 -> 0.8.63. Statuslabels en laad-indicatoren
      gebruiken nu nldd-tag / nldd-activity-indicator en de button-variant
      neutral-base; de dark-mode tag-fix komt mee.
    • Afhankelijkheids- en digest-bumps: renovate-image -> 43.245.0, Node
      24.16.0 -> 24.18.0, TipTap 3.26.0 -> 3.27.1, @axe-core/cli 4.11.3 ->
      4.12.1, uv -> 0.11.25, actions/cache v5 -> v6 plus digest-bumps voor
      dev-Keycloak 26.6 en Postgres 17.
    • Release-notes bevatten nu per service een klikbare link naar de
      container-image (image-ref als linktekst naar de package-pagina).
    • Renovate bundelt updates in logische lanes: naast npm / npm-dev / Python /
      nldd nu ook een container images-lane (postgres, keycloak, node, nginx) en
      trivy/uv terug bij de CI-lane. prHourlyLimit 2 -> 5. Security, digest-
      rebuilds en majors blijven losse PR's.
    • Markdown-sanitisatietests draaien onder jsdom i.p.v. happy-dom; happy-dom
      past DOMPurify's allow-lists vanaf 3.4.11 verkeerd toe (blok-tags ontwrapt,
      class= lekt door). Test-only, geen browser-regressie; deblokkeert de
      dompurify security-bump.
    • Renovate bumpt Postgres niet meer voorbij major 17 (allowedVersions <18):
      ZAD draait op 17, dev-compose blijft gelijk tot ZAD meegaat.
    • Security-bumps tegen gepubliceerde advisories, zodat de fail-closed
      pip-/npm-audit-stappen groen blijven. Backend: msgpack 1.1.2 -> 1.2.1
      (GHSA-6v7p-g79w-8964), pydantic-settings 2.13.1 -> 2.14.2
      (GHSA-4xgf-cpjx-pc3j) en joserfc 1.6.5 -> 1.7.1 (CVE-2026-48990).
      Frontend: dompurify 3.4.1 -> 3.4.11 (GHSA-cmwh-pvxp-8882), vite 8.0.10 ->
      8.0.16 (CVE-2026-53571) en via npm-overrides linkify-it 5.0.0 -> 5.0.1
      (GHSA-22p9-wv53-3rq4) + markdown-it 14.1.1 -> 14.2.0 (GHSA-6v5v-wf23-fmfq).

    Container images

  • v2026.6.16 d209132fee

    v2026.6.16
    All checks were successful
    security-scan / Python SCA (pip-audit) (push) Successful in 54s
    security-scan / JS SCA (npm audit) (push) Successful in 32s
    security-scan / SBOM (trivy) (push) Successful in 14s
    CI / release-scripts (push) Successful in 8s
    security-scan / Python SAST (bandit) (push) Successful in 31s
    security-scan / Filesystem scan (trivy fs) (push) Successful in 19s
    CI / backend-test (push) Successful in 4m5s
    CI / frontend-test (push) Successful in 2m29s
    build-containers / build (backend) (push) Successful in 1m45s
    build-containers / build (frontend) (push) Successful in 1m48s
    release / release (push) Successful in 24s
    CI / e2e (push) Successful in 4m7s
    CI / backend-test-postgres (push) Successful in 7m14s
    CI / pre-commit (pull_request) Successful in 41s
    build-containers / build (backend) (pull_request) Successful in 1m38s
    build-containers / build (frontend) (pull_request) Successful in 1m51s
    CI / release-scripts (pull_request) Successful in 9s
    security-scan / Python SCA (pip-audit) (pull_request) Successful in 51s
    security-scan / Python SAST (bandit) (pull_request) Successful in 30s
    CI / frontend-test (pull_request) Successful in 2m53s
    CI / e2e (pull_request) Successful in 3m28s
    security-scan / JS SCA (npm audit) (pull_request) Successful in 36s
    security-scan / SBOM (trivy) (pull_request) Successful in 15s
    CI / backend-test (pull_request) Successful in 4m39s
    CI / backend-test-postgres (pull_request) Successful in 6m47s
    security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 16s
    CI / pre-commit (push) Successful in 42s
    Stable

    robbertbos released this 2026-06-16 21:37:45 +00:00 | 157 commits to main since this release

    Meerdere Mattermost-servers koppelen

    • Veel overheidsorganisaties draaien hun eigen Mattermost-instantie; je kunt
      nu meerdere servers tegelijk koppelen, zodat berichten uit verschillende
      organisaties samen in één Waggle-overzicht komen. Een community-server
      ernaast werkt ook prima. Elke server heeft een eigen token, basis-URL en
      status; de instellingen tonen ze als een lijst met per server token
      vervangen, synchroniseren en loskoppelen.
    • Geef een server een eigen label; laat je het leeg, dan toont Waggle de host
      van de basis-URL als naam.
    • Bij twee of meer gekoppelde servers krijgt de breadcrumb op een kaart de
      server-naam voorop, zodat je ziet uit welke omgeving een bewaard bericht komt.
    • Synchronisatie is per server gescheiden: een verlopen token op de ene server
      houdt het synchroniseren van een gezonde server niet langer tegen, en de
      waarschuwingsbalk benoemt welke server opnieuw gekoppeld moet worden.

    @-vermeldingen

    • Een @naam in een bewaard bericht of thread-reactie toont nu de echte
      weergavenaam. Klik (of Enter) opent een kaartje met foto, functie en
      een knop om de persoon in Mattermost te openen. Werkt met muis,
      toetsenbord en schermlezer. Een onbekende of verwijderde gebruiker
      blijft gewoon als @naam staan.
    • Herkenning blijft binnen het kanaal van de kaart; namen worden alleen
      kort lokaal onthouden en bij uitloggen gewist.

    Onder de motorkap

    Security & CI-hardening:

    • De image-build-gate (trivy image op het gebouwde artefact) draait nu op
      elke PR i.p.v. pas na merge: build + scan zonder push, zodat OS-package-CVE's
      al vóór merge geblokkeerd worden. De frontend-runtime draait daarbij
      apk upgrade (net als de backend al apt-get upgrade deed), zodat
      gefixte base-OS-CVE's bij build-time meekomen i.p.v. te wachten op een
      upstream-rebuild.
    • trivy fs scant nu ook misconfiguraties (Containerfile/compose) naast vuln
      en secret, en de SBOM-generatie is van syft naar trivy verhuisd - één
      CI-dependency minder.
    • CI authentiseert tegen ghcr.io (geen anonymous-pull rate-limit-flakes meer
      op trivy/uv-pulls). Renovate draait via een nachtelijke Forgejo-runner met
      OSV-alerts en een eigen snelle image-digest-lane, zodat base-image-CVE's
      binnen een dag als PR verschijnen. Geen automerge.
    • nginx-base bijgewerkt naar de gepatchte digest met openssl 3.5.7-r0
      (CVE-2026-45447, heap use-after-free in PKCS7_verify, HIGH); de trivy
      image-scan-gate is daarmee weer groen.

    Releases & CI-infra:

    • Releases worden nu automatisch aangemaakt bij een CalVer-tag: de
      release-notes komen uit de bijbehorende CHANGELOG-sectie, en de build faalt
      bewust als die sectie ontbreekt of leeg is.
    • CI-actions grote versie-bumps: actions/checkout v4 -> v6.0.3,
      actions/cache v3 -> v5, actions/setup-node v4 -> v6.4.0 en de frontend
      build-image van node:20 naar node:24.16.0-alpine.
    • CI hergebruikt uv-, npm-, pre-commit- en Playwright-caches tussen runs;
      ~1-2 min sneller per build en minder netwerk-afhankelijk.

    Afhankelijkheden:

    • Backend Python 3.13 -> 3.14 (container, CI-tests en lockfile); dev-Postgres
      16 -> 17, gelijk aan de engine op ZAD en op digest vastgezet.
    • Security-bumps tegen gepubliceerde CVE's: cryptography 46.0.7 -> 49.0.0
      (GHSA-537c-gmf6-5ccf), python-multipart 0.0.28 -> 0.0.32
      (CVE-2026-53537/53538/53539/53540), starlette 1.0.0 -> 1.3.1
      (PYSEC-2026-161, CVE-2026-48817/48818, incl. de bijbehorende
      deprecation-fix), idna 3.11 -> 3.15 (CVE-2026-45409) en cachetools 5.x ->
      7.1.4. pip (dev-tooling) 26.1.1 -> 26.1.2 tegen PYSEC-2026-196, zodat de
      fail-closed pip-audit-stap groen blijft.
    • Frontend: NLDD design-system 0.8.44 -> 0.8.56 - import-, export- en
      account-verwijderen-knoppen tonen tijdens uitvoering een laad-indicator en
      negeren een tweede klik (geen dubbele actie meer). eslint 9 -> 10
      (no-useless-assignment ruimde drie overbodige initialisaties op), TipTap
      3.22.5 -> 3.26.0 plus kleinere bumps. @types/dompurify verwijderd -
      DOMPurify levert sinds 3.0 eigen TypeScript-types.
    • Dev-tooling- en CI-bumps: uv 0.11.14 -> 0.11.19 (incl. UV_SHA256), trivy
      0.70 -> 0.71, @axe-core/cli 4.11.2 -> 4.11.3 en Keycloak (dev) 26.0 ->
      26.6; resterende CI-images vastgepind op digest.
    • Frontend-coverage zichtbaar via @vitest/coverage-v8 (just coverage +
      CI-artefact; baseline 51%, geen drempel).
  • v2026.5.18 2721ddd925

    v2026.5.18
    All checks were successful
    build-containers / build (backend) (push) Successful in 2m8s
    build-containers / build (frontend) (push) Successful in 2m3s
    Stable

    robbertbos released this 2026-05-18 05:03:24 +00:00 | 181 commits to main since this release

    Overig

    • Bewaarde berichten die zijn opgehaald voordat de avatar-versiefunctie
      bestond, tonen weer de echte profielfoto in plaats van de
      initialen-fallback.
    • De sectiekop "Wacht op verzending" heeft nu dezelfde tekstgrootte als de
      andere sectiekoppen, in zowel de inbox als de leeslijst.

    Onder de motorkap

    • Toeleveringsketen-hardening: GitHub Actions, container-basisimages en
      de security-tools (trivy, syft, uv) in CI verankeren nu altijd op een
      onveranderlijke hash - nooit meer een kaal versienummer. Trivy en uv
      draaien waar mogelijk als digest-gepinde container; syft wordt
      geverifieerd tegen een vooraf in de repo vastgelegde sha256. Wijkt een
      hash af, dan stopt de build met een fout. Renovate houdt de digests
      bij. Geen zichtbare wijziging.
    • De gedeelde Mattermost-clientfabriek valideert nu, net als het
      avatar-pad, de opgeslagen server-URL tegen interne adressen
      (verdediging-in-de-diepte; bestaande accounts waren al niet
      kwetsbaar). Geen zichtbare wijziging.
  • v2026.5.17 f99a200c73

    v2026.5.17
    All checks were successful
    build-containers / build (backend) (push) Successful in 1m51s
    build-containers / build (frontend) (push) Successful in 1m59s
    Stable

    robbertbos released this 2026-05-17 19:54:00 +00:00 | 185 commits to main since this release

    @-vermeldingen in antwoorden

    • Je kunt in een antwoord collega's met @ vermelden. Typ @ voor een
      lijst van mensen uit het kanaal van de kaart - personen die je recent
      hebt genoemd staan bovenaan - of typ door om gericht te zoeken. Je
      mag ook een volledige naam met spatie typen, zodat je collega's met
      dezelfde voornaam uit elkaar houdt. Alleen kanaalleden worden getoond;
      staat er meer dan er past, dan meldt de lijst dat je verder kunt
      typen.
    • Heeft iemand geen avatar, dan toont de lijst diens initialen. De lijst
      is volledig met het toetsenbord te bedienen en voor schermlezers
      toegankelijk (gepind kopje, aangekondigde status, zichtbare selectie).

    Weergave van threads en kaarten

    • Lange threads blijven leesbaar: het oorspronkelijke bericht plakt niet
      meer bovenaan, maar scrollt mee met de reacties - een lang bericht duwt
      de reacties niet langer weg.
    • De kaartdetail-weergave benut de schermhoogte beter en houdt op grote
      schermen een vaste, kleine rand aan in plaats van veel loze ruimte.
    • Een duidelijke scheidingslijn tussen het oorspronkelijke bericht en de
      reacties.
    • Kaarten in de leeslijst hebben meer ademruimte op desktop en een
      prettiger regellengte; de lijst en de detailweergave hebben nu een
      consistente, leesbare breedte.
    • De leeslijst heeft nu exact dezelfde breedte als de inbox en het
      zoekveld erboven.
    • Het bericht in de kaartdetail-modal breekt nu ongeveer op hetzelfde
      punt af als in de lijst.

    Mobiel scrollen en slepen

    • Op iOS Safari springt de leeslijst niet meer naar boven tijdens
      scrollen, bij een snelle actie (gelezen of voltooien) of bij het
      herordenen van kaarten.
    • Kaarten herordenen met slepen selecteert niet langer per ongeluk de
      tekst eronder.
    • De pagina verspringt niet meer wanneer de Safari-adresbalk in- of
      uitschuift.

    Overig

    • Emoji-reacties tonen Mattermost-shortcodes nu correct; de reactie-knop
      is compacter.
    • De bubble-up-status wordt server-side bepaald, wat 'm betrouwbaarder
      maakt rond tijdzone- en middernachtgrenzen.
    • De avatar-fallback in de leeslijst is robuuster: geen verspringende
      layout meer en geen losse DOM-manipulatie.
    • Vet en doorhalen werken nu ook met de Mattermost-schrijfwijze, met een
      spatie net binnen de markeertekens (**woord **, ~~woord ~~); eerder
      bleven de tekens dan letterlijk staan.
    • Vetgedrukte tekst is zwaarder gezet, zodat het duidelijker opvalt.
    • Het "Wacht op verzending"-icoon wijst nu vooruit in plaats van terug, en
      de knop om de herstelcode te kopiëren heeft een icoon gekregen.
    • Het Waggle-menu en optioneel het zoekveld blijven nu bovenaan in
      beeld tijdens het scrollen op Focus en de leeslijst.

    Onder de motorkap

    • De instellingenpagina gebruikt nu hetzelfde scroll- en
      sticky-mechanisme als de overige pagina's.
    • De volledige-hoogte-paginaopmaak staat nu in één gedeelde class in
      plaats van per pagina herhaald. Idem voor de iOS-Safari-veilige
      full-height-stijl.
    • Het NLDD-design-system is bijgewerkt naar 0.8.44; codeblokken gebruiken
      nu het JetBrains Mono-lettertype en enkele iconen zijn hertekend.
    • De scheidingslijn in de verzendknop blijft subtiel zichtbaar in
      uitgeschakelde staat, en de lettertype-fallbacks in de tokens verwijzen
      weer naar de juiste namen (RijksSans, JetBrains Mono).
    • Wijzigt iemand zijn Mattermost-profielfoto, dan tonen we voortaan de
      nieuwe foto in plaats van een verouderde uit de browsercache: de
      avatar-URL bevat nu een versiemarkering die met de foto meeverandert.
    • Ongebruikte board-/Kanban-sleepcode (useBoardDnd) verwijderd en de
      resterende Kanban-verwijzingen (verouderde comments, een onjuiste
      release-notitie) opgeschoond: de Kanban-weergave staat niet meer op de
      roadmap en de code was nergens gekoppeld. Geen zichtbare wijziging.
    • Ontwikkelaarsmodus: een dev-login-knop (alleen zichtbaar als
      synthetic-auth aanstaat) en een dev-seed voor realistische lokale
      testdata, met harde beveiliging tegen draaien tegen productie. Deze
      dev-hulpmiddelen zitten niet in de productie-build. De norm voor
      testdata staat nu in de projectdocumentatie.
    • Inbox en leeslijst delen nu een kaart- en lijst-implementatie in
      plaats van twee bijna-identieke kopieen; weergave en gedrag zijn
      ongewijzigd.
  • v2026.5.12 38142ab18d

    v2026.5.12 Stable

    robbertbos released this 2026-05-16 22:23:26 +00:00 | 205 commits to main since this release

    Eerste publieke release. Een persoonlijk command-centrum voor je gevlaggede
    Mattermost-berichten. Iedereen die via Keycloak inlogt krijgt een eigen,
    afgeschermde werkruimte; er zijn geen rollen of beheerderstooling.

    Je berichten ordenen

    • Een focus-overzicht met zes secties - Doe nu, Wacht op verzending, Nieuw,
      Backlog, Later oppakken en Voltooid - plus een aparte leeslijst voor
      referentiemateriaal.
    • Kaarten tussen secties slepen; je volgorde blijft bewaard.
    • Een "Nieuw"-markering op berichten die je nog niet hebt bekeken.
    • Een detailweergave per kaart met de threadcontext, bijlagen, je notities
      en een antwoordveld.
    • Snelacties per kaart: nu oppakken, afronden, uitstellen naar later, een notitie
      maken of antwoorden.

    Mattermost-koppeling

    • Tweerichtingssynchronisatie van je gevlaggede berichten: ze worden
      opgehaald, en als je een kaart afrondt wordt het bericht in Mattermost
      automatisch ge-unsaved (met automatische herhaalpogingen). Andersom
      geldt ook: haal je de vlag weg in Mattermost zelf, dan wordt de kaart
      hier voltooid.
    • Koppelen kan met een persoonlijk toegangstoken (voorkeur) of met je
      browser-sessiecookie, voor omgevingen waar tokens uitstaan (o.a.
      Digilab).
    • Tokens worden versleuteld opgeslagen.
    • Automatisch synchroniseren op een instelbaar interval (1 tot 60 minuten,
      standaard elke 5 minuten).
    • Avatars en bestanden lopen via de server, zodat je Mattermost-
      inloggegevens nooit in de browser belanden.
    • Per kaart de volledige thread inzien, met een verwijzing naar het
      oorspronkelijke kanaal.

    Antwoorden en plannen

    • Een tekstverwerker met emoji- en kaomoji-suggesties.
    • Emoji-reacties toevoegen en verwijderen.
    • Bijlagen meesturen bij een antwoord.
    • Een concept-antwoord per kaart bewaren voor later.
    • Berichten inplannen voor latere verzending, met een aparte wachtrij.

    Account en instellingen

    • Een instellingenpagina voor je account, synchronisatie, Mattermost-
      koppeling, export en voorkeuren.
    • Je eigen gegevens exporteren en weer importeren als versleuteld bestand,
      beveiligd met een herstelsleutel.
    • Je account verwijderen, met een duidelijke bevestigingsstap.
    • Een donker en licht thema, en volledige bediening met het toetsenbord.

    Inloggen en sessie

    • Inloggen via Keycloak (single sign-on).
    • Je sessie blijft tot zeven dagen geldig en wordt bij gebruik vanzelf
      verlengd. Daarna log je opnieuw in zonder wachtwoordprompt zolang je
      Keycloak-sessie nog loopt.
    • Centrale uitlog-afhandeling, zodat een sessie ook van buitenaf kan
      worden beëindigd.

    Onder de motorkap

    • Beveiliging: snelheidsbegrenzing tegen brute force, CSRF-bescherming en
      beveiligingsheaders.
    • Een auditlogboek van beveiligingsrelevante gebeurtenissen, standaard 90
      dagen bewaard.
    • Een statusbanner in de interface wanneer de server of Mattermost
      onbereikbaar is.
    • Postgres in productie, SQLite voor lokale ontwikkeling.
    • Te installeren als progressive web app (PWA).