diff --git a/CHANGELOG.md b/CHANGELOG.md index 163c05b6..1541d93d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -641,5 +641,6 @@ Added: - Hardened the existing dry-run-first demo export cleanup command with a `--max-delete` safety cap. - Added repeated `--export-type` filters so operators can clean only selected artifact kinds. - Cleanup apply runs now report a `blocked_reason` instead of deleting when selected candidates exceed the cap. +- Dry-run output now includes `candidate_exports` with export ids so duplicate storage paths remain auditable. - Updated root and backend cleanup entrypoints, docs and regression coverage. - No API contracts, migrations, product capabilities, live provider fetching or AI/model dependency changes were introduced. diff --git a/backend/scripts/cleanup_demo_artifacts.py b/backend/scripts/cleanup_demo_artifacts.py index fe2859a6..127af7ae 100644 --- a/backend/scripts/cleanup_demo_artifacts.py +++ b/backend/scripts/cleanup_demo_artifacts.py @@ -88,6 +88,7 @@ def cleanup_demo_exports( "type_filtered_export_count": 0, "selected_export_count": 0, "deleted_export_count": 0, + "candidate_exports": [], "candidate_files": [], "deleted_files": [], "missing_files": [], @@ -140,6 +141,13 @@ def cleanup_demo_exports( summary["pruned_dirs"].extend(prune_empty_parents(path, storage_root)) summary["deleted_files"].append(str(path)) else: + summary["candidate_exports"].append( + { + "export_id": str(export.id), + "export_type": str(getattr(export, "export_type", "")), + "storage_path": str(path), + } + ) summary["candidate_files"].append(str(path)) else: summary["missing_files"].append({"export_id": str(export.id), "storage_path": str(path)}) diff --git a/backend/tests/test_sprint24_cleanup_demo_artifacts.py b/backend/tests/test_sprint24_cleanup_demo_artifacts.py index 0d9f98a8..44e43fc6 100644 --- a/backend/tests/test_sprint24_cleanup_demo_artifacts.py +++ b/backend/tests/test_sprint24_cleanup_demo_artifacts.py @@ -121,6 +121,9 @@ def test_cleanup_script_reports_dry_run_candidates_separately() -> None: content = script.read_text(encoding="utf-8") assert '"candidate_files": []' in content + assert '"candidate_exports": []' in content + assert '"export_id": str(export.id)' in content + assert '"export_type": str(getattr(export, "export_type", ""))' in content assert 'summary["candidate_files"].append(str(path))' in content assert '"max_delete": max_delete' in content assert "blocked_reason" in content diff --git a/docs/CODEX_EXECUTION_LOG.md b/docs/CODEX_EXECUTION_LOG.md index 68a7521c..abb14693 100644 --- a/docs/CODEX_EXECUTION_LOG.md +++ b/docs/CODEX_EXECUTION_LOG.md @@ -2274,7 +2274,7 @@ Changed: - Hardened the existing dry-run-first demo export cleanup command instead of creating a parallel cleanup path. - Added `--max-delete` with a default cap of 25 so large `--apply` runs are blocked until explicitly reviewed and raised. - Added repeatable `--export-type` filters for targeted cleanup, e.g. reports only. -- Extended the cleanup summary with `keep_latest`, `max_delete`, `export_types`, `type_filtered_export_count` and `blocked_reason`. +- Extended the cleanup summary with `keep_latest`, `max_delete`, `export_types`, `type_filtered_export_count`, `candidate_exports` and `blocked_reason`. - Updated the root wrapper to expose the new filter helper. - Updated `scripts/README.md`, `docs/STORAGE_ARCHITECTURE.md`, `backend/README.md`, `docs/TODO.md` and `CHANGELOG.md`. - Added regression coverage for export-type filtering, parser defaults and max-delete options. @@ -2282,9 +2282,12 @@ Changed: Tested: - `python -m py_compile scripts/cleanup_demo_artifacts.py backend/scripts/cleanup_demo_artifacts.py` - `cd backend && python -m pytest tests/test_sprint24_cleanup_demo_artifacts.py tests/test_readiness_gate.py -q` (`16 passed`) +- Tower dry-run command passed without deleting data: + `docker exec geointel /opt/geointel/venv/bin/python /app/scripts/cleanup_demo_artifacts.py --keep-latest 10 --max-delete 100 --export-type project_report_html` +- Tower dry-run reported `matched_export_count=51`, `type_filtered_export_count=17`, `selected_export_count=7`, `deleted_export_count=0`. Open: -- Run full readiness, deploy Tower and optionally perform a live cleanup dry run inside the all-in-one container before using `--apply`. +- Run full readiness and redeploy Tower with the clearer `candidate_exports` dry-run output. Limitations: - Cleanup still targets demo export records/files only. It does not delete source uploads, vector features, projects, AOIs, QA/QC records, rasters, tiles, masks or production data.