# joejamal029/playlist-haven architecture

> Architecture diagram of the GitHub repository joejamal029/playlist-haven, 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/joejamal029/playlist-haven
- Repository: https://github.com/joejamal029/playlist-haven

## Overview

Playlist Haven is a browser-based music-curation workspace for organizing playlists, processing discovery intake, and shaping a long-term listening library. Users enter through the dashboard and select focused tools; the documented lifecycle moves from discovery and playlist comparison into triage, language grouping, metadata repair, and resequencing, then into listening-history-driven Sonic Sieve rotations. Other tools support acoustic analysis, consensus gathering, and visual playlist creation. The README documents capabilities beyond the sampled source, so those are shown as product modules without speculative wiring; edges reflect only visible dispatches and sampled service calls.

Main entry points: [`App.tsx`](https://github.com/joejamal029/playlist-haven/blob/main/App.tsx) (Dashboard), [`services/triageEngine.ts`](https://github.com/joejamal029/playlist-haven/blob/main/services/triageEngine.ts) (Triage engine), [`services/metadataEnrichmentEngine.ts`](https://github.com/joejamal029/playlist-haven/blob/main/services/metadataEnrichmentEngine.ts) (Metadata enrichment), [`services/classificationEngine.ts`](https://github.com/joejamal029/playlist-haven/blob/main/services/classificationEngine.ts) (Classification engine)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_workspace["Workspace"]
  node_app["Dashboard<br/>[App.tsx]"]
end

subgraph group_discovery["Discovery"]
  node_manipulator["Playlist manipulator"]
  node_matcher["Playlist matcher"]
  node_merger["Playlist merger"]
  node_splitter["Playlist splitter"]
  node_randomizer["Playlist randomizer"]
  node_appearance["Appearance tools"]
  node_scraper["Scrape stripper"]
  node_vision["Vision to playlist"]
  node_consensus["Consensus aggregator"]
  node_consensus_engine["Consensus engine<br/>[consensusEngine.ts]"]
  node_vision_engine["AI and vision service<br/>[visionEngine.ts]"]
end

subgraph group_ingestion["Ingestion"]
  node_triage_view["Discovery triage"]
  node_triage_engine["Triage engine<br/>[triageEngine.ts]"]
  node_clustering["Language clustering"]
  node_classification["Classification engine"]
  node_area_dictionary["Area dictionary<br/>[areaDictionary.ts]"]
  node_enrichment_view["Deep enrichment"]
  node_enrichment_engine["Metadata enrichment"]
  node_metadata_db[("Metadata store<br/>[metadataDb.ts]")]
  node_resequencer_view["Playlist resequencer"]
  node_resequencer["Resequencer engine"]
end

subgraph group_experience["Experience and analysis"]
  node_sieve_view["Sonic Sieve<br/>[SonicSieveView.tsx]"]
  node_sieve_worker["Sieve worker<br/>[sieve.worker.ts]"]
  node_audimote_view["Audimote<br/>[AudimoteView.tsx]"]
  node_audimote_engine["Audimote engine<br/>[audimoteEngine.ts]"]
  node_audimote_worker["Audio analysis worker<br/>[audimote.worker.ts]"]
  node_audio_context["Audio preview context"]
  node_itunes["iTunes API service<br/>[itunesApi.ts]"]
  node_sieve_engine["Sieve engine<br/>[sieveEngine.ts]"]
end

node_curator(("Curator"))

node_curator -->|"opens"| node_app
node_app -->|"dispatches"| node_sieve_view
node_app -->|"dispatches"| node_merger
node_app -->|"dispatches"| node_splitter
node_app -->|"dispatches"| node_randomizer
node_app -->|"dispatches"| node_matcher
node_app -->|"dispatches"| node_scraper
node_app -->|"dispatches"| node_clustering
node_app -->|"dispatches"| node_triage_view
node_triage_engine -->|"reads and initializes"| node_classification
node_triage_engine -->|"resolves and saves"| node_metadata_db
node_triage_engine -->|"reads config"| node_vision_engine
node_triage_engine -->|"classifies"| node_classification
node_triage_engine --> node_resequencer
node_enrichment_engine -->|"reads cache"| node_metadata_db
node_enrichment_engine -->|"reads cache"| node_classification
node_enrichment_engine -->|"reads config"| node_vision_engine
node_enrichment_engine -->|"supplements tracks"| node_itunes
node_classification -->|"resolves areas"| node_area_dictionary
node_resequencer -->|"parses and normalizes"| node_triage_engine
node_consensus_engine -->|"uses AI services"| node_vision_engine
node_sieve_worker -->|"uses processing helpers"| node_sieve_engine
node_audimote_engine -->|"sends audio data"| node_audimote_worker
node_audimote_engine -->|"loads and saves profiles"| node_metadata_db
node_audimote_engine -->|"resolves previews"| node_itunes
node_audio_context -->|"resolves previews"| node_itunes

click node_app "https://github.com/joejamal029/playlist-haven/blob/main/App.tsx"
click node_manipulator "https://github.com/joejamal029/playlist-haven/blob/main/views/PlaylistManipulatorView.tsx"
click node_matcher "https://github.com/joejamal029/playlist-haven/blob/main/views/PlaylistMatcherView.tsx"
click node_merger "https://github.com/joejamal029/playlist-haven/blob/main/views/PlaylistMergerView.tsx"
click node_splitter "https://github.com/joejamal029/playlist-haven/blob/main/views/PlaylistSplitterView.tsx"
click node_randomizer "https://github.com/joejamal029/playlist-haven/blob/main/views/PlaylistRandomizerView.tsx"
click node_appearance "https://github.com/joejamal029/playlist-haven/blob/main/views/PlaylistAppearanceView.tsx"
click node_scraper "https://github.com/joejamal029/playlist-haven/blob/main/views/ScrapeStripperView.tsx"
click node_vision "https://github.com/joejamal029/playlist-haven/blob/main/views/VisionToPlaylistView.tsx"
click node_consensus "https://github.com/joejamal029/playlist-haven/blob/main/views/ConsensusAggregatorView.tsx"
click node_consensus_engine "https://github.com/joejamal029/playlist-haven/blob/main/services/consensusEngine.ts"
click node_vision_engine "https://github.com/joejamal029/playlist-haven/blob/main/services/visionEngine.ts"
click node_triage_view "https://github.com/joejamal029/playlist-haven/blob/main/views/DiscoveryTriageView.tsx"
click node_triage_engine "https://github.com/joejamal029/playlist-haven/blob/main/services/triageEngine.ts"
click node_clustering "https://github.com/joejamal029/playlist-haven/blob/main/views/LanguageClusteringView.tsx"
click node_classification "https://github.com/joejamal029/playlist-haven/blob/main/services/classificationEngine.ts"
click node_area_dictionary "https://github.com/joejamal029/playlist-haven/blob/main/services/areaDictionary.ts"
click node_enrichment_view "https://github.com/joejamal029/playlist-haven/blob/main/views/DeepMetadataEnrichmentView.tsx"
click node_enrichment_engine "https://github.com/joejamal029/playlist-haven/blob/main/services/metadataEnrichmentEngine.ts"
click node_metadata_db "https://github.com/joejamal029/playlist-haven/blob/main/services/metadataDb.ts"
click node_resequencer_view "https://github.com/joejamal029/playlist-haven/blob/main/views/PlaylistResequencerView.tsx"
click node_resequencer "https://github.com/joejamal029/playlist-haven/blob/main/services/resequencerEngine.ts"
click node_sieve_view "https://github.com/joejamal029/playlist-haven/blob/main/views/SonicSieveView.tsx"
click node_sieve_worker "https://github.com/joejamal029/playlist-haven/blob/main/sieve.worker.ts"
click node_audimote_view "https://github.com/joejamal029/playlist-haven/blob/main/views/AudimoteView.tsx"
click node_audimote_engine "https://github.com/joejamal029/playlist-haven/blob/main/services/audimoteEngine.ts"
click node_audimote_worker "https://github.com/joejamal029/playlist-haven/blob/main/workers/audimote.worker.ts"
click node_audio_context "https://github.com/joejamal029/playlist-haven/blob/main/components/AudioPreviewContext.tsx"
click node_itunes "https://github.com/joejamal029/playlist-haven/blob/main/services/itunesApi.ts"
click node_sieve_engine "https://github.com/joejamal029/playlist-haven/blob/main/services/sieveEngine.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_app toneBlue
class node_manipulator,node_matcher,node_merger,node_splitter,node_randomizer,node_appearance,node_scraper,node_vision,node_consensus,node_consensus_engine,node_vision_engine toneAmber
class node_triage_view,node_triage_engine,node_clustering,node_classification,node_area_dictionary,node_enrichment_view,node_enrichment_engine,node_metadata_db,node_resequencer_view,node_resequencer toneMint
class node_sieve_view,node_sieve_worker,node_audimote_view,node_audimote_engine,node_audimote_worker,node_audio_context,node_itunes,node_sieve_engine toneRose
class node_curator toneIndigo
```

## Components

### Workspace

- [Dashboard](https://github.com/joejamal029/playlist-haven/blob/main/App.tsx): `App.tsx`

### Discovery

- [Playlist manipulator](https://github.com/joejamal029/playlist-haven/blob/main/views/PlaylistManipulatorView.tsx): `views/PlaylistManipulatorView.tsx`
- [Playlist matcher](https://github.com/joejamal029/playlist-haven/blob/main/views/PlaylistMatcherView.tsx): `views/PlaylistMatcherView.tsx`
- [Playlist merger](https://github.com/joejamal029/playlist-haven/blob/main/views/PlaylistMergerView.tsx): `views/PlaylistMergerView.tsx`
- [Playlist splitter](https://github.com/joejamal029/playlist-haven/blob/main/views/PlaylistSplitterView.tsx): `views/PlaylistSplitterView.tsx`
- [Playlist randomizer](https://github.com/joejamal029/playlist-haven/blob/main/views/PlaylistRandomizerView.tsx): `views/PlaylistRandomizerView.tsx`
- [Appearance tools](https://github.com/joejamal029/playlist-haven/blob/main/views/PlaylistAppearanceView.tsx): `views/PlaylistAppearanceView.tsx`
- [Scrape stripper](https://github.com/joejamal029/playlist-haven/blob/main/views/ScrapeStripperView.tsx): `views/ScrapeStripperView.tsx`
- [Vision to playlist](https://github.com/joejamal029/playlist-haven/blob/main/views/VisionToPlaylistView.tsx): `views/VisionToPlaylistView.tsx`
- [Consensus aggregator](https://github.com/joejamal029/playlist-haven/blob/main/views/ConsensusAggregatorView.tsx): `views/ConsensusAggregatorView.tsx`
- [Consensus engine](https://github.com/joejamal029/playlist-haven/blob/main/services/consensusEngine.ts): `services/consensusEngine.ts`
- [AI and vision service](https://github.com/joejamal029/playlist-haven/blob/main/services/visionEngine.ts): `services/visionEngine.ts`

### Ingestion

- [Discovery triage](https://github.com/joejamal029/playlist-haven/blob/main/views/DiscoveryTriageView.tsx): `views/DiscoveryTriageView.tsx`
- [Triage engine](https://github.com/joejamal029/playlist-haven/blob/main/services/triageEngine.ts): `services/triageEngine.ts`
- [Language clustering](https://github.com/joejamal029/playlist-haven/blob/main/views/LanguageClusteringView.tsx): `views/LanguageClusteringView.tsx`
- [Classification engine](https://github.com/joejamal029/playlist-haven/blob/main/services/classificationEngine.ts): `services/classificationEngine.ts`
- [Area dictionary](https://github.com/joejamal029/playlist-haven/blob/main/services/areaDictionary.ts): `services/areaDictionary.ts`
- [Deep enrichment](https://github.com/joejamal029/playlist-haven/blob/main/views/DeepMetadataEnrichmentView.tsx): `views/DeepMetadataEnrichmentView.tsx`
- [Metadata enrichment](https://github.com/joejamal029/playlist-haven/blob/main/services/metadataEnrichmentEngine.ts): `services/metadataEnrichmentEngine.ts`
- [Metadata store](https://github.com/joejamal029/playlist-haven/blob/main/services/metadataDb.ts): `services/metadataDb.ts`
- [Playlist resequencer](https://github.com/joejamal029/playlist-haven/blob/main/views/PlaylistResequencerView.tsx): `views/PlaylistResequencerView.tsx`
- [Resequencer engine](https://github.com/joejamal029/playlist-haven/blob/main/services/resequencerEngine.ts): `services/resequencerEngine.ts`

### Experience and analysis

- [Sonic Sieve](https://github.com/joejamal029/playlist-haven/blob/main/views/SonicSieveView.tsx): `views/SonicSieveView.tsx`
- [Sieve worker](https://github.com/joejamal029/playlist-haven/blob/main/sieve.worker.ts): `sieve.worker.ts`
- [Audimote](https://github.com/joejamal029/playlist-haven/blob/main/views/AudimoteView.tsx): `views/AudimoteView.tsx`
- [Audimote engine](https://github.com/joejamal029/playlist-haven/blob/main/services/audimoteEngine.ts): `services/audimoteEngine.ts`
- [Audio analysis worker](https://github.com/joejamal029/playlist-haven/blob/main/workers/audimote.worker.ts): `workers/audimote.worker.ts`
- [Audio preview context](https://github.com/joejamal029/playlist-haven/blob/main/components/AudioPreviewContext.tsx): `components/AudioPreviewContext.tsx`
- [iTunes API service](https://github.com/joejamal029/playlist-haven/blob/main/services/itunesApi.ts): `services/itunesApi.ts`
- [Sieve engine](https://github.com/joejamal029/playlist-haven/blob/main/services/sieveEngine.ts): `services/sieveEngine.ts`

### Other components

- **Curator**

## Connections

- Curator → Dashboard: opens
- Dashboard → Sonic Sieve: dispatches
- Dashboard → Playlist merger: dispatches
- Dashboard → Playlist splitter: dispatches
- Dashboard → Playlist randomizer: dispatches
- Dashboard → Playlist matcher: dispatches
- Dashboard → Scrape stripper: dispatches
- Dashboard → Language clustering: dispatches
- Dashboard → Discovery triage: dispatches
- Triage engine → Classification engine: reads and initializes
- Triage engine → Metadata store: resolves and saves
- Triage engine → AI and vision service: reads config
- Triage engine → Classification engine: classifies
- Triage engine → Resequencer engine
- Metadata enrichment → Metadata store: reads cache
- Metadata enrichment → Classification engine: reads cache
- Metadata enrichment → AI and vision service: reads config
- Metadata enrichment → iTunes API service: supplements tracks
- Classification engine → Area dictionary: resolves areas
- Resequencer engine → Triage engine: parses and normalizes
- Consensus engine → AI and vision service: uses AI services
- Sieve worker → Sieve engine: uses processing helpers
- Audimote engine → Audio analysis worker: sends audio data
- Audimote engine → Metadata store: loads and saves profiles
- Audimote engine → iTunes API service: resolves previews
- Audio preview context → iTunes API service: resolves previews
