Lab21

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

KolomBron-veldToelichting
OrdernummerPlannings_nummerLinkt naar planning-detail
KlantnaamKlantnaam_1
WoonplaatsVerzendadres_plaats_1
VoorinspectiedatumVoorinspecties.Datum (via Planning-lookup)
EgalisatiedatumEgalisatiedatumKolom alleen zichtbaar als minstens één rij waarde heeft
2de egalisatiedatumTweede_egalisatiedatumKolom alleen zichtbaar als minstens één rij waarde heeft
Leverdatum materialenGewenste_leverdatum
Start legdatum vloerDatum
Opleverdatum vloerEinddatum
Aktie vereistVerzoek_actie_verkoperBij lege waarde wordt de actie afgeleid

Afleidingsregel “Aktie vereist”

Als Verzoek_actie_verkoper leeg is, kiest de UI de eerstpassende regel:

  1. Geen voorinspectie EN (Fase = Voorinspectie OF geen startdatum) → Voorinspectie inplannen
  2. Voorinspectie-status = AandachtVoorinspectie aandacht
  3. Fase = Voorinspectie en voorinspectie nog niet Akkoord Voorinspectie afronden
  4. Geen Gewenste_leverdatum maar wel een startdatum → Materialen plannen
  5. 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

  1. Het schema leeft in de workflows-repo (Drizzle-migraties). Voeg de kolom daar toe en pas zo nodig de RLS-grants aan.
  2. Map de kolom in de juiste map*()-functie in lib/data.ts naar het property in lib/types.ts.
  3. Gebruik het in de page-component.
  4. 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)