# phnem/vetro architecture

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

- Interactive diagram: https://gitdiagram.com/phnem/vetro
- Repository: https://github.com/phnem/vetro

## Overview

#### Purpose and runtime
Vetro is a local-first Android media-library app for collecting anime, manga/manhwa, films, and series; tracking progress; streaming/downloading video; and reading manga. The primary runtime is Kotlin on Android API 26+, using Jetpack Compose, Koin, SQLDelight, WorkManager, Ktor/Apollo GraphQL, and Media3/ExoPlayer. The app module is `app/`; reusable network/database/design modules are `core/`.

#### Application composition and entry points
`VetroApplication` initializes application-level dependencies; `MainActivity` hosts the Compose/navigation UI. Navigation routes separate collection screens from dedicated streaming, local-player, and manga-reader activities.
- `app/src/main/java/com/example/myapplication/VetroApplication.kt`
- `app/src/main/java/com/example/myapplication/MainActivity.kt`
- `app/src/main/java/com/example/myapplication/ui/navigation/NavGraph.kt`

#### Collection core: local persistence and domain operations
The collection is authoritative locally: SQLDelight schemas store titles, airing/progress, settings, attachments, and sync state. Repository/data-source abstractions feed domain use cases for add/edit, search/import, title normalization, and settings repair/migration. UI ViewModels expose immutable state and dispatch actions through this boundary.
- `app/src/main/sqldelight/com/example/myapplication/data/local/Anime.sq`
- `app/src/main/java/com/example/myapplication/data/local/SQLDelightDatabaseFactory.kt`
- `app/src/main/java/com/example/myapplication/domain/addedit/SaveAnimeUseCase.kt`

#### Collection UI, discovery, and intelligence
Compose feature screens are organized around home/library, details, add/edit, settings, and image inspection. Recommendations derive genre affinity, scoring, and optional cover visual similarity from local collection data; stats can use cached or BYOK AI-generated explanations. AI credentials, provider routing, and Gemini client integrations remain optional.
- `app/src/main/java/com/example/myapplication/ui/home/HomeViewModel.kt`
- `app/src/main/java/com/example/myapplication/domain/recommendations/RecommendationEngine.kt`
- `app/src/main/java/com/example/myapplication/data/ai/AiLlmFallbackRouter.kt`

#### Catalog, metadata, and background enrichment
The network core integrates AniList GraphQL plus Kitsu, Shikimori, AniLibria, trace.moe, and GitHub release endpoints. Enrichment coordinates title/metadata/web-link gaps and maintenance through WorkManager, with throttling and a user-facing pause gate for interactive media work. Episode/update workers refresh persisted catalog state and trigger notifications.
- `core/network/src/main/java/com/example/myapplication/network/AniListRemoteDataSource.kt`
- `app/src/main/java/com/example/myapplication/domain/enrichment/CollectionEnrichmentCoordinator.kt`
- `app/src/main/java/com/example/myapplication/worker/AnimeUpdateWorker.kt`

#### Streaming and offline video pipeline
Details UI requests season/episode resolution, which queries and ranks provider adapters (Kodik, JutSu, AnimeGo, AniLibria, etc.) through the source engine. The stream player consumes resolved playback sources, persists episode progress, applies recovery/diagnostics policies, and supports auto-advance. Downloads use HLS segment retrieval, validation, optional FFmpeg remuxing, and background jobs; local playback separately scans device folders and resolves skip segments, including AniSkip.
- `app/src/main/java/com/example/myapplication/media/source/SourceEngine.kt`
- `app/src/main/java/com/example/myapplication/media/ui/StreamWatchViewModel.kt`
- `app/src/main/java/com/example/myapplication/media/download/MediaDownloadWorker.kt`

#### Manga acquisition and reading
A manga source engine adapts MangaDex and Remanga. Chapter discovery/page resolution feeds cache/download stores and WorkManager download execution. Reader activities/view models render paged or vertical layouts, prefetch pages, and persist reading position/preferences independently of video progress.
- `app/src/main/java/com/example/myapplication/manga/source/MangaSourceEngine.kt`
- `app/src/main/java/com/example/myapplication/manga/download/MangaDownloadWorker.kt`
- `app/src/main/java/com/example/myapplication/manga/ui/MangaReaderViewModel.kt`

#### Optional cloud synchronization boundary
Supabase sync is optional and does not replace local persistence. Coordinators synchronize collection/progress, API-key metadata, and attachments, with passphrase/crypto management and safe logging. Supabase Edge Functions mint Cloudflare R2 presigned upload/download URLs and delete remote attachments; database schema/RLS live in Supabase migrations.
- `app/src/main/java/com/example/myapplication/sync/supabase/SupabaseSyncCoordinator.kt`
- `supabase/functions/r2-presign-upload/index.ts`
- `supabase/migrations/20260625000000_initial_schema.sql`

Main entry points: [`app/src/main/java/com/example/myapplication/data/local/SQLDelightDatabaseFactory.kt`](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/data/local/SQLDelightDatabaseFactory.kt) (Local collection store), [`app/src/main/java/com/example/myapplication/media/source/SourceEngine.kt`](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/media/source/SourceEngine.kt) (Video source engine), [`app/src/main/java/com/example/myapplication/sync/supabase/SupabaseSyncCoordinator.kt`](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/sync/supabase/SupabaseSyncCoordinator.kt) (Supabase sync), [`app/src/main/java/com/example/myapplication/ui/navigation/NavGraph.kt`](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/ui/navigation/NavGraph.kt) (Navigation graph)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_android["Android app"]
  node_application["Vetro application<br/>Android bootstrap"]
  node_main_ui["Main Compose UI<br/>activity host<br/>[MainActivity.kt]"]
  node_navigation["Navigation graph<br/>Compose routes<br/>[NavGraph.kt]"]
  node_collection_ui["Collection ViewModels<br/>UI state<br/>[HomeViewModel.kt]"]
  node_collection_domain["Collection domain<br/>use cases"]
  node_local_db[("Local collection store<br/>SQLDelight")]
  node_schema["Collection schema<br/>SQLDelight schema<br/>[Anime.sq]"]
  node_recommendations["Recommendations<br/>local intelligence"]
  node_ai_router["Optional AI router<br/>BYOK provider routing"]
  node_catalog_network["Catalog network<br/>remote data sources"]
  node_source_engine["Video source engine<br/>provider resolver<br/>[SourceEngine.kt]"]
  node_stream_player["Stream player<br/>Media3 ViewModel"]
  node_manga_engine["Manga source engine<br/>chapter/page resolver"]
  node_manga_reader["Manga reader<br/>reader ViewModel"]
end

subgraph group_background["Background pipelines"]
  node_enrichment["Enrichment coordinator<br/>catalog orchestration"]
  node_update_worker["Episode update worker<br/>WorkManager worker"]
  node_video_download["Video download worker<br/>offline video pipeline"]
  node_manga_download["Manga download worker<br/>offline manga pipeline"]
end

subgraph group_cloud["Optional cloud sync"]
  node_sync_coordinator["Supabase sync<br/>optional sync coordinator"]
  node_supabase_schema[("Supabase schema and RLS<br/>cloud database schema")]
  node_r2_function{{"R2 presign function<br/>Supabase Edge Function<br/>[index.ts]"}}
end

node_application -->|"starts"| node_main_ui
node_application -->|"initializes"| node_local_db
node_main_ui -->|"hosts"| node_navigation
node_navigation -->|"routes to"| node_collection_ui
node_collection_ui -->|"dispatches actions"| node_collection_domain
node_collection_domain -->|"reads and writes"| node_local_db
node_schema -->|"defines"| node_local_db
node_collection_ui -->|"requests"| node_recommendations
node_recommendations -->|"analyzes"| node_local_db
node_ai_router -.->|"explains stats"| node_recommendations
node_enrichment -->|"queries"| node_catalog_network
node_enrichment -->|"persists gaps"| node_local_db
node_update_worker -->|"runs"| node_enrichment
node_navigation -->|"opens streaming"| node_source_engine
node_source_engine -.->|"uses provider metadata"| node_catalog_network
node_stream_player -->|"consumes resolved source"| node_source_engine
node_stream_player -->|"persists progress"| node_local_db
node_video_download -->|"downloads resolved streams"| node_source_engine
node_manga_reader -->|"resolves chapters and pages"| node_manga_engine
node_manga_reader -->|"persists reading state"| node_local_db
node_manga_download -->|"downloads pages"| node_manga_engine
node_sync_coordinator -->|"synchronizes"| node_local_db
node_sync_coordinator -.->|"syncs with"| node_supabase_schema
node_sync_coordinator -.->|"transfers attachments"| node_r2_function

click node_application "https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/VetroApplication.kt"
click node_main_ui "https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/MainActivity.kt"
click node_navigation "https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/ui/navigation/NavGraph.kt"
click node_collection_ui "https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/ui/home/HomeViewModel.kt"
click node_collection_domain "https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/domain/addedit/SaveAnimeUseCase.kt"
click node_local_db "https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/data/local/SQLDelightDatabaseFactory.kt"
click node_schema "https://github.com/phnem/vetro/blob/main/app/src/main/sqldelight/com/example/myapplication/data/local/Anime.sq"
click node_recommendations "https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/domain/recommendations/RecommendationEngine.kt"
click node_ai_router "https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/data/ai/AiLlmFallbackRouter.kt"
click node_catalog_network "https://github.com/phnem/vetro/blob/main/core/network/src/main/java/com/example/myapplication/network/AniListRemoteDataSource.kt"
click node_enrichment "https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/domain/enrichment/CollectionEnrichmentCoordinator.kt"
click node_update_worker "https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/worker/AnimeUpdateWorker.kt"
click node_source_engine "https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/media/source/SourceEngine.kt"
click node_stream_player "https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/media/ui/StreamWatchViewModel.kt"
click node_video_download "https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/media/download/MediaDownloadWorker.kt"
click node_manga_engine "https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/manga/source/MangaSourceEngine.kt"
click node_manga_download "https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/manga/download/MangaDownloadWorker.kt"
click node_manga_reader "https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/manga/ui/MangaReaderViewModel.kt"
click node_sync_coordinator "https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/sync/supabase/SupabaseSyncCoordinator.kt"
click node_supabase_schema "https://github.com/phnem/vetro/blob/main/supabase/migrations/20260625000000_initial_schema.sql"
click node_r2_function "https://github.com/phnem/vetro/blob/main/supabase/functions/r2-presign-upload/index.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_application,node_main_ui,node_navigation,node_collection_ui,node_collection_domain,node_local_db,node_schema,node_recommendations,node_ai_router,node_catalog_network,node_source_engine,node_stream_player,node_manga_engine,node_manga_reader toneBlue
class node_enrichment,node_update_worker,node_video_download,node_manga_download toneAmber
class node_sync_coordinator,node_supabase_schema,node_r2_function toneMint
```

## Components

### Android app

Local-first collection, media, and reader runtime.

- [Vetro application](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/VetroApplication.kt): Android bootstrap · `app/src/main/java/com/example/myapplication/VetroApplication.kt`
- [Main Compose UI](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/MainActivity.kt): activity host · `app/src/main/java/com/example/myapplication/MainActivity.kt`
- [Navigation graph](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/ui/navigation/NavGraph.kt): Compose routes · Routes collection screens and dedicated media activities. · `app/src/main/java/com/example/myapplication/ui/navigation/NavGraph.kt`
- [Collection ViewModels](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/ui/home/HomeViewModel.kt): UI state · Home, library, details, add/edit, and settings state. · `app/src/main/java/com/example/myapplication/ui/home/HomeViewModel.kt`
- [Collection domain](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/domain/addedit/SaveAnimeUseCase.kt): use cases · Add/edit, import, normalization, and settings repair. · `app/src/main/java/com/example/myapplication/domain/addedit/SaveAnimeUseCase.kt`
- [Local collection store](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/data/local/SQLDelightDatabaseFactory.kt): SQLDelight · Authoritative titles, progress, settings, attachments, and sync state. · `app/src/main/java/com/example/myapplication/data/local/SQLDelightDatabaseFactory.kt`
- [Collection schema](https://github.com/phnem/vetro/blob/main/app/src/main/sqldelight/com/example/myapplication/data/local/Anime.sq): SQLDelight schema · `app/src/main/sqldelight/com/example/myapplication/data/local/Anime.sq`
- [Recommendations](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/domain/recommendations/RecommendationEngine.kt): local intelligence · Genre, score, and optional cover-similarity recommendations. · `app/src/main/java/com/example/myapplication/domain/recommendations/RecommendationEngine.kt`
- [Optional AI router](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/data/ai/AiLlmFallbackRouter.kt): BYOK provider routing · Provides cached or generated stats explanations. · `app/src/main/java/com/example/myapplication/data/ai/AiLlmFallbackRouter.kt`
- [Catalog network](https://github.com/phnem/vetro/blob/main/core/network/src/main/java/com/example/myapplication/network/AniListRemoteDataSource.kt): remote data sources · AniList plus metadata, image, and release providers. · `core/network/src/main/java/com/example/myapplication/network/AniListRemoteDataSource.kt`
- [Video source engine](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/media/source/SourceEngine.kt): provider resolver · Ranks streaming providers and resolves seasons and episodes. · `app/src/main/java/com/example/myapplication/media/source/SourceEngine.kt`
- [Stream player](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/media/ui/StreamWatchViewModel.kt): Media3 ViewModel · Consumes sources, tracks progress, recovers playback, and auto-advances. · `app/src/main/java/com/example/myapplication/media/ui/StreamWatchViewModel.kt`
- [Manga source engine](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/manga/source/MangaSourceEngine.kt): chapter/page resolver · Adapts MangaDex and Remanga. · `app/src/main/java/com/example/myapplication/manga/source/MangaSourceEngine.kt`
- [Manga reader](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/manga/ui/MangaReaderViewModel.kt): reader ViewModel · Renders pages, prefetches, and persists reader position. · `app/src/main/java/com/example/myapplication/manga/ui/MangaReaderViewModel.kt`

### Background pipelines

Scheduled enrichment and offline acquisition.

- [Enrichment coordinator](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/domain/enrichment/CollectionEnrichmentCoordinator.kt): catalog orchestration · Fills metadata and link gaps with throttling and pause controls. · `app/src/main/java/com/example/myapplication/domain/enrichment/CollectionEnrichmentCoordinator.kt`
- [Episode update worker](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/worker/AnimeUpdateWorker.kt): WorkManager worker · Refreshes catalog state and triggers notifications. · `app/src/main/java/com/example/myapplication/worker/AnimeUpdateWorker.kt`
- [Video download worker](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/media/download/MediaDownloadWorker.kt): offline video pipeline · Retrieves and validates HLS segments with optional remuxing. · `app/src/main/java/com/example/myapplication/media/download/MediaDownloadWorker.kt`
- [Manga download worker](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/manga/download/MangaDownloadWorker.kt): offline manga pipeline · Caches chapter pages in background. · `app/src/main/java/com/example/myapplication/manga/download/MangaDownloadWorker.kt`

### Optional cloud sync

Sync augments but does not replace local data.

- [Supabase sync](https://github.com/phnem/vetro/blob/main/app/src/main/java/com/example/myapplication/sync/supabase/SupabaseSyncCoordinator.kt): optional sync coordinator · Synchronizes collection, progress, key metadata, and attachments. · `app/src/main/java/com/example/myapplication/sync/supabase/SupabaseSyncCoordinator.kt`
- [Supabase schema and RLS](https://github.com/phnem/vetro/blob/main/supabase/migrations/20260625000000_initial_schema.sql): cloud database schema · `supabase/migrations/20260625000000_initial_schema.sql`
- [R2 presign function](https://github.com/phnem/vetro/blob/main/supabase/functions/r2-presign-upload/index.ts): Supabase Edge Function · Mints attachment transfer URLs and deletes remote attachments. · `supabase/functions/r2-presign-upload/index.ts`

## Connections

- Vetro application → Main Compose UI: starts
- Vetro application → Local collection store: initializes
- Main Compose UI → Navigation graph: hosts
- Navigation graph → Collection ViewModels: routes to
- Collection ViewModels → Collection domain: dispatches actions
- Collection domain → Local collection store: reads and writes
- Collection schema → Local collection store: defines
- Collection ViewModels → Recommendations: requests
- Recommendations → Local collection store: analyzes
- Optional AI router → Recommendations: explains stats
- Enrichment coordinator → Catalog network: queries
- Enrichment coordinator → Local collection store: persists gaps
- Episode update worker → Enrichment coordinator: runs
- Navigation graph → Video source engine: opens streaming
- Video source engine → Catalog network: uses provider metadata
- Stream player → Video source engine: consumes resolved source
- Stream player → Local collection store: persists progress
- Video download worker → Video source engine: downloads resolved streams
- Manga reader → Manga source engine: resolves chapters and pages
- Manga reader → Local collection store: persists reading state
- Manga download worker → Manga source engine: downloads pages
- Supabase sync → Local collection store: synchronizes
- Supabase sync → Supabase schema and RLS: syncs with
- Supabase sync → R2 presign function: transfers attachments
