# mih-ap/favourites architecture

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

- Interactive diagram: https://gitdiagram.com/mih-ap/favourites
- Repository: https://github.com/mih-ap/favourites

## Overview

Favourites turns submitted links into searchable Obsidian notes. Telegram (or the CLI) enqueues a URL; the worker claims it, extracts text/media, optionally transcribes audio, analyzes sufficient text with an OpenAI-compatible LLM, writes a Markdown card and updates SQLite, then may notify the submitter. The web app serves the library, search and card actions. README documents key capabilities such as retries, partial cards and photo attachments; unsampled implementation details are represented only where documented.

Main entry points: [`app/worker.py`](https://github.com/mih-ap/favourites/blob/main/app/worker.py) (Queue worker), [`app/db.py`](https://github.com/mih-ap/favourites/blob/main/app/db.py) (SQLite queue), [`app/web.py`](https://github.com/mih-ap/favourites/blob/main/app/web.py) (Web API server), [`app/bot.py`](https://github.com/mih-ap/favourites/blob/main/app/bot.py) (Telegram bot)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_intake["Link intake"]
  node_telegram_bot["Telegram bot<br/>[bot.py]"]
  node_cli["CLI<br/>[cli.py]"]
end

subgraph group_processing["Content processing"]
  node_worker["Queue worker<br/>[worker.py]"]
  node_extract["Content extraction<br/>[extract.py]"]
  node_asr["Audio transcription<br/>[asr.py]"]
  node_analysis["Summary analysis<br/>[analyze.py]"]
end

subgraph group_storage["Library storage"]
  node_queue[("SQLite queue<br/>[db.py]")]
  node_vault["Obsidian card writer<br/>[vault.py]"]
  node_markdown["Vault notes and images<br/>[vault.py]"]
end

subgraph group_web["Web reference"]
  node_web_server["Web API server<br/>[web.py]"]
  node_web_ui["Library interface<br/>[app.js]"]
  node_web_html["Interface shell<br/>[index.html]"]
  node_web_styles["Interface styles<br/>[style.css]"]
end

subgraph group_integrations["External services"]
  node_llm{{"LLM endpoint"}}
  node_telegram_api{{"Telegram API"}}
  node_media_sources{{"Content sources"}}
end

node_telegram_user(("Telegram user"))

node_telegram_user -->|"sends links"| node_telegram_bot
node_telegram_bot -->|"enqueues URLs"| node_queue
node_telegram_bot -->|"polls and replies"| node_telegram_api
node_cli -->|"enqueues URLs"| node_queue
node_queue -->|"provides queued items"| node_worker
node_worker -->|"claims and updates"| node_queue
node_worker -->|"fetches content"| node_extract
node_extract -->|"retrieves media"| node_media_sources
node_extract -->|"requests transcription"| node_asr
node_worker -->|"analyzes extracted data"| node_analysis
node_analysis -->|"requests summary"| node_llm
node_worker -->|"writes analyzed card"| node_vault
node_vault -->|"writes notes and attachments"| node_markdown
node_worker -->|"stores item metadata"| node_queue
node_worker -->|"sends completion notice"| node_telegram_api
node_web_ui -->|"calls library API"| node_web_server
node_web_server -->|"queries and requeues items"| node_queue
node_web_server -->|"reads and trashes cards"| node_vault
node_web_server -->|"serves interface"| node_web_html
node_web_html -.->|"loads interface logic"| node_web_ui
node_web_html -.->|"loads styles"| node_web_styles

click node_telegram_bot "https://github.com/mih-ap/favourites/blob/main/app/bot.py"
click node_cli "https://github.com/mih-ap/favourites/blob/main/app/cli.py"
click node_queue "https://github.com/mih-ap/favourites/blob/main/app/db.py"
click node_worker "https://github.com/mih-ap/favourites/blob/main/app/worker.py"
click node_extract "https://github.com/mih-ap/favourites/blob/main/app/extract.py"
click node_asr "https://github.com/mih-ap/favourites/blob/main/app/asr.py"
click node_analysis "https://github.com/mih-ap/favourites/blob/main/app/analyze.py"
click node_vault "https://github.com/mih-ap/favourites/blob/main/app/vault.py"
click node_markdown "https://github.com/mih-ap/favourites/blob/main/app/vault.py"
click node_web_server "https://github.com/mih-ap/favourites/blob/main/app/web.py"
click node_web_ui "https://github.com/mih-ap/favourites/blob/main/web/static/app.js"
click node_web_html "https://github.com/mih-ap/favourites/blob/main/web/static/index.html"
click node_web_styles "https://github.com/mih-ap/favourites/blob/main/web/static/style.css"

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_telegram_bot,node_cli,node_telegram_user toneBlue
class node_worker,node_extract,node_asr,node_analysis toneAmber
class node_queue,node_vault,node_markdown toneMint
class node_web_server,node_web_ui,node_web_html,node_web_styles toneRose
class node_llm,node_telegram_api,node_media_sources toneIndigo
```

## Components

### Link intake

- [Telegram bot](https://github.com/mih-ap/favourites/blob/main/app/bot.py): `app/bot.py`
- [CLI](https://github.com/mih-ap/favourites/blob/main/app/cli.py): `app/cli.py`

### Content processing

- [Queue worker](https://github.com/mih-ap/favourites/blob/main/app/worker.py): `app/worker.py`
- [Content extraction](https://github.com/mih-ap/favourites/blob/main/app/extract.py): `app/extract.py`
- [Audio transcription](https://github.com/mih-ap/favourites/blob/main/app/asr.py): `app/asr.py`
- [Summary analysis](https://github.com/mih-ap/favourites/blob/main/app/analyze.py): `app/analyze.py`

### Library storage

- [SQLite queue](https://github.com/mih-ap/favourites/blob/main/app/db.py): `app/db.py`
- [Obsidian card writer](https://github.com/mih-ap/favourites/blob/main/app/vault.py): `app/vault.py`
- [Vault notes and images](https://github.com/mih-ap/favourites/blob/main/app/vault.py): `app/vault.py`

### Web reference

- [Web API server](https://github.com/mih-ap/favourites/blob/main/app/web.py): `app/web.py`
- [Library interface](https://github.com/mih-ap/favourites/blob/main/web/static/app.js): `web/static/app.js`
- [Interface shell](https://github.com/mih-ap/favourites/blob/main/web/static/index.html): `web/static/index.html`
- [Interface styles](https://github.com/mih-ap/favourites/blob/main/web/static/style.css): `web/static/style.css`

### External services

- **LLM endpoint**
- **Telegram API**
- **Content sources**

### Other components

- **Telegram user**

## Connections

- Telegram user → Telegram bot: sends links (evidence: `README.md`)
- Telegram bot → SQLite queue: enqueues URLs (evidence: `app/bot.py`)
- Telegram bot → Telegram API: polls and replies (evidence: `app/bot.py`)
- CLI → SQLite queue: enqueues URLs (evidence: `app/cli.py`)
- SQLite queue → Queue worker: provides queued items (evidence: `README.md`)
- Queue worker → SQLite queue: claims and updates (evidence: `app/worker.py`)
- Queue worker → Content extraction: fetches content (evidence: `app/worker.py`)
- Content extraction → Content sources: retrieves media (evidence: `README.md`)
- Content extraction → Audio transcription: requests transcription (evidence: `README.md`)
- Queue worker → Summary analysis: analyzes extracted data (evidence: `app/worker.py`)
- Summary analysis → LLM endpoint: requests summary (evidence: `app/analyze.py`)
- Queue worker → Obsidian card writer: writes analyzed card (evidence: `app/worker.py`)
- Obsidian card writer → Vault notes and images: writes notes and attachments (evidence: `README.md`)
- Queue worker → SQLite queue: stores item metadata (evidence: `app/worker.py`)
- Queue worker → Telegram API: sends completion notice (evidence: `app/worker.py`)
- Library interface → Web API server: calls library API (evidence: `README.md`)
- Web API server → SQLite queue: queries and requeues items (evidence: `app/web.py`)
- Web API server → Obsidian card writer: reads and trashes cards (evidence: `app/web.py`)
- Web API server → Interface shell: serves interface (evidence: `app/web.py`)
- Interface shell → Library interface: loads interface logic
- Interface shell → Interface styles: loads styles
