57 lines
3.5 KiB
Markdown
57 lines
3.5 KiB
Markdown
# 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]]
|