4.7 KiB
4.7 KiB
AGENTS.md
PWA для менеджмента homelab: монорепозиторий Go-сервер + SPA-фронт, общаются через ConnectRPC. Таргет — iPhone «На экран Домой» (standalone PWA).
Стек
- Сервер: Go + echo +
connectrpc.com/connect. Отдаёт RPC на/homelab.v1.HomelabService/*и статику изdist/(SPA-fallback включён). Порт из envPORT(дефолт:8080). - Фронт: Preact + Vite + TypeScript, daisyUI v5 (tailwind v4), lucide-preact. Клиент —
@connectrpc/connect-web, same-origin transport, в dev — прокси на :8080. - Контракт:
proto/homelab/v1/homelab.proto→ кодоген вgen/(Go) иweb/src/gen/(TS). Сгенерённый код коммитится, buf CLI не используется — только protoc. - Конфиг:
config.yaml(секции → items → bash-скрипты). Мониторы гоняются по таймеру на сервере, response-скрипты запускаются по кнопке с аргументами.
Структура
proto/homelab/v1/ контракт (единственный источник правды)
gen/ сгенерённый Go-код (коммитим)
server/main.go весь сервер: конфиг, мониторы, RPC, статика
web/src/App.tsx layout, сайдбар секций, поллинг ListSections (3s)
web/src/components/ MonitorCard (мониторы), ScriptCard (response-форма + модалка результата)
web/src/gen/ сгенерированный TS-клиент
web/public/ PWA-обвязка: manifest, sw.js, иконки
scripts/ bash-скрипты, пути из config.yaml
Команды (всё через make)
make dev— сервер :8080 + vite :5173 (работать на http://localhost:5173)make dev-srv/make dev-web— по отдельности в два терминалаmake proto— кодоген Go+TS из protomake web— сборка фронта вdist/(tsc --noEmit + vite build;tsc— линтер, падение = ошибка типов)make server— Go-бинарьbin/hub-apimake test— smoke-тест RPC (поднимает сервер на :8080, дергает curl'ом)
Никаких других способов сборки нет: CI делает ровно make web server.
Деплой (CI)
.gitea/workflows/deploy.yml: push в master → checkout → make web server → cp на бокс → systemctl --user restart hub-api.
На боксе юнит должен иметь WorkingDirectory=~/apps/hub — сервер ищет dist/, config.yaml, scripts/ относительно cwd. Локально всё то же самое из корня репо.
Конвенции
- Один корень статики:
dist/. Не вводить fallback-ов (web/distне существует послеmake web— vite собирает вweb/dist, make копирует в./dist). int64в proto →bigintв TS (неnumber!).- Поля protobuf в TS — camelCase (
arg_types→argTypes). - Новый item-тип или поле в yaml = обновить proto + валидацию в
loadConfig+ компонент на фронте. - Иконки секций: строка из конфига → ручной маппинг
ICONSвApp.tsx(не тянуть весь lucide черезicons— раздувает бандл в 5 раз). - Логи сервера: monitors и RunScript пишут в stdout;
ListSections(поллинг-шум) исключён из HTTP-лога echo. - SW:
web/public/sw.js, версия кэшаhomelab-shell-vN— бампить при изменении офлайн-логики, иначе iOS не обновит. - Тесты:
make test(smoke RPC) +tsc --noEmitвнутриmake web. Не плодить фреймворки.
Подводные камни
- iOS PWA требует https (или localhost). Через Caddy-домен бокса — ок.
- SW на iOS у установленной PWA обновляется неохотно: правки SW → удалить иконку, открыть в Safari, добавить заново. Bump версии кэша в sw.js обязателен.
- Connect JSON:
int64сериализуется строкой — в smoke-тестах grep'ать с кавычками. - Джобы CI — host (не docker), user
homelab; не добавлять docker-шаги.