From 36d6a9282574621ed5fc0c6ad842c0070854cf64 Mon Sep 17 00:00:00 2001 From: Codex Date: Tue, 14 Jul 2026 21:48:51 +0200 Subject: [PATCH] fix: polish live regional workbench labels --- CHANGELOG.md | 1 + ...t_sprint155_detection_operator_profiles.py | 6 ++-- .../test_sprint193_end_user_workbench.py | 17 +++++++++- docs/CODEX_EXECUTION_LOG.md | 5 +++ .../components/detection/detectionProfiles.ts | 18 +++++----- frontend/src/components/project/AreaPanel.tsx | 12 ++++++- .../src/components/project/ProjectPanel.tsx | 34 ++++++++++++++----- .../quality/QualityResultsPanel.tsx | 11 ++++-- frontend/src/lib/datasetDisplay.ts | 2 +- 9 files changed, 80 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3beb007..043c91b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - Replaced technical dataset names with theme/source labels and moved benchmark projects, raw source metadata, provider internals, QA evidence and model diagnostics behind advanced disclosures. - Defaulted Detection Lab to the configured local YOLO asset, active local model profile and measured operating threshold; model quality remains explicitly review-required rather than presented as production-perfect. - Simplified Quality, Downloads, Status and Beheer around end-user tasks without changing API contracts, migrations, persistence or inference behavior. +- Followed the live browser audit by moving the legacy Mol-only workspace under advanced management, adding friendly regional-boundary dataset names, translating the active model profiles and replacing the empty `waiting` quality status with end-user language. ## Sprint 192 Regional map state correctness (2026-07-14) diff --git a/backend/tests/test_sprint155_detection_operator_profiles.py b/backend/tests/test_sprint155_detection_operator_profiles.py index 3fb36988..467c0538 100644 --- a/backend/tests/test_sprint155_detection_operator_profiles.py +++ b/backend/tests/test_sprint155_detection_operator_profiles.py @@ -23,9 +23,9 @@ def test_detection_operator_profiles_define_explicit_yolo_candidates_and_promote assert "f1: 0.5824578631584316" in source assert "f1: 0.5432865390636915" in source assert "maxBackgroundDetections: 0" in source - assert "pure-empty gate passed" in source - assert "1,571 fewer false negatives" in source - assert "higher false-positive review load" in source + assert "lege-achtergrondtest is geslaagd" in source + assert "1.571 minder gemiste gebouwen" in source + assert "onterecht gevonden objecten" in source def test_detection_lab_surfaces_profiles_as_deliberate_operator_actions() -> None: diff --git a/backend/tests/test_sprint193_end_user_workbench.py b/backend/tests/test_sprint193_end_user_workbench.py index ad2f4855..3d111dd1 100644 --- a/backend/tests/test_sprint193_end_user_workbench.py +++ b/backend/tests/test_sprint193_end_user_workbench.py @@ -34,12 +34,17 @@ def test_technical_projects_and_metadata_are_progressively_disclosed() -> None: projects = read("frontend/src/components/project/ProjectPanel.tsx") areas = read("frontend/src/components/project/AreaPanel.tsx") datasets = read("frontend/src/components/datasets/DatasetPanel.tsx") + dataset_names = read("frontend/src/lib/datasetDisplay.ts") assert "TECHNICAL_PROJECT_PATTERN" in projects - assert "technische test- en benchmarkruns" in projects + assert "project.name === LEGACY_MOL_PROJECT_NAME" in projects + assert "alternatieve en technische werkruimtes" in projects + assert "Kempen · volledige regionale werkruimte" in projects assert "area-catalog-disclosure" in areas assert "dataset-technical-details" in datasets assert "getDatasetDisplayName" in datasets + assert "dataset.source_metadata?.layer_type" in dataset_names + assert "regional_boundary: 'Grens vervoerregio Kempen'" in dataset_names def test_configured_yolo_and_active_asset_are_selected_without_hiding_limitations() -> None: @@ -53,3 +58,13 @@ def test_configured_yolo_and_active_asset_are_selected_without_hiding_limitation assert 'aria-label="Status gebouwdetectie"' in lab assert "resultaten blijven controleplichtig" in lab assert "Modelkalibratie voor beheerders" in lab + + +def test_visible_ai_and_quality_labels_are_end_user_facing() -> None: + profiles = read("frontend/src/components/detection/detectionProfiles.ts") + quality = read("frontend/src/components/quality/QualityResultsPanel.tsx") + + assert "Aanbevolen controleprofiel kleine gebouwen" in profiles + assert "Controleer wel extra op onterecht gevonden objecten" in profiles + assert "qualityStatusLabel" in quality + assert "nog niet uitgevoerd" in quality diff --git a/docs/CODEX_EXECUTION_LOG.md b/docs/CODEX_EXECUTION_LOG.md index 453b2642..442bacf4 100644 --- a/docs/CODEX_EXECUTION_LOG.md +++ b/docs/CODEX_EXECUTION_LOG.md @@ -18,6 +18,11 @@ Tested before deployment: - The false-positive review validator returned the expected `review_required` gate with all 48 selected decisions still `unreviewed`; no unreviewed QA mismatch was promoted into training data. - Local Docker validation was unavailable because the Windows workstation has no Docker CLI; live container/PostGIS validation remains part of the Tower deployment pass. +Live browser follow-up: +- Tower rebuilt the AI-enabled all-in-one image successfully; container health, PostGIS 3.6, required schema objects, Alembic head `202607140001`, frontend, API proxy and icon checks passed. +- The map opened directly on the complete regional workspace with 29 work Areas, no region selector, the full region selected and 466,078 buildings, 88,332 water objects, 84,504 roads and 415,288 parcels available. +- The browser audit found four remaining presentation leaks: the legacy Mol-only project was still prominent, boundary datasets showed filenames, profile names were English and an empty quality status said `waiting`. These were corrected and protected by the now `561`-test suite. + Next: - Extend official population and modern land-use time series from Mol to all 28 municipalities, then expose a guided raster-import and configured-detection run over a drawn map selection. diff --git a/frontend/src/components/detection/detectionProfiles.ts b/frontend/src/components/detection/detectionProfiles.ts index 5e77725b..210fd3a6 100644 --- a/frontend/src/components/detection/detectionProfiles.ts +++ b/frontend/src/components/detection/detectionProfiles.ts @@ -17,7 +17,7 @@ export interface DetectionOperatorProfile { export const DETECTION_OPERATOR_PROFILES: DetectionOperatorProfile[] = [ { id: 'small-building-balanced-review', - displayName: 'Recommended small-building review', + displayName: 'Aanbevolen controleprofiel kleine gebouwen', modelAssetId: 'geointel-building-yolov8s-smallbld-minpx3-img640-ft30-pt', confidenceThreshold: 0.15, defaultApproved: true, @@ -28,13 +28,13 @@ export const DETECTION_OPERATOR_PROFILES: DetectionOperatorProfile[] = [ positiveSampleCount: 7, maxBackgroundDetections: 0, description: - 'Recommended recall-balanced profile for building review, with improved small-building coverage across seven Kempen AOIs.', + 'Aanbevolen profiel met een evenwicht tussen gevonden en gemiste kleine gebouwen, gemeten over zeven testgebieden in de Kempen.', limitationMessage: - 'The pure-empty gate passed and persisted QA found 1,571 fewer false negatives than the previous balanced profile; expect a higher false-positive review load.', + 'De lege-achtergrondtest is geslaagd en de kwaliteitsmeting vond 1.571 minder gemiste gebouwen dan het vorige profiel. Controleer wel extra op onterecht gevonden objecten.', }, { id: 'expanded-balanced-review', - displayName: 'Legacy expanded balanced review', + displayName: 'Voorgaand gebalanceerd controleprofiel', modelAssetId: 'geointel-building-yolov8s-aoi1024expandedminpx4vis035e50-pt', confidenceThreshold: 0.15, defaultApproved: true, @@ -44,13 +44,13 @@ export const DETECTION_OPERATOR_PROFILES: DetectionOperatorProfile[] = [ f1: 0.5432865390636915, positiveSampleCount: 7, maxBackgroundDetections: 0, - description: 'Legacy expanded-AOI profile for review sessions where precision matters more than the newest recall gain.', + description: 'Voorgaand profiel voor controles waarbij minder foutieve vondsten belangrijker zijn dan maximale dekking.', limitationMessage: - 'The pure-empty gate passed; this profile has fewer false positives but more persistent small-building misses than the recommended profile.', + 'De lege-achtergrondtest is geslaagd. Dit profiel vindt minder onterechte objecten, maar mist meer kleine gebouwen dan het aanbevolen profiel.', }, { id: 'conservative-review', - displayName: 'Promoted conservative review', + displayName: 'Conservatief controleprofiel', modelAssetId: 'geointel-building-yolov8s-aoi1024bg512r3e50-pt', confidenceThreshold: 0.35, defaultApproved: true, @@ -60,8 +60,8 @@ export const DETECTION_OPERATOR_PROFILES: DetectionOperatorProfile[] = [ f1: 0.32086574003576274, positiveSampleCount: 7, maxBackgroundDetections: 0, - description: 'Legacy high-precision profile for review sessions where fewer false positives matter more than recall.', + description: 'Profiel met hoge precisie voor controles waarbij zo weinig mogelijk foutieve vondsten zwaarder wegen dan volledige dekking.', limitationMessage: - 'Default-approved after the split-background pure-empty gate passed; sparse-context detections remain review-only evidence.', + 'Goedgekeurd na de lege-achtergrondtest. Resultaten in dun bebouwde context blijven altijd controlebewijs en geen automatische waarheid.', }, ] diff --git a/frontend/src/components/project/AreaPanel.tsx b/frontend/src/components/project/AreaPanel.tsx index b4c7c991..04aec770 100644 --- a/frontend/src/components/project/AreaPanel.tsx +++ b/frontend/src/components/project/AreaPanel.tsx @@ -1,6 +1,16 @@ import type { FormEvent } from 'react' import type { AreaRead, ProjectRead } from '../../types' +function projectDisplayName(project: ProjectRead | null): string { + if (project?.name === 'Kempen Regional Workbench') { + return 'Kempen · volledige regio' + } + if (project?.name === 'Mol Municipality Workbench') { + return 'Mol · lokale historische werkruimte' + } + return project?.name ?? 'Geen werkruimte actief' +} + interface AreaFormState { name: string geometry: string @@ -41,7 +51,7 @@ export function AreaPanel({ {areas.length} -

{selectedProject ? selectedProject.name : 'Geen werkruimte actief'}

+

{projectDisplayName(selectedProject)}

Getoond op de kaart diff --git a/frontend/src/components/project/ProjectPanel.tsx b/frontend/src/components/project/ProjectPanel.tsx index 3fa03abb..f4b8a53e 100644 --- a/frontend/src/components/project/ProjectPanel.tsx +++ b/frontend/src/components/project/ProjectPanel.tsx @@ -2,11 +2,27 @@ import type { FormEvent } from 'react' import type { ProjectCreate, ProjectRead } from '../../types' const TECHNICAL_PROJECT_PATTERN = /^(GeoIntel Detection Quality Matrix|GeoIntel hard-negative|GeoIntel training|Mol Building QA)/i +const REGIONAL_PROJECT_NAME = 'Kempen Regional Workbench' +const LEGACY_MOL_PROJECT_NAME = 'Mol Municipality Workbench' function isTechnicalProject(project: ProjectRead): boolean { return TECHNICAL_PROJECT_PATTERN.test(project.name) } +function isAdvancedProject(project: ProjectRead): boolean { + return isTechnicalProject(project) || project.name === LEGACY_MOL_PROJECT_NAME +} + +function projectDisplayName(project: ProjectRead): string { + if (project.name === REGIONAL_PROJECT_NAME) { + return 'Kempen · volledige regionale werkruimte' + } + if (project.name === LEGACY_MOL_PROJECT_NAME) { + return 'Mol · lokale historische werkruimte' + } + return project.name +} + interface ProjectPanelProps { projects: ProjectRead[] selectedProjectId: string | null @@ -33,9 +49,9 @@ export function ProjectPanel({ onLoadDemoWorkflow, }: ProjectPanelProps): JSX.Element { const selectedProject = projects.find((project) => project.id === selectedProjectId) - const regularProjects = projects.filter((project) => !isTechnicalProject(project)) - const technicalProjects = projects.filter(isTechnicalProject) - const visibleProjects = selectedProject && isTechnicalProject(selectedProject) + const regularProjects = projects.filter((project) => !isAdvancedProject(project)) + const advancedProjects = projects.filter(isAdvancedProject) + const visibleProjects = selectedProject && isAdvancedProject(selectedProject) ? [selectedProject, ...regularProjects] : regularProjects @@ -52,7 +68,7 @@ export function ProjectPanel({
Actieve werkruimte - {selectedProject?.name ?? 'Geen werkruimte actief'} + {selectedProject ? projectDisplayName(selectedProject) : 'Geen werkruimte actief'} {selectedProject?.region ?? 'De regionale werkruimte wordt automatisch gekozen.'}
@@ -68,7 +84,7 @@ export function ProjectPanel({ aria-pressed={project.id === selectedProjectId} data-testid={`project-select-${project.id}`} > - {project.name} + {projectDisplayName(project)} {project.region || 'Regio niet opgegeven'} @@ -118,11 +134,11 @@ export function ProjectPanel({ {demoWorkflowMessage ?

{demoWorkflowMessage}

: null}
- {technicalProjects.length > 0 ? ( + {advancedProjects.length > 0 ? (
- {technicalProjects.length} technische test- en benchmarkruns + {advancedProjects.length} alternatieve en technische werkruimtes