Update
This commit is contained in:
+48
-14
@@ -45,27 +45,37 @@ Any valid GeoJSON geometry object. V1 primarily expects `Polygon` and `MultiPoly
|
||||
}
|
||||
```
|
||||
|
||||
## Operator authentication
|
||||
## Operator authentication and guest demo
|
||||
|
||||
Authentication is an optional single-operator access gate, not multi-user
|
||||
account management. When `GEOINTEL_AUTH_ENABLED=true`, every `/api/v1/*`
|
||||
request except the three authentication endpoints below requires a valid
|
||||
signed `geointel_session` cookie. Missing, expired or modified sessions return
|
||||
HTTP 401 with `AUTHENTICATION_REQUIRED`. Direct loopback calls to the backend
|
||||
without proxy headers remain available to trusted in-container operator tools;
|
||||
the backend is bound to loopback in the all-in-one runtime.
|
||||
Authentication remains an optional single-operator access gate, not multi-user
|
||||
account management or tenant isolation. When `GEOINTEL_AUTH_ENABLED=true`,
|
||||
every `/api/v1/*` request except the four authentication endpoints below
|
||||
requires a valid signed `geointel_session` cookie. Missing, expired or modified
|
||||
sessions return HTTP 401 with `AUTHENTICATION_REQUIRED`. Direct loopback calls
|
||||
to the backend without proxy headers remain available to trusted in-container
|
||||
operator tools; the backend is bound to loopback in the all-in-one runtime.
|
||||
|
||||
The runtime stores only a PBKDF2-SHA256 password hash and an independent
|
||||
session-signing secret. The browser receives an HttpOnly, SameSite=Strict,
|
||||
time-limited cookie. Five failed attempts for one client/username combination
|
||||
within five minutes temporarily return HTTP 429 `LOGIN_RATE_LIMITED`.
|
||||
The runtime stores only a PBKDF2-SHA256 operator password hash and an
|
||||
independent session-signing secret. The browser receives an HttpOnly,
|
||||
SameSite=Strict, time-limited cookie. Five failed operator-login attempts for
|
||||
one client/username combination within five minutes temporarily return HTTP
|
||||
429 `LOGIN_RATE_LIMITED`.
|
||||
|
||||
Optional guest access is a configuration-gated demonstration mode. It creates
|
||||
a shorter signed session with role `guest`, scopes that session to the
|
||||
idempotently seeded demo project and blocks mutating operator routes. Project
|
||||
listing is filtered to the bound demo project. The frontend exposes only the
|
||||
map and the already calculated quality evidence. This is deliberately **not**
|
||||
a substitute for user accounts, authorization or tenant isolation; expose it
|
||||
only on a dedicated demo installation without private or operational data.
|
||||
|
||||
### GET `/api/v1/auth/session`
|
||||
|
||||
Public session probe used by the frontend before it mounts the workbench.
|
||||
When authentication is disabled, `authenticated` is true and
|
||||
`authentication_required` is false so local development retains its existing
|
||||
direct workflow.
|
||||
direct workflow. `guest_access_enabled` tells the landing page whether it may
|
||||
show the guest action.
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -73,11 +83,18 @@ direct workflow.
|
||||
"authentication_required": true,
|
||||
"authenticated": false,
|
||||
"username": null,
|
||||
"expires_at": null
|
||||
"expires_at": null,
|
||||
"role": null,
|
||||
"guest_access_enabled": true,
|
||||
"guest_project_id": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Authenticated operator sessions return `role: "operator"`. Guest sessions
|
||||
return `role: "guest"` and the UUID of their bound demo project in
|
||||
`guest_project_id`.
|
||||
|
||||
### POST `/api/v1/auth/login`
|
||||
|
||||
```json
|
||||
@@ -91,6 +108,23 @@ Successful login sets the session cookie and returns the authenticated session
|
||||
shape. Invalid credentials return HTTP 401 `INVALID_CREDENTIALS`; username
|
||||
existence is not disclosed.
|
||||
|
||||
### POST `/api/v1/auth/guest`
|
||||
|
||||
No request body is required. The endpoint is available only when both
|
||||
`GEOINTEL_AUTH_ENABLED=true` and `GEOINTEL_GUEST_ACCESS_ENABLED=true`. It
|
||||
idempotently prepares the canonical demo workflow, creates a short-lived guest
|
||||
session bound to that project and returns the normal session shape.
|
||||
|
||||
Disabled guest access returns HTTP 403 `GUEST_ACCESS_DISABLED`. A guest request
|
||||
for a different project returns HTTP 403 `GUEST_PROJECT_SCOPE_REQUIRED`; a
|
||||
blocked mutation returns HTTP 403 `GUEST_READ_ONLY`. Unscoped read routes that
|
||||
are not needed by the demo return HTTP 403 `GUEST_ROUTE_NOT_AVAILABLE`.
|
||||
Guest reads are limited to the filtered project list, provider metadata and the
|
||||
bound project tree. A small, explicit set of `POST` selection/read-analysis
|
||||
routes remains available because those routes query persisted evidence without
|
||||
exposing operator administration. Coverage resolution additionally verifies
|
||||
the `project_id` in the request body against the guest-session scope.
|
||||
|
||||
### POST `/api/v1/auth/logout`
|
||||
|
||||
Clears the browser cookie and returns an unauthenticated session. Logout is
|
||||
|
||||
@@ -1,3 +1,34 @@
|
||||
## 2026-07-27 - Guest demo and product professionalization
|
||||
|
||||
- Audited the access experience, workbench information density, responsive
|
||||
layout and accumulated frontend styling; recorded findings in
|
||||
`docs/PROJECT_PROFESSIONALIZATION_AUDIT_2026-07-27.md`.
|
||||
- Added configuration-gated guest access with a short signed session, explicit
|
||||
guest role, demo-project scope, filtered project listing and backend-enforced
|
||||
read-only/cross-project restrictions.
|
||||
- Rebuilt the landing and login hierarchy, added **Als gast verkennen**, mapped
|
||||
authentication failures to user-facing Dutch messages and improved mobile
|
||||
navigation and accessibility states.
|
||||
- Reduced the guest workbench to map exploration and existing quality evidence,
|
||||
added persistent demo context and removed operator-only controls from the
|
||||
guest surface.
|
||||
- Added targeted final layout overrides instead of destructively rewriting the
|
||||
four historical workbench stylesheets without a complete visual-regression
|
||||
baseline.
|
||||
- Added Compose, Unraid, DockerMan and runtime validation settings for guest
|
||||
enablement. A later packaging follow-up changed the default to enabled whenever
|
||||
operator authentication is active; installations can still opt out explicitly.
|
||||
- Validation: 6/6 targeted backend auth/guest tests and 2/2 direct frontend
|
||||
interaction smokes passed; Python compile, complete frontend TypeScript
|
||||
typecheck, CSS parsing, Compose YAML, Unraid XML, DockerMan shell syntax and
|
||||
scoped diff-whitespace checks passed.
|
||||
- Environment boundary: the supplied frontend dependency tree contains only
|
||||
Windows-native Rollup/esbuild packages. Vitest and Vite therefore could not
|
||||
start in this Linux review container, and the available package proxy returned
|
||||
503 responses/time-outs while fetching Linux replacements. Re-run unit tests
|
||||
and the production bundle after a clean `npm ci` in the normal Windows or
|
||||
Linux CI/Docker environment.
|
||||
|
||||
## 2026-07-26 - Complete Belgium PyTorch training roadmap
|
||||
|
||||
- Added `docs/PYTORCH_TRAINING_ROADMAP_BELGIUM.md` as the executable programme board.
|
||||
|
||||
@@ -7,9 +7,11 @@ CRITICAL or HIGH release defect. Coverage and capability responses remain the
|
||||
runtime source of truth.
|
||||
|
||||
- The access gate intentionally supports one environment-configured operator
|
||||
account. There is no registration, password-recovery email, role model,
|
||||
organisation management or multi-user database. Password rotation is an
|
||||
operator configuration action followed by a runtime restart.
|
||||
account. There is no registration, password-recovery email, organisation
|
||||
management or multi-user database. Optional guest access is a short-lived,
|
||||
read-only, demo-project-scoped role; it is not tenant isolation and must be
|
||||
used only on a dedicated demo instance without private data. Operator
|
||||
password rotation remains a configuration action followed by a restart.
|
||||
|
||||
## Source coverage
|
||||
|
||||
@@ -72,8 +74,8 @@ runtime source of truth.
|
||||
- Long AI/GIS work still uses the existing synchronous job abstraction rather
|
||||
than a distributed durable queue. Interrupted synchronous work is marked
|
||||
failed on restart and must be retried explicitly.
|
||||
- GeoIntel RC is a controlled single-operator deployment. Authentication,
|
||||
multi-user authorization and tenant isolation are outside the frozen RC
|
||||
scope.
|
||||
- GeoIntel remains a controlled single-operator product. The optional guest
|
||||
demo adds bounded presentation access only; multi-user authorization and
|
||||
tenant isolation remain outside the product scope.
|
||||
- Cleanup remains manual, dry-run-first and confirmation-gated. No automatic
|
||||
retention schedule is installed.
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
# GeoIntel professionaliseringsaudit — 27 juli 2026
|
||||
|
||||
## Managementsamenvatting
|
||||
|
||||
GeoIntel is inhoudelijk veel sterker dan de eerste visuele indruk deed
|
||||
vermoeden. De repository bevat een volwassen, documentatiegestuurde
|
||||
GIS-architectuur, expliciete bron- en provenancecontracten, uitgebreide
|
||||
kwaliteitscontrole en een product dat bewust geen resultaten fabriceert wanneer
|
||||
brondata of modellen ontbreken. De grootste productrisico's zaten niet in de
|
||||
GIS-kern, maar in de toegangservaring, de presentatie van de functiedichtheid
|
||||
en de gegroeide frontend-stijllagen.
|
||||
|
||||
Deze pass professionaliseert de eerste gebruikerservaring en voegt een veilige
|
||||
gastdemonstratie toe. Een bezoeker kan nu rechtstreeks vanaf de landingspagina
|
||||
een tijdelijke demowerkruimte openen. Die sessie is server-side aan één
|
||||
voorbeeldproject gebonden, heeft een kortere levensduur en kan geen
|
||||
operatorwijzigingen uitvoeren. De interface toont in gastmodus alleen de kaart
|
||||
en bestaand kwaliteitsbewijs.
|
||||
|
||||
## Wat al sterk was
|
||||
|
||||
- **Inhoudelijke geloofwaardigheid.** Officiële bronnen, meeteenheden, CRS,
|
||||
dekking, beperkingen en provenance worden als productgegevens behandeld en
|
||||
niet als decoratieve metadata.
|
||||
- **Fail-closed gedrag.** Niet-geconfigureerde bronnen en modellen worden niet
|
||||
stilzwijgend vervangen door fixtures of gesimuleerd succes.
|
||||
- **Map-first productmodel.** Project, gebied, dataset, analyse en QA delen een
|
||||
ruimtelijke context, wat veel sterker is dan een verzameling losse dashboards.
|
||||
- **Operationele discipline.** De repository bevat releasegates, Unraid-assets,
|
||||
migraties, herstelpaden, tests en expliciete scope-/beperkingsdocumentatie.
|
||||
- **Bestaande demofundering.** Het idempotente demoworkflowcontract maakte een
|
||||
gecontroleerde gastbeleving mogelijk zonder een tweede fictieve applicatie te
|
||||
bouwen.
|
||||
|
||||
## Belangrijkste bevindingen
|
||||
|
||||
### P0 — Er ontbrak een toegankelijke productdemo
|
||||
|
||||
De oorspronkelijke ingang bood alleen een operatorlogin. Voor een recruiter,
|
||||
stakeholder of eerste beoordelaar was daardoor niet zichtbaar wat het platform
|
||||
kan zonder vooraf accounts of wachtwoorden uit te wisselen. Een onbegrensde
|
||||
“login zonder wachtwoord” zou echter toegang tot operationele functies hebben
|
||||
gegeven.
|
||||
|
||||
**Oplossing:** een config-gated `POST /api/v1/auth/guest`, een gesigneerde
|
||||
gastrol met projectscope, server-side mutatieblokkering en een expliciete knop
|
||||
**Als gast verkennen**. De demo wordt bij openen idempotent voorbereid.
|
||||
|
||||
### P1 — De landingspagina communiceerde de productwaarde onvoldoende snel
|
||||
|
||||
De informatie was aanwezig, maar de primaire actie, productbelofte,
|
||||
betrouwbaarheidssignalen en demonstratiemogelijkheid concurreerden visueel met
|
||||
elkaar. Op kleinere schermen voelde de ingang langer en minder doelgericht.
|
||||
|
||||
**Oplossing:** nieuwe hero- en loginhiërarchie, heldere keuze tussen operator en
|
||||
gast, compactere capability-sectie, concreter vierstappenproces, betere mobiele
|
||||
navigatie en begrijpelijke foutmeldingen in plaats van ruwe servicefouten.
|
||||
|
||||
### P1 — De workbench was voor een gast te breed en te technisch
|
||||
|
||||
De volledige operatornavigatie bevat projectbeheer, imports, AI-taken, exports
|
||||
en geavanceerde analyses. Dat is gepast voor een beheerder, maar werkt tegen een
|
||||
snelle demonstratie.
|
||||
|
||||
**Oplossing:** de gastrol ziet alleen **Kaart** en **Kwaliteit**, krijgt een
|
||||
blijvende alleen-lezen contextbanner en ziet geen creatie-, import-, export-,
|
||||
AI- of beheeracties. De backend blijft de autoritatieve grens.
|
||||
|
||||
### P1 — De visuele laag is historisch gegroeid
|
||||
|
||||
Vier opeenvolgende workbench-stijlbestanden bevatten samen 13.818 regels CSS:
|
||||
`app.css`, `premium.css`, `atlas-workbench.css` en `atlas-premium-v2.css`. Over
|
||||
de volledige actieve stijllaag zijn tientallen mediaqueries aanwezig. Dat
|
||||
verhoogt de kans op cascadeconflicten, onverwachte responsive afwijkingen en
|
||||
onnodig moeilijke toekomstige aanpassingen.
|
||||
|
||||
**Oplossing in deze pass:** een kleine, als laatste geladen
|
||||
`professionalization.css` met gerichte correcties voor navigatierail, contextbalk,
|
||||
werkruimtehoogte, gaststatus, truncation en responsive gedrag. De historische
|
||||
lagen zijn bewust niet massaal herschreven zonder volledige visuele
|
||||
regressiebaseline.
|
||||
|
||||
**Aanbevolen vervolgstap:** component voor component consolideren naar tokens,
|
||||
layout primitives en één stylesheet per functioneel domein, telkens beschermd
|
||||
door desktop-, ultrawide- en mobiele screenshots.
|
||||
|
||||
### P2 — Twee frontendcomponenten dragen te veel verantwoordelijkheid
|
||||
|
||||
`App.tsx` telt circa 1.400 regels en `MapWorkspace.tsx` circa 3.900 regels. Dat
|
||||
is nog werkbaar, maar maakt layout-, permissie- en interactiewijzigingen
|
||||
risicovoller dan nodig.
|
||||
|
||||
**Aanbevolen vervolgstap:** splits shell/navigatie, workspace-routing,
|
||||
gastsessiecontext, kaartselectie, bronresolutie en analysepresentatie in
|
||||
afzonderlijke domeincomponenten en hooks. Doe dit pas na de huidige
|
||||
regressietests, zodat gedrag niet tegelijk met structuur wordt gewijzigd.
|
||||
|
||||
### P2 — Gastmodus is geen tenantisolatie
|
||||
|
||||
De sessie is cryptografisch gesigneerd, kort geldig, projectgebonden en
|
||||
alleen-lezen. Toch blijft GeoIntel architecturaal een single-operatorproduct. De
|
||||
gastrol is bedoeld voor een aparte demo-installatie, niet om operationele en
|
||||
publieke gebruikers veilig in dezelfde datastore te mengen.
|
||||
|
||||
## Geleverde wijzigingen
|
||||
|
||||
| Domein | Professionalisering |
|
||||
|---|---|
|
||||
| Toegang | Nieuwe gastactie, wachtwoordzichtbaarheid, heldere operator/gastkeuze en bruikbare foutmeldingen |
|
||||
| Sessies | Versie 2-sessietoken met expliciete `operator`/`guest`-rol, TTL en optionele projectscope |
|
||||
| Backendgrens | Positieve read-allowlist, gastprojectfilter, cross-projectblokkering en mutatieblokkering met stabiele foutcodes |
|
||||
| Demo | Canonieke demoworkflow wordt idempotent voorbereid bij gastlogin |
|
||||
| Workbench | Gereduceerde gastnavigatie, alleen-lezen statusbanner en verborgen beheerfuncties |
|
||||
| Kaart | Alleen-lezen variant zonder on-demand acquisitie of geavanceerde operatorcontrole |
|
||||
| Layout | Rustigere desktop-shell, betere truncation, responsieve gaststatus en reduced-motion ondersteuning |
|
||||
| Deployment | Gastvariabelen in Compose, Unraid-env, DockerMan-template en runtimevalidatie |
|
||||
| Documentatie | API-contract, README, Unraid-instructies, beperkingen, TODO en uitvoeringslog bijgewerkt |
|
||||
|
||||
## Configuratie
|
||||
|
||||
Gasttoegang staat standaard ingeschakeld zodra de operator-login actief is.
|
||||
Voor een afzonderlijke demo-installatie:
|
||||
|
||||
```env
|
||||
GEOINTEL_AUTH_ENABLED=true
|
||||
GEOINTEL_AUTH_USERNAME=operator
|
||||
GEOINTEL_AUTH_PASSWORD_HASH=pbkdf2_sha256$...
|
||||
GEOINTEL_AUTH_SESSION_SECRET=<minstens-32-willekeurige-tekens>
|
||||
GEOINTEL_GUEST_ACCESS_ENABLED=true
|
||||
GEOINTEL_GUEST_DISPLAY_NAME=Gast
|
||||
GEOINTEL_GUEST_SESSION_TTL_SECONDS=7200
|
||||
```
|
||||
|
||||
Zet `GEOINTEL_GUEST_ACCESS_ENABLED=false` om gasttoegang expliciet uit te schakelen.
|
||||
Gebruik een afzonderlijke container, database en storage-root wanneer de demo
|
||||
van buiten het vertrouwde LAN bereikbaar wordt. Plaats geen private, klant- of
|
||||
operationele datasets in die omgeving.
|
||||
|
||||
## Validatie
|
||||
|
||||
De volgende controles zijn op 27 juli 2026 uitgevoerd:
|
||||
|
||||
| Controle | Resultaat |
|
||||
|---|---|
|
||||
| Gerichte backend auth-/gastbeveiligingstests | **Geslaagd — 6/6** |
|
||||
| Python compile van `backend/app` en de nieuwe authtests | **Geslaagd** |
|
||||
| Volledige frontend TypeScript-typecheck | **Geslaagd** |
|
||||
| Gerichte frontend-interactiesmokes: gast/operator-login en beperkte bootstrap | **Geslaagd — 2/2** |
|
||||
| CSS-syntax van de vernieuwde landing en professionaliseringslaag | **Geslaagd** |
|
||||
| Compose YAML, Unraid XML en DockerMan-shellsyntax | **Geslaagd** |
|
||||
| Whitespacecontrole op alle in deze pass gewijzigde bestanden | **Geslaagd** |
|
||||
|
||||
De gerichte backendtests draaiden met SQLite en een tijdelijke minimale
|
||||
`geoalchemy2`-importstub buiten de repository, omdat de reviewcontainer de
|
||||
PostGIS-runtimepackages niet bevatte. Daarmee zijn tokenvalidatie, cookies,
|
||||
login/logout, gastscope, cross-projectblokkering en route-/mutatieblokkering
|
||||
wel rechtstreeks getest; het is geen vervanging voor de bestaande volledige
|
||||
PostgreSQL/PostGIS-integratiegate.
|
||||
|
||||
De nieuwe logincomponent en de beperkte workbench-bootstrap zijn aanvullend
|
||||
rechtstreeks in JSDOM uitgevoerd via een tijdelijke TypeScript-loader buiten de
|
||||
repository. Daarmee zijn de zichtbaarheid van gastacties, de `POST` naar de
|
||||
gastendpoint, de operatorlogin en het uitschakelen van operator-only
|
||||
bootstrapcalls interactief gecontroleerd.
|
||||
|
||||
De aangeleverde `node_modules` bevat alleen Windows-native Rollup- en
|
||||
esbuildpakketten. Daardoor konden de normale Vitest-runner en de
|
||||
Vite-productiebundel in deze Linux-reviewcontainer niet starten. Een schone
|
||||
dependency-installatie was niet mogelijk doordat de beschikbare packageproxy
|
||||
tijdens de controle 503-responses en time-outs gaf. De TypeScript-compiler voltooide wel zonder fouten. De
|
||||
frontend-unit- en productiebuildgates moeten daarom na `npm ci` op Windows of
|
||||
in de normale Linux CI-/Dockeromgeving nogmaals worden uitgevoerd.
|
||||
|
||||
## Aanbevolen roadmap
|
||||
|
||||
1. Leg visuele regressiesnapshots vast voor login, kaart, kwaliteit en alle
|
||||
primaire workspaces op mobiel, desktop en ultrawide.
|
||||
2. Consolideer de vier historische workbench-CSS-lagen incrementeel; verwijder
|
||||
pas selectors nadat screenshots en interactietests gelijkwaardig zijn.
|
||||
3. Splits `App.tsx` en `MapWorkspace.tsx` langs domeingrenzen, zonder API- of
|
||||
analysegedrag te wijzigen.
|
||||
4. Voeg een expliciete demo-reset/refreshstrategie en misbruiktelemetrie toe
|
||||
wanneer de demo publiek wordt blootgesteld.
|
||||
5. Bouw alleen bij echte multi-userbehoefte een afzonderlijk identiteits-,
|
||||
autorisatie- en tenantmodel; breid gastmodus daar niet ad hoc voor uit.
|
||||
@@ -13,6 +13,21 @@ Uitvoeringsbord: `docs/PYTORCH_TRAINING_ROADMAP_BELGIUM.md`.
|
||||
|
||||
## Actieve post-RC datadekkingsfase
|
||||
|
||||
Professionaliseringspass (2026-07-27):
|
||||
|
||||
- [x] Voeg een expliciete gastknop toe aan de toegangspoort en open daarmee
|
||||
een korte, projectgebonden, alleen-lezen demowerkruimte.
|
||||
- [x] Beperk de gastinterface tot kaartverkenning en bestaand kwaliteitsbewijs;
|
||||
blokkeer operatoracties en toegang tot andere projecten ook server-side.
|
||||
- [x] Herwerk de landingspagina, aanmeldhiërarchie, mobiele navigatie en
|
||||
workbenchcontext tot één rustigere en professionelere productervaring.
|
||||
- [ ] Consolideer na visuele regressiesnapshots de vier historische
|
||||
workbench-stijllagen (`app`, `premium`, `atlas-workbench`,
|
||||
`atlas-premium-v2`) tot een kleiner gelaagd stijlsysteem.
|
||||
- [ ] Ontwerp alleen bij een toekomstige publieke multi-projectinstallatie een
|
||||
volwaardig account-, autorisatie- en tenantisolatiemodel; gastmodus is daar
|
||||
uitdrukkelijk geen vervanging voor.
|
||||
|
||||
- [x] Voeg een interactieve, data-gedreven projectatlas toe aan de statuswerkruimte met toegankelijke navigatie, echte readiness-toestanden en reduced-motion ondersteuning.
|
||||
- [x] Geef alle primaire werkruimtes een eigen geanimeerde signaalillustratie, verbeter lege toestanden en verwijder de dubbele kaartfoutmelding bij sessieverval.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user