crud.delete_project_files(db, projectId)
crud.delete_project_v2(db, projectId)
backend/app/modules/code/code_projects_api.py:226
Two of the four things a project owns get cleaned up. Not cleaned up:
- the on-disk tree at
data/code_projects/<id>/repo created in create_project (backend/app/services/code_project_service.py:91)
- the
exports/ directory and its zips (backend/app/services/code_project_service.py:93)
CodeProjectGeneration rows — crud.py has create_project_generation and update_project_generation but no delete (backend/app/db/crud.py:538)
CodeProjectExport rows — same, only create and get exist (backend/app/db/crud.py:569)
Trigger: create a project, export it, delete it, then GET /api/v1/code/projects/exports/{exportId}/download.
Observed: 200 with the full zip of a deleted project. get_export_path only checks that the file exists on disk (backend/app/services/code_project_service.py:446) — it never verifies the parent project still does, and the endpoint at backend/app/modules/code/code_projects_api.py:404 performs no ownership check either. Meanwhile disk usage grows monotonically and /workspace/monitor keeps scanning the orphaned trees.
Expected: delete in a single transaction — generations, exports, file index, project row — then shutil.rmtree(os.path.join(CODE_PROJECTS_DIR, project_id)), and have get_export_path join through to the project.
The two operations also run outside a transaction: if delete_project_v2 throws after delete_project_files committed (backend/app/db/crud.py:533), the project survives with an empty file index and its browser shows an empty repo forever.
backend/app/modules/code/code_projects_api.py:226Two of the four things a project owns get cleaned up. Not cleaned up:
data/code_projects/<id>/repocreated increate_project(backend/app/services/code_project_service.py:91)exports/directory and its zips (backend/app/services/code_project_service.py:93)CodeProjectGenerationrows —crud.pyhascreate_project_generationandupdate_project_generationbut no delete (backend/app/db/crud.py:538)CodeProjectExportrows — same, onlycreateandgetexist (backend/app/db/crud.py:569)Trigger: create a project, export it, delete it, then
GET /api/v1/code/projects/exports/{exportId}/download.Observed: 200 with the full zip of a deleted project.
get_export_pathonly checks that the file exists on disk (backend/app/services/code_project_service.py:446) — it never verifies the parent project still does, and the endpoint atbackend/app/modules/code/code_projects_api.py:404performs no ownership check either. Meanwhile disk usage grows monotonically and/workspace/monitorkeeps scanning the orphaned trees.Expected: delete in a single transaction — generations, exports, file index, project row — then
shutil.rmtree(os.path.join(CODE_PROJECTS_DIR, project_id)), and haveget_export_pathjoin through to the project.The two operations also run outside a transaction: if
delete_project_v2throws afterdelete_project_filescommitted (backend/app/db/crud.py:533), the project survives with an empty file index and its browser shows an empty repo forever.