Werking
Hoe het Aannemerportal werkt — pagina's, datavelden en logica. Documentatie ook beschikbaar als docs/werking.md.
Doel
Het portal geeft het team één gedeeld beeld van lopende uitvoeringen (planningen) en bijbehorende voorinspecties en aannemers. Alles draait om de tabel op /opdrachten. De data komt uit Postgres (tabellen aannemers, planningen, voorinspecties).
Pagina's
Opdrachtenoverzicht (/opdrachten) — centrale tabel met alle planningen, gesorteerd op startdatum. Datums kleuren oranje binnen 2 dagen, bordeauxrood als ze in het verleden liggen. Klik op een ordernummer voor de detailpagina.
Voorinspecties (/voorinspecties) — lijst van voorinspecties met statussen Open, Aandacht, Akkoord.
Aannemer-detail (/aannemers/[id]) — contact-, bedrijf- en financiele gegevens van één aannemer plus de gekoppelde planningen en voorinspecties. Bereikbaar via een planning of voorinspectie; er is geen overzicht van alle aannemers in dit portaal.
Detailpagina's — /aannemers/[id] en /planningen/[id].
Root — / redirect naar /opdrachten.
Kolommen op het Opdrachtenoverzicht
| Kolom | Bron-veld | Toelichting |
|---|---|---|
| Ordernummer | Plannings_nummer | Linkt naar planning-detail |
| Klantnaam | Klantnaam_1 | — |
| Woonplaats | Verzendadres_plaats_1 | — |
| Voorinspectiedatum | Voorinspecties.Datum (via Planning-lookup) | — |
| Egalisatiedatum | Egalisatiedatum | Kolom alleen zichtbaar als minstens één rij waarde heeft |
| 2de egalisatiedatum | Tweede_egalisatiedatum | Kolom alleen zichtbaar als minstens één rij waarde heeft |
| Leverdatum materialen | Gewenste_leverdatum | — |
| Start legdatum vloer | Datum | — |
| Opleverdatum vloer | Einddatum | — |
| Aktie vereist | Verzoek_actie_verkoper | Bij lege waarde wordt de actie afgeleid |
Afleidingsregel “Aktie vereist”
Als Verzoek_actie_verkoper leeg is, kiest de UI de eerstpassende regel:
- Geen voorinspectie EN (
Fase = VoorinspectieOF geen startdatum) → Voorinspectie inplannen - Voorinspectie-status =
Aandacht→ Voorinspectie aandacht Fase = Voorinspectieen voorinspectie nog nietAkkoord→ Voorinspectie afronden- Geen
Gewenste_leverdatummaar wel een startdatum → Materialen plannen - Anders → geen actie (“—”)
Data & integratie
Sinds de DB-consolidatie (2026-06-07) leest het portal RLS-scoped uit de centrale workflows-database via lib/db.ts (postgres.js) als rol aannemers_app. De connectie-string staat in WORKFLOWS_APP_DATABASE_URL; bij connect zet de app twee session-GUC's — app.current_company (company-tenant) en app.current_aannemer(deze aannemer). De RLS-policies zorgen dat de aannemer alleen z'n eigen rijen ziet. De header rechtsboven toont Database verbonden wanneer dit gezet is, anders Demo-modus (mockdata uit lib/mock.ts).
De gedeelde tabellen (sales_orders, voorinspecties, planningen, ruimtes, articles, montage_partners) zijn alleen-lezen voor deze app. Wijzigingen aan gedeelde data lopen als intents via de workflows-API (lib/intents.ts), die na akkoord schrijft. Eigen aannemer-data (monteurs, monteur_x_artikel, vakanties en de monteur-toewijzing sales_order_lines.monteur_id) schrijft de app wél direct (RLS staat dat scoped toe).
Een nieuw veld toevoegen
- Het schema leeft in de workflows-repo (Drizzle-migraties). Voeg de kolom daar toe en pas zo nodig de RLS-grants aan.
- Map de kolom in de juiste
map*()-functie inlib/data.tsnaar het property inlib/types.ts. - Gebruik het in de page-component.
- Voor schrijfbare gedeelde velden: breid de intent-payload uit in de betreffende server-action (
app/.../actions.ts); voor eigen data: de directe write.
Tech-stack
- Next.js 16 (App Router, Server Components, Server Actions)
- React 19
- Tailwind CSS 4
- Postgres (postgres.js) als bron van waarheid
- Gehost via Nixpacks (Node ≥ 20.9)
