# Changelog Alle noemenswaardige, gebruikersgerichte wijzigingen aan Facturix. Datums in ISO-formaat. Facturix draait on-prem (single binary); zie [docs/deployment.md](docs/deployment.md). ## [0.3.0] — 2026-09-12 Een brede beveiligingsronde plus flink wat UX-verbeteringen aan de facturen en het dashboard. ### Beveiliging - **Admin-gate op gevoelige beheeracties**: het installeren/wissen van de licentie, het wijzigen van de branding (met SMTP-/betaal-/webhook-/ Peppol-secrets en logo/voorwaarden) en de AVG-acties (inzage-export en anonimiseren) vereisen nu een beheerder. Voorheen kon elke ingelogde gebruiker deze uitvoeren. Kiosk-modus (single-user) blijft vrij. - **Snelheidslimiet op zware operaties**: exports (ZIP/CSV), bulk-acties, bankimport, VIES-controle, Peppol-verzending en de publieke factuur-PDF zijn nu begrensd (standaard 20 per 5 minuten per beller, instelbaar via `FACTURIX_HEAVY_MAX`/`FACTURIX_HEAVY_WINDOW`), zodat één gebruiker of een gelekte deel-link de server of externe diensten niet kan overbelasten. Het openen van één factuur-PDF blijft onbeperkt. - De login-limiter ruimt nu verlopen sleutels op, zodat een stroom unieke gebruikersnamen het geheugen niet onbegrensd laat groeien. - **Login lekt niet langer of een gebruikersnaam bestaat**: bij een onbekende gebruiker wordt nu evenveel werk verzet (wachtwoordcontrole tegen een dummy-hash), zodat de reactietijd geen gebruikers-enumeratie toelaat. - **CSV-exports zijn beschermd tegen formule-injectie**: velden die met `=`, `+`, `-` of `@` beginnen (bv. een klantnaam) worden geneutraliseerd zodat ze niet als formule worden uitgevoerd wanneer de accountant het bestand in Excel/LibreOffice opent. - **Sessie-id's worden versleuteld (gehasht) opgeslagen**: de database bevat niet langer bruikbare sessietokens, alleen hun SHA-256-hash. Na deze update moeten bestaande sessies opnieuw inloggen. - **Webhooks worden niet meer zonder secret verstuurd**: zonder ingesteld webhook-secret zou de handtekening een HMAC met een lege sleutel zijn (schijn- ondertekening). Events worden nu pas verstuurd als er een secret is; de test-knop meldt het als het ontbreekt. - De publieke deel-pagina stuurt de deel-link (token) niet meer mee als Referer naar externe betaalpagina's (`referrer: no-referrer`), en een mislukte ontsleuteling van een opgeslagen secret logt nu een waarschuwing. - **Deel-links verlopen**: een publieke deel-link is nu standaard 90 dagen geldig (instelbaar via `share_link_days`; 0 = nooit verlopen), zodat een gelekte link niet eeuwig bruikbaar blijft. De vervaldatum staat bij het delen, en een link is nu ook **in te trekken** (kill-switch voor een gelekte link). Bestaande links blijven geldig. ### Robuustheid - **Migraties draaien nu atomair** (per bestand in één transactie). Een mislukking halverwege een migratie rolt volledig terug in plaats van de database in een half-gemigreerde staat achter te laten die bij de volgende start bleef falen. - **Webshop-connectoren lezen bedragen decimaal-veilig**: de regelprijs uit WooCommerce en Lightspeed gaat niet meer via een f64 (met dubbele afronding en een stille nul als de prijs als tekst kwam), maar wordt als decimale tekst overgenomen. ### Creditnota's - **Creditnota uit factuur**: op een nieuwe creditnota een afgeronde factuur opzoeken (op nummer of klant) en er in één klik een creditnota van maken; de klant en regels worden overgenomen. Handmatig invullen blijft mogelijk. ### Verplichte kosten & toeslagen - **Bijdrage als totaal tonen**: een verplichte kost kan per stuk als 'als één totaalregel tonen' worden ingesteld. Gekoppelde bijdragen van hetzelfde soort komen dan niet per product op de factuur, maar als één samengevoegde regel met het totaal (scheelt papier). Het bedrag beweegt mee met de aantallen. ### Dashboard - **KPI-bedragen schalen mee**: een breed bedrag wordt niet meer afgekapt maar verkleint zich zodat het in de kaart past (het euroteken blijft bij het bedrag). - **Grijphendel altijd rechtsboven**: de sleep-/grijphendel van een widget staat nu vast in de rechterbovenhoek, ook als de titel over meerdere regels loopt. - **Openstaande posten klikbaar**: een rij in de widget 'Openstaande posten' opent nu direct de bijbehorende factuur, net als bij de recente facturen. - **Instelbare 'Snel aan de slag'**: kies zelf welke snelkoppelingen op het dashboard verschijnen (via het tandwiel op de widget). Keuze wordt per browser bewaard; standaard blijven het Nieuwe factuur, Facturen bekijken en Rapportage. ### Facturen & documenten - **Afgeronde factuur is niet meer bewerkbaar**: op een verstuurde/afgeronde factuur waren de knoppen 'Tekstregel toevoegen' en de toeslag-keuze nog actief, waardoor het leek alsof je nog regels kon toevoegen of verwijderen. Alle bewerk-knoppen staan nu uit (de server weigerde de wijziging al). - **Dupliceren**: maak van een bestaand document (concept of afgerond) met één klik een nieuw, vrij bewerkbaar concept van dezelfde soort, met de klant en regels overgenomen en de datum van vandaag. - **Concept verwijderen**: een nog niet gefinaliseerd document is nu te verwijderen, zowel vanuit de editor als met een verwijderknop bij de conceptregels in het overzicht (facturen/offertes/orders/creditnota's). Een gefinaliseerd document blijft bewaard (fiscale bewaarplicht). - Het menu links markeert nu de juiste sectie per documentsoort: een creditnota, offerte of order valt onder de eigen ingang in plaats van altijd 'Facturen'. ### Abonnementen - De regels in de abonnement-editor staan nu in een nette tabel met kolomkoppen (Omschrijving/Aantal/Prijs/Btw), zodat duidelijk is welk veld wat is. ## [0.2.1] — 2026-09-11 ### Facturenoverzicht - **Meerdere facturen selecteren** met een **'alles selecteren'**-vinkje in de kolomkop. - **Bulk-boeken**: geselecteerde facturen in één keer in Ledgerix boeken; per factuur een eigen resultaat, één mislukking stopt de batch niet (alleen zichtbaar als de boekhoudkoppeling aanstaat). - **ZIP-export** van de factuur-PDF's met een **index.csv** (nummer, datum, klant, netto/btw/totaal, status) voor de accountant, op selectie of in één keer per **kwartaal/jaar** voor de aangifte. ## [0.2.0] — 2026-09-11 Koppelingen, importeren en een samenstelbaar dashboard, plus een volledig vertaalde interface. ### Interface & meertaligheid - De volledige UI is nu vertaald via i18n-keys in nl/en/de/fr; geen hardcoded teksten meer. Dark mode en taalkiezer in de header. ### Documenten - **Tekstregels** (kop-/toelichtingsregels zonder bedrag) in facturen, offertes en creditnota's én in herhaalfactuur-sjablonen; tellen niet mee in de totalen en komen niet in de UBL. - **Orders** (opdrachtbevestiging) als vierde documentsoort, in de keten offerte → order → factuur, met eigen gapless ORD-nummerreeks en conversie. Orders tellen niet als omzet. - Offertes en orders per administratie **aan/uit** te zetten. - Deelbetaling: het betaalveld wordt voorgevuld met het openstaande bedrag. ### Bank - Een onbekende storting zonder automatisch voorstel is nu **handmatig aan een openstaande factuur te koppelen**. ### Producten/diensten importeren - **CSV-import/-export** van de catalogus (NL/EN-kolommen, `,`/`;`-scheiding, NL/EN-bedragen), met upsert op omschrijving. ### Integraties — eigen koppeling (inbound API) - **API-sleutels** per koppeling (Bearer, Argon2-gehasht, per administratie, intrekbaar). - Inbound API `/api/v1/integration/*`: klant upserten, verkoopdocument (factuur/order) aanmaken met finalize/paid/email, status opvragen; idempotent op het externe kenmerk. Artikelen pushen via `/integration/catalog`. - Webshop-flow: een order bij verzending tot factuur maken. Kassa/POS: transacties verzamelen en als dagstaat (Z-afsluiting) in één betaalde factuur afsluiten. - **Uitgaande webhooks** (HMAC-SHA256 ondertekend) bij `invoice.finalized` en `invoice.paid`, met test-ping. ### Integraties — kant-en-klaar (connectoren) - **Integraties-pagina** met een catalogus per categorie en configuratie- formulieren die zich uit de veld-metadata opbouwen; versleutelde inloggegevens, test- en sync-knop, automatische sync via de scheduler en een **afleverlog** per sync-run. - Connectoren: **WooCommerce** en **Shopify** (webshop-orders → facturen), **Lightspeed** (kassa → betaalde bonnen, beta), **Mollie** en **Stripe** (betalingen matchen aan facturen op factuurnummer). Webshop-regels nemen het btw-tarief per regel over. ### Dashboard - Het dashboard is nu een **samenstelbaar raster**: widgets toevoegen/verwijderen en met **slepen** ordenen (bewaard per browser). - Inzicht-widgets: KPI's (openstaand, achterstallig, omzet jaar/maand, concepten), **omzet met instelbare periode** (week/maand/kwartaal/jaar), **liquiditeitsprognose**, **top klanten per periode**, openstaande posten, btw-overzicht, recente facturen, koppelingen-status en snelkoppelingen. Eén aggregatie-endpoint voedt alle widgets. ### Betalen & verzenden - **Werkende betaallink**: de betaal-seam maakt nu een echte betaling aan via **Mollie** (payment-links, inclusief iDEAL) of **Stripe** (checkout-sessie), met het openstaande bedrag en het factuurnummer als referentie. - **Peppol e-factuur**: een afgeronde factuur via een Access Point het Peppol-netwerk op sturen (UBL als payload, ontvanger afgeleid uit btw-/KvK- nummer), idempotent op het bericht-kenmerk. - **Gehoste factuur-/offertepagina**: een onraadbare deel-link waarmee de klant zonder in te loggen het document en de PDF bekijkt, online een **offerte accepteert** en een factuur **betaalt** via de betaallink. - **SEPA-incasso**: een pain.008-incassobestand (pain.008.001.02, CORE/RCUR) voor geselecteerde openstaande facturen van klanten met een machtiging (machtigingskenmerk + datum per relatie, Incassant-ID per administratie). ### Kortingen - **Klantkorting**: een standaard kortingspercentage per relatie dat de editor voorvult als factuurkorting voor die klant. - **Staffel-/bulkkorting**: prijsstaffels per catalogus-item (lagere stukprijs vanaf een aantal), automatisch toegepast op het ingevoerde aantal. - **Combinatie-/bundelkorting**: bundel-items met een pakketprijs; in de editor een pakketregel met de onderdelen eronder. ### Verplichte kosten & toeslagen - **Beheerbare lijst van verplichte kosten/bijdragen** (verwijderingsbijdrage, statiegeld, verzendkosten, ...): vast bedrag of percentage, eigen btw en een optionele landcode. Volledig aanpasbaar (toevoegen/wijzigen/verwijderen) met een knop voor NL-voorbeelden, zodat het meebeweegt met veranderende en per-land regels. - **Bijdrage per product**: koppel kosten aan een product; ze komen automatisch als aparte regel op de factuur (vast bedrag per stuk, percentage over de productwaarde). - **Toeslag op factuurniveau**: voeg een verplichte kost/toeslag als aparte factuurregel toe via een keuzelijst. ### Facturen - **Factuurkorting op factuurniveau** (percentage), naast de korting per regel; proportioneel over elk btw-tarief zodat elk tarief klopt. Zichtbaar op PDF, publieke pagina en als document-allowance in de UBL. - **Verzamelfactuur**: meerdere orders/offertes/facturen van dezelfde klant in een keer tot een conceptfactuur samenvoegen. - **Termijn-/deelfacturen**: factureer een percentage van een offerte, order of factuur, met een regel per btw-tarief en een verwijzing naar de bron. - **Extra PDF-layouts**: Ruim (ruime regelafstand) en Strak (zwart-wit, compact) naast Modern, Klassiek en Compact. - **Algemene voorwaarden** als PDF-bijlage bij de factuur-e-mail (in/uit per administratie). ### Btw & compliance - **VIES-controle** van het btw-nummer van een relatie (geldig/ongeldig + naam). - Wettelijke **btw-vermeldingen**: 'btw verlegd' bij verlegging en de **KOR**-vermelding, in de taal van de klant, op PDF en in de UBL. - **ICP-opgaaf**: rapport van verlegde leveringen aan EU-afnemers per btw-nummer. - **OSS (One Stop Shop)**: reken het btw-tarief van het EU-bestemmingsland op B2C-verkoop (standaardtarief) met een OSS-aangifte-rapport per land. ### Privacy & audit - **AVG-inzage**: exporteer alle gegevens over een relatie (relatie, documenten, betalingen) als JSON. - **AVG-verwijdering**: anonimiseer de persoonsgegevens van een relatie; de facturen blijven bewaard (fiscale bewaarplicht). - **Audit-log** in de beheerinstellingen: finaliseren, betalingen en de AVG-acties worden vastgelegd en zijn terug te zien. ### Documentatie - `docs/integraties.md` toegevoegd (inbound API + connectoren); functioneel overzicht en architectuur bijgewerkt. ## [0.1.0] — 2026-09-10 Eerste release. Standalone Nederlands facturatiepakket, koppelbaar met Ledgerix. ### Documenten - Facturen, offertes en creditnota's via één regelmodel; conversie (offerte → factuur, factuur → creditnota) met gapless nummering per soort. - PDF-opmaak: ingebouwd (printpdf, met correcte euro-weergave via ingebedde fonts) én via een externe SCML-engine voor toegankelijke uitvoer (PDF/UA). - Per-regel UBL 2.1 / NLCIUS-export. - Meertalig (nl/en/de/fr): documenttaal volgt de klant. ### Betalingen & bank - Handmatig (deel)betalingen afvinken; status concept → verstuurd → deels betaald → voldaan. - Bankimport (CAMT.053 / MT940) met een matcher die ontvangsten voorstelt bij openstaande facturen (factuurnummer/bedrag/IBAN/naam); herimport ontdubbelt. - Betaallink-seam met Mollie/Stripe-stubs (echte integratie volgt). ### Aanmaningen & abonnementen - Aanmaningen: vrij instelbaar traject, per niveau kiesbare kosten (geen / vast bedrag / WIK-staffel + rente), tekstmatrix per niveau × klantsegment met ingebouwde vertaalde standaardteksten; verzenden per e-mail (PDF-bijlage) of per post (printen). - Herhaalfacturen/abonnementen: sjabloon + schema (week/maand/kwartaal/jaar), concept of direct versturen. - Automatische scheduler die due herhaalfacturen genereert en aanmaningen verstuurt (opt-in per administratie). ### Beheer & beveiliging - Authenticatie (Argon2, sessies), login-rate-limiting, gebruikersbeheer-UI. - SMTP-wachtwoord en betaalsleutels versleuteld at-rest. - Tenant-integriteit via database-triggers. - Multi-company (administraties) met data-isolatie en bulkverzending. - Licentie-tiers ZZP / MKB / Accountant (offline ed25519), feature-gating. ### Rapportage - Openstaande posten, omzet (per maand/klant), btw-overzicht (presentatie). - CSV-export van facturen en relaties. ### Koppeling - Verkoopfacturen doorboeken naar Ledgerix via het trix-connect-contract. ### Deployment - Docker (Dockerfile + docker-compose), reverse-proxy-configs (Caddy/nginx/ Traefik), systemd-unit, Windows-installer.