=== BAMBUDDY FILE DELETION ISSUE - Jan 8, 2026 ===
=== ROOT CAUSE IDENTIFIED ===

WHAT HAPPENED:
- /opt was COMPLETELY DELETED on TWO containers:
  - Container 109 (claude): ~11:22 and ~12:22
  - Container 107 (3dp): ~13:28
- Container 107 was "untouched" (no SSH, no Claude Code) - just running BamBuddy

ROOT CAUSE FOUND:
Bug in backend/app/services/archive.py delete_archive() function (lines 914-929):

    file_path = settings.base_dir / archive.file_path
    if file_path.exists():
        archive_dir = file_path.parent
        shutil.rmtree(archive_dir, ignore_errors=True)  # <-- THE BUG

If archive.file_path is EMPTY or MALFORMED:
- file_path = /opt/bambuddy / "" = /opt/bambuddy
- archive_dir = file_path.parent = /opt
- shutil.rmtree("/opt") --> DELETES ENTIRE /opt DIRECTORY!

TRIGGER:
- User was deleting archives via BamBuddy web UI on container 107 (3dp)
- One archive had corrupted/empty file_path in database
- Deleting that archive triggered shutil.rmtree("/opt")
- This deleted the entire /opt directory including BamBuddy itself

TIMELINE FOR CONTAINER 107 (3dp):
- 13:28:19 - Normal operation (WebSocket disconnect)
- 13:28:44 - DELETE /api/v1/archives/* requests failing with 500
            (database already gone because /opt was deleted)
- ls -la / shows root directory modified at 13:28

FIX APPLIED (on container 109):
Safety checks added to delete_archive() in archive.py:
1. Check if file_path is not empty
2. Verify archive_dir is inside settings.archive_dir
3. Ensure archive_dir is at least 2 levels deep
4. Log error and refuse to delete if checks fail

TO INVESTIGATE AFTER ROLLBACK:
On container 107, after rolling back to autodaily260108003006:

    # Find corrupted archive records
    sqlite3 /opt/bambuddy/data/bambuddy.db \
      "SELECT id, filename, file_path FROM print_archives
       WHERE file_path = '' OR file_path IS NULL
       OR file_path NOT LIKE 'archive/%';"

    # Check all file_path values
    sqlite3 /opt/bambuddy/data/bambuddy.db \
      "SELECT id, file_path FROM print_archives ORDER BY id;"

CONTAINER 109 (this host):
- Were you also deleting archives around 11:22 and 12:22?
- Same bug could have been triggered here too

PROXMOX COMMANDS FOR ROLLBACK:
    # Container 107 (3dp)
    pct rollback 107 autodaily260108003006
    pct start 107

    # Container 109 (claude) - already done via UI
    # Current snapshot: autodaily260108003004

WHAT TO DO NEXT:
1. Rollback container 107 to morning snapshot
2. Run the SQL query above to find corrupted archive
3. Apply the fix from container 109 to container 107
4. Understand how the file_path got corrupted in the first place

THE FIX (apply to both containers):
In backend/app/services/archive.py, the delete_archive function now has:
- Empty file_path check
- Path traversal protection (relative_to check)
- Minimum depth check (must be 2+ levels inside archive dir)
- Error logging for refused deletions

NOT CLAUDE CODE'S FAULT:
This was a bug in BamBuddy's own code that was triggered by:
1. Corrupted database record (unknown how it got corrupted)
2. User action (deleting archives via web UI)
