Begin Go rewrite: remove Python, scaffold module and config
Pivot from FastAPI web portal to a Matrix command bot (modeled on Pete).
Users will issue !movie / !tv / !music commands in allowlisted rooms; the
bot performs a top-hit search against Radarr/Sonarr/Lidarr and adds it.
This commit is session 1 of a multi-session rewrite (see SESSION_PLAN.md):
- Delete app/, requirements.txt, old Dockerfile, .env.example
- Add go.mod (mautrix-go + yaml.v3)
- Add internal/config: YAML loader with ${ENV} expansion, validates
matrix creds, allowed_rooms, and per-service *arr config
- Reset .gitignore / .dockerignore for the Go layout
This commit is contained in:
57
SESSION_PLAN.md
Normal file
57
SESSION_PLAN.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Bellhop Go Rewrite — Session Plan
|
||||
|
||||
Rewriting Bellhop from a Python FastAPI web portal into a Go-based Matrix command bot, modeled after [Pete](../pete). Users issue commands like `!movie dune` in allowlisted Matrix rooms; the bot performs the top-hit search against Radarr/Sonarr/Lidarr and adds the result.
|
||||
|
||||
## Design decisions (locked in)
|
||||
|
||||
- **Command UX:** top-hit auto-add (no numbered picker, no reaction selector).
|
||||
- **Authz:** any member of an allowlisted room ID can issue commands. No per-user list.
|
||||
- **Old Python code:** deleted, clean-slate Go rewrite.
|
||||
- **Module layout:** mirrors Pete (`main.go` + `internal/<pkg>/`).
|
||||
- **Config:** YAML with `${ENV_VAR}` expansion (Pete-style).
|
||||
- **Matrix client:** mautrix-go with cryptohelper for E2EE support.
|
||||
|
||||
## Session breakdown
|
||||
|
||||
- [x] **Session 1 — Foundation**
|
||||
- Delete Python (`app/`, `requirements.txt`, `Dockerfile`, `.env.example`)
|
||||
- Reset `.gitignore` / `.dockerignore` for Go
|
||||
- `go.mod` (mautrix + yaml)
|
||||
- `internal/config/config.go` — YAML loader: matrix creds, `allowed_rooms`, `services.{radarr,sonarr,lidarr}`
|
||||
|
||||
- [ ] **Session 2 — Matrix client** (`internal/matrix/`)
|
||||
- Adapt Pete's `client.go`: login + device persistence + cryptohelper
|
||||
- Sync loop, auto-join on invite
|
||||
- Message handler scoped to `allowed_rooms` (not channel-name map like Pete)
|
||||
- Threaded reply helper for command responses
|
||||
- Drop Pete-specific bits: image upload, reaction handler, story formatting
|
||||
|
||||
- [ ] **Session 3 — *arr clients** (`internal/arr/`)
|
||||
- One file per service or a single generic client (TBD in session)
|
||||
- `Search(term) → []Result` and `Add(result) → error`
|
||||
- Radarr: `/api/v3/movie/lookup` + POST `/api/v3/movie`
|
||||
- Sonarr: `/api/v3/series/lookup` + POST `/api/v3/series`
|
||||
- Lidarr: `/api/v1/artist/lookup` + POST `/api/v1/artist`
|
||||
- All adds: monitored=true, search-on-add=true, quality profile + root folder from config
|
||||
- Unit tests with httptest
|
||||
|
||||
- [ ] **Session 4 — Command dispatch + main** (`internal/bot/`, `main.go`)
|
||||
- Parse `<prefix><cmd> <query>` (default prefix `!`)
|
||||
- Commands: `movie`, `tv`, `music`, `help`
|
||||
- On match: search → take `[0]` → add → reply with title/year (or error)
|
||||
- "Service not configured" reply if the corresponding *arr block is absent
|
||||
- `main.go`: load config, init matrix, wire handler, SIGINT/SIGTERM shutdown
|
||||
|
||||
- [ ] **Session 5 — Ship polish**
|
||||
- Multi-stage Dockerfile (`golang:1.25-alpine` → `alpine:3.21`, build with `-tags goolm`)
|
||||
- `config.example.yaml`
|
||||
- Rewrite `README.md`: command UX, install, config reference, Docker
|
||||
- `go build ./...` + `go vet ./...` clean
|
||||
|
||||
## Out of scope (for now)
|
||||
|
||||
- Reaction-based result picker
|
||||
- Per-user allowlist or power-level gating
|
||||
- Persistent request audit log (the Matrix room itself is the audit trail since requests are in-channel)
|
||||
- Removal/cancellation commands
|
||||
- Search-only mode (browse without adding)
|
||||
Reference in New Issue
Block a user