mirror of
https://github.com/IS1DI/x0gp.git
synced 2026-07-19 05:47:02 +00:00
107 lines
10 KiB
Markdown
107 lines
10 KiB
Markdown
# AGENTS.md — заметки для ассистента
|
||
|
||
Этот файл — заметки, которые нужно помнить между сессиями.
|
||
|
||
## MCP-инструменты, которые здесь работают
|
||
|
||
### blender-mcp
|
||
Управляет Blender-сценой напрямую. Используй когда нужно менять/осматривать 3D-модель машинки (OpenRC_F1_2018_Halo, BodyCam, LayoutCam, Battery и др.).
|
||
|
||
Типичные задачи:
|
||
- Осмотреть сцену: `blender-mcp_get_scene_info`, `blender-mcp_get_viewport_screenshot`
|
||
- Менять геометрию: `blender-mcp_execute_blender_code` (Python в Blender)
|
||
- Скачивать ассеты: `blender-mcp_download_polyhaven_asset`, `blender-mcp_search_sketchfab_models`, `blender-mcp_download_sketchfab_model`, `blender-mcp_set_texture`
|
||
- Генерировать 3D по тексту/картинке: `blender-mcp_generate_hyper3d_model_via_text`, `blender-mcp_generate_hyper3d_model_via_images`, `blender-mcp_generate_hunyuan3d_model`
|
||
|
||
В текущей сцене 78 объектов, 49 материалов. Корневая папка модели — `D:/x0gp`. Blender-сцену открывать не надо — MCP подключён к запущенному Blender.
|
||
|
||
### chrome-mcp-server
|
||
Управляет Chrome-браузером. Удобно для проверки ссылок на товары из `CART_MVP.md` (Ozon/WB/AliExpress).
|
||
|
||
Типичные задачи:
|
||
- Список открытых вкладок: `chrome-mcp-server_get_windows_and_tabs`
|
||
- Открыть URL: `chrome-mcp_navigate`
|
||
- Прочитать страницу: `chrome-mcp_read_page` (предпочтительнее скриншота), `chrome-mcp_get_web_content`
|
||
- Клик/ввод: `chrome-mcp_click_element`, `chrome-mcp_fill_or_select`, `chrome-mcp_keyboard`
|
||
- Переключить вкладку: `chrome-mcp_switch_tab`
|
||
- Скриншот: `chrome-mcp_computer` с `action=screenshot` или `chrome-mcp_screenshot`
|
||
|
||
> Сейчас уже открыто ~20 вкладок с товарами из корзины MVP. Не закрывай их без причины.
|
||
|
||
## Ключевые файлы проекта
|
||
|
||
- `D:/x0gp/hardware/CART_MVP.md` — корзина MVP (что заказать)
|
||
- `D:/x0gp/hardware/ASSEMBLY.md` — пошаговая сборка
|
||
- `D:/x0gp/hardware/BOM_v4.json` — структурированный BOM (машины в JSON)
|
||
- `D:/x0gp/hardware/SHOPPING_LIST.md` — каталог альтернатив (бонусы)
|
||
- `D:/x0gp/hardware/PLAN.md` — общий план
|
||
- `D:/x0gp/hardware/print/stl/*.stl` — STL для печати на P1S (13 шт)
|
||
- `D:/x0gp/hardware/print/parts_manifest.md` — манифест печати
|
||
- `D:/x0gp/ARCHITECTURE.md` — общая архитектура проекта
|
||
|
||
## Сервер x0gp (`D:/x0gp/server`)
|
||
|
||
- Go 1.26, бинарь `cmd/poc-server`. Сборка: `go build ./...` или `go build -o poc-server.exe ./cmd/poc-server`.
|
||
- HTTP+WebSocket, роутер `http.NewServeMux`. Запуск требует `DATABASE_URL` (см. `.env`).
|
||
- **База данных (Supabase)**:
|
||
- Используется self-hosted Supabase на порту `3402` (хост: `80.234.93.161:3402`).
|
||
- Расширение `timescaledb` отключено (закомментировано в `001_init.sql`), так как Supabase не поставляет его из коробки.
|
||
- Нативная папка `supabase/` содержит `config.toml`, объединенный дамп схемы `supabase/migrations/20260717000000_schema.sql` и каталог семян `supabase/seed.sql` (включает рескейл Монако).
|
||
- Объединенный дамп схемы автоматически заполняет таблицу `schema_migrations`, чтобы предотвратить ошибки повторного применения миграций Go-сервером на старте.
|
||
- **Абстракция данных (Store)**:
|
||
- Пакеты `clans` и `drivers` используют интерфейсы `Store` вместо прямого импорта `*PgStore`.
|
||
- Это позволяет писать юнит-тесты сервисов без подключения к реальной БД (через `memoryStore`).
|
||
- **Слепок структуры (Graphify)**:
|
||
- Утилита `scripts/graphify/main.go` собирает описание всех экспортируемых пакетов, структур, интерфейсов и функций в компактный файл [server/CODEBASE.md](file:///d:/x0gp/server/CODEBASE.md).
|
||
- Рекомендуется запускать `go run ./scripts/graphify/main.go` после значимых изменений API для поддержания карты проекта в актуальном состоянии и экономии токенов при чтении агентом.
|
||
- **Swagger UI**: `GET /swagger/index.html`, спека `GET /swagger/doc.json` (14 paths, 29 definitions).
|
||
- Генерация спеки: `swag init -g cmd/poc-server/main.go -o docs --parseInternal` из `D:/x0gp/server`. CLI ставится через `go install github.com/swaggo/swag/cmd/swag@v1.16.4`.
|
||
- Аннотации swag живут над хендлерами в `cmd/poc-server/main.go`, `catalog_handlers.go`, `races_handlers.go`. При добавлении нового REST-эндпоинта — добавить `@Router`/`@Param`/`@Success` и перегенерить `docs/`.
|
||
- Не использовать `--parseDependency`: падает на stdlib (`runtime/mprof.go`).
|
||
|
||
### Хранилище гонок (гибрид)
|
||
- **Live** (status=lobby|countdown|racing): in-memory `lobby.Service`.
|
||
- **Finished**: Postgres (`finished_races`), снапшот пишется в `lobby.SetRaceLifecycleHook` при `SetRaceStatus(finished)`.
|
||
- **Race plans** (`race_plans`): расписание, материализуется в lobby шедулером раз в 5 сек.
|
||
- **Queue** (`race_queue`): подписки `(driver_id, race_id)`.
|
||
|
||
### API гонок (keyset-пагинация)
|
||
- `GET /api/races` — список (live + finished), фильтры `status,track_id`, `cursor`, `limit` (1..200, default 50). Status enum: `all|lobby|racing|finished`. **Кастомных лобби нет** — гонки привязаны к физическим трекам, фильтр только по `track_id`. Cursor — base64(`ms:id[:src]`).
|
||
- `GET /api/races/upcoming?limit=3` — ближайшие lobby|countdown.
|
||
- `POST /api/races/queue/join` — встать в очередь на следующие N (body: `driver_id,limit` или header `X-Driver-Id`).
|
||
- `GET /api/races/queue?driver_id=...` — посмотреть.
|
||
- `DELETE /api/races/queue?driver_id=...&race_id=...` — выйти.
|
||
- `POST /api/races/plans` — создать расписание (`start_at_ms, interval_s, count, ...`).
|
||
- `GET /api/races/plans` — список планов (keyset `start_at_ms ASC, id ASC`).
|
||
- `DELETE /api/races/plans/{id}` — удалить.
|
||
|
||
### Сущности drivers и clans
|
||
- Таблицы `drivers` (id, nickname [3 uppercase letters], name, avatar_url, clan_id?) и `clans` (id, tag [3 uppercase letters], name, avatar_url).
|
||
- CRUD:
|
||
- `POST/GET /api/clans`, `GET/PUT/DELETE /api/clans/{id}`, `GET /api/clans/by-tag/{tag}`
|
||
- `POST/GET /api/drivers`, `GET/PUT/DELETE /api/drivers/{id}`, `GET /api/drivers/by-nick/{nick}`
|
||
- `PUT /api/drivers/{id}` принимает `clan_id` как `*string` (nil = оставить, "" = очистить, иначе = назначить).
|
||
- Сидер (через `--seed-races`) заполняет 3 клана и 8 водителей, треки берутся из `tracks` каталога (никаких выдуманных id в `finished_races`/`race_plans`).
|
||
- Podium в `LobbyRace` заполняется только для finished-гонок (top-3: position, driver_id, name, total_time_ms).
|
||
|
||
### TODO
|
||
- Реальная сущность driver ещё не используется для **lobby.DriverMeta** при входе через WS — там пока захардкоженный driver. При первой сессии надо подтягивать профиль из таблицы `drivers` и звать `lobby.SetDriverProfile(id, nick, avatar, clanID, clanTag)`.
|
||
|
||
### Сид моковых гонок
|
||
- `poc-server.exe --seed-races` — при старте наполняет БД и lobby детерминированными моками: 30 finished, 5 live, 5 plans, 4 queue-entries.
|
||
- `poc-server.exe --seed-races --reset` — сначала `TRUNCATE finished_races, race_plans, race_queue` и очищает lobby.
|
||
- Без флага `--seed-races` сидер не запускается, даже если `X0GP_SEED_RACES=1` (флаг > env).
|
||
- Драйвер — константный, водители в lobby под именами `driver-alice` … `driver-heidi`.
|
||
|
||
## Важные факты о машинке (x0gp F1 1/27)
|
||
|
||
- Масштаб: 1/27, wheelbase 102мм, deck 80×135мм, толщина 1.5мм PETG
|
||
- Мотор MVP: коллекторный 370 35T (Ø24×30мм) с Ozon
|
||
- ⚠️ `motor_mount.stl` сейчас под мотор 130/180 (Ø20мм) — надо перепечатать под Ø24мм до сборки
|
||
- Кузов печатаем сами (PETG, body_shell.stl), готовый Kyosho НЕ покупаем
|
||
- Подшипники: 684ZZ 4×9×4 (перед) + 693ZZ 3×8×4 (зад)
|
||
- ESP32-S3-DevKitC-1 N16R8 + U.FL (Wi-Fi агент, не RC-приёмник!)
|
||
- MPU-6050 пины: SDA=GPIO21, SCL=GPIO22 (это уже исправлено в ASSEMBLY.md)
|
||
- FPV: AIO модуль с WB (1997₽) + антенна RUSHFPV с AliExpress (1050₽) — это **разные вещи** (передатчик vs антенна к нему)
|
||
- VRX (приёмник видео) для MVP не нужен — показываем картинку через Wi-Fi стрим ESP32 на телефон/PC
|