Files
rikx-beheer/CLAUDE.md
T
remco-vermeer f9e4a1aa5d Verstuur uitnodigingen voor experts via SendGrid, zoals het ZRM-platform
- lib/mail.ts gebruikt SendGrid met dezelfde variabelen als het Rikx
  ZRM-platform (SENDGRID_API_KEY, SENDGRID_FROM_EMAIL, SENDGRID_FROM_NAME);
  SMTP blijft beschikbaar als alternatief
- Uitnodigingsmail krijgt ook een HTML-versie met knop
- Zonder SendGrid of SMTP blijft de pagina Experts de link tonen
- .env.example en CLAUDE.md bijgewerkt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 15:05:45 +02:00

78 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# rikx-beheer
Beheerportaal voor de Rikx-methodiek. Beheert de sociaal ondernemers (accounts in de ZRM-platformdatabase) en de projecten van Module 1 (Projects flow).
## Pagina's
- `/tenants` — sociaal ondernemers aanmaken, bewerken, verwijderen, auto-inlog (leest/schrijft de platformdatabase via `lib/platform-db.ts`)
- `/projecten` — projecten als pipeline (standaard, kolom per status) of tabel (`?weergave=tabel`), met filter op status, Rikx Ronde en zoeken. De knop "+ Project toevoegen" maakt direct een project aan ("Nieuw project", status Aanvraag) en opent de projectpagina
- `/waardebepaling` — Waardebepaling projecten: tabel met projecten in status Waardebepaling (projectnaam, impactmaker, kosten/impact), gerangschikt op kosten/impact van laag naar hoog, filter op Rikx Ronde. Alleen bij een gekozen Rikx ronde (niet bij Alle/Zonder ronde) een dikke oranje lijn onder het 75%-project: plek ⌈0,75 × n⌉ van de projecten met een berekende kosten/impact (zie `index75Procent`), volgens de Waarderingssystematiek; erboven de 75% meest efficiënte. Bovenaan een Rikx Waarde-veld: rekent live door met Rikx prijs = 10% voor de getoonde projecten met een ronde, en slaat waarde en prijs (na 0,8 s of bij verlaten van het veld) op in de Rikx ronde(s) van die projecten (`app/waardebepaling/actions.ts`)
- Impactmaker van een project = sociaal ondernemer: `projects.impactmaker_account_id` verwijst naar `accounts.id` in de platformdatabase (geen foreign key; namen via `listAccountNames()` in `lib/platform-db.ts`)
- `/rondes` — Rikx rondes beheren (label, Rikx waarde, Rikx prijs, gekoppelde experts; dezelfde koppeling `expert_rondes` als op `/experts`); een project hoort optioneel bij één ronde (`projects.ronde_id`)
- `/projecten/[id]` — projectpagina met tabs: Project plan (velden en keuzelijsten gedefinieerd in `lib/projectPlan.ts`) en Rikx calculatie (alleen zichtbaar vanaf status Waardebepaling, zie `RIKX_CALCULATIE_VANAF_STATUS` in `lib/projectStatus.ts`; rekenmethode `arbeid`, `jeugd` is zichtbaar maar nog niet beschikbaar). Onderaan de tab: Beoordeling (`beoordeling`: goedgekeurd/afgekeurd/leeg) met `beoordeling_reden`. Kolom `rikx_calculatie_aan` is van de oude schuif en wordt niet meer gebruikt. Uitkomsten worden live berekend met `lib/rikxCalculatie.ts`
- `/experts` (CRM → Experts) — experts uitnodigen, rondes koppelen, opnieuw uitnodigen (ook voor een vergeten wachtwoord), verwijderen, en "Inloggen als": een admin bekijkt `/expert` als die expert (alleen lezen; sessie met `impersonatorId`, terug via "Terug naar beheer"). Uitnodiging per e-mail via SendGrid of SMTP; zonder beide toont de pagina de link om zelf door te geven
- `/uitnodiging/[token]` — openbaar: expert stelt wachtwoord in (token 7 dagen geldig, eenmalig; alleen de SHA-256-hash staat in de database)
- `/expert` — de enige pagina voor experts: projecten in Waardebepaling uit hun rondes, project plan (alleen lezen) en hun eigen beoordeling (3 scores 1–10, advies Bonus/Malus, toelichting). Experts zien elkaars beoordeling niet
- Rollen: `users.role` = `admin` of `expert`. Elke beheerpagina en -actie begint met `requireAdmin()`, de expertpagina met `requireExpert()` (`lib/auth.ts`); de rol komt uit de database, niet uit de cookie
- Gedeelde kop met navigatie: `app/AppHeader.tsx` (oranje Rikx-balk, menu per module; items zonder pagina tonen "binnenkort")
- Huisstijlkleuren als Tailwind-tokens in `app/globals.css`: `rikx-orange`, `rikx-purple` (actief menu-item), `rikx-maroon` (primaire knop). Statuskleuren in `lib/projectStatus.ts`
- Conventie: server actions in `actions.ts` per map, geen API-routes (behalve `app/api/auto-login`)
## Stack
- Next.js 16 + TypeScript + Tailwind CSS
- SQLite via `node:sqlite` (ingebouwd in Node 22, geen extra package)
- HMAC-signed sessie-cookie auth (geen externe auth-provider)
- E-mail via SendGrid (zoals het ZRM-platform) of Nodemailer/SMTP — `lib/mail.ts`
## Lokaal draaien
```bash
npm install
cp .env.example .env.local
# Vul SESSION_SECRET in (.env.local) — minimaal 32 tekens willekeurig
mkdir -p data
npm run dev # http://localhost:3000
# Lokaal de platformdatabase gebruiken: RIKX_PLATFORM_DB_PATH=./data/platform.db
```
## Admin aanmaken
```bash
npm run create-admin maarten@rikx.nl wachtwoord "Maarten"
```
## Database
- Locatie lokaal: `./data/app.db`
- Locatie productie: `/data/app.db` (absoluut pad — Next.js standalone doet process.chdir bij start)
- Schema: `lib/db.ts` — migraties draaien automatisch bij eerste verbinding
- Tabellen: `users`, `projects` (`name`, `status`; statussen in `lib/projectStatus.ts`, standaard `aanvraag`; plus de velden uit de rekenmethode als kolommen; overige project plan-velden als JSON in `project_plan`), `expert_beoordelingen` (per project en expert; Impactscore M = gemiddelde over de experts; de Rikx calculatie-tab toont ze alleen-lezen), `expert_rondes`, `expert_uitnodigingen`. `project_expert_scores` (oude handmatige scores) wordt niet meer gebruikt maar blijft staan, `rikx_rondes` (Rikx waarde en prijs per ronde; de calculatie haalt ze uit de ronde van het project, prijs standaard waarde / 10)
- Rekenmethode (Rikx Waardeberekening Arbeid): `_doc/Rikx rekenmethode uitleg.xlsx`, tabblad Uitleg; achtergrond in `_doc/Waarderingssystematiek Rikx juni 2023.pdf`. Afwijkingen van de sheet: N-score = ((werk×5)+skills)/6 (sheet mist haakjes), Bonus/Malus `-` = 0,9 en `--` = 0,8 (sheet heeft typefouten)
- De oude offerte-tabellen (`clients`, `projects` met `client_id`, `quotes`, `quote_items`) worden bij de migratie verwijderd als ze leeg zijn; met gegevens worden ze hernoemd naar `legacy_*`
- Tweede database (alleen-platform): `RIKX_PLATFORM_DB_PATH` (standaard `/rikx-platform-data/app.db`) met `accounts` en `users` van het ZRM-platform
## Infrastructuur (mx-platform.com)
- **Platform:** Coolify v4 op mx-platform.com (37.97.203.131)
- **Git repo:** https://git.mx-platform.com/admin/rikx-beheer
- **Dockerfile:** `/Dockerfile` (Node 22 Alpine, Next.js standalone)
- **Port:** 3000
- **URL:** https://beheer.rikxplatform.nl
## Environment variables
| Variabele | Standaard | Uitleg |
|-----------|-----------|--------|
| `SESSION_SECRET` | — | HMAC-secret voor sessie-cookies — per omgeving uniek genereren |
| `DB_PATH` | `./data/app.db` | **In productie: `/data/app.db`** (absoluut pad) |
| `RIKX_PLATFORM_DB_PATH` | `/rikx-platform-data/app.db` | Database van het ZRM-platform (sociaal ondernemers) |
| `NODE_ENV` | `development` | In productie: `production` |
| `SENDGRID_API_KEY` | — | E-mail via SendGrid (uitnodigingen voor experts); zelfde key als het Rikx ZRM-platform. Nooit committen. Leeg én geen SMTP = geen e-mail, link wordt in beeld getoond |
| `SENDGRID_FROM_EMAIL` | `no-reply@rikxplatform.nl` | Afzender bij SendGrid (domein is daar al geverifieerd voor ZRM) |
| `SENDGRID_FROM_NAME` | `Rikx` | Afzendernaam |
| `SMTP_HOST` | — | Alternatief voor SendGrid: SMTP server (alleen gebruikt als `SENDGRID_API_KEY` leeg is) |
| `SMTP_PORT` | `587` | SMTP poort |
| `SMTP_USER` | — | SMTP gebruikersnaam |
| `SMTP_PASS` | — | SMTP wachtwoord |
| `SMTP_FROM` | `noreply@rikx.nl` | Afzenderadres |
## Auto-deploy
Gitea webhook → Coolify. Na elke push naar `main` automatisch live.
## Collega's
Wijzigingen alleen via Git. Push naar `main` → automatisch live.