# fed-republic/tv-board architecture

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

- Interactive diagram: https://gitdiagram.com/fed-republic/tv-board
- Repository: https://github.com/fed-republic/tv-board

## Overview

TV Board is a Vue app for browsing TVmaze shows by genre, with rating-sorted dashboard rows as its main workflow. Readers can expand a genre, search the live API, open show details, and view bookmarked or liked shows; genre and search filters are shareable through the URL. The README documents index paging, session caching, device-local saved IDs, and theme preferences. The graph follows documented architecture and capabilities; some page-to-store wiring is inferred from that documentation because those source files were not sampled.

Main entry points: [`src/router/index.ts`](https://github.com/fed-republic/tv-board/blob/main/src/router/index.ts) (Router), [`src/stores/shows.ts`](https://github.com/fed-republic/tv-board/blob/main/src/stores/shows.ts) (Show index store), [`src/services/tvmaze/endpoints.ts`](https://github.com/fed-republic/tv-board/blob/main/src/services/tvmaze/endpoints.ts) (TVmaze endpoints), [`src/pages/HomePage.vue`](https://github.com/fed-republic/tv-board/blob/main/src/pages/HomePage.vue) (Genre dashboard)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_navigation["App navigation"]
  node_router["Router<br/>[index.ts]"]
  node_app["App shell<br/>[App.vue]"]
end

subgraph group_discovery["Show discovery"]
  node_home["Genre dashboard<br/>[HomePage.vue]"]
  node_searchpage["Search page<br/>[SearchPage.vue]"]
  node_detailpage["Show detail<br/>[ShowDetailPage.vue]"]
  node_savedpage["Saved shows<br/>[SavedShowsPage.vue]"]
  node_showrows["Genre rows<br/>[GenreRow.vue]"]
  node_searchfield["Search field<br/>[SearchField.vue]"]
end

subgraph group_state["Shared state"]
  node_searchquery["Search URL state<br/>[useSearchQuery.ts]"]
  node_searchresults["Search results"]
  node_genreview["Genre view<br/>[useGenreView.ts]"]
  node_genrefilter["Genre filter<br/>[useGenreFilter.ts]"]
  node_showsstore["Show index store<br/>[shows.ts]"]
  node_savedstore["Saved IDs store<br/>[saved.ts]"]
  node_theme["Theme preference<br/>[useTheme.ts]"]
end

subgraph group_integration["API and persistence"]
  node_endpoints["TVmaze endpoints<br/>[endpoints.ts]"]
  node_http["HTTP client<br/>[client.ts]"]
  node_mapper["Response mapping<br/>[mappers.ts]"]
  node_indexcache["Index cache<br/>[shows-cache.ts]"]
end

node_reader(("Reader"))
node_tvmaze["TVmaze API"]
node_sessionstorage[("sessionStorage")]
node_localstorage[("localStorage")]

node_reader -->|"navigates"| node_router
node_router -->|"dispatches"| node_home
node_router -->|"dispatches"| node_searchpage
node_router -->|"dispatches"| node_detailpage
node_router -->|"dispatches"| node_savedpage
node_app -->|"renders routes"| node_router
node_home -->|"loads index"| node_showsstore
node_home -->|"renders rows"| node_showrows
node_showrows -->|"expands genre"| node_genreview
node_genreview -->|"updates query"| node_router
node_searchfield -->|"sets query"| node_searchquery
node_searchquery -->|"writes URL"| node_router
node_searchpage -->|"requests results"| node_searchresults
node_searchresults -->|"searches shows"| node_endpoints
node_searchresults -->|"narrows results"| node_genrefilter
node_showsstore -->|"loads index"| node_endpoints
node_endpoints -->|"requests JSON"| node_http
node_http -->|"fetches data"| node_tvmaze
node_endpoints -->|"maps responses"| node_mapper
node_showsstore -->|"caches index"| node_indexcache
node_indexcache -->|"reads and writes"| node_sessionstorage
node_savedpage -->|"loads saved IDs"| node_savedstore
node_savedpage -->|"resolves shows"| node_showsstore
node_savedstore -->|"reads and writes"| node_localstorage
node_app -->|"provides theme"| node_theme

click node_router "https://github.com/fed-republic/tv-board/blob/main/src/router/index.ts"
click node_app "https://github.com/fed-republic/tv-board/blob/main/src/App.vue"
click node_home "https://github.com/fed-republic/tv-board/blob/main/src/pages/HomePage.vue"
click node_searchpage "https://github.com/fed-republic/tv-board/blob/main/src/pages/SearchPage.vue"
click node_detailpage "https://github.com/fed-republic/tv-board/blob/main/src/pages/ShowDetailPage.vue"
click node_savedpage "https://github.com/fed-republic/tv-board/blob/main/src/pages/SavedShowsPage.vue"
click node_showrows "https://github.com/fed-republic/tv-board/blob/main/src/components/show/GenreRow.vue"
click node_searchfield "https://github.com/fed-republic/tv-board/blob/main/src/components/search/SearchField.vue"
click node_searchquery "https://github.com/fed-republic/tv-board/blob/main/src/composables/useSearchQuery.ts"
click node_searchresults "https://github.com/fed-republic/tv-board/blob/main/src/composables/useSearchResults.ts"
click node_genreview "https://github.com/fed-republic/tv-board/blob/main/src/composables/useGenreView.ts"
click node_genrefilter "https://github.com/fed-republic/tv-board/blob/main/src/composables/useGenreFilter.ts"
click node_showsstore "https://github.com/fed-republic/tv-board/blob/main/src/stores/shows.ts"
click node_savedstore "https://github.com/fed-republic/tv-board/blob/main/src/stores/saved.ts"
click node_endpoints "https://github.com/fed-republic/tv-board/blob/main/src/services/tvmaze/endpoints.ts"
click node_http "https://github.com/fed-republic/tv-board/blob/main/src/services/http/client.ts"
click node_mapper "https://github.com/fed-republic/tv-board/blob/main/src/services/tvmaze/mappers.ts"
click node_indexcache "https://github.com/fed-republic/tv-board/blob/main/src/stores/shows-cache.ts"
click node_theme "https://github.com/fed-republic/tv-board/blob/main/src/composables/useTheme.ts"

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_router,node_app toneBlue
class node_home,node_searchpage,node_detailpage,node_savedpage,node_showrows,node_searchfield,node_sessionstorage,node_localstorage toneAmber
class node_searchquery,node_searchresults,node_genreview,node_genrefilter,node_showsstore,node_savedstore,node_theme,node_tvmaze toneMint
class node_endpoints,node_http,node_mapper,node_indexcache toneRose
class node_reader toneIndigo
```

## Components

### App navigation

- [Router](https://github.com/fed-republic/tv-board/blob/main/src/router/index.ts): `src/router/index.ts`
- [App shell](https://github.com/fed-republic/tv-board/blob/main/src/App.vue): `src/App.vue`

### Show discovery

- [Genre dashboard](https://github.com/fed-republic/tv-board/blob/main/src/pages/HomePage.vue): `src/pages/HomePage.vue`
- [Search page](https://github.com/fed-republic/tv-board/blob/main/src/pages/SearchPage.vue): `src/pages/SearchPage.vue`
- [Show detail](https://github.com/fed-republic/tv-board/blob/main/src/pages/ShowDetailPage.vue): `src/pages/ShowDetailPage.vue`
- [Saved shows](https://github.com/fed-republic/tv-board/blob/main/src/pages/SavedShowsPage.vue): `src/pages/SavedShowsPage.vue`
- [Genre rows](https://github.com/fed-republic/tv-board/blob/main/src/components/show/GenreRow.vue): `src/components/show/GenreRow.vue`
- [Search field](https://github.com/fed-republic/tv-board/blob/main/src/components/search/SearchField.vue): `src/components/search/SearchField.vue`

### Shared state

- [Search URL state](https://github.com/fed-republic/tv-board/blob/main/src/composables/useSearchQuery.ts): `src/composables/useSearchQuery.ts`
- [Search results](https://github.com/fed-republic/tv-board/blob/main/src/composables/useSearchResults.ts): `src/composables/useSearchResults.ts`
- [Genre view](https://github.com/fed-republic/tv-board/blob/main/src/composables/useGenreView.ts): `src/composables/useGenreView.ts`
- [Genre filter](https://github.com/fed-republic/tv-board/blob/main/src/composables/useGenreFilter.ts): `src/composables/useGenreFilter.ts`
- [Show index store](https://github.com/fed-republic/tv-board/blob/main/src/stores/shows.ts): `src/stores/shows.ts`
- [Saved IDs store](https://github.com/fed-republic/tv-board/blob/main/src/stores/saved.ts): `src/stores/saved.ts`
- [Theme preference](https://github.com/fed-republic/tv-board/blob/main/src/composables/useTheme.ts): `src/composables/useTheme.ts`

### API and persistence

- [TVmaze endpoints](https://github.com/fed-republic/tv-board/blob/main/src/services/tvmaze/endpoints.ts): `src/services/tvmaze/endpoints.ts`
- [HTTP client](https://github.com/fed-republic/tv-board/blob/main/src/services/http/client.ts): `src/services/http/client.ts`
- [Response mapping](https://github.com/fed-republic/tv-board/blob/main/src/services/tvmaze/mappers.ts): `src/services/tvmaze/mappers.ts`
- [Index cache](https://github.com/fed-republic/tv-board/blob/main/src/stores/shows-cache.ts): `src/stores/shows-cache.ts`

### Other components

- **Reader**
- **TVmaze API**
- **sessionStorage**
- **localStorage**

## Connections

- Reader → Router: navigates
- Router → Genre dashboard: dispatches
- Router → Search page: dispatches
- Router → Show detail: dispatches
- Router → Saved shows: dispatches
- App shell → Router: renders routes
- Genre dashboard → Show index store: loads index
- Genre dashboard → Genre rows: renders rows
- Genre rows → Genre view: expands genre
- Genre view → Router: updates query
- Search field → Search URL state: sets query
- Search URL state → Router: writes URL
- Search page → Search results: requests results
- Search results → TVmaze endpoints: searches shows
- Search results → Genre filter: narrows results
- Show index store → TVmaze endpoints: loads index
- TVmaze endpoints → HTTP client: requests JSON
- HTTP client → TVmaze API: fetches data
- TVmaze endpoints → Response mapping: maps responses
- Show index store → Index cache: caches index
- Index cache → sessionStorage: reads and writes
- Saved shows → Saved IDs store: loads saved IDs
- Saved shows → Show index store: resolves shows
- Saved IDs store → localStorage: reads and writes
- App shell → Theme preference: provides theme
