1b7b70426c
- config: koanf-based loading (defaults → YAML → KINDEXR_ env vars) - db: embedded SQLite migrations with BEGIN/END-aware statement splitter - server: chi router, GET /health returns JSON stats - cmd/kindexr: graceful SIGTERM shutdown - cmd/kindexr-cli: stub - deploy: systemd unit, example config, nginx snippet - all packages covered by race-clean tests
72 lines
3.3 KiB
Markdown
72 lines
3.3 KiB
Markdown
# Architecture
|
|
|
|
nzbstr is a two-halves daemon:
|
|
|
|
- **Reader** (Phase 1+): subscribes to Nostr relays for kind 2003 (torrent) and kind 2004 (torrent comment) events, indexes them locally in SQLite, and exposes a Torznab-compatible HTTP API.
|
|
- **Writer** (Phase 4+): watches a download client (qBittorrent / Transmission / Deluge) for completed downloads, builds NIP-35 events signed by your npub, and publishes them to configured outbox relays.
|
|
|
|
## Data flow
|
|
|
|
```
|
|
Sonarr / Radarr / Lidarr / Readarr / Prowlarr
|
|
|
|
|
v Torznab HTTP/XML
|
|
|
|
|
+-----------+
|
|
| nzbstr |
|
|
| reader | <-- subscribes to relays via WebSocket
|
|
| writer | --> publishes via WebSocket
|
|
+-----------+
|
|
^ ^
|
|
| |
|
|
v v
|
|
Nostr relays qBittorrent / Transmission / Deluge
|
|
(NIP-35 events) (download client)
|
|
```
|
|
|
|
## Components
|
|
|
|
### `cmd/nzbstr` — main daemon
|
|
|
|
Entry point. Loads config, opens the SQLite database (applying any pending migrations), starts the HTTP server, and installs signal handlers for graceful shutdown.
|
|
|
|
### `internal/config`
|
|
|
|
koanf-based configuration loading. Load order: compiled-in defaults → YAML file → environment variables (`NZBSTR_` prefix). Missing files are silently skipped so the daemon can start with all defaults.
|
|
|
|
### `internal/db`
|
|
|
|
SQLite access via `modernc.org/sqlite` (pure Go, no CGO). Includes an embedded migration runner that applies numbered SQL files from `internal/db/migrations/` on startup. Uses WAL journal mode and a single writer connection for safe concurrent reads.
|
|
|
|
### `internal/server`
|
|
|
|
chi-based HTTP server. Phase 0 exposes only `/health`. Phase 1 adds `/api?t=caps`, `/api?t=search`, etc.
|
|
|
|
### `internal/nostr` (Phase 1+)
|
|
|
|
Relay subscription loop using `github.com/nbd-wtf/go-nostr`. NIP-77 negentropy bootstrap for efficient historical sync. Parses kind 2003 events into the internal `Torrent` struct and writes them to SQLite.
|
|
|
|
### `internal/torznab` (Phase 1+)
|
|
|
|
chi routes for the Torznab API. Auth middleware validates API keys. Returns XML in Torznab RSS format. Categories mapped from NIP-35 `i` tags to newznab integer codes.
|
|
|
|
### `internal/enrich` (Phase 2+)
|
|
|
|
Title parser (extracts season/episode/quality/source from release names) and TMDB client for backfilling IMDB/TMDB/TVDB IDs on events that lack them.
|
|
|
|
### `internal/wot` (Phase 3+)
|
|
|
|
Web-of-Trust filter. Fetches the operator's kind 3 follow list and optionally follows-of-follows to build an allowed-pubkey set. Integrates with NIP-51 curation sets.
|
|
|
|
### `internal/publisher` (Phase 4+)
|
|
|
|
qBittorrent / Transmission / watch-dir integration. Polls for completed downloads in the configured category, builds kind 2003 events, signs them via NIP-46 bunker or local key, and publishes to outbox relays.
|
|
|
|
## Storage
|
|
|
|
Single SQLite file at `/var/lib/nzbstr/nzbstr.db`. Schema managed by embedded SQL migrations in `internal/db/migrations/`. FTS5 virtual table on `(title, description)` with triggers to keep it in sync.
|
|
|
|
## Deployment
|
|
|
|
Single static binary + systemd unit. No external services required. Sits behind nginx for TLS termination. See `deploy/nzbstr.service` and `deploy/nginx.conf.example`.
|