docs: update AGENTS and README with engineering rules and guidelines
CI / changes (push) Successful in 11s
CI / openapi (push) Has been skipped
CI / go (push) Successful in 43s
CI / docker-web (push) Has been skipped
CI / docker-bird (push) Has been skipped
CI / bird2 (push) Successful in 21s
CI / docker-go (push) Successful in 3m41s
CI / changes (push) Successful in 11s
CI / openapi (push) Has been skipped
CI / go (push) Successful in 43s
CI / docker-web (push) Has been skipped
CI / docker-bird (push) Has been skipped
CI / bird2 (push) Successful in 21s
CI / docker-go (push) Successful in 3m41s
- Added engineering rules references in AGENTS.md for code changes and specific areas (web, BIRD). - Enhanced README.md to include links to engineering rules for different development areas. - Updated birdfmt documentation to specify engineering rules for BIRD/BGP/IP. - Clarified UI development guidelines in web/README.md to follow shadcn-svelte documentation and repository rules.
This commit is contained in:
@@ -0,0 +1,241 @@
|
||||
---
|
||||
description: Инженерные правила EvoBGP — Go, API, migrations, общие стандарты
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# Engineering Guidelines — EvoBGP
|
||||
|
||||
Специализированные правила: **Web UI** → `.cursor/rules/web-shadcn.mdc`; **BIRD2 / BGP / IP** → `.cursor/rules/networking-bird.mdc`.
|
||||
|
||||
Карта репозитория: `AGENTS.md`, `docs/architecture.md`. HTTP-контракт: `docs/openapi.yaml`.
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
**ARCH-01** | MUST | Новая persistence-логика — метод `store.Backend` + реализации в `repository` и `store.Memory`; SQL не в `httpapi`.
|
||||
*Rationale:* единая абстракция данных.
|
||||
*Проверка:* grep SQL в `internal/httpapi` — отсутствие; review.
|
||||
|
||||
**ARCH-02** | MUST | HTTP-маршруты только в `internal/httpapi`; регистрация через `http.ServeMux` с паттернами `METHOD /v1/...`.
|
||||
*Rationale:* один слой REST.
|
||||
*Проверка:* маршруты только в `routes.go`, `routes_crud.go`.
|
||||
|
||||
**ARCH-03** | MUST | Долгие операции (refresh, apply, rollback) — `jobs.Registry`; ответ `202` + `job_id` где задано OpenAPI.
|
||||
*Rationale:* не блокировать HTTP worker.
|
||||
*Проверка:* OpenAPI + handlers.
|
||||
|
||||
**ARCH-04** | MUST | Кросс-процессные воркеры — HTTP к API или общая БД; не shared memory (кроме `evobgp-all`).
|
||||
*Rationale:* `jobs.Registry` in-process only.
|
||||
*Проверка:* `docs/architecture.md`; review.
|
||||
|
||||
**ARCH-05** | MUST | `birdfmt` не импортирует `httpapi` / `store`.
|
||||
*Rationale:* направление зависимостей вниз.
|
||||
*Проверка:* `go list -deps` / review imports.
|
||||
|
||||
**ARCH-06** | MUST | Точки входа `cmd/*` — тонкий `main`: config, wiring, signal/shutdown; без бизнес-логики.
|
||||
*Rationale:* тестируемость `internal/`.
|
||||
*Проверка:* review `main.go`.
|
||||
|
||||
**ARCH-07** | MUST | Инициализация store + jobs для API и воркеров — `httpapi.BootstrapWorkers`.
|
||||
*Rationale:* единый wiring.
|
||||
*Проверка:* `bootstrap.go`.
|
||||
|
||||
**ARCH-08** | MUST | Ingest+render префиксов — `internal/pipeline`; генерация BIRD-текста — `internal/birdfmt`.
|
||||
*Rationale:* разделение data plane / control plane.
|
||||
*Проверка:* review пакетов.
|
||||
|
||||
**ARCH-09** | NEVER | Прямой доступ handler'ов к `pgxpool` для CRUD; только `store.Backend`.
|
||||
*Rationale:* абстракция бэкенда.
|
||||
*Проверка:* review `httpapi`.
|
||||
|
||||
**ARCH-10** | MUST | Подпись бандлов — `internal/bundle` + `internal/signing`; не дублировать crypto в handlers.
|
||||
*Rationale:* единая криптография артефактов.
|
||||
*Проверка:* review.
|
||||
|
||||
---
|
||||
|
||||
## Code Style
|
||||
|
||||
**STYLE-01** | MUST | Go-код после `gofmt`; перед PR — `go vet ./...`.
|
||||
*Rationale:* единый стиль.
|
||||
*Проверка:* CI job `go`.
|
||||
|
||||
**STYLE-02** | MUST | Экспортируемые типы/функции публичных пакетов — godoc-комментарий.
|
||||
*Rationale:* навигация по API пакетов.
|
||||
*Проверка:* review.
|
||||
|
||||
**STYLE-03** | NEVER | `panic` в `internal/*` вне `init` и тестов.
|
||||
*Rationale:* предсказуемые ошибки.
|
||||
*Проверка:* grep `panic(`.
|
||||
|
||||
**STYLE-04** | MUST | Ошибки пакетов с префиксом (`birdfmt:`, `db:`, `httpapi:`) и `%w` при оборачивании.
|
||||
*Rationale:* трассировка.
|
||||
*Проверка:* review.
|
||||
|
||||
**STYLE-05** | MUST | HTTP-ошибки — `writeProblem` / `writeJSON` (`application/problem+json` для 4xx/5xx).
|
||||
*Rationale:* RFC 9457, OpenAPI.
|
||||
*Проверка:* `problem.go`.
|
||||
|
||||
**STYLE-06** | MUST | JSON полей HTTP DTO согласованы с `docs/openapi.yaml`.
|
||||
*Rationale:* контракт API.
|
||||
*Проверка:* OpenAPI diff + review.
|
||||
|
||||
---
|
||||
|
||||
## Dependency Management
|
||||
|
||||
**DEP-01** | MUST | Go-зависимости — через `go get` / `go.mod`; версия Go как в `go.mod` и CI (1.24).
|
||||
*Проверка:* `go.mod`, `.gitea/workflows/ci.yaml`.
|
||||
|
||||
**DEP-02** | NEVER | Vendor-копирование без явного решения в репозитории.
|
||||
*Проверка:* review.
|
||||
|
||||
**DEP-03** | MUST | Миграции схемы — пары `.up.sql`/`.down.sql` для **postgres** и **sqlite**, синхронная нумерация.
|
||||
*Проверка:* `migrations/postgres/`, `migrations/sqlite/`.
|
||||
|
||||
**DEP-04** | MUST | Web UI-библиотеки — только экосистема shadcn-svelte/bits-ui (см. `web-shadcn.mdc`).
|
||||
*Проверка:* `web/package.json` review.
|
||||
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
**ERR-01** | MUST | HTTP 5xx — без сырого `err.Error()` клиенту; detail через `writeProblem`.
|
||||
*Проверка:* review handlers.
|
||||
|
||||
**ERR-02** | MUST | Публичные функции I/O — `(T, error)`; `errors.Is`/`errors.As` для sentinel.
|
||||
*Проверка:* review.
|
||||
|
||||
**ERR-03** | MUST | `context.Context` — первый аргумент для I/O; таймауты на внешние HTTP (CDN, DoH, RIPEstat).
|
||||
*Проверка:* `pipeline`, `bootstrap.go`.
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
**TEST-01** | MUST | Перед PR: `go test ./... -race -count=1`.
|
||||
*Проверка:* CI job `go`.
|
||||
|
||||
**TEST-02** | MUST | Табличные тесты — эталон для `birdfmt`, `pipeline`, `bundle`.
|
||||
*Проверка:* `*_test.go`.
|
||||
|
||||
**TEST-03** | MUST | Новые BIRD-сценарии в `internal/birdfmt/testdata/scenarios/*/bird.conf` + `bird -p`.
|
||||
*Проверка:* CI job `bird2`.
|
||||
|
||||
**TEST-04** | MUST | Изменения `web/` — локально `npm run check` и `npm run lint` (CI web пока не в scope).
|
||||
*Проверка:* локальные команды.
|
||||
|
||||
**TEST-05** | MUST | Изменения OpenAPI — `npx @redocly/cli lint docs/openapi.yaml`.
|
||||
*Проверка:* CI job `openapi`.
|
||||
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
**DOC-01** | MUST | Пользовательская документация в `docs/` — на русском.
|
||||
*Проверка:* review.
|
||||
|
||||
**DOC-02** | MUST | Изменение HTTP API: сначала `docs/openapi.yaml`, затем handlers/store, затем `docs/api.md` при необходимости.
|
||||
*Проверка:* PR diff order.
|
||||
|
||||
**DOC-03** | MUST | Расхождение spec/код — явно в `docs/access.md` или description операции OpenAPI.
|
||||
*Проверка:* review (напр. `X-Tenant-Id`).
|
||||
|
||||
**DOC-04** | NEVER | Дублировать длинные фрагменты OpenAPI в комментариях; ссылка на путь/operationId.
|
||||
*Проверка:* review.
|
||||
|
||||
---
|
||||
|
||||
## Naming Conventions
|
||||
|
||||
**NAME-01** | MUST | Бинарники: `cmd/evobgp-<role>/main.go`.
|
||||
*Проверка:* `cmd/`.
|
||||
|
||||
**NAME-02** | MUST | Env-переменные: префикс `EVOBGP_`.
|
||||
*Проверка:* `internal/config`, `docs/access.md`.
|
||||
|
||||
**NAME-03** | MUST | Job kinds — константы в `internal/jobs/worker.go` (`module_refresh`, …).
|
||||
*Проверка:* grep `Kind`.
|
||||
|
||||
**NAME-04** | MUST | ID сущностей — UUID-строки; tenant только из API-ключа (auth context), не из недокументированных заголовков.
|
||||
*Проверка:* `auth.go`, `docs/access.md`.
|
||||
|
||||
---
|
||||
|
||||
## Performance
|
||||
|
||||
**PERF-01** | MUST | Списки API — пагинация `cursor` + `limit`; не unbounded выборки в handlers.
|
||||
*Проверка:* OpenAPI + store methods.
|
||||
|
||||
**PERF-02** | MUST | CDN HTTP — переиспользуемый `http.Client` с таймаутом (45s в bootstrap).
|
||||
*Проверка:* `bootstrap.go`.
|
||||
|
||||
**PERF-03** | MUST | Новые метрики — `internal/observability`, экспорт `/metrics`.
|
||||
*Проверка:* review.
|
||||
|
||||
---
|
||||
|
||||
## Security
|
||||
|
||||
**SEC-01** | NEVER | Секреты, API-ключи, токены в Git.
|
||||
*Проверка:* review; `docs/access.md`.
|
||||
|
||||
**SEC-02** | NEVER | `EVOBGP_DEV_INSECURE=1` в production.
|
||||
*Проверка:* ops review.
|
||||
|
||||
**SEC-03** | MUST | Роль `node` — только node API; CRUD — `403` для `node`.
|
||||
*Проверка:* `auth.go`, handlers.
|
||||
|
||||
**SEC-04** | MUST | apply/rollback/settings — operator (или выше по `roleLevel`).
|
||||
*Проверка:* review handlers.
|
||||
|
||||
**SEC-05** | MUST | Бандл на ноде — `verify-bundle` перед `apply-bundle`.
|
||||
*Проверка:* `docs/access.md`.
|
||||
|
||||
**SEC-06** | MUST | CORS — явный whitelist `EVOBGP_CORS_ORIGINS`.
|
||||
*Проверка:* `cors.go`.
|
||||
|
||||
---
|
||||
|
||||
## Documentation Sync Rules
|
||||
|
||||
| Область | Источник |
|
||||
|---------|----------|
|
||||
| Go / net/http | https://go.dev/doc/ |
|
||||
| pgx v5 | https://pkg.go.dev/github.com/jackc/pgx/v5 |
|
||||
| OpenAPI / problem+json | `docs/openapi.yaml`, RFC 9457 |
|
||||
| Svelte / Kit | https://svelte.dev/docs , https://kit.svelte.dev/docs |
|
||||
| shadcn-svelte | https://shadcn-svelte.com/docs |
|
||||
| BIRD 2 | https://bird.network.cz/?get_doc |
|
||||
| Prometheus Go | https://pkg.go.dev/github.com/prometheus/client_golang |
|
||||
|
||||
**DOC-SYNC-01** | MUST | Новый API библиотеки — сверка версии в `go.mod`/`package.json` с официальной документацией.
|
||||
**DOC-SYNC-02** | NEVER | Устаревшие примеры (Svelte 4 `export let`, deprecated pgx).
|
||||
**DOC-SYNC-03** | MUST | Конфликт docs: **OpenAPI (HTTP)** → **код** → обзорные `docs/`; `.cursor/plans/` не контракт.
|
||||
**DOC-SYNC-04** | MUST | Сомнения по Svelte — Svelte MCP / `npm run check`.
|
||||
**DOC-SYNC-05** | MUST | BIRD — официальная документация BIRD2 + `networking-bird.mdc` + `go test ./internal/birdfmt/...`.
|
||||
|
||||
Приоритет при сомнениях — **официальные источники**, не блоги и не «память модели».
|
||||
|
||||
---
|
||||
|
||||
## Enforcement Strategy
|
||||
|
||||
**CI (Gitea):** OpenAPI lint; `go vet`, `go test -race`, build `cmd/*`; `bird -p` на scenarios; Docker bake на push.
|
||||
|
||||
**Локально перед PR:**
|
||||
|
||||
```powershell
|
||||
go vet ./...
|
||||
go test ./... -race -count=1
|
||||
npx @redocly/cli lint docs/openapi.yaml
|
||||
# web: cd web; npm run check; npm run lint
|
||||
# birdfmt: go test ./internal/birdfmt/... -count=1
|
||||
```
|
||||
|
||||
**Рекомендуется (не внедрено):** CI job `web`; `.golangci.yml`; pre-commit gofmt/prettier.
|
||||
|
||||
**Только code review:** слои SQL; роли; idempotency; OpenAPI bodies; secrets в compose.
|
||||
|
||||
**Известные ограничения:** `X-Tenant-Id` в OpenAPI не реализован в handlers; `jobs.Registry` не shared между процессами API и отдельными воркерами без HTTP.
|
||||
@@ -0,0 +1,219 @@
|
||||
---
|
||||
description: EvoBGP — BIRD2, BGP policy, IP/CIDR, маршрутизация, валидация конфигов
|
||||
globs:
|
||||
- internal/birdfmt/**
|
||||
- internal/birddeploy/**
|
||||
- internal/pipeline/**
|
||||
- deploy/bird/**
|
||||
- "**/testdata/scenarios/**"
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
# Networking & Routing Rules
|
||||
|
||||
Общие правила: `.cursor/rules/engineering.mdc`. Пакет BIRD: `internal/birdfmt/doc.go`.
|
||||
|
||||
## Single source of truth
|
||||
|
||||
| Домен | SSOT |
|
||||
|-------|------|
|
||||
| Префиксы для анонса | Модули tenant → materialized snapshot → ревизия (`store`, `pipeline`, `CreateRenderRevision`) |
|
||||
| Текст BIRD-фрагментов | `internal/birdfmt` — только генератор `evobgp_*.conf` |
|
||||
| Каркас `bird.conf` | Operator skeleton + `include` (`StandardIncludeFragments`) |
|
||||
| Параметры BIRD tenant | Global settings: `bird_router_id`, `bird_local_asn`, … (`docs/manual.md`) |
|
||||
| BGP peers | `BGPPeer` + `ParsePeerNeighbor` |
|
||||
|
||||
**BIRD2 docs:** https://bird.network.cz/?get_doc
|
||||
|
||||
---
|
||||
|
||||
## A. BIRD2 Configuration Rules
|
||||
|
||||
**BIRD-01** | MUST | Имена фрагментов — константы `Fragment*` (`evobgp_prefixes_v4.conf`, …); include `bird.d/<name>`.
|
||||
*Rationale:* совместимость deploy.
|
||||
*Проверка:* `layout.go`; `go test ./internal/birdfmt/...`
|
||||
|
||||
**BIRD-02** | MUST | Порядок include: filters v4/v6 → BGP template → prefixes v4/v6 → peers (`StandardIncludeFragments`).
|
||||
*Rationale:* фильтры до ссылок.
|
||||
*Проверка:* scenario `standard_layout`; `bird -p`
|
||||
|
||||
**BIRD-03** | MUST | `bird.conf` (router id, device, direct, includes) отдельно от `bird.d/evobgp_*` (политика, префиксы).
|
||||
*Rationale:* атомарная подмена фрагментов.
|
||||
*Проверка:* review layout.
|
||||
|
||||
**BIRD-04** | MUST | Новая логика фильтрации — функция в `birdfmt` + unit-тест; NEVER дублировать filter-блок в два `.conf` вручную.
|
||||
*Rationale:* DRY v4/v6.
|
||||
*Проверка:* `filter_test.go`; review.
|
||||
|
||||
**BIRD-05** | MUST | Filter: префикс `evobgp_`, суффикс `_v4`/`_v6`; templates `bgp_template` / `bgp_template_v6`.
|
||||
*Проверка:* `bgp.go`, `layout.go`.
|
||||
|
||||
**BIRD-06** | MUST | `router id` — валидный IPv4 dotted-quad (`RenderMainBirdConf`).
|
||||
*Проверка:* `birdfmt` error; `bird -p`
|
||||
|
||||
**BIRD-07** | MUST | Communities — `RouteCommunityAttrs`; синтаксис `((a,b))` в `add()`, не `add(65000,1)`.
|
||||
*Проверка:* `community_bird_test.go`
|
||||
|
||||
**BIRD-08** | SHOULD | Комментарии `#` в preamble; в фрагментах — revision/module id где уместно.
|
||||
*Проверка:* review.
|
||||
|
||||
**BIRD-09** | NEVER | Ручное редактирование `evobgp_*.conf` на ноде без ревизии/бандла в control plane.
|
||||
*Rationale:* drift.
|
||||
*Проверка:* `evobgp-deploy` logs.
|
||||
|
||||
**BIRD-10** | MUST | Новый scenario: `testdata/scenarios/<name>/bird.conf` (+ `bird.d/`) проходит `bird -p`.
|
||||
*Проверка:* CI `bird2`
|
||||
|
||||
**BIRD-11** | MUST | Только BIRD **2.x**, не 1.6.
|
||||
*Проверка:* `bird --version`
|
||||
|
||||
**BIRD-12** | MUST | Apply: staging → `bird -p` → atomic swap → `birdc configure`; NEVER configure без parse check.
|
||||
*Проверка:* `birdctl.go`; `birddeploy` review.
|
||||
|
||||
---
|
||||
|
||||
## B. Routing Policy Rules
|
||||
|
||||
**RTE-01** | MUST | BGP template: `import none` на каждый AFI, если задача явно не добавляет import policy.
|
||||
*Rationale:* deny-by-default.
|
||||
*Проверка:* `bgp.go`
|
||||
|
||||
**RTE-02** | MUST | Export filter завершается `reject;`.
|
||||
*Проверка:* `filter.go`; `filter_export` scenario.
|
||||
|
||||
**RTE-03** | MUST | Анонс только префиксов materialized revision; NEVER static `route` вне pipeline/birdfmt без operator approval.
|
||||
*Проверка:* store snapshot; review.
|
||||
|
||||
**RTE-04** | NEVER | Анонс `0.0.0.0/0`, `::/0`, RFC1918/ULA, loopback, link-local, multicast, reserved без documented exception.
|
||||
*Проверка:* ingest validation; review.
|
||||
|
||||
**RTE-05** | NEVER | Префиксы чужих ASN без авторизации (IRR/RPKI — ops review).
|
||||
*Проверка:* ops review.
|
||||
|
||||
**RTE-06** | MUST | Отдельные export filters IPv4 и IPv6.
|
||||
*Проверка:* `RenderExportFilterIPv4/IPv6`
|
||||
|
||||
**RTE-07** | SHOULD | AS_PATH match — ASN из tenant modules; дедуп `filterUniqueASNs`.
|
||||
*Проверка:* unit tests.
|
||||
|
||||
**RTE-08** | MUST | Peer import/export overrides — расширение `birdfmt`, не ad-hoc в operator `bird.conf`.
|
||||
*Проверка:* review.
|
||||
|
||||
**RTE-09** | SHOULD | hold 90s / keepalive 30s — менять только с обоснованием в settings/docs.
|
||||
*Проверка:* review.
|
||||
|
||||
**RTE-10** | MUST | После apply — post-check `birdc`/метрики (`mergeBirdPostApplyMeta`, `EVOBGP_BIRDC_SOCKET`).
|
||||
*Проверка:* jobs meta; observability poller.
|
||||
|
||||
---
|
||||
|
||||
## C. IP Addressing Rules
|
||||
|
||||
**IP-01** | MUST | CIDR в Go — `netip.Prefix`; строка — `Masked().String()`.
|
||||
*Проверка:* `pipeline/parse.go`
|
||||
|
||||
**IP-02** | MUST | IPv4/IPv6 — отдельные fragments/filters.
|
||||
*Проверка:* `layout.go`
|
||||
|
||||
**IP-03** | MUST | BGP neighbor — `ParsePeerNeighbor`; `/32`/`/128` нормализуются в host addr.
|
||||
*Проверка:* `peer_neighbor_test.go`
|
||||
|
||||
**IP-04** | NEVER | Hardcoded production CIDR вне testdata/fixtures.
|
||||
*Проверка:* grep; review.
|
||||
|
||||
**IP-05** | MUST | Fixtures/docs — TEST-NET (RFC 5737, 3849): `203.0.113.0/24`, `198.51.100.0/24`, `2001:db8::/32`.
|
||||
*Проверка:* scenarios.
|
||||
|
||||
**IP-06** | MUST | Domain→IP: host routes `/32`, `/128` via `ipToHostPrefix`; invalid отбрасывается.
|
||||
*Проверка:* `collect_parallel.go`
|
||||
|
||||
**IP-07** | MUST | IP range entries — валидный CIDR на границе API/store.
|
||||
*Проверка:* httpapi; review.
|
||||
|
||||
**IP-08** | SHOULD | Множество префиксов — без дубликатов; агрегация — policy decision.
|
||||
*Проверка:* snapshot dedup.
|
||||
|
||||
**IP-09** | MUST | `router id`, `local as` — из tenant settings, не hardcode в callers `birdfmt`.
|
||||
*Проверка:* `docs/manual.md`
|
||||
|
||||
**IP-10** | NEVER | Reserved blocks (`0.0.0.0/8`, `127.0.0.0/8`, `169.254.0.0/16`, `224.0.0.0/4`, IPv6 analogs) в materialized prefixes.
|
||||
*Проверка:* review; future validator.
|
||||
|
||||
---
|
||||
|
||||
## D. Internet Compliance
|
||||
|
||||
**COMP-01** | SHOULD | Policy changes — сверка RFC 4271, 4760, 7454 (обзор).
|
||||
*Проверка:* review.
|
||||
|
||||
**COMP-02** | MUST | No excessive deaggregation без need.
|
||||
*Проверка:* review prefix list.
|
||||
|
||||
**COMP-03** | MUST | Standard community 0..65535; large — schema store.
|
||||
*Проверка:* `community_bird_test.go`
|
||||
|
||||
**COMP-04** | NEVER | AS_PATH/MED manipulation без product spec.
|
||||
*Проверка:* review output.
|
||||
|
||||
**COMP-05** | SHOULD | Revision/job meta: source, counts, samples (`revisionLogEntry`).
|
||||
*Проверка:* jobs.
|
||||
|
||||
**COMP-06** | MUST | Node: `evobgp-node verify-bundle` перед apply.
|
||||
*Проверка:* `docs/access.md`
|
||||
|
||||
**COMP-07** | SHOULD | `bird_local_asn` = `local as` в templates/peers.
|
||||
*Проверка:* settings + birdfmt.
|
||||
|
||||
**COMP-08** | NEVER | Default route leak без named `default-originate` policy.
|
||||
*Проверка:* export filter review.
|
||||
|
||||
---
|
||||
|
||||
## Validation & Observability
|
||||
|
||||
**VAL-01** | MUST | Перед деплоем: `bird -c <bird.conf> -p` (main + includes).
|
||||
*Проверка:* CI `bird2`; `ParseCheck`
|
||||
|
||||
**VAL-02** | MUST | Preview ревизии read-only; apply — jobs/apply/bundle only.
|
||||
*Проверка:* OpenAPI + httpapi.
|
||||
|
||||
**VAL-03** | MUST | Изменения birdfmt — `go test ./internal/birdfmt/...`.
|
||||
*Проверка:* CI `go`
|
||||
|
||||
**VAL-04** | SHOULD | Dry-run apply где API поддерживает `dry_run`.
|
||||
*Проверка:* routes.go.
|
||||
|
||||
**VAL-05** | MUST | `/metrics` Prometheus; `EVOBGP_BIRDC_SOCKET` — BGP session poller.
|
||||
*Проверка:* `observability`
|
||||
|
||||
**VAL-06** | MUST | Логировать job_id, revision_id, speaker_id на apply/refresh/rollback.
|
||||
*Проверка:* jobs API.
|
||||
|
||||
**VAL-07** | SHOULD | После apply — `birdc show protocols` / parsers в `birdfmt`.
|
||||
*Проверка:* `protocols.go`
|
||||
|
||||
**VAL-08** | MUST | Мониторить drift: `last_applied_revision_id` vs published (`evobgp-deploy`).
|
||||
*Проверка:* deploy worker.
|
||||
|
||||
---
|
||||
|
||||
## Documentation Sync
|
||||
|
||||
**DOC-SYNC-05** | MUST | BIRD — https://bird.network.cz/?get_doc
|
||||
**DOC-SYNC-08** | MUST | BGP policy — RFC 4271, 4760, 7454 + BIRD docs + `birdfmt`
|
||||
**DOC-SYNC-09** | MUST | CIDR — https://pkg.go.dev/net/netip ; примеры — RFC 5737, 3849
|
||||
|
||||
---
|
||||
|
||||
## Enforcement
|
||||
|
||||
```powershell
|
||||
go test ./internal/birdfmt/... ./internal/pipeline/... -count=1
|
||||
bird -c internal/birdfmt/testdata/scenarios/<name>/bird.conf -p
|
||||
```
|
||||
|
||||
**PR checklist `birdfmt/**`, `pipeline/**`, `deploy/bird/**`:**
|
||||
- [ ] filter + unit-test + `bird -p`
|
||||
- [ ] нет дубли filter logic v4/v6 без общей Go-функции
|
||||
- [ ] префиксы только store/revision path
|
||||
- [ ] `import none` на templates сохранён
|
||||
@@ -0,0 +1,109 @@
|
||||
---
|
||||
description: EvoBGP WebUI — shadcn-svelte, Svelte 5, слои ui/core|patterns|app
|
||||
globs:
|
||||
- web/**
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
# Web UI — shadcn-svelte
|
||||
|
||||
**Источник правды:** https://shadcn-svelte.com/docs (не React shadcn/ui, не Legacy Docs).
|
||||
|
||||
Общие правила Go/API: `.cursor/rules/engineering.mdc`. Локальная карта: `web/README.md`.
|
||||
|
||||
## Слои UI
|
||||
|
||||
| Слой | Путь | Назначение |
|
||||
|------|------|------------|
|
||||
| Примитивы | `src/lib/ui/core/` | shadcn-svelte (только CLI `add`) |
|
||||
| Паттерны | `src/lib/ui/patterns/` | FormField, AppDataTable, ConfirmDialog, EmptyState |
|
||||
| App chrome | `src/lib/ui/app/` | Layout, PageHeader, `notify` |
|
||||
| Legacy | `src/lib/components/ui/` | Re-export; **не добавлять новые файлы** |
|
||||
|
||||
Тема: `src/routes/layout.css`, `src/lib/ui/app/tokens.md`. CLI из `web/`: `npx shadcn-svelte@latest add <component> -y -o`.
|
||||
|
||||
---
|
||||
|
||||
## Правила
|
||||
|
||||
**WEB-01** | MUST | Перед новым UI — проверить https://shadcn-svelte.com/docs/components; использовать компонент, не HTML+CSS с нуля.
|
||||
*Rationale:* Open Code + единый дизайн.
|
||||
*Проверка:* review; нет голых `<button class=…>`.
|
||||
|
||||
**WEB-02** | MUST | Отсутствующий примитив — `npx shadcn-svelte@latest add <component> -y -o` → `src/lib/ui/core/`.
|
||||
*Rationale:* Distribution через CLI и `components.json`.
|
||||
*Проверка:* файлы только в `ui/core`.
|
||||
|
||||
**WEB-03** | NEVER | Альтернативные UI-kit'ы (Material, Vuetify, DaisyUI-only без shadcn-примитива).
|
||||
*Проверка:* `package.json` review.
|
||||
|
||||
**WEB-04** | MUST | Комозиция по docs: все sub-компоненты (`DialogHeader`, `TableRow`, `Field`, …).
|
||||
*Проверка:* сверка со страницей компонента в docs.
|
||||
|
||||
**WEB-05** | MUST | Формы — Formsnap + `sveltekit-superforms`; UI в `ui/patterns/form`, не ad-hoc валидация на странице.
|
||||
*Проверка:* https://shadcn-svelte.com/docs/components/form
|
||||
|
||||
**WEB-06** | MUST | Таблицы — Data Table + `@tanstack/table-core`; на страницах — `AppDataTable` из patterns.
|
||||
*Проверка:* https://shadcn-svelte.com/docs/components/data-table
|
||||
|
||||
**WEB-07** | MUST | Toast — Sonner через `notify` из `ui/app/toast.js`.
|
||||
*Проверка:* https://shadcn-svelte.com/docs/components/sonner
|
||||
|
||||
**WEB-08** | MUST | Иконки — `@lucide/svelte` (`components.json` → `iconLibrary: lucide`).
|
||||
*Проверка:* imports.
|
||||
|
||||
**WEB-09** | MUST | Цвета — CSS-переменные `layout.css` и токены `tokens.md`; не hex/rgb на страницах.
|
||||
*Проверка:* grep `#[0-9a-f]{3,6}` в `routes/`.
|
||||
|
||||
**WEB-10** | SHOULD | Кастомизация — правка `ui/core` (Open Code), не `!important` поверх API.
|
||||
*Проверка:* review.
|
||||
|
||||
**WEB-11** | MUST | `routes/**` — композиция `ui/core` + `ui/patterns` + `ui/app`; не копировать целые примитивы shadcn в route.
|
||||
*Проверка:* review.
|
||||
|
||||
**WEB-12** | NEVER | Примеры React shadcn/ui или Svelte 4 Legacy без адаптации под https://shadcn-svelte.com/docs/migration/svelte-5
|
||||
*Проверка:* `npm run check`.
|
||||
|
||||
**WEB-13** | MUST | Реактивность — Svelte 5 runes (`$state`, `$derived`, `$effect`); не `export let` для локального state страниц.
|
||||
*Проверка:* `npm run check`; Svelte MCP.
|
||||
|
||||
**WEB-14** | SHOULD | Нетривиальный UI — прочитать страницу компонента (props, a11y).
|
||||
*Проверка:* PR description.
|
||||
|
||||
**WEB-15** | MUST | Сомнения — https://shadcn-svelte.com/llms.txt , Svelte MCP, `npm run check`.
|
||||
*Проверка:* локально.
|
||||
|
||||
**WEB-16** | MUST | Подтверждение удаления — `ConfirmDialog` из patterns, не `window.confirm`.
|
||||
*Проверка:* review.
|
||||
|
||||
**WEB-17** | MUST | Пустые списки — `EmptyState` из patterns.
|
||||
*Проверка:* review.
|
||||
|
||||
**WEB-18** | SHOULD | Повторяемая комбинация core (≥2 раза) — вынести в `ui/patterns/`.
|
||||
*Проверка:* review.
|
||||
|
||||
---
|
||||
|
||||
## Documentation Sync (Web)
|
||||
|
||||
**DOC-SYNC-06** | MUST | UI — первично https://shadcn-svelte.com/docs; при конфликте с блогами/Stack Overflow побеждает официальная страница компонента.
|
||||
**DOC-SYNC-07** | MUST | Перед `add` — сверить Installation/Theming с `web/components.json` и `src/routes/layout.css`.
|
||||
|
||||
Tailwind v4: https://shadcn-svelte.com/docs/migration/tailwind-v4
|
||||
|
||||
---
|
||||
|
||||
## Enforcement
|
||||
|
||||
```powershell
|
||||
cd web
|
||||
npm run check
|
||||
npm run lint
|
||||
```
|
||||
|
||||
**PR checklist `web/**`:**
|
||||
- [ ] `ui/core` / `ui/patterns`, не дубли примитивов
|
||||
- [ ] Новые примитивы через shadcn CLI
|
||||
- [ ] Ссылка на docs компонента (если новый паттерн)
|
||||
|
||||
**CI:** job `web` рекомендован; пока обязательно локально.
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
## С чего начать (минимум чтения)
|
||||
|
||||
0. **Инженерные правила** — при изменении кода следовать [.cursor/rules/engineering.mdc](.cursor/rules/engineering.mdc); для `web/` — [.cursor/rules/web-shadcn.mdc](.cursor/rules/web-shadcn.mdc); для `birdfmt` / `pipeline` / BIRD — [.cursor/rules/networking-bird.mdc](.cursor/rules/networking-bird.mdc).
|
||||
1. **[docs/README.md](docs/README.md)** — оглавление и роли читателя.
|
||||
2. **[docs/architecture.md](docs/architecture.md)** — компоненты `cmd/`, карта `internal/`, потоки данных (одного этого файла обычно достаточно для ориентации).
|
||||
3. Задача-специфично: [docs/api.md](docs/api.md), [docs/access.md](docs/access.md), [web/README.md](web/README.md) — только если меняете API, доступ или фронт.
|
||||
|
||||
+9
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
## По роли читателя
|
||||
|
||||
- **ИИ-агент / ассистент в репозитории** — [../AGENTS.md](../AGENTS.md): с чего начать чтение, карта `internal/` и `cmd/`, что не тащить в контекст.
|
||||
- **ИИ-агент / ассистент в репозитории** — [../AGENTS.md](../AGENTS.md): с чего начать чтение, карта `internal/` и `cmd/`, что не тащить в контекст. **Инженерные правила:** [../.cursor/rules/engineering.mdc](../.cursor/rules/engineering.mdc) (общие), [../.cursor/rules/web-shadcn.mdc](../.cursor/rules/web-shadcn.mdc) (Web UI), [../.cursor/rules/networking-bird.mdc](../.cursor/rules/networking-bird.mdc) (BIRD2/BGP/IP).
|
||||
- **Оператор / DevOps** — [quickstart.md](quickstart.md), [architecture.md](architecture.md), [access.md](access.md), [deploy/compose/docker-compose.yaml](../deploy/compose/docker-compose.yaml).
|
||||
- **Разработчик бэкенда или интегратор API** — [api.md](api.md), [access.md](access.md), [openapi.yaml](openapi.yaml), исходники маршрутов в `internal/httpapi/`.
|
||||
- **Разработчик фронтенда** — [quickstart.md](quickstart.md) (раздел про `web/` и CORS), [api.md](api.md), [../web/README.md](../web/README.md).
|
||||
@@ -24,6 +24,14 @@
|
||||
| [OPENAPI-GITEA.md](OPENAPI-GITEA.md) | Как открыть HTML-документацию API (в т.ч. из Gitea) |
|
||||
| [evobgp-api-sketches.md](evobgp-api-sketches.md) | Ранний черновик идей API (контекст, не замена OpenAPI) |
|
||||
|
||||
## Инженерные правила (Cursor / разработка)
|
||||
|
||||
| Файл | Область |
|
||||
|------|---------|
|
||||
| [../.cursor/rules/engineering.mdc](../.cursor/rules/engineering.mdc) | Go, API, migrations, security, enforcement |
|
||||
| [../.cursor/rules/web-shadcn.mdc](../.cursor/rules/web-shadcn.mdc) | SvelteKit, shadcn-svelte |
|
||||
| [../.cursor/rules/networking-bird.mdc](../.cursor/rules/networking-bird.mdc) | BIRD2, BGP policy, IP/CIDR |
|
||||
|
||||
## Репозиторий и CI
|
||||
|
||||
- [../.gitea/README.md](../.gitea/README.md) — Gitea Actions, runner, сборка образов и push в Container Registry.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// Engineering rules for BIRD/BGP/IP: .cursor/rules/networking-bird.mdc
|
||||
//
|
||||
// Package birdfmt builds BIRD 2 configuration text: main bird.conf skeleton, include
|
||||
// fragments under bird.d/, export filters, static route protocols, BGP templates, and
|
||||
// BGP peer protocols (from template or standalone). Runtime helpers parse-check configs
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
SvelteKit-приложение панели управления EvoBGP. Запуск — [docs/quickstart.md](../docs/quickstart.md).
|
||||
|
||||
Разработка UI **обязательно** следует официальной документации [shadcn-svelte](https://shadcn-svelte.com/docs) и правилам репозитория [.cursor/rules/web-shadcn.mdc](../.cursor/rules/web-shadcn.mdc): максимум нативных компонентов из registry, установка только через CLI в `src/lib/ui/core/`.
|
||||
|
||||
## UI-архитектура
|
||||
|
||||
| Путь | Назначение |
|
||||
|
||||
Reference in New Issue
Block a user