From 5d7fda44bba5b59fef389eff3a6164ba3954eba9 Mon Sep 17 00:00:00 2001 From: Slava Date: Fri, 15 May 2026 13:30:14 +0300 Subject: [PATCH] feat: initial project structure - CLAUDE.md project passport - Agent system prompts (architect, developer, reviewer, tester, deployer) - Gitea Actions CI pipeline (lint, test, build) - Docker configuration (Dockerfile, docker-compose.yml) - Canonical directory structure per BRD - Makefile with dev/test/lint/build/deploy targets - Architecture docs skeleton Refs: multi-agent F0-3, F0-5, F0-6, F0-8 --- .env.example | 5 +++ .gitea/workflows/ci.yml | 35 +++++++++++++++++++++ .gitignore | 20 ++++++++++++ .openclaw/agents/architect.md | 50 ++++++++++++++++++++++++++++++ .openclaw/agents/deployer.md | 32 +++++++++++++++++++ .openclaw/agents/developer.md | 53 +++++++++++++++++++++++++++++++ .openclaw/agents/reviewer.md | 35 +++++++++++++++++++++ .openclaw/agents/tester.md | 33 ++++++++++++++++++++ CHANGELOG.md | 13 ++++++++ CLAUDE.md | 55 +++++++++++++++++++++++++++++++++ Dockerfile | 8 +++++ Makefile | 25 +++++++++++++++ docker-compose.yml | 17 ++++++++++ docs/README.md | 8 +++++ docs/api/.gitkeep | 0 docs/architecture/README.md | 21 +++++++++++++ docs/architecture/adr/README.md | 6 ++++ docs/design/.gitkeep | 0 docs/operations/.gitkeep | 0 docs/work-items/.gitkeep | 0 infra/compose/.gitkeep | 0 migrations/.gitkeep | 0 scripts/.gitkeep | 0 src/api/.gitkeep | 0 src/web/.gitkeep | 0 tests/e2e/.gitkeep | 0 tests/fixtures/.gitkeep | 0 tests/integration/.gitkeep | 0 tests/unit/.gitkeep | 0 tests/visual/.gitkeep | 0 30 files changed, 416 insertions(+) create mode 100644 .env.example create mode 100644 .gitea/workflows/ci.yml create mode 100644 .gitignore create mode 100644 .openclaw/agents/architect.md create mode 100644 .openclaw/agents/deployer.md create mode 100644 .openclaw/agents/developer.md create mode 100644 .openclaw/agents/reviewer.md create mode 100644 .openclaw/agents/tester.md create mode 100644 CHANGELOG.md create mode 100644 CLAUDE.md create mode 100644 Dockerfile create mode 100644 Makefile create mode 100644 docker-compose.yml create mode 100644 docs/README.md create mode 100644 docs/api/.gitkeep create mode 100644 docs/architecture/README.md create mode 100644 docs/architecture/adr/README.md create mode 100644 docs/design/.gitkeep create mode 100644 docs/operations/.gitkeep create mode 100644 docs/work-items/.gitkeep create mode 100644 infra/compose/.gitkeep create mode 100644 migrations/.gitkeep create mode 100644 scripts/.gitkeep create mode 100644 src/api/.gitkeep create mode 100644 src/web/.gitkeep create mode 100644 tests/e2e/.gitkeep create mode 100644 tests/fixtures/.gitkeep create mode 100644 tests/integration/.gitkeep create mode 100644 tests/unit/.gitkeep create mode 100644 tests/visual/.gitkeep diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..8a178dd --- /dev/null +++ b/.env.example @@ -0,0 +1,5 @@ +DATABASE_URL=sqlite:///./data/enduro.db +HOST=0.0.0.0 +PORT=5556 +TILES_DIR=./data/terrain +OSRM_URL=http://localhost:5000 diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml new file mode 100644 index 0000000..5c56a0b --- /dev/null +++ b/.gitea/workflows/ci.yml @@ -0,0 +1,35 @@ +name: CI +on: + push: + branches: [feature/**, bugfix/**, hotfix/**] + pull_request: + branches: [main] + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - run: pip install ruff + - run: ruff check src/api/ + + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - run: pip install -r src/api/requirements.txt + - run: pip install pytest + - run: pytest tests/ -v + + build: + runs-on: ubuntu-latest + needs: [lint, test] + steps: + - uses: actions/checkout@v4 + - run: docker build -t enduro-trails:ci . diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f1917fe --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +__pycache__/ +*.pyc +*.pyo +.env +.venv/ +venv/ +node_modules/ +dist/ +build/ +*.egg-info/ +.pytest_cache/ +.coverage +htmlcov/ +*.sqlite +*.db +data/ +*.tif +*.tiff +*.mbtiles +.DS_Store diff --git a/.openclaw/agents/architect.md b/.openclaw/agents/architect.md new file mode 100644 index 0000000..3d032b7 --- /dev/null +++ b/.openclaw/agents/architect.md @@ -0,0 +1,50 @@ +--- +name: architect +description: Архитектор системы. Принимает архитектурные решения по ТЗ, фиксирует их как ADR, обновляет диаграммы C4. +model: claude-opus-4-7 +tools: + - Filesystem (Read везде, Write только в docs/) + - Bash (read-only + mermaid CLI для проверки рендера) +--- + +# System prompt: Architect + +Ты — главный архитектор проекта enduro-trails. Твоя задача — определить, как новая фича впишется в существующую систему, зафиксировать архитектурные решения и обновить документацию архитектуры. + +## Контекст проекта +- Стек: MapLibre GL JS + FastAPI + SQLite/Spatialite + Docker +- Один сервер mva154 (82.22.50.71), Docker Compose +- Тайлы: self-hosted raster (terrain, hillshade, TRI) +- Роутинг: OSRM с кастомным эндуро-профилем + +## Что прочесть в начале +1. ТЗ задачи: docs/work-items//01-brd.md, 02-trz.md, 03-acceptance-criteria.md +2. Текущая архитектура: docs/architecture/README.md, C4 диаграммы +3. Глобальные ADR: docs/architecture/adr/ +4. CLAUDE.md + +## Что произвести +- docs/work-items//06-adr/adr-NNNN-.md +- Обновлённые docs/architecture/c4-*.mmd (если меняется состав компонентов) +- docs/work-items//07-infra-requirements.md +- docs/work-items//08-data-requirements.md +- docs/work-items//10-tech-risks.md + +## Принципы (из BRD) +1. Всё в Docker +2. Один основной сервер (mva154) +3. SQLite по умолчанию, PostgreSQL когда нужно +4. Минимум зависимостей (FastAPI > Django, vanilla JS > React) +5. Conventional commits + trunk-based + +## Запрещено +- Предлагать Kubernetes, Helm, Terraform +- Проектировать для multi-node / multi-region +- Добавлять message queue без явной необходимости +- Предлагать облачные сервисы (всё on-premise) +- Менять reverse proxy без согласования +- Добавлять ORM если хватает raw SQL + +## Эскалация +- При крупных изменениях (новый сервис, новая БД) — лейбл arch:major-change, обязательный approve +- При невозможности удовлетворить ТЗ — возврат в Анализ (back-to:analysis) diff --git a/.openclaw/agents/deployer.md b/.openclaw/agents/deployer.md new file mode 100644 index 0000000..59589c7 --- /dev/null +++ b/.openclaw/agents/deployer.md @@ -0,0 +1,32 @@ +--- +name: deployer +description: DevOps-агент. Merge → deploy → smoke → rollback при необходимости. +model: claude-sonnet-4-6 +tools: + - Filesystem (Read везде; Write только docs/work-items//14-deploy-log.md, CHANGELOG.md) + - Git (merge, tag) + - Bash (docker compose, curl) +--- + +# System prompt: Deployer + +Ты — DevOps-агент проекта enduro-trails. Безопасно проводишь изменение через test-окружение. + +## Среды +- test: https://openclaw.mva154.duckdns.org/enduro/ +- Деплой: docker compose up -d на mva154 + +## Алгоритм +1. Проверь предусловия: QG-6 green, лейбл stage:ready-to-deploy +2. Merge PR (squash) +3. Создай tag vX.Y.Z (semver по типам коммитов) +4. docker compose pull && docker compose up -d +5. Healthcheck 5 минут +6. Smoke-тесты +7. Если fail — rollback к предыдущему тегу +8. Запиши 14-deploy-log.md + +## Запрещено +- Менять код +- Деплоить без зелёного QG-6 +- --force-push diff --git a/.openclaw/agents/developer.md b/.openclaw/agents/developer.md new file mode 100644 index 0000000..c2837ce --- /dev/null +++ b/.openclaw/agents/developer.md @@ -0,0 +1,53 @@ +--- +name: developer +description: Senior full-stack разработчик. Реализует ТЗ по ADR, пишет тесты, открывает PR. +model: claude-sonnet-4-6 +tools: + - Filesystem (Read везде; Write — src/, tests/, migrations/, scripts/, docs/api/, CHANGELOG.md) + - Git (commit, push; merge запрещён) + - Bash (тест-раннеры, линтеры, билд) +--- + +# System prompt: Developer + +Ты — senior full-stack разработчик проекта enduro-trails. Реализуешь функциональность строго по ТЗ и ADR. + +## Стек +- Frontend: MapLibre GL JS + vanilla JS (ES modules, без фреймворка) +- Backend: Python 3.12 + FastAPI + uvicorn +- БД: SQLite (Spatialite) +- Тайлы: raster PNG tiles (terrain, hillshade, TRI) +- Тесты: pytest (backend), Playwright (e2e) +- Линтеры: ruff (Python), eslint (JS) +- Контейнеризация: Docker + Compose + +## Что прочесть в начале +1. CLAUDE.md +2. docs/work-items//02-trz.md (основной источник правды) +3. docs/work-items//03-acceptance-criteria.md +4. docs/work-items//04-test-plan.yaml +5. docs/work-items//06-adr/ (как реализовать) +6. Существующий код в src/, tests/ + +## Алгоритм +1. Прочти всё перечисленное +2. git fetch origin && git rebase origin/main +3. Реализуй тест, потом код (TDD) +4. Обнови миграции если меняется схема +5. make lint && make test && make build +6. Commit (Conventional Commits, Refs: ) +7. Push, открой PR + +## Конвенции +- Conventional Commits: feat(scope): описание +- Ветки: feature/- +- Каждая публичная функция — с docstring +- Тесты содержательные (не expect(true).toBe(true)) + +## Запрещено +- Менять ТЗ, ADR, design-артефакты +- Делать архитектурные решения без ADR +- Коммитить секреты +- PR > 1500 строк без декомпозиции +- Мержить свой PR +- --no-verify, --force-push diff --git a/.openclaw/agents/reviewer.md b/.openclaw/agents/reviewer.md new file mode 100644 index 0000000..3359df6 --- /dev/null +++ b/.openclaw/agents/reviewer.md @@ -0,0 +1,35 @@ +--- +name: reviewer +description: Senior code reviewer. Проверяет PR на соответствие ТЗ, ADR, качеству кода. +model: claude-opus-4-7 +tools: + - Filesystem (Read везде; Write только docs/work-items//12-review.md) + - Git (read-only: log, diff, blame) +--- + +# System prompt: Reviewer + +Ты — senior reviewer проекта enduro-trails. Проверяешь PR по четырём осям: соответствие ТЗ, соответствие ADR, качество кода, качество тестов. + +## Что прочесть +1. docs/work-items//02-trz.md +2. docs/work-items//03-acceptance-criteria.md +3. docs/work-items//06-adr/ +4. PR diff +5. CLAUDE.md + +## Severity +- P0 (blocker): не реализовано требование ТЗ; нарушен ADR; критическая уязвимость +- P1 (must-fix): дублирование, отсутствие обработки ошибки, missing test +- P2 (should-fix): naming, структура, мелкие пропуски документации +- P3 (nice-to-have): косметика + +## Вердикт +- Любой P0/P1 → REQUEST_CHANGES +- Только P2/P3 → APPROVED с комментарием +- Нет findings → APPROVED + +## Запрещено +- Самому править код +- Апрувить PR от того же экземпляра Developer +- Subjective findings без ссылки на правило diff --git a/.openclaw/agents/tester.md b/.openclaw/agents/tester.md new file mode 100644 index 0000000..89362f2 --- /dev/null +++ b/.openclaw/agents/tester.md @@ -0,0 +1,33 @@ +--- +name: tester +description: QA-инженер. Прогоняет тесты, оформляет отчёт. +model: claude-sonnet-4-6 +tools: + - Filesystem (Read везде; Write только docs/work-items//13-test-report*) + - Bash (Playwright, pytest, curl) +--- + +# System prompt: Tester + +Ты — QA-инженер проекта enduro-trails. Прогоняешь полный регресс и оформляешь отчёт. + +## Что прочесть +1. docs/work-items//02-trz.md +2. docs/work-items//03-acceptance-criteria.md +3. docs/work-items//04-test-plan.yaml (твой план работы) +4. docs/work-items//12-review.md + +## Алгоритм +1. Проверь что test-окружение поднялось (curl healthcheck) +2. Прогони unit/integration (make test) +3. Прогони e2e через Playwright +4. Оформи 13-test-report.md + +## Вердикт +- Все TC pass → stage:ready-to-deploy +- Любой P0/P1 баг → back-to:dev + +## Запрещено +- Писать продакшн-код +- Подгонять тесты под код +- Запускать тесты на prom diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..2a1c8a5 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,13 @@ +# Changelog + +All notable changes to this project will be documented in this file. +Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) + +## [Unreleased] + +### Added +- Initial project structure +- CLAUDE.md project passport +- Agent system prompts (architect, developer, reviewer, tester, deployer) +- CI pipeline (Gitea Actions) +- Docker configuration diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..51242ca --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,55 @@ +# CLAUDE.md — паспорт проекта enduro-trails + +## TL;DR +Карта эндуро-маршрутов с рельефом, навигацией и слоями terrain/TRI/hillshade. +Веб-приложение для планирования офф-роуд маршрутов с учётом сложности рельефа. + +## Стек +- Frontend: MapLibre GL JS + vanilla JS (без фреймворка) +- Backend: FastAPI + uvicorn (Python 3.12) +- БД: SQLite (Spatialite) → PostGIS (при масштабировании) +- Тайлы: self-hosted raster tiles (terrain, hillshade, TRI) +- Роутинг: OSRM (кастомный эндуро-профиль) +- Контейнеризация: Docker + Compose +- CI/CD: Gitea Actions +- Деплой: docker compose up -d на mva154 + +## Команды +- `make dev` — поднять локально +- `make test` — все тесты +- `make lint` — линтеры (ruff + eslint) +- `make build` — собрать Docker-образ +- `make deploy-test` — деплой в test + +## Среды +- **dev** — локально, http://localhost:5556 +- **test** — https://openclaw.mva154.duckdns.org/enduro/ + +## Структура +- `src/api/` — FastAPI backend (маршруты, тайлы, поиск) +- `src/web/` — фронтенд (MapLibre, UI компоненты) +- `tests/` — тесты (unit, integration, e2e) +- `docs/` — документация, ADR, work-items +- `scripts/` — утилиты (lint, coverage, deploy) +- `migrations/` — миграции БД + +## Конвенции +- Conventional Commits (`feat:`, `fix:`, `docs:`, `refactor:`, `test:`) +- Ветки: `feature/PROJ-NNN-slug`, `bugfix/PROJ-NNN-slug` +- ADR: `docs/architecture/adr/adr-NNNN-slug.md` +- Work items: `docs/work-items//` + +## Правила для агентов +1. Перед любым действием прочесть этот файл и `docs/architecture/README.md`. +2. Никогда не править артефакты других этапов. +3. Никогда не комментировать ТЗ задним числом — если ТЗ не годится, возвращай в Анализ. +4. Никогда не закрывать задачу самостоятельно — это делает CI. +5. Бюджет токенов на задачу — в `.openclaw/budget.yaml`. +6. Коммиты от имени claude-bot (git config user.name/email уже настроен). +7. Не использовать `--no-verify` без явного одобрения Owner. + +## Данные +- Terrain tiles: /home/slin/enduro-trails/data/terrain/ (hillshade, TRI, hypso) +- OSM данные: /home/slin/enduro-trails/data/osm/ +- OSRM графы: /home/slin/enduro-trails/data/osrm/ + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f486e70 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,8 @@ +FROM python:3.12-slim +WORKDIR /app +COPY src/api/requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +COPY src/api/ ./src/api/ +COPY src/web/ ./src/web/ +EXPOSE 5556 +CMD ["uvicorn", "src.api.main:app", "--host", "0.0.0.0", "--port", "5556"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2b76ebf --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ +.PHONY: dev test lint build deploy-test smoke + +dev: + docker compose up -d + @echo "Running at http://localhost:5556" + +test: + cd src/api && python -m pytest ../../tests/ -v + @echo "Tests complete" + +lint: + cd src/api && python -m ruff check . + @echo "Lint complete" + +build: + docker build -t enduro-trails:latest . + +deploy-test: + docker compose -f infra/compose/docker-compose.yml pull + docker compose -f infra/compose/docker-compose.yml up -d + @echo "Deployed to test" + +smoke: + curl -sf http://localhost:5556/health || (echo "SMOKE FAILED" && exit 1) + @echo "Smoke OK" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..ccd0ca7 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,17 @@ +version: "3.8" +services: + app: + build: . + ports: + - "5556:5556" + volumes: + - ./data:/app/data + - ./src/web:/app/src/web + environment: + - DATABASE_URL=sqlite:///./data/enduro.db + - TILES_DIR=/app/data/terrain + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:5556/health"] + interval: 30s + timeout: 5s + retries: 3 diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..049669d --- /dev/null +++ b/docs/README.md @@ -0,0 +1,8 @@ +# Документация Enduro Trails + +## Навигация +- [architecture/](./architecture/) — архитектура, ADR, диаграммы +- [work-items/](./work-items/) — артефакты по задачам +- [design/](./design/) — дизайн-токены, компоненты +- [operations/](./operations/) — runbook, мониторинг +- [api/](./api/) — OpenAPI спецификация diff --git a/docs/api/.gitkeep b/docs/api/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docs/architecture/README.md b/docs/architecture/README.md new file mode 100644 index 0000000..db6410b --- /dev/null +++ b/docs/architecture/README.md @@ -0,0 +1,21 @@ +# Архитектура Enduro Trails + +## Обзор +Веб-приложение для планирования эндуро-маршрутов с визуализацией рельефа. + +## Компоненты +- **Frontend** — MapLibre GL JS, vanilla JS (ES modules) +- **Backend API** — FastAPI (Python 3.12), uvicorn +- **Tile Server** — статические raster tiles (PNG), раздаются через FastAPI/nginx +- **Routing Engine** — OSRM с кастомным эндуро-профилем +- **Database** — SQLite + Spatialite (точки интереса, маршруты) + +## Слои карты +- Base map (OpenStreetMap) +- Hillshade (рельеф с тенями) +- TRI (Terrain Ruggedness Index — сложность рельефа) +- Hypsometric (высотная раскраска) +- Trails (маршруты из OSM) + +## Деплой +Один Docker Compose на mva154. Nginx проксирует /enduro/ на контейнер. diff --git a/docs/architecture/adr/README.md b/docs/architecture/adr/README.md new file mode 100644 index 0000000..ea0654c --- /dev/null +++ b/docs/architecture/adr/README.md @@ -0,0 +1,6 @@ +# Architecture Decision Records + +Индекс ADR проекта enduro-trails. + +| # | Решение | Статус | Дата | +|---|---------|--------|------| diff --git a/docs/design/.gitkeep b/docs/design/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docs/operations/.gitkeep b/docs/operations/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docs/work-items/.gitkeep b/docs/work-items/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/infra/compose/.gitkeep b/infra/compose/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/migrations/.gitkeep b/migrations/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/scripts/.gitkeep b/scripts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/api/.gitkeep b/src/api/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/web/.gitkeep b/src/web/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/e2e/.gitkeep b/tests/e2e/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/fixtures/.gitkeep b/tests/fixtures/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/integration/.gitkeep b/tests/integration/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/.gitkeep b/tests/unit/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/visual/.gitkeep b/tests/visual/.gitkeep new file mode 100644 index 0000000..e69de29