# avinaxhroy/tempo architecture

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

- Interactive diagram: https://gitdiagram.com/avinaxhroy/tempo
- Repository: https://github.com/avinaxhroy/tempo

## Overview

Tempo is a local-first Android music journal and scrobbler. Playback is detected from Android media sessions, filtered and recorded as listening events, then persisted locally for history, statistics, insights, and shareable visualizations. Users can also import histories, enrich track metadata, sync browser-extension plays, and back up their library. The README documents these capabilities; sampled source supports the tracking, import, enrichment, and desktop-ingestion details shown, while unsampled subsystem links are limited to documented relationships.

Main entry points: [`app/src/main/java/me/avinas/tempo/data/local/AppDatabase.kt`](https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/local/AppDatabase.kt) (Room library), [`app/src/main/java/me/avinas/tempo/MainActivity.kt`](https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/MainActivity.kt) (Android app), [`app/src/main/java/me/avinas/tempo/desktop/DesktopScrobbleIngestionService.kt`](https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/desktop/DesktopScrobbleIngestionService.kt) (Phone sync server), [`app/src/main/java/me/avinas/tempo/data/stats/StatsModels.kt`](https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/stats/StatsModels.kt) (Stats and insights)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_capture["Playback and sync"]
  node_tracking["Playback tracking"]
  node_extension["Browser companion<br/>[storage.ts]"]
  node_desktop["Phone sync server"]
end

subgraph group_library["Library and imports"]
  node_imports["History imports"]
  node_youtubeimport["YouTube imports"]
  node_spotifyhistory["Spotify history"]
  node_resolver["Track resolution<br/>[TrackResolver.kt]"]
  node_enrichment["Metadata enrichment"]
  node_librarytools["Library management"]
end

subgraph group_analysis["Insights and presentation"]
  node_appui["Android app<br/>[MainActivity.kt]"]
  node_stats["Stats and insights<br/>[StatsModels.kt]"]
  node_spotlight["Spotlight cards<br/>[SpotlightScreen.kt]"]
  node_widgets["Home widgets<br/>[TempoAppWidget.kt]"]
end

subgraph group_platform["Local data and services"]
  node_events["Listening repository"]
  node_database[("Room library<br/>[AppDatabase.kt]")]
end

subgraph group_recovery["Backup and privacy"]
  node_backup["Backup and export"]
  node_diagnostics["Privacy diagnostics"]
end

node_listener(("Listener"))
node_players(("Music players"))
node_metadataapi{{"Music metadata APIs"}}
node_drive[("Google Drive")]

node_listener -->|"uses"| node_appui
node_players -->|"play sessions"| node_tracking
node_tracking -->|"records plays"| node_events
node_events -->|"persists events"| node_database
node_appui -->|"queries history"| node_events
node_appui -->|"requests metrics"| node_stats
node_stats -->|"reads history"| node_database
node_appui -->|"opens cards"| node_spotlight
node_spotlight -->|"uses metrics"| node_stats
node_widgets -->|"shows summaries"| node_stats
node_listener -->|"selects history"| node_imports
node_imports -->|"imports plays"| node_database
node_listener -->|"selects export"| node_youtubeimport
node_youtubeimport -->|"resolves tracks"| node_resolver
node_youtubeimport -->|"stores events"| node_database
node_spotifyhistory -.->|"fetches history"| node_metadataapi
node_spotifyhistory -->|"resolves tracks"| node_resolver
node_spotifyhistory -->|"stores history"| node_database
node_enrichment -.->|"fetches metadata"| node_metadataapi
node_enrichment -->|"updates metadata"| node_database
node_appui -->|"manages library"| node_librarytools
node_librarytools -->|"updates records"| node_database
node_extension -->|"queues plays"| node_extension
node_extension -->|"syncs plays"| node_desktop
node_desktop -->|"resolves tracks"| node_resolver
node_desktop -->|"records plays"| node_events
node_desktop -->|"stores tracks"| node_database
node_appui -->|"starts backup"| node_backup
node_backup -->|"exports library"| node_database
node_backup -.->|"uploads backup"| node_drive
node_appui -->|"shares report"| node_diagnostics

click node_tracking "https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/service/MusicTrackingService.kt"
click node_events "https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/repository/ListeningRepository.kt"
click node_database "https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/local/AppDatabase.kt"
click node_appui "https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/MainActivity.kt"
click node_stats "https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/stats/StatsModels.kt"
click node_spotlight "https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/ui/spotlight/SpotlightScreen.kt"
click node_widgets "https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/widget/TempoAppWidget.kt"
click node_imports "https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/lastfm/LastFmImportService.kt"
click node_youtubeimport "https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/youtube/YouTubeMusicImportService.kt"
click node_spotifyhistory "https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/spotify/SpotifyHistoryReconstructionService.kt"
click node_resolver "https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/repository/TrackResolver.kt"
click node_enrichment "https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/enrichment/SpotifyEnrichmentService.kt"
click node_librarytools "https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/repository/ArtistMergeRepository.kt"
click node_extension "https://github.com/avinaxhroy/tempo/blob/main/browser-extension/src/background/storage.ts"
click node_desktop "https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/desktop/DesktopScrobbleIngestionService.kt"
click node_backup "https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/drive/GoogleDriveService.kt"
click node_diagnostics "https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/diagnostics/DiagnosticsReport.kt"

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_tracking,node_extension,node_desktop toneBlue
class node_imports,node_youtubeimport,node_spotifyhistory,node_resolver,node_enrichment,node_librarytools,node_drive toneAmber
class node_appui,node_stats,node_spotlight,node_widgets,node_metadataapi toneMint
class node_events,node_database toneRose
class node_backup,node_diagnostics,node_listener,node_players toneIndigo
```

## Components

### Playback and sync

- [Playback tracking](https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/service/MusicTrackingService.kt): `app/src/main/java/me/avinas/tempo/service/MusicTrackingService.kt`
- [Browser companion](https://github.com/avinaxhroy/tempo/blob/main/browser-extension/src/background/storage.ts): `browser-extension/src/background/storage.ts`
- [Phone sync server](https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/desktop/DesktopScrobbleIngestionService.kt): `app/src/main/java/me/avinas/tempo/desktop/DesktopScrobbleIngestionService.kt`

### Library and imports

- [History imports](https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/lastfm/LastFmImportService.kt): `app/src/main/java/me/avinas/tempo/data/lastfm/LastFmImportService.kt`
- [YouTube imports](https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/youtube/YouTubeMusicImportService.kt): `app/src/main/java/me/avinas/tempo/data/youtube/YouTubeMusicImportService.kt`
- [Spotify history](https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/spotify/SpotifyHistoryReconstructionService.kt): `app/src/main/java/me/avinas/tempo/data/spotify/SpotifyHistoryReconstructionService.kt`
- [Track resolution](https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/repository/TrackResolver.kt): `app/src/main/java/me/avinas/tempo/data/repository/TrackResolver.kt`
- [Metadata enrichment](https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/enrichment/SpotifyEnrichmentService.kt): `app/src/main/java/me/avinas/tempo/data/enrichment/SpotifyEnrichmentService.kt`
- [Library management](https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/repository/ArtistMergeRepository.kt): `app/src/main/java/me/avinas/tempo/data/repository/ArtistMergeRepository.kt`

### Insights and presentation

- [Android app](https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/MainActivity.kt): `app/src/main/java/me/avinas/tempo/MainActivity.kt`
- [Stats and insights](https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/stats/StatsModels.kt): `app/src/main/java/me/avinas/tempo/data/stats/StatsModels.kt`
- [Spotlight cards](https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/ui/spotlight/SpotlightScreen.kt): `app/src/main/java/me/avinas/tempo/ui/spotlight/SpotlightScreen.kt`
- [Home widgets](https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/widget/TempoAppWidget.kt): `app/src/main/java/me/avinas/tempo/widget/TempoAppWidget.kt`

### Local data and services

- [Listening repository](https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/repository/ListeningRepository.kt): `app/src/main/java/me/avinas/tempo/data/repository/ListeningRepository.kt`
- [Room library](https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/local/AppDatabase.kt): `app/src/main/java/me/avinas/tempo/data/local/AppDatabase.kt`

### Backup and privacy

- [Backup and export](https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/drive/GoogleDriveService.kt): `app/src/main/java/me/avinas/tempo/data/drive/GoogleDriveService.kt`
- [Privacy diagnostics](https://github.com/avinaxhroy/tempo/blob/main/app/src/main/java/me/avinas/tempo/data/diagnostics/DiagnosticsReport.kt): `app/src/main/java/me/avinas/tempo/data/diagnostics/DiagnosticsReport.kt`

### Other components

- **Listener**
- **Music players**
- **Music metadata APIs**
- **Google Drive**

## Connections

- Listener → Android app: uses
- Music players → Playback tracking: play sessions
- Playback tracking → Listening repository: records plays
- Listening repository → Room library: persists events
- Android app → Listening repository: queries history
- Android app → Stats and insights: requests metrics
- Stats and insights → Room library: reads history
- Android app → Spotlight cards: opens cards
- Spotlight cards → Stats and insights: uses metrics
- Home widgets → Stats and insights: shows summaries
- Listener → History imports: selects history
- History imports → Room library: imports plays
- Listener → YouTube imports: selects export
- YouTube imports → Track resolution: resolves tracks
- YouTube imports → Room library: stores events
- Spotify history → Music metadata APIs: fetches history
- Spotify history → Track resolution: resolves tracks
- Spotify history → Room library: stores history
- Metadata enrichment → Music metadata APIs: fetches metadata
- Metadata enrichment → Room library: updates metadata
- Android app → Library management: manages library
- Library management → Room library: updates records
- Browser companion → Browser companion: queues plays
- Browser companion → Phone sync server: syncs plays
- Phone sync server → Track resolution: resolves tracks
- Phone sync server → Listening repository: records plays
- Phone sync server → Room library: stores tracks
- Android app → Backup and export: starts backup
- Backup and export → Room library: exports library
- Backup and export → Google Drive: uploads backup
- Android app → Privacy diagnostics: shares report
