# airencracken/tidings architecture

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

- Interactive diagram: https://gitdiagram.com/airencracken/tidings
- Repository: https://github.com/airencracken/tidings

## Overview

Tidings is a household RSS/Atom reader served by one Go application backed by SQLite. A member signs in, adds or discovers feeds (or imports OPML), then reads a finite story table and manages read, saved, and skipped state; scheduled or requested fetching supplies stories to that table. The graph preserves the documented household, account, export/restore, article-copy, and administration capabilities. Some route wiring and background-service details are unsampled, so only documented or excerpt-supported relationships are drawn.

Main entry points: [`internal/reader/app.go`](https://github.com/airencracken/tidings/blob/master/internal/reader/app.go) (Routes and pages), [`internal/reader/store.go`](https://github.com/airencracken/tidings/blob/master/internal/reader/store.go) (SQLite store), [`internal/reader/fetch.go`](https://github.com/airencracken/tidings/blob/master/internal/reader/fetch.go) (Feed fetching), [`internal/reader/articles.go`](https://github.com/airencracken/tidings/blob/master/internal/reader/articles.go) (Story and full text)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_runtime["Application runtime"]
  node_server["HTTP service<br/>[main.go]"]
  node_webapp["Routes and pages<br/>[app.go]"]
end

subgraph group_reading["Reading experience"]
  node_story_table["Story table<br/>[app.go]"]
  node_article["Story and full text<br/>[articles.go]"]
  node_markup["Article cleanup<br/>[article_html.go]"]
  node_shortcuts["Keyboard controls<br/>[keyboard.js]"]
end

subgraph group_feeds["Feeds and discovery"]
  node_feed_fetch["Feed fetching<br/>[fetch.go]"]
  node_scheduler["Fetch scheduling<br/>[scheduling.go]"]
  node_discover["Feed discovery<br/>[discovery.go]"]
  node_catalog["Suggested sources<br/>[catalog.go]"]
  node_opml["OPML import/export<br/>[opml.go]"]
  node_groups["Feed groups and tags<br/>[groups.go]"]
end

subgraph group_household["Household administration"]
  node_signin["Sign-in and sessions<br/>[auth.go]"]
  node_household["Household sources<br/>[store.go]"]
  node_accounts["Invitations and members<br/>[invitations.go]"]
  node_metrics["Instance metrics<br/>[metrics.go]"]
end

subgraph group_data["Persistence and recovery"]
  node_backup["Backups and export<br/>[backup.go]"]
  node_restore["Data restore<br/>[restore.go]"]
  node_sqlite[("SQLite store<br/>[store.go]")]
end

node_member(("Reader or owner"))

node_member -->|"uses pages"| node_webapp
node_webapp -->|"authenticates"| node_signin
node_webapp -->|"loads session"| node_sqlite
node_member -->|"reads stories"| node_story_table
node_webapp -->|"renders"| node_story_table
node_story_table -->|"opens story"| node_article
node_article -->|"cleans markup"| node_markup
node_member -->|"uses shortcuts"| node_shortcuts
node_member -->|"finds feeds"| node_discover
node_member -->|"browses suggestions"| node_catalog
node_member -->|"imports or exports"| node_opml
node_member -->|"organizes sources"| node_groups
node_webapp -->|"starts refresh"| node_feed_fetch
node_scheduler -->|"schedules checks"| node_feed_fetch
node_feed_fetch -->|"stores feed stories"| node_sqlite
node_member -->|"opts into table"| node_household
node_member -->|"manages membership"| node_accounts
node_member -->|"views metrics"| node_metrics
node_member -->|"downloads data"| node_backup
node_server -->|"runs restore"| node_restore
node_backup -->|"backs up data"| node_sqlite
node_restore -->|"restores data"| node_sqlite
node_webapp -->|"reads and writes"| node_sqlite

click node_server "https://github.com/airencracken/tidings/blob/master/cmd/tidings/main.go"
click node_webapp "https://github.com/airencracken/tidings/blob/master/internal/reader/app.go"
click node_signin "https://github.com/airencracken/tidings/blob/master/internal/reader/auth.go"
click node_story_table "https://github.com/airencracken/tidings/blob/master/internal/reader/app.go"
click node_article "https://github.com/airencracken/tidings/blob/master/internal/reader/articles.go"
click node_markup "https://github.com/airencracken/tidings/blob/master/internal/reader/article_html.go"
click node_shortcuts "https://github.com/airencracken/tidings/blob/master/internal/reader/static/keyboard.js"
click node_feed_fetch "https://github.com/airencracken/tidings/blob/master/internal/reader/fetch.go"
click node_scheduler "https://github.com/airencracken/tidings/blob/master/internal/reader/scheduling.go"
click node_discover "https://github.com/airencracken/tidings/blob/master/internal/reader/discovery.go"
click node_catalog "https://github.com/airencracken/tidings/blob/master/internal/reader/catalog.go"
click node_opml "https://github.com/airencracken/tidings/blob/master/internal/reader/opml.go"
click node_groups "https://github.com/airencracken/tidings/blob/master/internal/reader/groups.go"
click node_household "https://github.com/airencracken/tidings/blob/master/internal/reader/store.go"
click node_accounts "https://github.com/airencracken/tidings/blob/master/internal/reader/invitations.go"
click node_metrics "https://github.com/airencracken/tidings/blob/master/internal/reader/metrics.go"
click node_backup "https://github.com/airencracken/tidings/blob/master/internal/reader/backup.go"
click node_restore "https://github.com/airencracken/tidings/blob/master/internal/reader/restore.go"
click node_sqlite "https://github.com/airencracken/tidings/blob/master/internal/reader/store.go"

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_server,node_webapp toneBlue
class node_story_table,node_article,node_markup,node_shortcuts toneAmber
class node_feed_fetch,node_scheduler,node_discover,node_catalog,node_opml,node_groups toneMint
class node_signin,node_household,node_accounts,node_metrics toneRose
class node_backup,node_restore,node_sqlite,node_member toneIndigo
```

## Components

### Application runtime

- [HTTP service](https://github.com/airencracken/tidings/blob/master/cmd/tidings/main.go): `cmd/tidings/main.go`
- [Routes and pages](https://github.com/airencracken/tidings/blob/master/internal/reader/app.go): `internal/reader/app.go`

### Reading experience

- [Story table](https://github.com/airencracken/tidings/blob/master/internal/reader/app.go): `internal/reader/app.go`
- [Story and full text](https://github.com/airencracken/tidings/blob/master/internal/reader/articles.go): `internal/reader/articles.go`
- [Article cleanup](https://github.com/airencracken/tidings/blob/master/internal/reader/article_html.go): `internal/reader/article_html.go`
- [Keyboard controls](https://github.com/airencracken/tidings/blob/master/internal/reader/static/keyboard.js): `internal/reader/static/keyboard.js`

### Feeds and discovery

- [Feed fetching](https://github.com/airencracken/tidings/blob/master/internal/reader/fetch.go): `internal/reader/fetch.go`
- [Fetch scheduling](https://github.com/airencracken/tidings/blob/master/internal/reader/scheduling.go): `internal/reader/scheduling.go`
- [Feed discovery](https://github.com/airencracken/tidings/blob/master/internal/reader/discovery.go): `internal/reader/discovery.go`
- [Suggested sources](https://github.com/airencracken/tidings/blob/master/internal/reader/catalog.go): `internal/reader/catalog.go`
- [OPML import/export](https://github.com/airencracken/tidings/blob/master/internal/reader/opml.go): `internal/reader/opml.go`
- [Feed groups and tags](https://github.com/airencracken/tidings/blob/master/internal/reader/groups.go): `internal/reader/groups.go`

### Household administration

- [Sign-in and sessions](https://github.com/airencracken/tidings/blob/master/internal/reader/auth.go): `internal/reader/auth.go`
- [Household sources](https://github.com/airencracken/tidings/blob/master/internal/reader/store.go): `internal/reader/store.go`
- [Invitations and members](https://github.com/airencracken/tidings/blob/master/internal/reader/invitations.go): `internal/reader/invitations.go`
- [Instance metrics](https://github.com/airencracken/tidings/blob/master/internal/reader/metrics.go): `internal/reader/metrics.go`

### Persistence and recovery

- [Backups and export](https://github.com/airencracken/tidings/blob/master/internal/reader/backup.go): `internal/reader/backup.go`
- [Data restore](https://github.com/airencracken/tidings/blob/master/internal/reader/restore.go): `internal/reader/restore.go`
- [SQLite store](https://github.com/airencracken/tidings/blob/master/internal/reader/store.go): `internal/reader/store.go`

### Other components

- **Reader or owner**

## Connections

- Reader or owner → Routes and pages: uses pages
- Routes and pages → Sign-in and sessions: authenticates (evidence: `internal/reader/app.go`)
- Routes and pages → SQLite store: loads session (evidence: `internal/reader/app.go`)
- Reader or owner → Story table: reads stories
- Routes and pages → Story table: renders (evidence: `internal/reader/app.go`)
- Story table → Story and full text: opens story
- Story and full text → Article cleanup: cleans markup
- Reader or owner → Keyboard controls: uses shortcuts
- Reader or owner → Feed discovery: finds feeds
- Reader or owner → Suggested sources: browses suggestions
- Reader or owner → OPML import/export: imports or exports
- Reader or owner → Feed groups and tags: organizes sources
- Routes and pages → Feed fetching: starts refresh (evidence: `internal/reader/app.go`)
- Fetch scheduling → Feed fetching: schedules checks
- Feed fetching → SQLite store: stores feed stories
- Reader or owner → Household sources: opts into table
- Reader or owner → Invitations and members: manages membership
- Reader or owner → Instance metrics: views metrics
- Reader or owner → Backups and export: downloads data
- HTTP service → Data restore: runs restore (evidence: `cmd/tidings/main.go`)
- Backups and export → SQLite store: backs up data
- Data restore → SQLite store: restores data
- Routes and pages → SQLite store: reads and writes (evidence: `internal/reader/store.go`)
