- TypeScript 95.2%
- Shell 3.5%
- CSS 0.6%
- JavaScript 0.5%
- Dockerfile 0.2%
UAPI Session::create_user_session bestaat niet (is een WHM API 1 call, niet UAPI). Per-account cPanel-tokens kunnen principieel geen sessies aanmaken - alleen WHM-tokens met reseller/root-scope kunnen dat. Voor echte one-click is Fase 2 met reseller-token nodig (bewust niet in scope). Nu: knop opent cPanel-login-page met username vooringevuld in nieuwe tab. Gebruiker voert zelf wachtwoord/token in (heeft die toch al). Audit-log behouden. createCpanelUserSession-helper uit src/lib/cpanel.ts verwijderd (was dead code, vervangen door comment over WHM-vereiste). |
||
|---|---|---|
| deploy | ||
| prisma | ||
| public | ||
| scripts | ||
| src | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| CHANGELOG.md | ||
| DEPLOY.md | ||
| docker-compose.override.yml | ||
| docker-compose.yaml | ||
| docker-entrypoint.sh | ||
| Dockerfile | ||
| HANDLEIDING.md | ||
| next.config.ts | ||
| package.json | ||
| postcss.config.mjs | ||
| prisma.config.ts | ||
| README.md | ||
| tailwind.config.ts | ||
| tsconfig.json | ||
CRM Portaal
Self-hosted CRM, offerte- en factuurpakket voor kleine dienstverleners en VOFs. Eén Docker-container, één klik in Coolify, eigen domein, geen SaaS-fees, alles in je eigen database.
Inhoud
- Wat is dit
- Snel beginnen
- Functies
- Architectuur
- Configuratie (.env)
- Lokaal ontwikkelen
- Coolify-deploy
- Off-site backup & restore
- Beveiliging
- Updates & CVE-management
- Release Notes · volledige commit-log in
CHANGELOG.md - Roadmap
Wat is dit
Een werkende web-app waarin je de hele relatie met je klanten afhandelt — van eerste lead tot betaalde factuur — met digitaal ondertekende offertes en contracten (incl. multi-signer voor VOFs), automatische herinneringen, AI-OCR voor bonnetjes, DNS-beheer en off-site backups.
Lead → Deal → Offerte (DocuSeal) → Project → Uren → Factuur → Mollie → Betaald
↘ ↗ ↘ ↗
Contracten · Bestanden · Wachtwoordkluis · Assets · DNS
↓
Boekhouder-ZIP (maandelijks) + Off-site backup (S3, dagelijks)
Doelgroep: ZZP, kleine bureaus, IT-dienstverleners, consultancies, VOFs — iedereen die zonder Moneybird/Hubspot/Pipedrive-abonnement een net CRM & factuurpakket wil hosten.
Snel beginnen
git clone https://code.vanmullemholding.eu/jesse-a/OpenCRM.git crm
cd crm
cp .env.example .env # vul minimaal AUTH_SECRET en DATABASE_URL in
docker compose up --build # bouwt + start app + postgres
Open http://localhost:3000. Bij eerste start maakt de container automatisch
een ADMIN-account aan met SEED_ADMIN_EMAIL / SEED_ADMIN_PASSWORD. Laat
SEED_ADMIN_PASSWORD leeg en de container genereert bij eerste boot een
sterk willekeurig wachtwoord dat éénmalig in de Coolify-logs verschijnt —
veiliger dan een hardcoded default.
Functies
🎯 Sales & klantbeheer
- Klanten met contactpersonen, tags, notities, bijlagen, BTW- en KVK-nummer, status (lead/actief/inactief).
- KVK-lookup bij aanmaken & bewerken: zoek op bedrijfsnaam in het
Handelsregister, klik op een resultaat en naam, adres, postcode, plaats en
KVK-nummer worden automatisch ingevuld. Twee providers: officiële KVK
Zoeken-API of overheid.io OpenKVK (schakel via
KVK_PROVIDER). - Pijplijn met Kanban-bord (LEAD → QUALIFIED → PROPOSAL → NEGOTIATION → WON/LOST). Sleep deals tussen kolommen.
- AI-klantsamenvatting in één klik (Claude analyseert geschiedenis, projecten, openstaande facturen, recente activiteit).
- Asset & licentie-tracking per klant: hardware, software-licenties, domeinen, hosting, certificaten, abonnementen — incl. verloopdatums voor verlengingsherinneringen.
- Wachtwoordkluis per klant: AES-256-GCM versleutelde credentials (logins, FTP, hosting-paneel). Reveal wordt audit-gelogd inclusief IP en browser; gebruiker krijgt een waarschuwing vóór tonen.
- NPS-enquête met publieke link per klant; score & toelichting zichtbaar op klantkaart.
📋 Offertes
- Offertes met regels (omschrijving / aantal / prijs), BTW, valuta, geldigheid, opmerkingen, en optionele projectkoppeling.
- Productcatalogus — voorgedefinieerde diensten en prijzen die je met één klik aan een offerte toevoegt.
- AI-offertegenerator: typ “Nieuwe website met blog, ~40 uur design + 60u development” en Claude vult de regels (incl. prijzen uit je catalogus) voor.
- Versies: maak een nieuwe versie van een afgewezen offerte; alle versies blijven gekoppeld en zichtbaar.
- PDF met logo, VAN/AAN-kolommen, totalen-blok, opmerkingen-sectie.
Apart facturatie-e-mailadres (
facturen@…) op de header. - Publieke akkoord-link (
/q/<token>) voor klanten zonder login — naam invullen, klikken op “Accorderen”, klaar. - DocuSeal-integratie met multi-signer-flow voor VOFs:
- Offertes ≤ €5.000 ex BTW: jij + klant tekenen.
- Offertes > €5.000 ex BTW: álle vennoten (gemarkeerd als
isSigner) plus klant tekenen. Configurabel via constante insrc/lib/vof-signers.ts. - Sender komt automatisch eerst in de submitter-lijst (DocuSeal mailt op array-volgorde).
- Webhook vangt status-updates op (
completed,declined,expired). - "Wachten op handtekening van X, Y + klant" tonen in de UI op basis van live ClouDNS-snapshot.
- Auto-factuur: zodra een offerte volledig is ondertekend wordt automatisch de bijbehorende factuur opgesteld, een Mollie-betaallink aangemaakt en de mail naar de klant verstuurd.
📃 Contracten
- Contractbeheer voor SLA, raamovereenkomst, algemene voorwaarden, NDA, licentie, verwerkersovereenkomst en overige.
- AI-contractgenerator: kies type, vul titel + extra instructies in, en
Claude schrijft het volledige contract met genummerde artikelen.
- Gebruikt expliciete vertegenwoordigers uit
User.isSigner-vlag ("te dezen rechtsgeldig vertegenwoordigd door J. van Mullem en G.A. van Mullem") in plaats van een AI-gegokte naam. - Strikte taalregels in de prompt voorkomen verzonnen Nederlandse vertalingen (geen "neertijd" meer voor downtime).
- Gebruikt expliciete vertegenwoordigers uit
- DocuSeal-ondertekening — altijd multi-signer voor contracten: alle
isSigner-users + klant. Ondertekenblok schaalt automatisch (2 partijen in 1 rij, 3-4 in 2×2-grid, 5+ over meerdere pagina's). - Looptijd-tracking met startdatum, einddatum, opzegtermijn, contractwaarde, automatische verlenging.
💰 Facturen
- Facturen met regels, BTW, valuta, vervaldatum, opmerkingen.
- Multi-currency: EUR, USD, GBP, CHF, NOK, SEK, DKK met wisselkoers naar EUR voor rapportages.
- PDF met logo, VAN/AAN-kolommen, betaalsectie en QR-code. Aparte
facturen@…-adres in header en QR-footer. - Mollie-checkout-QR op de PDF: klant scant met telefoon-camera → browser opent Mollie → kiest iDEAL → betaalt. Werkt op alle Nederlandse banken, inclusief ABN AMRO en Rabobank.
- E-mail verzenden met aanpasbare templates (
{{customer}},{{amount}},{{dueDate}}, …). - Mollie-payment-webhook zet factuur automatisch op PAID en logt de ontvangstdatum.
- Automatische herinneringen via cronjob: vriendelijke nudge, 2e herinnering, mogelijkheid tot ingebrekestelling-template.
- Abonnementen / terugkerende facturen (week, maand, kwartaal, jaar) met automatische dagelijkse run en mail naar klant.
- UBL-export voor PEPPOL-compatibele facturen (gebruikt
billingEmailvoor supplier-contact).
🧾 Boekhouding
Eigen sidebar-sectie met alle financiële items op één plek.
- Inkopen met AI-OCR. Sleep één bonnetje of een hele batch tegelijk — Claude leest leverancier, datum, BTW-tarief, factuurnummer en bedrag uit (PDF/JPG/PNG). Categorie wordt automatisch geraden.
- Bulk-upload: selecteer meerdere bonnen tegelijk, één bron en project voor de hele batch.
- 📷 Mobile snel-scan-flow (
/scan): één tap op de telefoon → achter-camera → preview → AI-OCR → klaar voor fiat. Bereikbaar via:- Banner op het dashboard (alleen op mobiele schermen)
- PWA-shortcut "Scan bon" via long-press op de homescreen-icoon
- Goedkeuringsworkflow voor inkopen (specifiek voor VOFs):
- Mail naar alle fiatteurs zodra een nieuwe inkoop is aangemaakt.
- Magic-link in de mail — fiatteur klikt, ziet de bon, keurt goed of af
zonder in te loggen. JWT-token gebonden aan
expenseId × approverId, 7 dagen geldig, single-use met DB-record. - Status wordt pas APPROVED als élke fiatteur heeft goedgekeurd. Eén afkeuring zet 'm op REJECTED.
- Bevestigingsmail naar uploader + alle fiatteurs zodra volledige goedkeuring rond is.
- Knop "Stuur mail opnieuw" in de detail-weergave.
- Externe verkoopfacturen — facturen die elders zijn opgesteld (Moneybird, Exact, papier). Upload één of meerdere PDFs tegelijk; AI vult factuurnummer, klant, datum, bedragen en BTW automatisch in. Gaan mee in de boekhouder-ZIP zodat alles op één plek samenkomt.
- Reis-registratie met auto-afstand-calculatie + factuurprijs per km. Doorbelaste ritten verschijnen op de factuur.
- Boekhouder-ZIP per maand met:
samenvatting.txtmet totalen en balans (verkoop − inkoop)inkopen-YYYY-MM.csvmet alle inkopenverkoopfacturen-YYYY-MM.csvmet CRM-facturen + externe facturen (kolombron)ritten-YYYY-MM.csvmet alle reisbewegingenbonnetjes/met originele PDFs van bonnenverkoopfacturen/met PDFs van alle verkoopfacturen (CRM + extern)
- Automatisch mailen naar boekhouder met de maand-ZIP als bijlage — e-mail uit Instellingen.
- Bankafschrift-import (CSV) met automatische match op IBAN, bedrag en factuurnummer. Ongekoppelde transacties worden gemarkeerd voor handmatige behandeling.
- BTW-aangifte-rapport per kwartaal met te declareren BTW per tarief.
🌐 DNS Beheer
ADMIN-only sidebar-item om domeinnamen aan klanten te koppelen en hun DNS-records rechtstreeks vanuit het CRM te beheren.
- Live ClouDNS-API: records leven bij ClouDNS, worden bij elke page-load opgehaald (geen DB-sync, geen drift).
- Ondersteunt A, AAAA, CNAME, MX, TXT, NS met TTL-presets (60s tot 1 dag).
- Inline edit-forms per record. Mutaties worden audit-gelogd
(
dns-record-add/dns-record-update/dns-record-delete). - Optionele verloopdatum + notitie per domein (handmatig — geen RDAP/WHOIS-koppeling).
- Op klant-detail-pagina verschijnt een Domeinen-kaart met deeplink naar de DNS-editor.
🏗️ Projecten & uren
- Projecten gekoppeld aan klanten, met status (PLANNED, ACTIVE, ON_HOLD, COMPLETED, CANCELLED).
- Tijdregistratie per project, met live timer-widget rechtsboven.
- Algemene uren (zonder project) ook ondersteund.
- Doorbelaste uren komen op de factuur.
- Projectrentabiliteit per project: uren × uurkostprijs vs gefactureerd vs inkopen → marge.
- iCal-feed per gebruiker zodat afspraken / deadlines in je eigen agenda komen.
📊 Rapportages
- Maandomzet (12 maanden) en gewonnen deals.
- Top-klanten op omzet.
- Uren per medewerker (laatste 30 dagen) + declarabele %.
- Cashflow-forecast 8 weken vooruit op basis van openstaande facturen en abonnementsruns.
- Projectrentabiliteit top-10 op marge.
🎨 Productiviteit
- Cmd+K globale zoekbalk (klanten, projecten, deals, facturen, offertes).
- Keyboard shortcuts:
g+ letter om te navigeren,n+ letter voor nieuw item,?voor help. - Donker thema met persistente keuze.
- PWA: installeer als app op telefoon of desktop, met homescreen- shortcuts ("Scan bon", "Uren", "Facturen", "Inkopen", "Dashboard").
- Audit-log van alle wijzigingen (wie, wat, wanneer) — alleen voor ADMIN.
🤖 AI
Alle AI-functies optioneel; werkt met ANTHROPIC_API_KEY en gebruikt Claude.
- AI-OCR voor inkoopbonnetjes (PDF + foto) → leverancier, datum, BTW, bedrag, categorie.
- AI-OCR voor externe verkoopfacturen → factuurnummer, klant, datum, bedragen.
- AI-offertegenerator op basis van vrije tekst + catalogus.
- AI-contractgenerator per type (SLA, AV, NDA, …) met expliciete vennoten als vertegenwoordigers.
- AI-klantsamenvatting per klant.
🔐 Security & admin
- 2FA / TOTP verplicht voor iedere gebruiker (Authenticator-app +
recovery-codes). Geen 2FA = geen toegang tot het CRM (behalve
/accountom 'm aan te zetten). - Actieve sessies-beheer: zie al je ingelogde apparaten (browser, IP, tijdstip, "dit apparaat"-markering), trek ze los of in één klik "overal anders uitloggen".
- Login-melding bij nieuw apparaat: stabiele device-cookie identificeert bekende browsers; vanaf onbekend apparaat krijg je direct een beveiligingsmail.
- Rollen + extra vlaggen:
ADMIN(alles),MANAGER(schrijven),VIEWER(alleen lezen)isApprover= fiatteur voor inkopenisSigner= ondertekenaar voor multi-signer-flow (contracten + offertes > €5K) — los van fiatteur instelbaar
- Audit-log van alle write-acties (incl. IP en User-Agent).
- HTTPS via Coolify reverse-proxy.
- TLS-hardening: zwakke CBC-ciphers verwijderd, HSTS, post-quantum
key exchange (X25519MLKEM768). Configuratie in
deploy/traefik-tls-hardening.yaml. - CSP/COOP/CORP/Permissions-Policy headers in
next.config.ts. - Step-up authenticatie voor gevoelige acties: 2FA-disable, TOTP-enrollment, e-mail-wijziging — vereist je huidige wachtwoord met rate-limit per account.
- Weak-password-blocklist + zxcvbn-achtige checks bij wachtwoord instellen of resetten.
- DocuSeal-webhook: HMAC-handtekening gevalideerd (5-min freshness
tegen replay), ondersteunt hex/base64/
timestamp.sigencoding. - Mollie-webhook bindt aan stored
mollieId(cross-tenant misbruik uitgesloten). - Cron-endpoints alleen POST +
Authorization: Bearer $CRON_SECRET, timing-safe vergelijking. - Security-alert mails bij wachtwoord-reset, 2FA-disable, e-mail- wijziging — gaat naar de eigenaar van het account, niet de actor.
Architectuur
┌───────────────────────────────────────────────────────┐
│ Next.js 16 (App Router, server actions, Turbopack) │
│ ├─ /app UI + server actions │
│ ├─ /api REST + webhooks │
│ └─ /middleware Sessie-validatie + public prefixes │
├───────────────────────────────────────────────────────┤
│ Prisma 6 ORM → PostgreSQL 17 │
│ pdf-lib → Facturen, offertes, contracten │
│ Anthropic SDK → Claude AI (OCR + generators) │
│ Mollie SDK → Online betalen (iDEAL etc.) │
│ nodemailer (SMTP) → Mail-verzending │
│ jszip → Boekhouder-ZIP │
│ tar + @aws-sdk → Off-site backups naar S3 │
│ jose 6 (JWT) → Sessions + magic-link tokens │
│ bcryptjs 3 → Wachtwoorden │
│ otpauth + qrcode → TOTP / 2FA │
│ DocuSeal API → Digitaal ondertekenen │
│ ClouDNS API → DNS-beheer │
│ KVK / overheid.io → Handelsregister-lookup │
└───────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Docker container (Node 24-alpine) │
│ docker-entrypoint.sh: │
│ 1. prisma db push --accept-data-loss│
│ 2. ensure-admin (eenmalig) │
│ 3. start Next.js (port 3000) │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Coolify (Traefik + HTTPS + HSTS) │
└─────────────────────────────────────┘
│
▼ (dagelijks)
┌─────────────────────────────────────┐
│ S3-compatible bucket (DO Spaces, │
│ Backblaze B2, Cloudflare R2) │
│ - db/crm-<timestamp>.sql.gz │
│ - files/uploads-<timestamp>.tar.gz │
└─────────────────────────────────────┘
Volumes (Docker):
/app/data/uploads— alle geuploade bestanden (bonnen, logo, contract-PDFs).- PostgreSQL data-volume.
Configuratie (.env)
Minimaal nodig om te starten:
DATABASE_URL="postgresql://user:pass@db:5432/crm"
AUTH_SECRET="genereer-een-string-van-minimaal-32-chars"
APP_URL="https://crm.jouwdomein.nl"
SEED_ADMIN_EMAIL="jij@bedrijf.nl"
SEED_ADMIN_PASSWORD="" # leeg = container genereert sterk willekeurig wachtwoord
COMPANY_NAME="Jouw Bedrijf"
Optionele blokken (alles wat leeg is, schakelt die feature uit):
# SMTP (onmisbaar voor goedkeurings-mails en factuur-mails)
SMTP_HOST="smtp.eu.mailgun.org"
SMTP_PORT="587"
SMTP_USER="postmaster@…"
SMTP_PASS="…"
MAIL_FROM="CRM <crm@jouwdomein.nl>"
SMTP_SECURE="false"
# Bedrijf — voor PDF-headers en betalingsinstructie
COMPANY_ADDRESS="Vestigingadres 1, 1234 AB Stad"
COMPANY_VAT="NL000000000B00"
COMPANY_IBAN="NL00BANK0000000000"
COMPANY_EMAIL="support@bedrijf.nl" # algemeen contact (contract-PDF, user-mail-footer)
COMPANY_BILLING_EMAIL="facturen@bedrijf.nl" # facturatie (factuur-PDF, offerte-PDF, UBL)
# Anthropic Claude — AI-OCR + generators
ANTHROPIC_API_KEY="sk-ant-…"
ANTHROPIC_MODEL="claude-sonnet-4-6"
# Mollie — online betalen
MOLLIE_API_KEY="live_… of test_…"
# DocuSeal — digitaal ondertekenen
DOCUSEAL_URL="https://ondertekenen.jouwdomein.nl"
DOCUSEAL_API_KEY="…"
DOCUSEAL_WEBHOOK_SECRET="HMAC-secret-uit-DocuSeal-instellingen"
# ClouDNS — DNS-beheer (auth via account-level)
CLOUDNS_AUTH_ID="12345"
CLOUDNS_AUTH_PASSWORD="…"
# KVK / overheid.io — handelsregister-lookup
KVK_PROVIDER="kvk" # of "overheid"
KVK_API_KEY=""
KVK_TEST_API_KEY="" # KVK-sandbox
OVERHEID_API_KEY=""
# Off-site backup (S3-compatibel — DO Spaces, B2, R2, AWS)
S3_BACKUP_ENDPOINT="https://ams3.digitaloceanspaces.com"
S3_BACKUP_BUCKET="mijn-crm-backups"
S3_BACKUP_ACCESS_KEY="…"
S3_BACKUP_SECRET_KEY="…"
S3_BACKUP_REGION="us-east-1" # DO Spaces negeert dit, AWS niet
S3_BACKUP_PREFIX="crm/" # optioneel
# Cron-token (beveiligt /api/cron/*)
CRON_SECRET="openssl rand -hex 32 → plak hier"
Lokaal ontwikkelen
# Node 24 + npm
nvm use 24
npm install
docker compose up -d db # alleen PostgreSQL starten
npm run dev # Next.js dev-server op :3000
Database-wijzigingen:
npx prisma db push # past schema toe (bij dev, no-migration)
npx prisma studio # browse data
Aanpassen seed-data: prisma/seed.ts → npx prisma db seed.
Coolify-deploy
- Coolify → New Resource → Docker Compose.
- Verwijs naar deze repo (
docker-compose.yaml). - Vul de env-variabelen in (zie boven).
- Domeinnaam koppelen → Coolify regelt HTTPS via Traefik.
- Persistent volume voor
/app/data. - Volg
DEPLOY.mdvoor de uitgebreide stap-voor-stap incl. TLS-hardening, post-quantum key-exchange, en off-site backup setup.
Bij elke deploy draait docker-entrypoint.sh:
prisma db push --accept-data-loss(we breken nooit oudere kolommen, dus de flag is veilig om additieve wijzigingen door te zetten).node prisma/ensure-admin.mjs(eenmalig ADMIN-account aanmaken).next start(Next.js standalone build).
Scheduled tasks in Coolify (alle endpoints met header
Authorization: Bearer $CRON_SECRET):
| Endpoint | Frequentie | Wat |
|---|---|---|
POST /api/cron/payment-reminders |
dagelijks 09:00 | 1e + 2e factuur-herinnering |
POST /api/cron/recurring-invoices |
dagelijks 07:00 | Abonnementsfacturen aanmaken + versturen |
POST /api/cron/backup |
dagelijks 03:15 | Off-site backup van DB + uploads naar S3 |
POST /api/cron/security-check |
dagelijks 06:00 | npm audit-run, mailt ADMINs bij HIGH/CRITICAL CVEs |
Off-site backup & restore
Ingebouwd. Eén klik in Instellingen → Off-site backup of cron-aanroep
naar POST /api/cron/backup dumpt in één keer de PostgreSQL-database en
de /app/data/uploads-map naar een S3-compatibele bucket. Streamt direct
(pg_dump | gzip | S3 + tar.gz | S3), geen tussenbestand op disk.
Status (datum, OK/FAILED, samenvatting, eventueel foutbericht) is zichtbaar op de instellingen-pagina.
Restore procedure (uitgebreid in DEPLOY.md → Stap 9):
# 1) Stop de app in Coolify; DB-container blijft draaien.
# 2) Wis huidige DB-schema (alleen bij rollback / disaster recovery):
psql "$DATABASE_URL" -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"
# 3) Restore de DB:
gunzip < crm-<timestamp>.sql.gz | psql "$DATABASE_URL"
# 4) Uploads terugzetten:
sudo tar xzf uploads-<timestamp>.tar.gz \
-C $(docker volume inspect <stack>_app_data --format '{{.Mountpoint}}')
sudo chown -R 1000:1000 .../uploads
# 5) Start de app weer in Coolify.
⚠️ Bewaar AUTH_SECRET apart in je password manager — zonder die zijn
versleutelde DB-kolommen (TOTP-secrets, wachtwoordkluis) bij restore
onleesbaar.
Beveiliging
- Auth: bcryptjs (cost 12) voor wachtwoorden, JWT-sessie (7 dagen) via
jose 6, HttpOnly cookies. 2FA verplicht voor iedere gebruiker. - Sessies-tabel met per-sessie revoke + sessionVersion-bump bij wachtwoord/role-wijzigingen.
- Device-cookie voor nieuw-apparaat-detectie + login-melding.
- CSRF: server actions van Next.js valideren herkomst via
serverActions.allowedOrigins. - Step-up authenticatie met per-account rate-limit voor 2FA-disable, TOTP-enrollment en e-mail-wijziging.
- Weak-password-blocklist + naam/e-mail-substring-check.
- DocuSeal-webhook: HMAC-SHA256 + 5-min freshness, constant-time vergelijking.
- Magic-link goedkeuringen: single-use ondertekende JWT met
expenseId × approverId, 7 dagen TTL, DB-record voorkomt replay. - Mollie-webhook bindt aan stored
mollieId. - TLS: alleen AEAD-ciphers (geen CBC); HSTS; ML-KEM post-quantum key-exchange ondersteund.
- HTTP-headers: CSP, HSTS, X-Frame-Options DENY, X-Content-Type-Options nosniff, Referrer-Policy strict-origin-when-cross-origin, Permissions-Policy (camera/microphone/geolocation uit), COOP same-origin, CORP same-origin.
- GDPR: audit-log van alle wijzigingen; export-functionaliteit voor klantgegevens.
Periodieke security-review met claude code /security-review.
Updates & CVE-management
Ingebouwde Beveiliging & Updates-pagina (/settings/updates,
ADMIN-only):
- Bij iedere deploy draait
scripts/generate-security-report.mjs(in de Dockerfile) →npm audit+npm outdated→ result in de image. - UI toont per CVE de severity, klikbare advisory-link, CVSS-score en het
exacte
npm install <pkg>@<safe-version>-commando om 'm te dichten. - "Verzamel-commando" om alle CVEs in één klik te genereren.
- Daily cron (
POST /api/cron/security-check) ververst de audit en mailt alle actieve ADMINs zodra er HIGH/CRITICAL CVEs zijn — met de fix-commando's in de mail zelf. - Lijst van verouderde packages (major-bumps eerst) met direct
npm install <pkg>@latest-snippet per regel.
Werkstroom:
# 1) /settings/updates → kopieer verzamel-commando
npm install <pakketten>
# 2) Test lokaal:
npm run build
# 3) Push:
git commit -am "Security: dicht CVE-..." && git push
# 4) Coolify rebuildt → audit draait opnieuw → teller in UI op 0.
Volledige uitleg in DEPLOY.md → Stap 10. Voor full-automatische
update-PRs is Renovate Bot (Gitea/GitLab/GitHub-compatibel) een
goede aanvulling.
Release Notes
Functionele samenvatting per versie. Voor de volledige commit-by-commit
historie (inclusief minors, fixes, refactors, docs en hotfixes): zie
CHANGELOG.md.
Conventie voor toekomstige releases: elke commit krijgt een regel in
CHANGELOG.mdonder de juiste[Unreleased]-categorie (Added / Changed / Fixed / Security / Removed / Deprecated / Infra). Zodra een nieuwevX.Ygetagged wordt, schuift de[Unreleased]-sectie naar boven onder die versie en wordt een functionele samenvatting toegevoegd aan deze README.
v0.16 (2026-05-24) — DNS Beheer + Mobile scan
- 🌐 DNS Beheer-module met live ClouDNS-API: domeinen aan klanten koppelen, records (A/AAAA/CNAME/MX/TXT/NS) inline editen, alles audit-gelogd. Sidebar-item onder Beheer.
- 📷 Mobile snel-scan-flow (
/scan): camera → AI-OCR → bon klaar. PWA-shortcut + dashboard-banner alleen op mobiel. - Aparte facturatie-e-mail (
COMPANY_BILLING_EMAIL/CompanySettings.billingEmail): factuur-PDF, offerte-PDF, factuurmail en UBL gebruiken het apart; contracten en interne mails blijven opemail/support@. - AI-contracten verbeterd: expliciete vennoten als vertegenwoordigers
uit
isSigner-vlag (geen "J. Mullem"-verzinsel meer); strikte taalregels voorkomen "neertijd" en andere onbestaande NL-vertalingen. - DocuSeal: sender tekent eerst: huidige sender komt vooraan in de submitter-array (was alfabetisch).
v0.15 (2026-05-24) — Multi-signer + Bump-ronde
- Multi-signer DocuSeal-flow voor VOFs: alle vennoten (
isSigner-vlag)- klant moeten tekenen op contracten en op offertes > €5.000 ex BTW. Signing-pagina schaalt automatisch (1-2 rij, 3-4 grid, 5+ multipagina). "Wachten op handtekening van X, Y + klant" in de UI met live snapshot.
- Aparte "Ondertekenaar"-rol (
isSigner) los vanisApprover— toggle-knop op/users+ uitleg-mail bij activeren. - Grote dependency-bump: Next 15 → 16, bcryptjs 2 → 3 (ESM), jose 5 → 6, nodemailer 6 → 8, typescript 5 → 6, @anthropic-ai/sdk 0.32 → 0.98, Node 22 → 24 LTS. Prisma blijft op 6.19 (v7-migratie staat open voor een dedicated sessie).
v0.14 (2026-05-24) — Security & ops
- 2FA verplicht voor iedereen: zonder ingeschakelde 2FA word je naar
/accountdoorgestuurd. Banner totdat 2FA aanstaat. - Actieve sessies-beheer + nieuw-apparaat-detectie: zie ingelogde apparaten op je account-pagina, trek ze los, "overal anders uitloggen"- knop. Nieuwe device-cookie + login-melding op onbekend apparaat.
- Beveiliging & Updates-pagina (
/settings/updates):npm audit-snapshot bij elke deploy, daily cron mailt admins bij HIGH/CRITICAL CVEs, met fix-commando's in de mail. - Off-site backup naar S3 (DigitalOcean Spaces, B2, R2, AWS) — één
knop in Instellingen of
POST /api/cron/backup. Streamt DB + uploads direct naar de bucket. - TLS-hardening: CBC-ciphers uit, HSTS, post-quantum
key-exchange (X25519MLKEM768). Config in
deploy/traefik-tls-hardening.yaml. - CSP / COOP / CORP / Permissions-Policy strenger.
- Hardening-ronde: step-up rate-limit, weak-password-blocklist, security-alert mails, extra HTTP-headers.
- Asset/license & wachtwoordkluis per klant (AES-256-GCM, audit-log met IP/UA bij reveal).
v0.13 (2026-05-22) — Mobile UI & UX
- Mobiele UI rondom forms, tables en Kanban-scroll opgepoetst (alle 19
tables krijgen
overflow-x-auto; Kanban-bord is swipeable metsnap-x snap-mandatory). - Drawer-z-index-bug op mobiel opgelost (createPortal naar body).
- Fiatteur-fallback: zelf-uploader mag eigen inkoop nu wél fiatten als hij de enige fiatteur is.
v0.12.1 (2026-05-21) — Hotfixes na security-release
- Login redirect-loop opgelost (middleware deed optimistic redirect; pagina doet nu zelf DB-validatie).
- Account-pagina UI bijgewerkt met wachtwoord-velden voor 2FA-disable / TOTP-enrollment / email-change (matched step-up auth uit v0.12).
- DocuSeal-URL voorbeeld in
.env.examplenaarondertekenen.je-ma.com. CHANGELOG.mdmet volledige commit-by-commit historie toegevoegd.
v0.12 (2026-05-21) — Security hardening
- Pentest-remediatie: 14 HIGH en 15 MEDIUM bevindingen opgelost
(volledig rapport in
CRM-Portaal-Pentest-Rapport-v0.12.pdf). - Per-request DB-revalidatie van sessies +
sessionVersion-mechanisme: role-changes, deactivatie en password-wijzigingen werken nu meteen door op álle apparaten. - TOTP-secrets versleuteld at-rest (AES-256-GCM, HKDF-key uit
AUTH_SECRET). - Recovery-codes nu bcrypt-hashed; atomic consumption voorkomt race-reuse.
- Step-up authenticatie (huidig wachtwoord vereist) voor 2FA-disable, TOTP-enrollment en e-mail-wijziging.
- Approval-token (fiatteur magic-link) is nu single-use met DB-record en TTL 7 dagen i.p.v. 30; uploader kan eigen inkoop niet meer goedkeuren.
- DocuSeal-webhook: 5-minuten freshness-check tegen replay-attacks.
- Mollie-webhook: bindt aan stored
mollieIdom cross-tenant misbruik uit te sluiten. - Cron-endpoints: alleen POST +
Authorization: Bearer, geen query-token meer. - CSV-export saniteert formula-injectie (
= + - @prefix). - Filename-sanitization tegen zip-slip in boekhouder-ZIP.
- iCal-feed alleen eigen toegewezen taken; facturen + projecten weggehaald.
AUTH_SECRETminimaal 32 chars; bcrypt cost 12; wachtwoord-minimum 12; JWT-alg expliciet gepind op HS256./api/ai/*en/api/travel/quotevereisen nu MANAGER-rol.- Server Actions
allowedOriginsexpliciet gezet.
v0.11 (2026-05-21)
- PDF-overhaul: factuur en offerte hertekend met VAN/AAN-kolommen, totalen-blok, mooie betaalsectie. Contract-handtekeningen krijgen altijd een eigen laatste pagina.
- Betaal-QR op factuur via Mollie-checkout-link (werkt op alle banken incl. ABN AMRO en Rabobank). EPC-QR verwijderd omdat te weinig banken het ondersteunen.
- AI-offertegenerator op
/quotes/new. - AI-contractgenerator voor SLA / AV / NDA / verwerkersovereenkomst / raamovereenkomst / licentie met directe PDF-opslag.
- Klantportaal verwijderd — flow paste niet bij de doelgroep (kleine bureaus); functionaliteit verschuift naar magic-link per document waar nodig.
- Boekhouding-sectie in sidebar met hub-pagina: inkopen, externe verkoopfacturen, bank, BTW-aangifte, maandstaat.
- Externe verkoopfacturen (model + UI): upload PDFs van Moneybird / Exact / papier, AI vult velden in, gaan mee in boekhouder-ZIP.
- Bulk-upload voor zowel inkopen als externe verkoopfacturen met parallel AI-OCR.
- Boekhouder-ZIP uitgebreid met verkoopfacturen (CSV + PDFs van CRM én externe).
- Auto-mail naar fiatteurs zodra een inkoop wordt aangemaakt, met magic-link voor digitaal goedkeuren zonder login.
- Bevestigingsmail naar uploader en fiatteurs zodra een inkoop volledig is goedgekeurd en op de inkooplijst staat.
v0.10 (2026-05-20)
- KVK-lookup bij klant aanmaken/bewerken (KVK Zoeken-API of overheid.io OpenKVK).
- Productcatalogus — voorgedefinieerde diensten met prijzen, één klik om op offerte / factuur te plaatsen.
- Multi-currency op offertes en facturen (EUR, USD, GBP, CHF, NOK, SEK, DKK) met wisselkoers naar EUR.
- Offerte-versies — nieuwe versie van afgewezen offerte, alle versies blijven gekoppeld.
- BTW-aangifte-rapport per kwartaal.
- Bankafschrift-import (CSV) met automatische match op IBAN, bedrag en factuurnummer.
v0.9 (2026-05-20)
- Goedkeuringsworkflow voor inkopen (VOF: beide partners moeten tekenen).
- Contractbeheer voor SLA, raamovereenkomst, AV, NDA, licentie, verwerkersovereenkomst.
- DocuSeal-flow ondersteunt nu zowel offertes als contracten.
- Tweerichtings-ondertekening: ondergetekende eerst, dan klant.
- Automatische factuur + Mollie-link + mail zodra een offerte volledig is ondertekend.
v0.8 (2026-05-20)
- Inkopen-module met AI-OCR (Claude vision) voor bonnetjes (PDF + foto).
- Maand-ZIP met inkopen + bonnen, mailen naar boekhouder.
- DocuSeal-integratie voor offertes.
- Projectrentabiliteit en cashflow-forecast in rapportages.
- UBL-export voor PEPPOL-compatibele facturen.
- iCal-feed per gebruiker.
- PWA — installeerbaar op telefoon, manifest + service worker.
v0.7 (2026-05-20)
- E-mail templates met variabelen (
{{customer}},{{amount}}). - Automatische factuur-herinneringen per cronjob.
- Donker thema met persistente switch.
- Keyboard shortcuts (
g+letter,n+letter,?voor help). - Audit-log viewer voor ADMIN-rol.
- Settings-pagina met logo-upload.
v0.6 (2026-05-20)
- Deals pijplijn met Kanban en sleep-functie.
- Offertes met publieke akkoord-link.
- Facturen met e-mail + Mollie-betaallink + webhook.
- AI-assistent voor klantsamenvattingen.
- Live tijdregistratie met timer-widget.
- Rapportages met grafieken.
- Cmd+K globale zoek.
- TOTP / 2FA voor login.
- Bijlagen op klanten en projecten.
- Abonnementen (terugkerende facturen).
v0.5 (2026-05-18)
- Eerste werkende versie met klanten, projecten, taken, notities en docker-compose deploy voor Coolify.
Roadmap
Praktische, geprioriteerde verbeteringen.
Geld & boekhouding
- 3-traps aanmaning-flow met wettelijke handelsrente.
- iDEAL-quicklink voor losse bedragen zonder factuur.
- Aanbetaling / termijnfacturen (50/50 of 30/40/30 split).
- Creditfactuur-flow met gekoppelde negatieve factuur.
- PSD2-bankkoppeling (Ponto / Tink) voor automatische transactie-import.
- PEPPOL-versturen via Storecove.
- Moneybird / Snelstart / e-Boekhouden API-koppeling (vervang ZIP-mail).
EU-handel
- VIES BTW-validatie bij EU-klanten (groen/rood).
- 0%-tarief BTW-verleggen bij geldige EU-BTW.
- ICP-aangifte rapport per kwartaal.
Workflow / UX
- Inbox-dashboard "Wachten op jou": openstaande te-tekenen, te-fiatten, vervalde facturen, etc. op één scherm.
- Bulk-acties op lijsten (mass-tag, mass-mailen, mass-status).
- Factureer ongefactureerde uren in één klik per klant of project.
- Quick-add menu (Cmd+N → kies type → mini-form).
- Web-push notificaties (PWA) voor contract-getekend / inkoop-fiat / betaling-binnen.
Infrastructuur
- Prisma 7-migratie (pure TS/WASM-runtime, driver-adapter
@prisma/adapter-pg). - Outgoing webhooks (n8n/Zapier) bij events (factuur betaald, contract getekend, klant aangemaakt).
- Renovate Bot voor automatische dependency-PRs.
AI
- AI-factuur-regels uit gewerkte uren (auto-omschrijvingen).
- Smart-search via Claude (“open facturen >€2k van Bakkerij Jansen”).
- AI-mail-antwoord-assistent met klantcontext.
- Pijplijn-forecast met kans-op-winnen.
DNS-uitbreiding
- DNSSEC-toggle vanuit het CRM.
- Bulk-import van een zone-file.
- WHOIS/RDAP-koppeling voor automatische verloopdatum-sync.
Licentie
Geen open-source licentie expliciet ingesteld. Gebruik voor eigen bedrijfsdoeleinden; voor commerciële herdistributie: vraag het even.
— gemaakt met heel veel git push origin main.