Initial commit: YouTube Studio Flow (backend, frontend, infrastructure, docs)
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
# Video Management
|
||||
|
||||
## User Perspective
|
||||
The Videos page (`/videos`) is the main workspace. It displays the team's full video library in a paginated, sortable table. Users can filter by status, search by title, switch between predefined tabs, and click any video to open the editor.
|
||||
|
||||
### Video List Features
|
||||
- **Tabs**: All Content, Published, Private, Scheduled, Conflicts, Push Pending, Lint Issues, Deleted (conditionally shown)
|
||||
- **Columns**: YouTube ID, Title, Privacy Status, Published Date, Lint Status, Playlists, Sync Status
|
||||
- **Sorting**: Click column headers
|
||||
- **Pagination**: Page size selector + prev/next
|
||||
- **Search**: Title search via URL param `search=`
|
||||
- **Middle-click**: Opens video in background tab (native anchor overlay)
|
||||
- **Lint status badges**: OK (no badge), WARNING (amber), ERROR (pink/red)
|
||||
- **Sync status badges**: In sync (green), Push pending (amber), Conflict (red)
|
||||
|
||||
### Video Editor Features
|
||||
The video editor (`/videos/[id]`) provides:
|
||||
- **Combined header**: thumbnail, YouTube/Studio links, meta info (ID, date, privacy, sync status), lint badge, action buttons
|
||||
- **Sortable two-column layout**: sections (Basic Info, Language, Audience & Content, Playlists, Description) can be dragged between columns. Layout persists to user preferences.
|
||||
- **Basic Info**: title, tags (chip input), privacy status, category, scheduled publish date, recording date, game title
|
||||
- **Language**: title/description language, video language
|
||||
- **Audience & Content**: Made for Kids toggle, Allow Embedding toggle, License selector
|
||||
- **Playlists**: add/remove from channel playlists via search dropdown
|
||||
- **Description**: description block config editor (see [[02 - Description Engine]])
|
||||
- **Actions**: Apply Template, Refresh from YouTube, Push to YouTube, Save Changes
|
||||
- **Diff view**: "See what changed" shows field-level diff against last synced YouTube state
|
||||
|
||||
### Game Title Field
|
||||
|
||||
`gameTitle` is a **custom metadata field** — it is not a YouTube API field and is never populated during channel import. Users enter it manually in the video editor's Basic Info section.
|
||||
|
||||
It serves two purposes:
|
||||
1. **Token `{video.gameTitle}`** — resolves in description blocks, allowing game name to appear in descriptions automatically.
|
||||
2. **Canva search link** — when `Team.showCanvaLink` is enabled in team settings, the video editor shows a "Search Canva" link that opens `https://www.canva.com/search?q={gameTitle}`, helping creators find thumbnail templates for their game.
|
||||
|
||||
It can also be set as a template default via `Template.videoFields.gameTitle`, so assigning a template pre-fills the game name.
|
||||
|
||||
## Developer Perspective
|
||||
|
||||
### Backend
|
||||
- **Module**: `backend/src/modules/videos/`
|
||||
- **Key service methods**: `findAll(query, teamId)`, `findOne(id)`, `update(id, dto)`, `syncVideo(id)`, `refreshFromYouTube(id)`, `renderDescription(id)`
|
||||
- **Sync flow**: `POST /videos/:id/sync` enqueues a `youtube-sync` BullMQ job. The processor renders description, checks hash, calls YouTube API, updates `lastSyncedHash` and `renderedDescription`.
|
||||
- **`hasPendingChanges`**: Computed in `findAll` by comparing `hashMetadata(currentFields)` against `lastSyncedHash`. If `lastSyncedHash` is null, falls back to comparing against YouTube baseline using `youtubeDescription`.
|
||||
- **Filters** (`GET /videos`): `search`, `lintStatus`, `privacyStatus`, `scheduled`, `notScheduled`, `remoteConflict`, `pendingSync`, `deletedOnYouTube`, `hasLintIssues` (matches ERROR or WARNING)
|
||||
|
||||
### Frontend
|
||||
- **Pages**: `frontend/src/app/(dashboard)/videos/page.tsx` (list) and `videos/[id]/page.tsx` (editor)
|
||||
- **Table component**: `VideoTable.tsx` uses TanStack Table v8
|
||||
- **URL state**: Tab, page, sort, and search are persisted in URL params
|
||||
- **Column layout persistence**: Saved to `User.preferences` via `PATCH /users/me/preferences` using keys `videoEditLeftCol` and `videoEditRightCol`
|
||||
|
||||
## Related
|
||||
- [[02 - Description Engine]]
|
||||
- [[03 - Metadata Linting]]
|
||||
- [[02 - Videos API]]
|
||||
Reference in New Issue
Block a user