# Session Summary: Duimstok PWA MVP Build
**Date:** 2026-04-16
**Project:** ProRail Duimstok-inspecties Bovenbouw
**Repo:** https://git.en-masse.nl/randy/duimstok.prorail.nl.git
---
## Phase 1: Monolithic HTML Refactor
**Goal:** Split a single-file app (`duimstok-wissel-gw-sw.html`, 1566 lines) into a layered DDD structure.
**What was done:**
- Created `src/Domain/`, `src/Application/`, `src/Infrastructure/` layers
- Converted ES modules to classic IIFE scripts attaching to `window.App.*` namespace
- Embedded CSV seed data as a string constant in `seedOrders.js` (no `fetch()` needed)
- Removed all inline styles (`style=""`) and inline event handlers (`onclick`, `oninput`, etc.)
- Replaced inline styles with CSS classes (`.flex-spacer`, `.cap-arrow.lg`, `.section-sub.sm`, `.fotonummers-cell`)
- Wired all event listeners via `addEventListener` in `main.js` and service modules
**Result:** 30 files, ~2163 lines. Runs by double-clicking `public/index.html` -- no server needed.
**File structure:**
```
01_Applicatie/
├── public/
│ ├── index.html
│ ├── css/ base.css, overview.css, form.css, modals.css, responsive.css
│ └── js/ namespace.js, main.js
└── src/
├── Domain/ sectionMap.js, scoring.js, orderParser.js
├── Application/ state.js, persistence.js, screens.js, photoService.js,
│ inspectionForm.js, orderOverview.js, xmlImport.js, exportService.js
└── Infrastructure/ utils.js, geolocation.js, db.js, seedOrders.js, csvLoader.js
```
---
## Phase 2: PWA Research & Planning
**Prompt used:** "what are the next steps create a PWA version of this MVP, ideally with offline photo upload functionality which sync when back online. Whats the current supported state of PWA regarding these offline functionalities atm"
**Key findings:**
- Service Worker, Cache API, IndexedDB, Manifest, installability all work cross-browser (Chromium, Firefox, Safari/iOS 16.4+)
- Background Sync (`sync` event) only works on Chromium -- not Firefox, not Safari/iOS
- Periodic Background Sync: Chromium only (engagement-gated)
- Background Fetch: Chromium only
- Push notifications: universal for installed PWAs (iOS 16.4+)
- Persistent storage: universal, but Safari historically aggressive on eviction
**Key constraint:** iOS has no true background sync. Design around draining the queue when the user reopens the app and when the `online` event fires.
**6-step incremental plan identified:**
1. Installable shell (manifest + service worker cache)
2. Switch photo storage from data URLs to Blobs
3. Sync queue in IndexedDB
4. Trigger drain on every available signal (online event, app open, SW sync, manual button)
5. Persistent storage + install hint
6. Backend stub (Symfony controller for POST /api/inspections)
---
## Phase 3: PWA Scaffold Implementation
**Prompt used:** "Goal is still conversion later on to Symfony, but for now we do want the PWA functionality (add an additional installation and instruction screen for the PWA installation)"
**Constraint flagged:** PWA features require HTTPS or localhost -- they cannot work from `file://`.
**Resolution:** Dual-mode codebase:
- `file://` mode: app works exactly as before; PWA init gated by `location.protocol !== 'file:'` and quietly skipped
- `http://localhost` or deployed mode: service worker registers, app becomes installable, install screen shows platform-specific instructions
**Files created:**
- `public/manifest.webmanifest` -- app manifest with icons, standalone display, ProRail blue theme
- `public/sw.js` -- service worker with app shell precaching (cache-first for statics, network-first for API)
- `public/icons/icon.svg` -- SVG app icon (ProRail blue with white ruler lines)
- `public/css/install.css` -- styles for the install instruction screen
- `src/Application/pwa.js` -- service worker registration, `beforeinstallprompt` capture, standalone detection
- `src/Application/installScreen.js` -- platform-specific install instructions (Chrome/Edge, iOS Safari, Firefox, generic)
**HTML changes:**
- Added PWA meta tags (`theme-color`, `apple-mobile-web-app-capable`, manifest link, apple-touch-icon)
- Added "Installeren" button to overview toolbar
- Added `screen-install` section with back button and dynamic body
- Added `` for `install.css`
- Added `