# ozencb/couchtube architecture

> Architecture diagram of the GitHub repository ozencb/couchtube, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-09). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/ozencb/couchtube
- Repository: https://github.com/ozencb/couchtube

## Overview

CouchTube serves a browser-based, scheduled YouTube channel experience and an optional channel editor. The main playback path loads channels, requests the video scheduled for the current time, and plays its configured section; editor and custom-list flows manage the same channel data. The graph follows the sampled route wiring and service/repository calls. README-described capabilities are retained where implementation excerpts are incomplete; those documentation-based links are labeled accordingly.

Main entry points: [`cmd/main.go`](https://github.com/ozencb/couchtube/blob/main/cmd/main.go) (HTTP server), [`static/script.js`](https://github.com/ozencb/couchtube/blob/main/static/script.js) (Playback UI), [`services/media.go`](https://github.com/ozencb/couchtube/blob/main/services/media.go) (Playback and lists), [`handlers/media.go`](https://github.com/ozencb/couchtube/blob/main/handlers/media.go) (Media API)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_runtime["Server runtime"]
  node_server["HTTP server<br/>[main.go]"]
  node_media_api["Media API<br/>[media.go]"]
  node_config_api["Config endpoint<br/>[config.go]"]
  node_json_models["Channel JSON models<br/>[media.go]"]
end

subgraph group_playback["Channel playback"]
  node_browser["Playback UI<br/>[script.js]"]
  node_youtube["YouTube player"]
  node_media_service["Playback and lists<br/>[media.go]"]
end

subgraph group_editor["Channel editor"]
  node_editor_api["Editor API<br/>[editor.go]"]
  node_editor_ui["Editor UI<br/>[editor.js]"]
  node_editor_service["Editor operations<br/>[editor.go]"]
  node_playlist["Playlist importer<br/>[editor.go]"]
  node_editor_guard["Editor access guard<br/>[editor-guard.go]"]
end

subgraph group_data["Persistence"]
  node_channel_repo["Channel repository"]
  node_video_repo["Video repository"]
  node_db_conn["SQLite connector<br/>[connector.go]"]
  node_sqlite[("SQLite database")]
  node_db_models["Database models<br/>[channel.go]"]
end

node_viewer(("Viewer"))
node_list_source(("Custom JSON source"))

node_viewer -->|"uses"| node_browser
node_browser -->|"plays video"| node_youtube
node_browser -->|"requests channels"| node_server
node_browser -->|"requests current video"| node_server
node_server -->|"routes requests"| node_media_api
node_server -->|"routes editor"| node_editor_api
node_server -->|"routes config"| node_config_api
node_server -->|"guards editor routes"| node_editor_guard
node_server -->|"opens database"| node_db_conn
node_server -->|"serves editor"| node_editor_ui
node_media_api -->|"delegates requests"| node_media_service
node_editor_api -->|"delegates operations"| node_editor_service
node_editor_ui -.->|"calls editor API"| node_server
node_media_service -->|"fetches channels"| node_channel_repo
node_media_service -->|"fetches scheduled video"| node_video_repo
node_editor_service -->|"manages channels"| node_channel_repo
node_editor_service -->|"manages videos"| node_video_repo
node_media_service -->|"replaces list data"| node_sqlite
node_editor_service -.->|"loads defaults"| node_sqlite
node_channel_repo -->|"queries channels"| node_sqlite
node_video_repo -->|"queries videos"| node_sqlite
node_db_conn -->|"opens file"| node_sqlite
node_channel_repo -->|"scans records"| node_db_models
node_video_repo -->|"scans records"| node_db_models
node_media_api -->|"decodes list request"| node_json_models
node_editor_api -->|"decodes import"| node_json_models
node_list_source -->|"submits JSON URL"| node_media_api
node_media_service -->|"fetches JSON list"| node_list_source
node_editor_api -->|"imports playlist"| node_playlist
node_playlist -->|"fetches playlist page"| node_youtube
node_browser -.->|"invalidates unavailable video"| node_media_api

click node_browser "https://github.com/ozencb/couchtube/blob/main/static/script.js"
click node_server "https://github.com/ozencb/couchtube/blob/main/cmd/main.go"
click node_media_api "https://github.com/ozencb/couchtube/blob/main/handlers/media.go"
click node_editor_api "https://github.com/ozencb/couchtube/blob/main/handlers/editor.go"
click node_editor_ui "https://github.com/ozencb/couchtube/blob/main/static/editor/editor.js"
click node_config_api "https://github.com/ozencb/couchtube/blob/main/handlers/config.go"
click node_media_service "https://github.com/ozencb/couchtube/blob/main/services/media.go"
click node_editor_service "https://github.com/ozencb/couchtube/blob/main/services/editor.go"
click node_channel_repo "https://github.com/ozencb/couchtube/blob/main/repositories/channel_repository.go"
click node_video_repo "https://github.com/ozencb/couchtube/blob/main/repositories/video_repository.go"
click node_db_conn "https://github.com/ozencb/couchtube/blob/main/db/connector.go"
click node_db_models "https://github.com/ozencb/couchtube/blob/main/models/db/channel.go"
click node_json_models "https://github.com/ozencb/couchtube/blob/main/models/json/media.go"
click node_playlist "https://github.com/ozencb/couchtube/blob/main/services/editor.go"
click node_editor_guard "https://github.com/ozencb/couchtube/blob/main/middleware/editor-guard.go"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_server,node_media_api,node_config_api,node_json_models,node_viewer toneBlue
class node_browser,node_youtube,node_media_service toneAmber
class node_editor_api,node_editor_ui,node_editor_service,node_playlist,node_editor_guard toneMint
class node_channel_repo,node_video_repo,node_db_conn,node_sqlite,node_db_models toneRose
class node_list_source toneIndigo
```

## Components

### Server runtime

- [HTTP server](https://github.com/ozencb/couchtube/blob/main/cmd/main.go): `cmd/main.go`
- [Media API](https://github.com/ozencb/couchtube/blob/main/handlers/media.go): `handlers/media.go`
- [Config endpoint](https://github.com/ozencb/couchtube/blob/main/handlers/config.go): `handlers/config.go`
- [Channel JSON models](https://github.com/ozencb/couchtube/blob/main/models/json/media.go): `models/json/media.go`

### Channel playback

- [Playback UI](https://github.com/ozencb/couchtube/blob/main/static/script.js): `static/script.js`
- **YouTube player**
- [Playback and lists](https://github.com/ozencb/couchtube/blob/main/services/media.go): `services/media.go`

### Channel editor

- [Editor API](https://github.com/ozencb/couchtube/blob/main/handlers/editor.go): `handlers/editor.go`
- [Editor UI](https://github.com/ozencb/couchtube/blob/main/static/editor/editor.js): `static/editor/editor.js`
- [Editor operations](https://github.com/ozencb/couchtube/blob/main/services/editor.go): `services/editor.go`
- [Playlist importer](https://github.com/ozencb/couchtube/blob/main/services/editor.go): `services/editor.go`
- [Editor access guard](https://github.com/ozencb/couchtube/blob/main/middleware/editor-guard.go): `middleware/editor-guard.go`

### Persistence

- [Channel repository](https://github.com/ozencb/couchtube/blob/main/repositories/channel_repository.go): `repositories/channel_repository.go`
- [Video repository](https://github.com/ozencb/couchtube/blob/main/repositories/video_repository.go): `repositories/video_repository.go`
- [SQLite connector](https://github.com/ozencb/couchtube/blob/main/db/connector.go): `db/connector.go`
- **SQLite database**
- [Database models](https://github.com/ozencb/couchtube/blob/main/models/db/channel.go): `models/db/channel.go`

### Other components

- **Viewer**
- **Custom JSON source**

## Connections

- Viewer → Playback UI: uses (evidence: `README.md`)
- Playback UI → YouTube player: plays video (evidence: `static/script.js`)
- Playback UI → HTTP server: requests channels (evidence: `static/script.js`)
- Playback UI → HTTP server: requests current video (evidence: `static/script.js`)
- HTTP server → Media API: routes requests (evidence: `cmd/main.go`)
- HTTP server → Editor API: routes editor (evidence: `cmd/main.go`)
- HTTP server → Config endpoint: routes config (evidence: `cmd/main.go`)
- HTTP server → Editor access guard: guards editor routes (evidence: `cmd/main.go`)
- HTTP server → SQLite connector: opens database (evidence: `cmd/main.go`)
- HTTP server → Editor UI: serves editor (evidence: `cmd/main.go`)
- Media API → Playback and lists: delegates requests (evidence: `handlers/media.go`)
- Editor API → Editor operations: delegates operations (evidence: `handlers/editor.go`)
- Editor UI → HTTP server: calls editor API
- Playback and lists → Channel repository: fetches channels (evidence: `services/media.go`)
- Playback and lists → Video repository: fetches scheduled video (evidence: `services/media.go`)
- Editor operations → Channel repository: manages channels (evidence: `services/editor.go`)
- Editor operations → Video repository: manages videos (evidence: `services/editor.go`)
- Playback and lists → SQLite database: replaces list data (evidence: `services/media.go`)
- Editor operations → SQLite database: loads defaults
- Channel repository → SQLite database: queries channels (evidence: `repositories/channel_repository.go`)
- Video repository → SQLite database: queries videos (evidence: `repositories/video_repository.go`)
- SQLite connector → SQLite database: opens file (evidence: `db/connector.go`)
- Channel repository → Database models: scans records (evidence: `repositories/channel_repository.go`)
- Video repository → Database models: scans records (evidence: `repositories/video_repository.go`)
- Media API → Channel JSON models: decodes list request (evidence: `handlers/media.go`)
- Editor API → Channel JSON models: decodes import (evidence: `handlers/editor.go`)
- Custom JSON source → Media API: submits JSON URL (evidence: `README.md`)
- Playback and lists → Custom JSON source: fetches JSON list (evidence: `services/media.go`)
- Editor API → Playlist importer: imports playlist (evidence: `handlers/editor.go`)
- Playlist importer → YouTube player: fetches playlist page (evidence: `services/editor.go`)
- Playback UI → Media API: invalidates unavailable video
