Initial commit: YouTube Studio Flow (backend, frontend, infrastructure, docs)
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
# Import / Export API
|
||||
|
||||
All endpoints require `Authorization: Bearer <jwt>`.
|
||||
|
||||
Related: [[02 - Videos API]], [[03 - Blocks API]], [[04 - Templates API]], [[05 - Collaborators API]]
|
||||
|
||||
---
|
||||
|
||||
## Import
|
||||
|
||||
Base path: `/api/v1/imports`
|
||||
|
||||
All import endpoints require `EDITOR` role.
|
||||
|
||||
---
|
||||
|
||||
### POST /imports/csv/preview
|
||||
|
||||
Upload and validate a CSV file before committing. Returns a validation report and an `importJobId` to use in the commit step.
|
||||
|
||||
**Content-Type:** `multipart/form-data`
|
||||
|
||||
**Form fields:**
|
||||
|
||||
| Field | Type | Description |
|
||||
|---|---|---|
|
||||
| `file` | file | CSV file to import |
|
||||
| `mapping` | string (JSON) | Maps CSV column names to video fields |
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"importJobId": "cuid",
|
||||
"validRows": 50,
|
||||
"errors": [
|
||||
{ "row": 3, "field": "privacyStatus", "message": "Invalid enum value" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| `importJobId` | Token to pass to the commit step. |
|
||||
| `validRows` | Count of rows that passed validation. |
|
||||
| `errors` | Array of per-row validation failures. Each entry has `row` (1-based), `field`, and `message`. Empty array means all rows are valid. |
|
||||
|
||||
The full validation detail is also stored in `ImportJob.validationReport` (shape: `{ validCount, errorCount, errors }`). There is no `warnings` array.
|
||||
|
||||
---
|
||||
|
||||
### POST /imports/csv/commit
|
||||
|
||||
Enqueues a BullMQ job to process a previously validated CSV import. Returns immediately — the actual row processing happens asynchronously in the worker.
|
||||
|
||||
> **Known limitation:** The import processor currently only marks the `ImportJob` as `committed` and writes an audit log entry. It does not create or update any `Video` rows. The validated rows from the preview step are not persisted and are not available to the processor. CSV import is effectively incomplete — see the backlog.
|
||||
|
||||
**Request body:**
|
||||
|
||||
```json
|
||||
{ "importJobId": "cuid" }
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{ "queued": true, "importJobId": "cuid" }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### POST /imports/json/preview
|
||||
|
||||
Validate a JSON workspace payload (blocks, templates, variables, collaborators) before committing. Returns an `importJobId` to use in the commit step.
|
||||
|
||||
> **Note:** The payload is **not stored** during preview. The `importJobId` is a commit-guard token only — it confirms a preview was completed and prevents double-commit. The full payload must be resent on commit.
|
||||
|
||||
**Request body:** Workspace JSON payload
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"importJobId": "cuid",
|
||||
"valid": true
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### POST /imports/json/commit
|
||||
|
||||
Apply a previously validated JSON workspace import. The full workspace payload must be included again — it was not stored during the preview step.
|
||||
|
||||
Commit is **synchronous** (no queue). Upserts `collaborators`, `blocks`, and `templates` by `id`. `videos`, `videoConfigs`, and `savedViews` in the payload are silently ignored.
|
||||
|
||||
**Request body:**
|
||||
|
||||
```json
|
||||
{
|
||||
"importJobId": "cuid",
|
||||
"payload": { }
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{ "committed": true }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Export
|
||||
|
||||
Base path: `/api/v1/exports`
|
||||
|
||||
---
|
||||
|
||||
### POST /exports/csv
|
||||
|
||||
Export video metadata as a CSV file download. There is no `scope` parameter — filtering is controlled by `videoIds` or `savedViewId`.
|
||||
|
||||
**Request body:**
|
||||
|
||||
```json
|
||||
{
|
||||
"videoIds": ["cuid1", "cuid2"],
|
||||
"savedViewId": "cuid"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Notes |
|
||||
|---|---|
|
||||
| `videoIds` | Export only these specific videos. If omitted, falls back to `savedViewId`. |
|
||||
| `savedViewId` | If `videoIds` is not provided, loads the saved view's stored `queryJson` and uses it to select which videos to export. |
|
||||
|
||||
If neither field is provided, all videos in the team are exported.
|
||||
|
||||
**CSV columns:** `youtube_video_id`, `title`, `tags`, `category_id`, `privacy_status`, `published_at`, `scheduled_at`, `template`, `lint_status`
|
||||
|
||||
**Response:** `text/csv` file download (`studioflow-export-<timestamp>.csv`)
|
||||
|
||||
---
|
||||
|
||||
### POST /exports/json
|
||||
|
||||
Export the full workspace as a JSON object. No request body, no filtering — exports everything.
|
||||
|
||||
**Response:** JSON object containing: `version`, `exportedAt`, `videos`, `videoConfigs`, `blocks`, `templates`, `collaborators`, `savedViews`
|
||||
|
||||
> **Note:** `ExportJob` rows are never written. There is no export history or re-download — each call generates the export fresh. See the backlog.
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- The preview-then-commit pattern for imports allows validation errors to be surfaced and reviewed before any data is written.
|
||||
- CSV column mapping must be provided as a JSON string in the `mapping` form field, mapping CSV header names to the corresponding video model fields accepted by `PATCH /videos/:id`.
|
||||
- JSON workspace exports can be re-imported via `POST /imports/json/preview` and `POST /imports/json/commit`, enabling workspace migration between teams or environments.
|
||||
Reference in New Issue
Block a user