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,97 @@
# Description Blocks API
Base path: `/api/v1/blocks`
All endpoints require `Authorization: Bearer <jwt>`.
Related: [[02 - Description Engine]], [[04 - Templates API]], [[04 - Database Schema]]
---
## GET /blocks
List all description blocks for the current team.
**Response:** `DescriptionBlock[]`
---
## GET /blocks/:id
Get a single block including its version history.
**Response:** `DescriptionBlock` with `versions: BlockVersion[]`
---
## POST /blocks
Create a new description block. Requires `EDITOR` role.
**Request body:**
```json
{
"name": "string",
"type": "STATIC|VARIABLE|CAMPAIGN|COLLABORATOR|CONDITIONAL",
"content": "string",
"language": "de",
"campaignId": "cuid",
"compact": false,
"tags": ["string"],
"variableDefinitions": []
}
```
**Field notes:**
| Field | Notes |
|---|---|
| `type` | See block type behavior below. `GLOBAL` and `REPEATABLE` are kept in the DB enum but are not exposed in the UI. |
| `campaignId` | Only applicable when `type` is `CAMPAIGN`. Links the block to a campaign date window. |
| `compact` | Block-level default for whether a blank line precedes the block in the rendered output. Can be overridden per video in `VideoConfig.blockOverrides`. |
| `variableDefinitions` | Metadata about custom variables used in the block's content. |
**Block type behavior:**
| Type | Render behavior |
|---|---|
| `STATIC` | Raw output, no token substitution |
| `VARIABLE` | Resolves `{custom_var}`, `{video.*}`, and `{collab.*}` tokens |
| `CAMPAIGN` | Auto-included at the end of the render when the linked campaign's date window is active (`startAt <= now <= endAt`), regardless of block order |
| `COLLABORATOR` | Resolved against assigned collaborators |
| `CONDITIONAL` | Rendered based on condition evaluation |
See [[02 - Description Engine]] for full rendering pipeline details.
---
## PATCH /blocks/:id
Update a block. Creates a version snapshot before applying changes. Requires `EDITOR` role.
**Request body:** Same fields as `POST /blocks`, all optional.
---
## DELETE /blocks/:id
Delete a block. Requires `ADMIN` role.
Returns `409 Conflict` if the block is referenced in any `VideoConfig.blockOrder` or template's `defaultBlocks`. Deletion is blocked until all references are removed. The error message includes the count of affected video configs and templates.
---
## GET /blocks/:id/versions
List the version history for a block, ordered most-recent first.
**Response:** `BlockVersion[]`
---
## Notes
- Free-text entries in a video's block order use IDs prefixed `freetext:` — no `DescriptionBlock` row exists for these. Their content comes entirely from `blockOverrides[id].content`.
- The `{collab.youtube}` token resolves to the full YouTube URL (e.g. `https://www.youtube.com/@handle`), not just the handle. See [[05 - Collaborators API]] for all available `collab.*` tokens.
- System variable tokens (`video.*`, `collab.*`) are registered in `shared/system-variables/system-variables.registry.ts`. New tokens must be added there or they will never resolve.