# Admin YouTube Integration — Frontend Handoff

This document explains the admin-side YouTube integration flow, endpoints, example requests/responses, and UI acceptance checklist.

## Overview
- The backend stores a single YouTube integration record in the database. The API key is stored encrypted (`encryptedApiKey`) and only a masked version (`maskedKey`) is returned to the UI.
- Admin users can view, update, and test the YouTube integration from the admin UI.
- The public search endpoint (`/api/v1/youtube/search`) uses the stored API key when available; otherwise it falls back to env keys.

Base URL: `http://127.0.0.1:4000/api/v1`

Important notes for frontend:
- All admin endpoints require an authenticated admin session. The server sets `dailydew_token` as an HttpOnly cookie on login — include credentials with `fetch` (see examples).
- Error responses for YouTube issues include specific codes `YOUTUBE_API_KEY_INVALID` or `YOUTUBE_API_ERROR` and a message that may contain the upstream Google reason.

---

## Endpoints

### Auth (admin session)
- POST `/auth/login` — Body `{ email, password }`. Response contains `data.user.role` and sets `dailydew_token` cookie.
- GET `/auth/admin-check` — Validates admin session (requires cookie).

### Admin integrations
- GET `/admin/integrations/youtube`
  - Purpose: Read current integration config.
  - Response example:
```json
{
  "success": true,
  "message": "YouTube integration config",
  "data": {
    "enabled": true,
    "maskedKey": "AIzaSy...tTE",
    "dailyQuota": { "used": 0, "limit": 12000 },
    "lastTestedAt": "2026-05-14T05:29:55.848Z"
  }
}
```

- PUT `/admin/integrations/youtube`
  - Body: `{ apiKey?: string, enabled?: boolean, dailyLimit?: number }`
  - Behavior: If `apiKey` is provided the server validates it with a light YouTube search. If valid, the key is encrypted and saved; `maskedKey` and `lastTestedAt` are returned.
  - Error: `YOUTUBE_API_KEY_INVALID` (400) with Google reason when validation fails.

- GET `/admin/integrations/youtube/test`
  - Tests the currently saved key (or env fallback) and returns a small sample if successful.

### YouTube search (used by admin search UI and scheduling)
- GET `/youtube/search?q=...&maxResults=...&pageToken=...`
  - Requires authentication (session cookie).
  - Returns: `{ items, pageInfo, source: 'cache'|'api', quotaRemaining }`
  - Errors: `YOUTUBE_API_KEY_INVALID` (400) for key problems; `YOUTUBE_API_ERROR` (502) for upstream failures.

Example call (include cookie):
```js
await fetch('http://127.0.0.1:4000/api/v1/admin/integrations/youtube', {
  credentials: 'include',
});
```

---

## UI Acceptance Checklist
- [ ] Login flow sets `dailydew_token` cookie and `data.user.role === 'ADMIN'` for admin users.
- [ ] Admin integrations page shows: `enabled`, `maskedKey` (masked), `dailyQuota.used`, `dailyQuota.limit`, `lastTestedAt`.
- [ ] Save API key flow:
  - Input accepts raw key.
  - `PUT` is called with `{ apiKey }`.
  - On success, the UI displays masked key and `lastTestedAt` update.
  - On validation failure, show the backend `error.message` (it may include Google reason like `accessNotConfigured` or `dailyLimitExceeded`).
- [ ] Test key button calls `/admin/integrations/youtube/test` and displays sample thumbnail(s) or validation error.
- [ ] Search UI uses `/youtube/search` with `credentials: 'include'` and renders `source` and `quotaRemaining`.

---

## Implementation Notes (for frontend developers)
- Use `credentials: 'include'` with `fetch` for all authenticated admin endpoints.
- Do not rely on reading cookies from JS — use the login response `data.user` or call `/auth/me`.
- When a key is saved, the backend stores it encrypted; always show the masked version returned by the server.
- Treat backend `YOUTUBE_API_KEY_INVALID` as actionable: show an input with the validation error and a hint to check API Console (key enabled for YouTube Data API, IP restrictions, etc.).

---

## Next enhancements (optional)
- Add an endpoint for bulk topic import: accept comma-separated topics when creating/updating a course and create `Topic` rows automatically.
- Add a semester scheduler endpoint: POST semester start date + courseId → returns week→topic assignment.

---

If you want, I can also produce a Postman collection or ready Axios / fetch snippets for the frontend team.
