← Terug naar masterplan

Bossuyt Changenotes

Versiegeschiedenis van het plan, de cursus en de service app β€” met uitleg van elke nieuwe functie.

v1.10 11 april 2026 Rijkere staging-dataset voor volgende toestel-flow
Nieuw Rijkere staging-database met ongeveer 15 klanten

De staging database bevat nu een veel grotere en realistischer dataset, met extra klanten, sites en toestellen. Daardoor kunnen de volgende versies testen hoe een technieker op dezelfde klant extra toestellen en extra opdrachten ziet zonder opnieuw basisdata te moeten uitvinden.

Verbeterd Bestaande planningsklanten kregen veel meer toestellen

De klanten die vandaag al in de planning zitten zijn bewust het sterkst uitgebreid. Dat maakt het mogelijk om in de volgende versie realistisch te testen hoe je op een klantsite een extra opdracht voor een ander toestel kan openen.

15 klanten 17 sites 47 toestellen huidige planning bewust verdiept
Verbeterd Historische dummy werkorders in de database

Voor de belangrijkste bestaande klanten en toestellen zijn oudere afgewerkte werkorders toegevoegd in de database. Die zijn nog niet zichtbaar in de huidige UI, maar vormen wel het fundament voor de toestelgeschiedenis die we in de volgende versie willen tonen.

πŸ’‘ Waarom al historiek toevoegen?

Omdat v1.11 niet eerst nog eens de database moet verbouwen voor testdata. De data ligt al klaar zodat we dan puur kunnen focussen op wat de technieker te zien krijgt: meerdere toestellen per klant, extra opdrachten op dezelfde site en historiek per toestel.

v1.9 11 april 2026 Staging nu echt DB-backed
Nieuw Shared PostgreSQL slice live op staging

staging.bossuyt.fixassistant.com draait nu op een echte PostgreSQL-laag voor techniekers, klanten, sites, toestellen, werkorders en toewijzingen. De demo-site bossuyt-service.fixassistant.com is bewust onaangeraakt gebleven en gebruikt nog steeds de oude mock-flow.

πŸ’‘ Waarom is deze split belangrijk?

Staging mag evolueren, breken en migreren. De demo moet stabiel blijven zolang Bossuyt die gebruikt. Daarom heeft staging nu zijn eigen app-container, eigen database en eigen volume.

Dat maakt de latere verhuis naar een andere server ook eenvoudiger: je exporteert de staging app + database als een aparte stack, zonder de demo mee te sleuren.

Nieuw Echte ochtend-sync via /api/sync/today

De ontbrekende sync-route is gebouwd en leest nu echte records uit PostgreSQL. Het dagoverzicht krijgt opnieuw max. 6 geplande jobs en 4 open pool jobs, maar nu via een serverlaag in plaats van rechtstreeks uit lib/mock-data.ts.

Live check op staging
curl 'https://staging.bossuyt.fixassistant.com/api/sync/today?technicianId=u1&date=2026-04-11'
# β†’ planned: 6 jobs, open: 1 job
Verbeterd Dagoverzicht en interventiedetail lezen niet langer direct uit mock-data

Het homescreen leest nu eerst uit IndexedDB en synchroniseert daarna met de server. De interventiedetailpagina probeert eerst de offline cache en valt pas daarna terug op een serverroute per interventie. Daardoor begint de service app eindelijk een echte offline-first read path te krijgen.

Verbeterd Staging database tooling klaar voor export naar andere server

De envs zijn opgesplitst tussen host tooling en Docker runtime. In de container praat de app met db-staging; buiten Docker kunnen tools zoals Drizzle of seed-scripts naar localhost:5433 connecteren. Dat voorkomt dat migratie- en seed-commando's per ongeluk naar de verkeerde host wijzen.

staging.bossuyt.fixassistant.com db-staging op localhost:5433 8 seeded work orders demo-site bewust onaangeraakt
v1.8 11 april 2026 Route, release-discipline en mobiele verfijning
Nieuw Vrij start- en eindadres in de route

Je kan nu een vrij adres intypen als vertrek- of eindpunt. De app zoekt automatisch de GPS-coΓΆrdinaten op via Nominatim (OpenStreetMap), zodat je niet meer aan een vaste lijst vastzit.

Verbeterd Route refresht automatisch op relevante wijzigingen

De timeline herberekent nu niet alleen bij drag & drop, maar ook wanneer je startadres, eindadres of pauzepositie verandert. Een debounce van 350 ms voorkomt dat de route bij elke toetsaanslag meteen vuurt.

Verbeterd Centrale versiebron voor badge + changelog

De actieve versie staat nu op één plaats in de service-app repo. Daardoor blijven de badge rechtsonder en /changenotes synchroon, in plaats van dat ze los van elkaar divergeren.

Fix Duidelijkere mobiele uitleg bij geblokkeerde locatie tijdens pauze

Wanneer Android de geolocatie-popup blokkeert door overlays of zwevende vensters, toont de app nu een explicietere uitleg in plaats van een vage fout. Dat maakt het probleem begrijpelijker voor de technieker op mobiel.

v1.7 10 april 2026 Echte routing en realistische demo-locaties
Nieuw Echte rijtijden via OpenRouteService

De route-timeline toont nu echte rijtijden en afstanden via OpenRouteService. Zonder ORS-key valt de app in development nog altijd terug op mock-waarden, maar staging kan nu echte routeberekeningen tonen.

Nieuw GPS-coΓΆrdinaten en geocoder voor alle demo-sites

Alle locaties kregen lat/lon-coΓΆrdinaten en nieuwe adressen kunnen via Nominatim automatisch naar GPS vertaald worden. Daardoor zit de route-engine niet meer vast op placeholders.

Verbeterd Demo-dag realistischer gemaakt

Er kwamen extra demo-klanten en een geloofwaardigere route door Oost-Vlaanderen, zodat de service-app dichter bij de uiteindelijke Bossuyt-flow komt.

v1.6 9 april 2026 Route-timeline als nieuwe dagweergave
Nieuw Planning werd een echte route-timeline

Het dagoverzicht toont sindsdien niet langer alleen een lijst, maar een verticale route: start, rijtijd, job, pauze, volgende job en einde. Zo ziet een technieker sneller hoe de dag eruitziet.

Nieuw Instelbare start- en eindlocatie

Je kan het depot vervangen door een ander vertrekpunt en eventueel ook een ander eindpunt kiezen, bijvoorbeeld thuis in plaats van het depot.

Verbeterd Sleepbare middagpauze en dagsamenvatting

Een middagpauze van 30 minuten wordt automatisch ingevoegd en kan mee verplaatst worden in de route. Bovenaan de timeline zie je sindsdien live het aantal jobs, werkuren en rijtijd.

v1.5 9 april 2026 Staging workflow + server migratie plan
Nieuw docker-compose.staging.yml β€” Tijdelijke testomgeving

Aparte Docker Compose file die een staging versie opstart op staging.bossuyt.fixassistant.com. Eigen database zodat productiedata nooit geriskeerd wordt. Container herstart niet automatisch β€” staging is bewust tijdelijk.

πŸ’‘ Hoe gebruik je dit?

Opstarten: docker compose -f docker-compose.staging.yml up --build -d

Stoppen na testen: docker compose -f docker-compose.staging.yml down

De -f flag vertelt Docker Compose welk bestand te gebruiken. Zonder die flag gebruikt het altijd docker-compose.yml (productie). Zo kunnen beide naast elkaar draaien zonder conflict β€” andere container naam, andere subdomain, andere Traefik router.

Workflow per sessie (1 dag/week)
# 1. Code schrijven β€” geen impact op productie

# 2. Staging opstarten en testen
docker compose -f docker-compose.staging.yml up --build -d
# β†’ https://staging.bossuyt.fixassistant.com

# 3. Alles ok? Naar productie
docker compose up --build -d

# 4. Staging opruimen
docker compose -f docker-compose.staging.yml down
Nieuw Fase 5 β€” Server migratie Hetzner β†’ Bossuyt

Nieuwe fase toegevoegd aan het masterplan (post Week 40): volledige verhuizing van de Hetzner server naar een Bossuyt-eigen server. Inclusief database backup strategie, Docker image inventarisatie, DNS switch procedure en rollback plan.

πŸ’‘ Waarom is migratie risicovol?

Een server migratie heeft drie gevaarlijke momenten:

1. Database: als de dump niet compleet is of de restore mislukt, verlies je data. Oplossing: restore altijd eerst testen op de nieuwe server vΓ³Γ³r de echte migratie.

2. DNS: DNS wijzigingen propageren traag (soms uren). Oplossing: TTL vooraf verlagen naar 5 minuten, zodat een rollback snel effectief is.

3. Environment variables: .env bestanden zijn nooit in git. Oplossing: inventariseer ze expliciet vΓ³Γ³r de migratie.

Database backup commando's
# Backup (op oude server)
docker exec bossuyt-db pg_dump -U bossuyt -Fc bossuyt > bossuyt.dump
docker exec keycloak-db pg_dump -U keycloak -Fc keycloak > keycloak.dump

# Overbrengen naar nieuwe server
scp bossuyt.dump user@nieuwe-server:/backups/

# Restore (op nieuwe server)
docker exec -i bossuyt-db pg_restore -U bossuyt -d bossuyt < bossuyt.dump
Nieuw Staging workflow β€” plan website sectie

Stap-voor-stap staging workflow toegevoegd aan de "Waar starten" sectie van het masterplan: code schrijven β†’ staging bouwen β†’ testen β†’ productie deployen β†’ staging stoppen.

docker-compose.staging.yml Plan: Fase 5 server migratie Plan: staging workflow sectie
v1.4 9 april 2026 Service App fundament
Nieuw types/planning.ts β€” Planning types

Nieuwe TypeScript types die de plannningslogica beschrijven: WorkOrder (een werkbon met type planned of open), RemovedReason (waarom een technieker een job uit zijn planning haalt), RouteStep (rijtijd tussen twee stops) en TechnicianDayCache (alles wat gecached wordt bij dagstart).

πŸ’‘ Wat zijn TypeScript types?

Types zijn als afspraken: je beschrijft de vorm van je data zodat TypeScript je waarschuwt als je iets vergeet of een typfout maakt. Het zijn geen echte objecten β€” ze bestaan enkel tijdens het compileren.

types/planning.ts (fragment)
// RemovedReason is een "union type" β€” één van deze exacte strings
type RemovedReason =
  | 'cant_finish'        // Lukt niet meer
  | 'missing_material'   // Materiaal ontbreekt
  | 'impossible_timing'  // Onmogelijke timing voor klant
  | 'other'              // Andere (verplicht vrij tekstveld)

// Als je nu ergens removedReason = 'verkeerd' schrijft β†’ TypeScript fout
// Als je removedReason vergeet in te vullen β†’ TypeScript fout
Nieuw lib/routing/ β€” Swappable routing service

Een IRoutingService interface plus een OrsRoutingService implementatie. De interface definieert wat de service doet, de implementatie definieert hoe. Later swap je ORS naar TomTom zonder de rest van de app te wijzigen.

πŸ’‘ Wat is een interface?

Een interface is een contract. Het zegt: "alles wat dit interface implementeert, moet deze functies hebben." De OrsRoutingService tekent dit contract en levert de echte code. Morgen maak je TomTomRoutingService β€” zelfde contract, andere code.

lib/routing/IRoutingService.ts
// Het contract β€” geen implementatie, enkel de signatuur
export interface IRoutingService {
  getETA(from: Coordinates, to: Coordinates): Promise<RouteResult>
}

// ORS tekent het contract
export class OrsRoutingService implements IRoutingService {
  async getETA(from, to) { /* echte ORS code */ }
}

// Gebruik: je kent enkel het contract β€” niet welke provider
const eta = await routingService.getETA(depot, klant)
// ↑ werkt met ORS Γ©n TomTom zonder aanpassing
Nieuw lib/idb.ts β€” Offline database

De browser-database van de Service App. Slaat interventies, werkbon-formulierdata, offline acties en sync-metadata op zodat alles werkt zonder internet.

πŸ’‘ Wat is IndexedDB?

IndexedDB is een database ingebouwd in elke browser. Je kan er grote hoeveelheden data in opslaan β€” ook als je offline bent. We gebruiken het idb pakket dat de moeilijke native API omzet naar gewone async functies.

4 stores (tabellen):

lib/idb.ts β€” stores overzicht
// interventions β€” de werkbonnen van de dag (planned + open)
// werkbonnen    β€” ingevulde formulieren per werkbon
// pendingWrites β€” acties gedaan offline, wachten op sync
// dayMeta       β€” wanneer was de laatste sync?

// Voorbeeld: werkbon opslaan (elke keystroke)
await saveWerkbon({
  interventionId: 'int-42',
  parts: [{ articleId: 'art-1', qty: 2 }],
  notes: 'Filter vervangen',
  followUpRequired: false,
  // ...
})
// β†’ opgeslagen in IndexedDB, overleeft refresh en offline

Transaction: wanneer we de dagcache vervangen, gebruiken we een transaction. Dat garandeert dat Γ³f alles lukt Γ³f niets verandert β€” nooit halfweg.

Nieuw lib/sync.ts β€” Dagstart synchronisatie

Haalt elke ochtend max 10 werkbonnen op (6 planned + 4 open pool) en slaat ze offline op. Vraagt ook rijtijden op voor de geplande stops. Als de sync mislukt door geen internet β€” geen probleem, gisteren's cache blijft bruikbaar.

πŸ’‘ Hoe werkt de sync flow?
lib/sync.ts β€” flow
// 1. Controleer of sync nodig is (slechts 1x per dag)
const nodig = await shouldSync(technicianId)
if (!nodig) return  // cache is nog geldig

// 2. Haal data op van de server
const res = await fetch(`/api/sync/today?technicianId=...`)
const { planned, open } = await res.json()

// 3. Beperk tot max 6 planned + 4 open
const beperkt = [...planned.slice(0, 6), ...open.slice(0, 4)]

// 4. Sla op in IndexedDB (vervangt vorige dag)
await cacheInterventions(beperkt)

// 5. Haal rijtijden op (ORS matrix call)
const route = await fetchDailyRoute(planned)

// 6. Klaar β€” app werkt nu volledig offline

Pending writes: als je offline een status wijzigt, gaat die actie in de pendingWrites store. Zodra je terug online bent roept syncPendingWrites() ze allemaal op de server β€” in volgorde.

Nieuw app/api/route/ β€” ORS routing endpoints

Twee Next.js API routes: /api/route voor een enkele hop, /api/route/daily voor de volledige dagroute. De ORS API key zit server-side β€” nooit zichtbaar in de browser. Werkt ook zonder key (geeft mock-data terug in development).

πŸ’‘ Waarom een backend endpoint?

Je kan ORS niet rechtstreeks vanuit de browser aanroepen met je API key β€” dan is de key zichtbaar voor iedereen. De Next.js route handler draait op de server, leest de key uit process.env.ORS_API_KEY (een geheime omgevingsvariabele) en stuurt de route terug naar de browser.

app/api/route/route.ts β€” kern
// Server-side: key is veilig
const routingService = new OrsRoutingService(
  process.env.ORS_API_KEY ?? ''  // uit .env, nooit in de code
)

export async function POST(req: NextRequest) {
  const { from, to } = await req.json()
  const result = await routingService.getETA(from, to)
  return NextResponse.json(result)
  // β†’ { distanceKm: 12.4, travelMinutes: 22, provider: 'ors' }
}
types/planning.ts lib/routing/IRoutingService.ts lib/routing/OrsRoutingService.ts lib/idb.ts lib/sync.ts app/api/route/route.ts app/api/route/daily/route.ts
v1.3 8 april 2026 Planning logica + routing service in plan & cursus
Nieuw Planningssysteem β€” planned/open split

De Service App krijgt 10 gecachte werkbonnen per dag: max 6 geplande items (dispatcher-assigned met deadline) en max 4 open pool items (technieker kiest zelf). Technieker kan een gepland item verwijderen met een reden. Drag & drop om volgorde aan te passen. Optionele collega-view.

Nieuw Routing service abstractie β€” ORS fase 1

Provider-agnostisch routingService.getETA(from, to). Fase 1: OpenRouteService (gratis, account.heigit.org). Fase 2: TomTom swap met traffic-aware ETA β€” enkel server.ts wijzigt. UI toont disclaimer "zonder file-rekening" op basis van provider veld in response.

Nieuw Core API Cursus β€” Les 8: Routing service

Nieuwe les in de cursus op /coreapi: IRoutingService interface, ORS implementatie, dependency injection, beide endpoints, en UI disclaimer logica.

Nieuw MD bestanden β€” spec & code documentatie

service-app-planning.md en routing-service.md aangemaakt β€” volledige TypeScript code en uitleg voor toekomstige sessies.

v1.2 8 april 2026 Core API cursus (8 lessen)
Nieuw /coreapi β€” Stap-voor-stap cursus

Aparte pagina op /coreapi met 8 lessen: Project setup β†’ Fastify β†’ Docker + PostgreSQL β†’ Drizzle schema β†’ Keycloak JWT β†’ Endpoints β†’ NAV sync β†’ Routing service. Sidebar navigatie, highlight.js syntax highlighting, callout boxes, progress bar.

Verbeterd /coreapi β€” Mobile-friendly

Vaste top bar op mobiel met huidige les-titel en hamburger menu. Code blocks scrollen horizontaal. Kleinere typografie op kleine schermen. Prev/next navigatie stapelt verticaal.

v1.1 8 april 2026 Mobile-friendly plan website
Nieuw Full / Compact view toggle

Pill-knop in de sticky nav: πŸ–₯ Full (brede layout, Gantt chart) en πŸ“± Compact (mobiele layout, fase-progress bars, gestapelde kolommen). Auto-detecteert telefoon bij eerste bezoek. Keuze opgeslagen in localStorage.

Verbeterd Architectuurdiagram β€” compact versie

In compact mode: gestapelde versie van het architectuurdiagram i.p.v. het brede 5-koloms grid.

Verbeterd Gantt β†’ Fase progress bars

De 40-koloms Gantt chart is onleesbaar op mobiel. In compact mode vervangen door 4 gekleurde progress bars per fase met week-indicaties.

v1.0 6–7 april 2026 Initieel masterplan
Nieuw Plan website β€” volledig masterplan

Gebaseerd op Gemini brainstorm sessie, uitgewerkt met Claude + OMC. 40 weken (1 dag/week), 4 fases: Foundation β†’ NAV Bridge β†’ Admin Portal β†’ App Modularisatie. Gantt chart, architectuurdiagram, tech stack, risico register, analyse sectie.

Nieuw Docker + Traefik deployment

nginx:alpine container geserveerd via Traefik op plan.bossuyt.fixassistant.com. Directory volume mount zodat bewerkingen direct zichtbaar zijn zonder container restart.

Nieuw PWA offline-first strategie

Service App strategie: 10 werkbonnen cachen bij dagstart (later verhoogd van 5), klant/toesteldata ad-hoc + gecached, wagenstock (~1000 lijnen) enkel bij verbinding, Service Worker als offline fallback.