# Remove Redundant Synchronous Video Pre-Write in /detect Endpoint

**Task**: AZ-177_remove_redundant_video_prewrite
**Name**: Remove redundant synchronous video file writes in /detect endpoint
**Description**: The `/detect` endpoint writes video bytes to disk synchronously before calling `run_detect_video`, which writes them again in a background thread concurrently with frame detection. Remove the redundant pre-writes so videos are written only once — by inference.pyx — concurrently with detection, as AZ-173 intended.
**Complexity**: 2 points
**Dependencies**: AZ-173 (stream-based run_detect)
**Component**: Main
**Jira**: AZ-177
**Parent**: AZ-172

## Problem

After AZ-173 implemented simultaneous disk-write + frame-detection in `inference.pyx`, the `/detect` endpoint in `main.py` still writes video bytes to disk **synchronously before** calling `run_detect_video`. Since `run_detect_video` internally spawns a thread to write the same bytes to the same path, every video upload gets written to disk **twice**:

1. **Auth'd path** (lines 394-395): `storage_path` is written synchronously via `open(storage_path, "wb").write(image_bytes)`, then `run_detect_video(..., save_path=storage_path, ...)` writes to the same path again in a background thread.

2. **Non-auth'd path** (lines 427-430): A temp file is created and written synchronously via `tempfile.mkstemp` + `open(tmp_video_path, "wb").write(image_bytes)`, then `run_detect_video(..., save_path=tmp_video_path, ...)` writes to the same path again.

This defeats the purpose of AZ-173's concurrent design: the video data is fully written before detection starts, so there is no actual concurrency between writing and detecting.

### How inference.pyx handles it (correctly)

```python
# inference.pyx run_detect_video:
writer_done = threading.Event()
wt = threading.Thread(target=_write_video_bytes_to_path, args=(save_path, video_bytes, writer_done))
wt.start()                        # thread A: writes bytes to disk
bio = io.BytesIO(video_bytes)
container = av.open(bio)           # thread B (caller): decodes frames via PyAV
self._process_video_pyav(...)      # detection happens concurrently with disk write
writer_done.wait()                 # wait for write to finish
```

## Target State

### Auth'd video uploads
- Do NOT write file at line 394 for videos — only write for images (since `run_detect_image` doesn't write to disk)
- Pass `storage_path` to `run_detect_video`; let inference handle the concurrent write

### Non-auth'd video uploads
- Do NOT create/write a temp file with `tempfile.mkstemp` + `open().write()`
- Instead, only create a temp file **path** (empty) and pass it to `run_detect_video` which writes the data concurrently with detection
- Alternatively: use `tempfile.mktemp` or build the path manually without pre-writing

### Image uploads (no change needed)
- `run_detect_image` does NOT write to disk, so the synchronous write at line 394 remains necessary for images

## Acceptance Criteria

- [ ] Video bytes are written to disk exactly once (by `_write_video_bytes_to_path` in inference.pyx), not twice
- [ ] For videos, disk write and frame detection happen concurrently (not sequentially)
- [ ] Image storage behavior is unchanged (synchronous write before detection)
- [ ] Temp file cleanup in the `finally` block still works correctly
- [ ] Auth'd video uploads: media record and status updates unchanged
- [ ] All existing tests pass

## File Changes

| File | Action | Description |
|------|--------|-------------|
| `src/main.py` | Modified | Split storage write by media kind; remove redundant video pre-writes |

## Technical Notes

- The `finally` block (lines 463-468) cleans up `tmp_video_path` — this must still work after the change. Since `run_detect_video` waits for the writer thread with `writer_done.wait()`, the file will exist when cleanup runs.
- `tempfile.mkstemp` creates the file atomically (open + create); we may need `tempfile.mkstemp` still just for the safe path generation, but skip the `write()` call. Or use a different approach to generate the temp path.
