Files
jellybit/CLAUDE.md
T
2026-06-14 11:35:14 +03:00

77 lines
4.6 KiB
Markdown

# CLAUDE.md
Памятка для работы над jellybit. Перед задачей прочитай также
[README.md](README.md), [BRIEF.md](BRIEF.md) и
[docs/specs/architecture.md](docs/specs/architecture.md).
## Что это
Связующий сервис qBittorrent ↔ Jellyfin: принимает торрент + контекст,
качает, распознаёт фильм/сериал (LLM + контекст + опц. метабазы) и
раскладывает файлы для Jellyfin хардлинками. Деплоится на домашний
медиа-сервер umbar (`/home/av/projects/private/umbar`) — туда копируется
готовый бинарь.
## Стек и принципы
- **Go**, один статический бинарь (`CGO_ENABLED=0`). Почему — см.
[ADR-2026-06-13-go-single-binary](docs/adr/ADR-2026-06-13-go-single-binary.md).
- **SQLite** как хранилище (чистый Go-драйвер `modernc.org/sqlite`).
- **Конфигурация — TOML**. **Логи — структурированный JSON** (`log/slog`).
- **Хардлинки, источник не трогаем** — qBittorrent продолжает раздачу,
диск не дублируется.
- **Единое ядро, тонкие транспорты** — вся логика приёма в use-case
`Ingest`; HTTP API, веб-UI и Telegram — лишь обёртки над ним.
- **Минимум компонентов** — в духе umbar, без зоопарка сервисов. Внешние
базы метаданных (TMDB/TVDB) опциональны, включаются конфигом.
## Инварианты (безопасность данных)
- **Источник неприкосновенен:** только `mkdir` / `link(2)` / `unlink`
своих ссылок; никогда не трогаем файлы под `paths.downloads`.
- **Целевой путь санитизируется** и проверяется, что он строго под
`paths.movies`/`series` (защита от traversal); существующее не
перезаписываем.
- **Выход LLM недоверенный** — безопасность на валидации пути, не на
промпте. Авто-раскладка только при подтверждённом матче в базе.
- **Запуск:** контейнер под `1000:1000`, в общей docker-сети (адресация
по именам), mount `/srv/media` (единая песочница) + data-том для
SQLite/конфига.
## Документация: три раздела
- `docs/specs/`**живые** спецификации целевого состояния. Меняем по
мере развития, держим в соответствии с кодом.
- `docs/adr/`**неизменяемый** журнал решений, пишется постфактум,
хранит *почему*. Правила — [docs/adr/README.md](docs/adr/README.md).
- `docs/drafts/` — черновики: планы, идеи, ещё не принятые решения. Не
источник истины.
## Язык
- Документация, комментарии, сообщения коммитов — **русский**.
- Код и идентификаторы — английский.
## Команды
Запуск через [Task](https://taskfile.dev) (`task --list` — полный список):
- `task setup` — установка тулинга (golangci-lint + git-хуки lefthook)
- `task run` — локальный запуск (`go run ./cmd/jellybit --config ./config.toml`)
- `task build` — статический бинарь `linux/amd64` для сервера
- `task test` / `task lint` — тесты и golangci-lint
- `task tidy``go mod tidy`
- `task image` — docker-образ из готового бинаря
Module path — `git.vakhrushev.me/av/jellybit`. Go 1.26, `CGO_ENABLED=0`.
Стек: `chi`, `sqlx` + `modernc.org/sqlite`, `goose` (миграции),
`pelletier/go-toml/v2`, `log/slog`.
## Конвенции кода
- Раскладка: `cmd/jellybit` (точка входа) + `internal/<пакет>` по
компонентам из [architecture.md](docs/specs/architecture.md).
- Ошибки оборачиваем с контекстом (`fmt.Errorf("...: %w", err)`).
- Логирование только через `slog`, без `fmt.Println`.
- Время — всегда с явным TZ (сервер в `Europe/Moscow`).