diff --git a/CHANGELOG.md b/CHANGELOG.md index 93051b9b..994c3377 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -695,3 +695,11 @@ Added: - Added regression coverage for AppError, HTTPException and validation-error envelopes. - Added static frontend parser coverage so API client error parsing does not drift silently. - No migrations, product capabilities, live provider fetching or AI/model dependency changes were introduced. + +## Sprint 64 export/report handoff polish (2026-06-18) + +- Added a handoff readiness summary to the Export Center for selected dataset, detection run, segmentation run and latest artifact context. +- Grouped existing export actions into scan-friendly artifact cards for project report, metadata, vector GeoJSON, detection GeoJSON and segmentation GeoJSON. +- Added clearer export history provenance with formatted export-type badges, analysis-run ids and created timestamps when available. +- Added regression coverage for the Export Center handoff structure and responsive styling. +- No API contracts, migrations, product capabilities, live provider fetching or AI/model dependency changes were introduced. diff --git a/backend/tests/test_sprint64_export_handoff_polish.py b/backend/tests/test_sprint64_export_handoff_polish.py new file mode 100644 index 00000000..0cd1e25d --- /dev/null +++ b/backend/tests/test_sprint64_export_handoff_polish.py @@ -0,0 +1,33 @@ +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[2] + + +def test_export_center_surfaces_handoff_readiness_context() -> None: + export_center = (ROOT / "frontend" / "src" / "components" / "exports" / "ExportCenter.tsx").read_text( + encoding="utf-8" + ) + + assert 'className="handoff-summary-card"' in export_center + assert 'className="handoff-readiness-grid"' in export_center + assert 'className="handoff-action-grid"' in export_center + assert 'className="export-type-badge"' in export_center + assert "Latest handoff artifact" in export_center + assert "Project report" in export_center + assert "Detection run" in export_center + assert "Segmentation run" in export_center + assert "selectedDetectionRunId || 'none'" in export_center + assert "selectedSegmentationRunId || 'none'" in export_center + + +def test_export_handoff_polish_has_responsive_styles() -> None: + css = (ROOT / "frontend" / "src" / "styles" / "app.css").read_text(encoding="utf-8") + + assert ".handoff-summary-card" in css + assert ".handoff-readiness-grid" in css + assert ".handoff-action-grid" in css + assert ".export-type-badge" in css + assert ".handoff-action-card" in css + assert "grid-template-columns: repeat(4, minmax(0, 1fr));" in css + assert ".handoff-action-grid" in css and "@media (max-width: 980px)" in css diff --git a/docs/CODEX_EXECUTION_LOG.md b/docs/CODEX_EXECUTION_LOG.md index ef870748..a6541532 100644 --- a/docs/CODEX_EXECUTION_LOG.md +++ b/docs/CODEX_EXECUTION_LOG.md @@ -2460,3 +2460,30 @@ Limitations: Next recommended pass: - Continue with export/report handoff polish or add a live browser smoke that explicitly visits every workspace after deployment. + +## Sprint 64 Export/report handoff polish (2026-06-18) + +Changed: +- Added a handoff readiness card to the Export Center using existing project, selected dataset, selected detection run, selected segmentation run and latest export state. +- Reworked existing export actions into artifact cards for refresh, project report, project metadata, selected vector GeoJSON, detection GeoJSON and segmentation GeoJSON. +- Added formatted export-type badges and extra export-card provenance for analysis-run ids and created timestamps when those fields are available. +- Added responsive styling for handoff summary/action cards. +- Added `backend/tests/test_sprint64_export_handoff_polish.py`. +- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`. + +Tested: +- Red step: `python -m pytest backend/tests/test_sprint64_export_handoff_polish.py -q` failed on missing handoff summary/action structure and styles. +- `python -m pytest backend/tests/test_sprint64_export_handoff_polish.py backend/tests/test_sprint51_quality_export_polish.py -q` (`4 passed`) +- `cd frontend && npm run typecheck` +- `cd frontend && npm run build` +- Local Chrome/Playwright check against `http://127.0.0.1:5175` with live API proxy: Exports workspace opened, handoff summary/actions present, no console warnings/errors, no horizontal page overflow on desktop or mobile. +- `bash scripts/run_readiness_check.sh` (`233 passed`) + +Open: +- Deploy Tower and run live browser verification after this pass. + +Limitations: +- This is a frontend handoff usability pass only. It does not add export endpoints, change export persistence, introduce provider fetching or add AI/model behavior. + +Next recommended pass: +- Run a live browser smoke across Exports and Overview after deployment, then continue with report artifact readability if the exported HTML itself needs visual polish. diff --git a/docs/TODO.md b/docs/TODO.md index 2213403c..cee7a964 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -336,3 +336,4 @@ This file now starts with the current implementation status. Older preparation/b - [x] Expand golden datasets beyond the original single building QA fixture pair. - [x] Add workbench visual polish pass for command bar, panel surfaces, empty states and mobile nav density. - [x] Add map/result overlay ergonomics for active layer provenance and feature property summaries. +- [x] Add export/report handoff polish for artifact readiness, action grouping and export provenance. diff --git a/frontend/README.md b/frontend/README.md index 3c6dd942..55814d69 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -220,6 +220,7 @@ The workbench now uses a task-based shell instead of a single long panel stack. - Offline demo workflow orchestration lives in `src/hooks/useDemoWorkflow.ts`, because it coordinates project, dataset, map, QA/QC, detection, segmentation and export state after the backend fixture seed. - Workbench bootstrap and reload effects live in `src/hooks/useWorkbenchBootstrap.ts`, keeping `App.tsx` focused on composing hooks into panels. - The workbench shell includes a compact command bar, consistent raised/sunken surfaces, structured empty states and scroll-safe AI result tables to keep the V1 workflow usable across desktop and mobile widths. +- The Export Center includes a handoff readiness summary, grouped artifact actions and provenance-rich export cards so report/GeoJSON handoff stays understandable in long-running demo projects. ## Workbench shell refactor diff --git a/frontend/src/components/exports/ExportCenter.tsx b/frontend/src/components/exports/ExportCenter.tsx index 7e60aefb..d9fa3bdb 100644 --- a/frontend/src/components/exports/ExportCenter.tsx +++ b/frontend/src/components/exports/ExportCenter.tsx @@ -43,6 +43,14 @@ function compactPath(value: string): string { return parts.slice(-2).join('/') } +function formatExportType(value: string): string { + return value + .split('_') + .filter(Boolean) + .map((part) => part.charAt(0).toUpperCase() + part.slice(1)) + .join(' ') +} + function exportMatchesSearch(item: ExportRead, query: string): boolean { const normalizedQuery = query.trim().toLowerCase() if (!normalizedQuery) { @@ -79,6 +87,7 @@ export function ExportCenter({ const canExportDataset = Boolean(selectedDataset && isVectorDatasetType(selectedDataset.dataset_type)) const geojsonExports = exports.filter((item) => item.export_type.includes('geojson')).length const reportExports = exports.filter((item) => item.export_type === 'project_report_html').length + const handoffStatus = selectedProjectId ? 'project selected' : 'select project' const exportTypes = useMemo(() => Array.from(new Set(exports.map((item) => item.export_type))).sort(), [exports]) const exportStatuses = useMemo(() => Array.from(new Set(exports.map((item) => item.status))).sort(), [exports]) const filteredExports = useMemo( @@ -117,43 +126,102 @@ export function ExportCenter({ {selectedDataset?.name ?? 'none'} +
Pick the artifact that matches the current review state before sharing data outside the workbench.
+Reload the persisted artifact list for the selected project.
+ +Generate the human-readable V1 handoff report from persisted project state.
+ +Export project, dataset, QA and artifact metadata for machine-readable review.
+ +Export the active vector/reference dataset when it is selected and ready.
+ +Export persisted detection geometries for the selected analysis run.
+ +Export persisted segmentation polygons for the selected analysis run.
+ +{exportError}
: null} {latestExport ? ({latestExport.path}