Доработка документации

This commit is contained in:
Maxim
2026-07-17 15:57:05 +03:00
parent 5b403d7ee4
commit 9fa3d172a8
22 changed files with 1371 additions and 481 deletions

59
docs/tech-debt.md Normal file
View File

@@ -0,0 +1,59 @@
# Реестр технического долга
Известные проблемы и упрощения, принятые в текущей реализации. Реестр ведётся, чтобы долг был видим и осознан; исправления — отдельные задачи. При закрытии пункта удаляйте его отсюда, при появлении нового — добавляйте с указанием места и влияния.
**Аудитория:** разработчики.
Состояние на 2026-07-17. Маркеров `TODO`/`FIXME` в коде нет — этот файл единственный источник.
## Go-сервер (cmd/server/main.go)
| # | Проблема | Где | Влияние | Направление исправления |
|---|---|---|---|---|
| 1 | Монолит: 8 HTTP-хендлеров, разбор флагов, чтение `.bin`, прокси камеры — всё в одном файле на ~750 строк | `main.go` | Затрудняет навигацию и тестирование хендлеров | Вынести HTTP-слой в `internal/api`, чтение `.bin` — в `internal/logger` |
| 2 | Мёртвый код: `handleCamProxy` не вызывается (роутер использует `handleCamProxyWithURL`) | `main.go:474` | Путает при чтении, дублирует логику | Удалить после подтверждения |
| 3 | `HandleStream` проверяет доступность камеры по захардкоженному `localhost:1984`, игнорируя `-camera-url` | `main.go:460` | При нестандартном URL камеры `available` врёт | Строить URL проверки из `-camera-url` |
| 4 | Разбор байта GPIO продублирован: `HandleLogData` сдвигает биты сам вместо `logger.ParseGPIO` | `main.go:297298``internal/logger/parser.go` | Риск рассинхронизации формата | Использовать `ParseGPIO` |
| 5 | `/api/log/data` читает весь `.bin`-файл в память до пагинации | `main.go:278308` | На больших файлах — всплеск памяти на каждый запрос | Читать нужный диапазон по смещению (записи фиксированные, 9 байт) |
| 6 | CORS открыт для всех источников (`*`) | `main.go:522535` | Приемлемо для изолированной сети; риск при выходе наружу | Осознанное решение зафиксировано; при необходимости — allowlist |
| 7 | `/api/log/files` возвращает `null` вместо `[]` при отсутствии файлов; `/api/latest` отдаёт 200 с `{"error":"no data"}` | `main.go:67,105`, `main.go:435` | Клиентам нужны доп. проверки | Инициализировать слайс; вернуть 204/404 либо задокументированную схему |
## Пакеты internal/
| # | Проблема | Где | Влияние | Направление исправления |
|---|---|---|---|---|
| 8 | Два параллельных механизма расчёта скорости пишут в одни атомики: периодический (250 мс) и скользящее окно (1 с); публичный `GetWindowSpeed()` не используется | `internal/adapter/buffer.go:77162` | Значение `bytes_per_sec` зависит от того, кто записал последним; лишний код и память (`recentBytes`) | Оставить один механизм |
| 9 | Конфигурация размазана: значения по умолчанию во флагах (`retention-hours=48`), в deb-юните (`72`), в `scripts/go2monitor.service` (`72`) и в справочном `/etc/gpio-monitoring/config`, который сервис **не читает** | `main.go`, `debian/gpio-monitor-server.service`, `debian/gpio-monitor-server.conf` | Непонятно, что «истина»; правка конфига не влияет на сервис | Либо читать `EnvironmentFile=/etc/gpio-monitoring/config` в юните, либо удалить конфиг-файл |
| 10 | `DataLogger.flush` молча глотает ошибку записи (комментарий «тут должен быть event» в коде) | `internal/logger/data_logger.go:6670` | Потеря данных при полном диске останется незамеченной | Прокинуть EventLogger и писать событие |
## Тесты и CI
| # | Проблема | Где | Влияние | Направление исправления |
|---|---|---|---|---|
| 11 | Единственный тест-файл на проект — retention; без тестов `parser.go`, `buffer.go` (конкурентность), `rotation.go`, `data_logger.go` (бинарный формат), `reader.go` | `internal/logger/retention_test.go` | Регрессии форматов/конкурентности не ловятся | Начать с parser (тривиально) и data_logger (формат 9 байт) |
| 12 | CI отсутствует (нет `.gitea/workflows/`) | — | Сборка и тесты не проверяются автоматически | Gitea Actions: `make build-frontend`, `go vet`, `go test` |
## Сборка и инфраструктура
| # | Проблема | Где | Влияние | Направление исправления |
|---|---|---|---|---|
| 13 | Цели `docker-build`/`docker-run` есть, Dockerfile — нет | `Makefile:249256` | Цели заведомо падают | Удалить цели или добавить Dockerfile |
| 14 | C-программа захвата `gpio-interrupt` — ключевой компонент системы — не версионируется в репозитории (живёт на устройстве в `/home/user/WiringPi/examples`) | `scripts/monitor-gpio.service` | Невоспроизводимость: систему нельзя собрать целиком из репозитория | Добавить исходник в репозиторий (например `capture/gpio-interrupt.c`) |
| 15 | `go build` требует предварительно собранного `web/dist` (`go:embed`) — чистый checkout не собирается командой `go build ./...` | `cmd/server/main.go:28` | Неочевидная ошибка для новичка; ломает go-инструментарий на чистом дереве | Задокументировано ([development.md](development.md#порядок-сборки)); вариант — коммитить заглушку `dist/.keep` с `embed` через `all:` |
| 16 | Захардкоженные пути под конкретное устройство: `build.sh` и `start-server.sh` (`~/temp/golang`), `emulatohackrf.sh`, systemd-юниты в `scripts/` (`/home/user/...`) | `build.sh`, `start-server.sh`, `scripts/*` | Скрипты не переносимы | Параметризовать или пометить как шаблоны |
## Фронтенд (cmd/server/web/js/)
| # | Проблема | Где | Влияние | Направление исправления |
|---|---|---|---|---|
| 17 | Крупные модули без разбивки: `logs.ts` (747 строк), `app.ts` (434), `ui.ts` (414) | `js/` | Сложно поддерживать | Разбить `logs.ts` на api/таблицы/пагинацию |
| 18 | Типы ответов API объявлены дважды: в `data.ts` и `logs.ts` | `js/data.ts`, `js/logs.ts` | Рассинхронизация с сервером ловится только вручную | Общий `js/api-types.ts` |
| 19 | Нет линтера/форматтера (eslint/prettier) и ни одного теста фронтенда; `make fmt` вызывает несуществующий `npm run format` | `package.json`, `Makefile:112` | Стиль и регрессии не контролируются | Добавить prettier + script `format` |
| 20 | `logs.ts:284` передаёт в `/api/log/events` параметр `order=newest_first`, который сервер не читает | `js/logs.ts:284` | Мусорный параметр, вводит в заблуждение | Убрать параметр |
## SDR/
| # | Проблема | Где | Влияние | Направление исправления |
|---|---|---|---|---|
| 21 | makefile ожидает `receiver.c`, реальный файл — `reciever.c` (опечатка): цель сборки приёмника не срабатывает | `SDR/makefile`, `SDR/reciever.c` | `make` собирает только передатчик; приёмник — только вручную (обходная команда в [SDR/README.md](../SDR/README.md)) | Переименовать файл в `receiver.c` (или поправить makefile) |
| 22 | Статус подпроекта не определён: SDR не связан с основной системой ни сборкой, ни CI | `SDR/` | Непонятно, поддерживается ли код | Зафиксировать статус в SDR/README (актуален/эксперимент/заморожен) |