## Enhanced Ticket
Type:
Bug
Priority Recommendation:
High - Export is a core feature for Team tier users
---
### Description
Analytics export functionality returns 404 errors because the frontend
ExportButton
component uses a direct
fetch()
call instead of the generated hey-api client, causing requests to go to the Next.js server instead of the Django backend.
---
### Root Cause Analysis
The
ExportButton
component at
/apps/frontend/src/components/analytics/export-button.tsx
(lines 68-73) makes a direct fetch call:
```typescript
const response = await fetch(
/api/v1/analytics/export/?${params.toString()}
, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
```
Problems:
  1. Missing Base URL
    : The relative URL
    /api/v1/analytics/export/
    resolves to the Next.js server (port 3100) instead of the Django backend (port 8100)
  2. Missing Authorization Header
    : Unlike the hey-api client which automatically injects the JWT token via the
    auth
    configuration in
    /apps/frontend/src/lib/api/client.ts
    , this direct fetch has no authentication
  3. Ignores Generated Client
    : A properly configured
    analyticsExportRetrieve
    function exists in
    /apps/frontend/src/lib/api/generated/sdk.gen.ts
    but isn't being used
---
### Technical Context
Backend endpoint is correctly implemented:
  • Location:
    /apps/backend/apps/analytics/views/analytics.py
    (lines 747-815)
  • URL:
    /api/v1/analytics/export/
  • Supports
    format
    (csv/json) and
    type
    (overview/matches/games/etc.) query params
  • Returns proper file download responses
Frontend has generated client available:
  • analyticsExportRetrieve
    in
    /apps/frontend/src/lib/api/generated/sdk.gen.ts
  • Automatically handles auth and base URL
  • Should be used for all API calls per project conventions
---
### Affected Files
| File | Change Required |
|------|-----------------|
|
/apps/frontend/src/components/analytics/export-button.tsx
| Replace direct
fetch()
with
analyticsExportRetrieve
from hey-api client |
---
### Implementation Notes
  1. Import the generated SDK function:
```typescript
import { analyticsExportRetrieve } from "@/lib/api/generated";
```
  1. Replace the fetch call
    with the hey-api client function which handles:
- Base URL resolution
- JWT authentication header injection
- Proper error handling
  1. Handle blob response
    - The hey-api client may need special handling for file downloads. Consider using
    response.blob()
    or implementing a custom fetch wrapper that preserves the file download functionality.
  2. Alternative approach
    - If hey-api doesn't support blob responses well, update the fetch to use proper base URL and auth:
```typescript
const baseUrl = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:8100";
const token = localStorage.getItem("nexlog_access_token");
const response = await fetch(
${baseUrl}/api/v1/analytics/export/?${params}
, {
headers: {
Authorization:
Bearer ${token}
,
},
});
```
---
### Acceptance Criteria
  • [ ] Clicking "Export as CSV" downloads a CSV file with analytics data
  • [ ] Clicking "Export as JSON" downloads a JSON file with analytics data
  • [ ] Export respects current filter selections (date range, users, decks, etc.)
  • [ ] Export shows loading state during download
  • [ ] Export shows error toast if download fails
  • [ ] Subscription tier gating still works (Team tier required for CSV export)
  • [ ] No 404 errors in browser console or network tab
---
### Testing Requirements
  1. Replicate the bug:
- Navigate to Analytics page
- Click Export button
- Select "Export as CSV" or "Export as JSON"
- Observe 404 error in Network tab
  1. Verify fix:
- Same steps should now trigger successful download
- Check Network tab shows request to correct backend URL (port 8100)
- Check request includes Authorization header
- Verify downloaded file contains expected data
  1. Edge cases to test:
- Export with various filter combinations
- Export when not logged in (should fail gracefully)
- Export for users without Team tier (should show upgrade prompt)
---
### Questions for Stakeholder
  1. Should the export include a timestamp in the filename (currently does:
    analytics_export_2024-01-15.csv
    )?
  2. For large datasets, should we consider async export with email delivery instead of direct download?
---
### Estimated Complexity
S (Small)
- Single file change, straightforward fix using existing patterns