Initial commit: YouTube Studio Flow (backend, frontend, infrastructure, docs)

This commit is contained in:
2026-08-11 12:27:44 +02:00
commit d5af006443
304 changed files with 74604 additions and 0 deletions
@@ -0,0 +1,148 @@
# Bulk Jobs API
Base path: `/api/v1/bulk-jobs`
All endpoints require `Authorization: Bearer <jwt>`.
Related: [[02 - Videos API]], [[08 - Saved Views API]], [[10 - Quota API]]
---
## GET /bulk-jobs
List bulk jobs for the current team.
**Query parameters:**
| Param | Type | Description |
|---|---|---|
| `status` | string | Optional filter by job status |
**Response:** `BulkJob[]`
---
## GET /bulk-jobs/:id
Get a single bulk job with all of its individual item records.
**Response:** `BulkJob` with `items: BulkJobItem[]`
---
## POST /bulk-jobs/:id/rollback
Roll back a completed bulk job, reverting the changes made to each item. Requires `EDITOR` role.
**Response:** Updated `BulkJob`
**What rollback does:**
For each `BulkJobItem` with `status: "done"`, the rollback service writes `item.beforeSnapshot` back to the `Video` row. `beforeSnapshot` contains the `youtubeSnapshot` fields captured before the push: `title`, `tags`, `categoryId`, `privacyStatus`, `defaultLanguage`, `defaultAudioLanguage`, `selfDeclaredMadeForKids`, `embeddable`, `license`, `recordingDate`.
**For `SYNC_PUSH` jobs specifically:**
Rollback is a **local-only operation**. YouTube is not contacted and the data already pushed to YouTube is not reversed. After rollback:
- The `Video` row's fields are restored to their pre-push values.
- `lastSyncedHash` is **not** restored — it retains the hash computed at push time.
- Because the local fields no longer match `lastSyncedHash`, the video will show as "push pending" again. This is the expected outcome: the local DB now diverges from YouTube, and a new push is required to re-align them.
This means rollback on a `SYNC_PUSH` job does not undo anything on YouTube — it only rewinds the local record and marks the video as needing another sync.
---
## GET /bulk-jobs/push-pending/preview
Preview all push-pending videos with field-level diffs showing what will change when pushed to YouTube.
**Query parameters:**
| Param | Type | Description |
|---|---|---|
| `sort` | string | Field to sort by |
| `order` | `asc\|desc` | Sort direction |
**Response:** Array of per-video diff previews
---
## POST /bulk-jobs/push-pending
Create a bulk sync job for a selected set of push-pending videos. Enqueues YouTube sync jobs for each video. Requires `EDITOR` role.
**Request body:**
```json
{ "videoIds": ["cuid", "cuid"] }
```
> Tip: use `POST /saved-views/:id/execute` to get a `videoIds` list from a saved view. See [[08 - Saved Views API]].
**Response:** Created `BulkJob`
---
## Bulk Change (Header modal)
The following endpoints power the bulk metadata change modal in the application header.
### POST /bulk-jobs/preview
Preview the effect of a bulk metadata change before applying it.
**Request body:**
```json
{
"type": "SET_PRIVACY|SET_TEMPLATE|ADD_TAGS|REMOVE_TAGS|SEARCH_REPLACE_TITLE",
"payload": {},
"savedViewId": "cuid"
}
```
**`type` values:**
| Type | Description |
|---|---|
| `SET_PRIVACY` | Change privacy status for matched videos |
| `SET_TEMPLATE` | Apply a template to matched videos |
| `ADD_TAGS` | Add tags to matched videos |
| `REMOVE_TAGS` | Remove tags from matched videos |
| `SEARCH_REPLACE_TITLE` | Find and replace in video titles |
`savedViewId` is optional. When provided, the operation is scoped to videos matching that saved view.
**Response:**
```json
{
"count": 5,
"type": "SET_PRIVACY",
"previews": [
{
"videoId": "cuid",
"before": { "privacyStatus": "PRIVATE" },
"after": { "privacyStatus": "PUBLIC" }
}
]
}
```
---
### POST /bulk-jobs/apply
Apply a previewed bulk metadata change. Creates a `BulkJob` record and processes each matched video. Requires `EDITOR` role.
**Request body:** Same shape as `POST /bulk-jobs/preview`.
**Response:** Created `BulkJob`
---
## Notes
- Bulk sync jobs consume YouTube API quota (50 units per video pushed). Check remaining quota via `GET /quota/today` before triggering large bulk pushes. See [[10 - Quota API]].
- `BulkJob` items record `before` and `after` snapshots for each video, enabling rollback.
- Rollback is only available for completed jobs and reverses the stored `before` snapshot.