162 lines
3.9 KiB
Markdown
162 lines
3.9 KiB
Markdown
# Teams API
|
||
|
||
Base path: `/api/v1/teams`
|
||
|
||
All endpoints require `Authorization: Bearer <jwt>`.
|
||
|
||
Related: [[01 - Auth API]], [[06 - Linting API]], [[04 - Database Schema]]
|
||
|
||
---
|
||
|
||
## GET /teams/mine
|
||
|
||
List all teams the current user belongs to.
|
||
|
||
**Response:** `Team[]`
|
||
|
||
---
|
||
|
||
## GET /teams/:teamId
|
||
|
||
Get team details including members and connected channels.
|
||
|
||
**Response:** `TeamDetail`
|
||
|
||
---
|
||
|
||
## GET /teams/:teamId/channels
|
||
|
||
List connected YouTube channels for a team.
|
||
|
||
**Response:** `Channel[]`
|
||
|
||
---
|
||
|
||
## POST /teams/:teamId/members
|
||
|
||
Invite a user to the team by email address. Requires `ADMIN` role.
|
||
|
||
**Request body:**
|
||
|
||
```json
|
||
{
|
||
"email": "user@example.com",
|
||
"role": "EDITOR"
|
||
}
|
||
```
|
||
|
||
**Possible `role` values:** `ADMIN`, `EDITOR`, `REVIEWER`, `READONLY`
|
||
|
||
> `OWNER` is assigned at team creation and cannot be set via this endpoint.
|
||
|
||
**Response:** `TeamMember`
|
||
|
||
---
|
||
|
||
## PATCH /teams/:teamId/members/:userId
|
||
|
||
Change a team member's role. Requires `ADMIN` role.
|
||
|
||
**Request body:**
|
||
|
||
```json
|
||
{ "role": "EDITOR" }
|
||
```
|
||
|
||
---
|
||
|
||
## DELETE /teams/:teamId/members/:userId
|
||
|
||
Remove a member from the team. Requires `ADMIN` role.
|
||
|
||
---
|
||
|
||
## GET /teams/:teamId/settings
|
||
|
||
Get team-level render and feature settings.
|
||
|
||
**Response:**
|
||
|
||
```json
|
||
{
|
||
"dateFormat": "DD.MM.YYYY",
|
||
"timezone": "Europe/Berlin",
|
||
"publishingSchedule": [],
|
||
"showCanvaLink": false,
|
||
"disabledLintRules": [],
|
||
"showDeletedVideos": false,
|
||
"conflictDetectionEnabled": false,
|
||
"conflictDetectionBatchSize": 50,
|
||
"conflictDetectionMinAgeDays": 7
|
||
}
|
||
```
|
||
|
||
**Field notes:**
|
||
|
||
| Field | Notes |
|
||
|---|---|
|
||
| `dateFormat` | Default date format applied by the render engine to `{video.scheduledAt}` and `{video.recordingDate}` tokens when no inline format is specified (e.g. `{video.scheduledAt\|DD.MM.YYYY}` overrides this). |
|
||
| `timezone` | Team's local timezone, used for scheduling display. |
|
||
| `publishingSchedule` | Array of preferred publishing time slots used by the next-slot calculator. |
|
||
| `showCanvaLink` | Whether to show Canva thumbnail link in the video editor UI. |
|
||
| `disabledLintRules` | Array of rule codes (e.g. `TITLE_WEAK`) that are suppressed for this team. |
|
||
| `showDeletedVideos` | Whether soft-deleted videos appear in the video list. |
|
||
| `conflictDetectionEnabled` | Opt-in for the scheduled remote-conflict sweep. Only takes effect when the operator has also set `CONFLICT_DETECTION_ENABLED=true` on the worker. |
|
||
| `conflictDetectionBatchSize` | Max videos checked per sweep for this team (1–500). |
|
||
| `conflictDetectionMinAgeDays` | Skip videos whose `lastSyncedAt` is within the last N days (≥0). |
|
||
|
||
---
|
||
|
||
## PATCH /teams/:teamId/settings
|
||
|
||
Update team settings. Requires `ADMIN` role.
|
||
|
||
**Request body** (all fields optional):
|
||
|
||
```json
|
||
{
|
||
"dateFormat": "DD.MM.YYYY",
|
||
"timezone": "Europe/Berlin",
|
||
"publishingSchedule": [],
|
||
"showCanvaLink": true,
|
||
"disabledLintRules": ["TITLE_WEAK"],
|
||
"showDeletedVideos": false,
|
||
"conflictDetectionEnabled": true,
|
||
"conflictDetectionBatchSize": 100,
|
||
"conflictDetectionMinAgeDays": 14
|
||
}
|
||
```
|
||
|
||
**Validation:**
|
||
|
||
- `conflictDetectionBatchSize` must be `1 ≤ n ≤ 500`
|
||
- `conflictDetectionMinAgeDays` must be `≥ 0`
|
||
|
||
Invalid values return `400 Bad Request`.
|
||
|
||
**Side effects:**
|
||
|
||
- If `disabledLintRules` changes, existing `LintResult` rows for any newly disabled rules are deleted and `Video.lintStatus` is recomputed for all affected videos automatically.
|
||
|
||
See [[06 - Linting API]] for more on lint result management. See [[05 - Queue System]] for how the conflict-detection settings drive the scheduled sweep.
|
||
|
||
---
|
||
|
||
## GET /teams/:teamId/next-publish-slot
|
||
|
||
Find the next available publishing slot based on the team's configured publishing schedule.
|
||
|
||
**Query parameters:**
|
||
|
||
| Param | Type | Required | Description |
|
||
|---|---|---|---|
|
||
| `channelId` | string | Yes | The channel to check slots for |
|
||
|
||
**Response:**
|
||
|
||
```json
|
||
{ "slot": "ISO datetime | null" }
|
||
```
|
||
|
||
`null` is returned if no publishing schedule has been configured for the team.
|