Initial commit: YouTube Studio Flow (backend, frontend, infrastructure, docs)
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
# Team Settings
|
||||
|
||||
## User Perspective
|
||||
The Settings page (`/settings`) covers:
|
||||
- **Team members**: view, invite, change role, remove
|
||||
- **Connected channels**: view connected YouTube channels
|
||||
- **Render settings** (ADMIN+):
|
||||
- Date format for date tokens (`{video.scheduledAt}`, `{video.recordingDate}`)
|
||||
- Timezone
|
||||
- Publishing schedule (weekly time slots for the "Next free slot" feature in the video editor)
|
||||
- Show Canva link in video editor (for teams that use Canva for thumbnails)
|
||||
- Disabled lint rules
|
||||
- Show deleted videos in video list
|
||||
- **Remote conflict detection** (ADMIN+):
|
||||
- Enable scheduled conflict detection (opt-in per team)
|
||||
- Videos per run (batch size)
|
||||
- Only check videos older than N days
|
||||
|
||||
## Developer Perspective
|
||||
|
||||
### Team Settings Fields
|
||||
| Field | Type | Description |
|
||||
|---|---|---|
|
||||
| `dateFormat` | `String?` | strftime-like format for date tokens |
|
||||
| `timezone` | `String` | IANA timezone string, default "UTC" |
|
||||
| `publishingSchedule` | `Json?` | Array of weekly time slots |
|
||||
| `showCanvaLink` | `Boolean` | Shows Canva search link in video editor |
|
||||
| `disabledLintRules` | `String[]` | Rule codes excluded from lint runs |
|
||||
| `showDeletedVideos` | `Boolean` | Shows the Deleted tab in video list |
|
||||
| `conflictDetectionEnabled` | `Boolean` | Opt-in for the scheduled remote-conflict sweep (default `false`) |
|
||||
| `conflictDetectionBatchSize` | `Int` | Max videos checked per run (1–500, default 50) |
|
||||
| `conflictDetectionMinAgeDays` | `Int` | Skip videos whose `lastSyncedAt` is within N days (≥0, default 7) |
|
||||
|
||||
### Disabling Lint Rules (Side Effect)
|
||||
When `disabledLintRules` is updated via `PATCH /teams/:teamId/settings`:
|
||||
1. All unresolved `LintResult` rows for the newly disabled rules are deleted
|
||||
2. `Video.lintStatus` is recomputed for all affected videos
|
||||
|
||||
### Publishing Schedule
|
||||
Used by the "Next free slot" button in the video editor's Basic Info section. The schedule defines which days/times are available for publishing. `GET /teams/:teamId/next-publish-slot?channelId=` returns the next available ISO datetime.
|
||||
|
||||
The slot-finder walks candidate slots day by day and checks whether any existing `scheduledAt` on the channel falls within the **collision window**. Two hardcoded constants govern this behavior (`teams.service.ts`):
|
||||
|
||||
| Constant | Value | Effect |
|
||||
|---|---|---|
|
||||
| Collision window | ±30 minutes | A slot is considered taken if any video on that channel is already scheduled within 30 minutes either side of it |
|
||||
| Lookahead limit | 90 days | If no free slot is found within 90 days, the endpoint returns `{ slot: null }` |
|
||||
|
||||
These values are not configurable per-team. The 30-minute collision window means teams that publish multiple videos per day with closely spaced slots may find legitimate adjacent slots blocked if a video is already scheduled in between. See the backlog.
|
||||
|
||||
### Remote Conflict Detection Settings
|
||||
The three `conflictDetection*` fields control the per-team share of the global sweep queued by `ConflictDetectionScheduler`. The sweep itself only runs if the operator has set `CONFLICT_DETECTION_ENABLED=true` on the worker (see [[02 - Environment Variables]]) — the team toggle alone does nothing without it. Validation in `TeamsService.updateSettings` enforces `1 ≤ batchSize ≤ 500` and `minAgeDays ≥ 0`. See [[05 - Queue System]] for how the processor uses these values, and [[02 - Videos API]] for how detected conflicts are resolved (`POST /videos/:id/accept-remote` vs `POST /videos/:id/sync`).
|
||||
|
||||
## Related
|
||||
- [[09 - Teams API]]
|
||||
- [[03 - Metadata Linting]]
|
||||
Reference in New Issue
Block a user