# Avatar Upload Debugging Guide

Last Updated: 2025-08-29

## Issue Summary

The avatar upload functionality was experiencing file corruption during transmission from the frontend to the backend. PNG files were being corrupted where the PNG header `\x89PNG` was being replaced with UTF-8 replacement characters `\xef\xbf\xbdPNG`.

## Root Cause Analysis

### Next.js Proxy Issue (ACTUAL ROOT CAUSE)
The primary issue was in the Next.js API proxy route that converts binary FormData to text:

**File:** `/Users/talor/dyad-apps/thrillwiki-real/src/app/api/[...path]/route.ts`

1. **Problematic code:**
   ```typescript
   body = await clonedRequest.text(); // This corrupts binary data!
   ```

2. **Why this causes corruption:**
   - FormData containing binary image files gets converted to UTF-8 text
   - Binary bytes like `\x89` (PNG signature) become UTF-8 replacement characters `\xef\xbf\xbd`
   - This mangles the file data before it even reaches the backend


## Solutions Implemented

### Next.js Proxy Fix (PRIMARY FIX)
**File:** `/Users/talor/dyad-apps/thrillwiki-real/src/app/api/[...path]/route.ts`

Fixed the proxy to preserve binary data instead of converting to text:

```typescript
// BEFORE (problematic)
body = await clonedRequest.text(); // Corrupts binary data!

// AFTER (fixed)
const arrayBuffer = await clonedRequest.arrayBuffer();
body = new Uint8Array(arrayBuffer); // Preserves binary data
```

**Why this works:**
- `arrayBuffer()` preserves the original binary data
- `Uint8Array` maintains the exact byte sequence
- No UTF-8 text conversion that corrupts binary files

### Backend Cleanup
**File:** `/Users/talor/thrillwiki_django_no_react/backend/apps/api/v1/serializers/accounts.py`

Simplified the avatar validation to basic file validation only:

```python
# Removed complex corruption repair logic
# Now just validates file size, format, and dimensions with PIL
def validate_avatar(self, value):
    # Basic file validation only
    # Let Cloudflare Images handle the rest
```

## Technical Details

### API Flow
1. **Frontend:** `AvatarUploader` → `useAuth.uploadAvatar()` → `accountApi.uploadAvatar(file)`
2. **Next.js Proxy:** Preserves binary data using `arrayBuffer()` instead of `text()`
3. **Backend:** `AvatarUploadView` → `AvatarUploadSerializer.validate_avatar()` → Cloudflare Images API

## Testing

### Manual Testing Steps
1. Select a PNG image file in the avatar uploader
2. Upload the file
3. Verify the upload succeeds without corruption
4. Check that the avatar displays correctly


## Prevention

### Frontend Best Practices
- Always pass `FormData` objects directly to API calls
- Avoid extracting and re-wrapping files unnecessarily
- Use proper file validation on the client side

### Backend Best Practices
- Use Django's proper file upload classes (`InMemoryUploadedFile`, `TemporaryUploadedFile`)
- Implement robust file validation and corruption detection
- Provide detailed logging for debugging file upload issues

## Related Files

### Frontend
- `/Users/talor/dyad-apps/thrillwiki-real/src/components/profile/avatar-uploader.tsx`
- `/Users/talor/dyad-apps/thrillwiki-real/src/hooks/use-auth.tsx`
- `/Users/talor/dyad-apps/thrillwiki-real/src/lib/api.ts`

### Backend
- `/Users/talor/thrillwiki_django_no_react/backend/apps/api/v1/serializers/accounts.py`
- `/Users/talor/thrillwiki_django_no_react/backend/apps/api/v1/accounts/views.py`
- `/Users/talor/thrillwiki_django_no_react/backend/apps/accounts/services.py`

## Status

✅ **RESOLVED** - File corruption issue fixed in Next.js proxy
✅ **CLEANED UP** - Removed unnecessary corruption repair code from backend
✅ **DOCUMENTED** - Comprehensive debugging guide created

The avatar upload functionality should now work correctly without file corruption. The Next.js proxy properly preserves binary data, and the backend performs basic file validation only.
