fix(gateway): remove generated markdown on upload delete (#1170)

* fix(gateway): remove generated markdown on upload delete

Keep thread upload storage consistent by deleting the generated markdown companion when the original convertible upload is removed.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Ryanba
2026-03-18 16:31:26 +08:00
committed by GitHub
parent f737fbeae8
commit 4c78188896
2 changed files with 18 additions and 1 deletions

View File

@@ -187,7 +187,10 @@ async def delete_uploaded_file(thread_id: str, filename: str) -> dict:
raise HTTPException(status_code=403, detail="Access denied")
try:
file_path.unlink()
if file_path.suffix.lower() in CONVERTIBLE_EXTENSIONS:
companion_markdown = file_path.with_suffix(".md")
companion_markdown.unlink(missing_ok=True)
file_path.unlink(missing_ok=True)
logger.info(f"Deleted file: {filename}")
return {"success": True, "message": f"Deleted {filename}"}
except Exception as e:

View File

@@ -96,3 +96,17 @@ def test_upload_files_rejects_dotdot_and_dot_filenames(tmp_path):
# Only the safely normalised file should exist
assert [f.name for f in thread_uploads_dir.iterdir()] == ["passwd"]
def test_delete_uploaded_file_removes_generated_markdown_companion(tmp_path):
thread_uploads_dir = tmp_path / "uploads"
thread_uploads_dir.mkdir(parents=True)
(thread_uploads_dir / "report.pdf").write_bytes(b"pdf-bytes")
(thread_uploads_dir / "report.md").write_text("converted", encoding="utf-8")
with patch.object(uploads, "get_uploads_dir", return_value=thread_uploads_dir):
result = asyncio.run(uploads.delete_uploaded_file("thread-aio", "report.pdf"))
assert result == {"success": True, "message": "Deleted report.pdf"}
assert not (thread_uploads_dir / "report.pdf").exists()
assert not (thread_uploads_dir / "report.md").exists()