Files
router-lists-ui/AI_READY_DEVELOPMENT_SPEC.md
denozord e8ba6d47e3
Publish Docker image / build-and-push (push) Successful in 1m0s
Refactor project structure and improve component organization
- Restructured project files for better maintainability and clarity.
- Enhanced component organization to streamline imports and improve readability.
- Updated relevant documentation to reflect changes in project structure.

Made-with: Cursor
2026-04-26 15:26:04 +07:00

32 KiB
Raw Permalink Blame History

AI-READY DEVELOPMENT SPEC

1. SYSTEM OVERVIEW (СИСТЕМНЫЙ КОНТЕКСТ)

Система router-lists-ui управляет сетевыми данными и конфигурациями RouterOS/MikroTik: домены, ASN, IP-диапазоны, фильтры, серверные конфиги, бэкапы и мониторинг доступности/ресурсов. UI (React + Vite) работает с API (Express) через /api/*.

Фактическая модель хранения гибридная:

  • справочники BGP (domains/asns/ip-ranges/communities/auto-urls) обслуживаются через EvoBGP API (evobgpClient);
  • локальные конфиги/кеш/версии хранятся в SQLite (better-sqlite3) через слой совместимости s3Service/blobStorage;
  • .rsc backup MikroTik хранится в локальной ФС (MIKROTIK_BACKUP_DIR).

Ключевые бизнес-процессы

  • Управление BGP-справочниками (CRUD через EvoBGP).
  • Управление фильтрами (global/simple) в app_filter_rules.
  • Управление серверами, server-configs, server-filters.
  • Генерация/применение MikroTik-конфигов и диагностические операции (ping/traceroute/speed-test).
  • Планировщики: network-map, ping-services, uptime-monitor, backups.
  • История/rollback для versioned blob-объектов.

Основные сущности

  • DomainCommunity: { domain, community }
  • AsnCommunity: { domain(asn), type(community) }
  • IpRangeCommunity: { ipRange, community }
  • Server: jumphost/exit + gateways + creds
  • FilterRule: { community, gateway, description, ...extra } + scope
  • BlobObject: logical key + body + etag + versions
  • UiSettings
  • MikrotikBackup

Критические ограничения (НЕ НАРУШАТЬ)

  • Нельзя заменять EvoBGP-данные локальной SQLite-логикой для domains-new/asns/ip-ranges/communities/auto-urls.
  • Нельзя удалять/ломать ETag-конкурентность (If-None-Match, If-Match, 412) в read/write API.
  • Нельзя ломать namespace/ключи blob-объектов (servers.json, filter-manager/*, bgp_data/rt_ui_settings.json и т.д.) без миграционного плана.
  • Нельзя отключать journal_mode=WAL, foreign_keys=ON, busy_timeout.
  • Нельзя менять формат ответа ошибок { code, message, details, requestId }.

2. REPOSITORY MAP (КАРТА РЕПОЗИТОРИЯ)

Примечание: в текущем репозитории нет отдельных top-level директорий /db, /services, /api, /agents; их роль реализована внутри backend/.

/frontend

  • Назначение: UI-приложение (React 19, react-router-dom, @tanstack/react-query, axios, Tabler).
  • Ключевые зоны:
    • src/App.jsx: роутинг, layout, providers (QueryClientProvider, NotifyProvider, PingProvider, AlertsProvider).
    • src/lib/api.js: единый HTTP-клиент, retry, ETag-based GET-cache, нормализация ошибок.
    • src/hooks/useApiQuery.js: реактивный data-layer + optimistic updates.
  • Правила изменений:
    • Любой новый экран регистрировать в App.jsx routes + navigation.
    • Новые API-вызовы делать только через src/lib/api.js.
    • Мутации должны инвалидацировать/обновлять react-query cache.
  • Зависимости: backend /api, browser localStorage (theme/lang/layout), глобальный notifier.

/backend

  • Назначение: API, интеграции, storage abstraction, schedulers.
  • Ключевые зоны:
    • server.js: composition root, middleware, endpoint registration.
    • routes/*.js: endpoint-level orchestration.
    • services/*.js: storage/EvoBGP/MikroTik/scheduler логика.
    • db/sqliteDb.js + db/migrations/*.sql: DB init/migrations.
    • middleware/*: unified errors + soft locks.
  • Правила изменений:
    • Новый endpoint добавлять через route/service, не встраивать бизнес-логику в server.js.
    • Для persistent данных использовать s3Service/filterRulesStorage/backupFsService по назначению.
    • Сохранять совместимость legacy-имен (s3*) пока фронт/интеграции их используют.
  • Зависимости: SQLite, EvoBGP HTTP API, локальная ФС для backups, env-конфиг.

/backend/db (внутренний /db)

  • Назначение: схема и поведение SQLite.
  • Состав:
    • migrations/001_init.sql: blobs/meta/cache/versioning.
    • migrations/002_filter_rules.sql: app_filter_rules.
  • Правила изменений:
    • Только миграциями; прямые ручные правки существующих таблиц запрещены.
    • Миграции должны быть backward-compatible и idempotent.

/backend/services (внутренний /services)

  • Назначение: слой бизнес-операций и инфраструктурных адаптеров.
  • Ключевые модули:
    • evobgpClient.js (внешний источник правды для BGP reference).
    • s3Service.js + blobStorage.js (SQLite-backed blob API).
    • filterRulesStorage.js (SQL-таблица фильтров).
    • mikrotik*, *Scheduler.js (операции и периодические задачи).
  • Правила изменений:
    • Не смешивать transport-логику endpoint с data-access.
    • Любая write-операция должна возвращать meta для sendOk.

/backend/routes (внутренний /api)

  • Назначение: HTTP contracts + валидация входа + orchestrator.
  • Правила изменений:
    • Вход валидируется до вызова сервиса.
    • Ошибки наружу только через sendError.
    • ETag/Last-Modified сохранять в GET/POST где уже реализовано.

/agents

  • В репозитории отсутствует.

3. ARCHITECTURE RULES (АРХИТЕКТУРНЫЕ ПРАВИЛА)

Слои и границы

  • DO: Route -> Service -> Storage/External API.
  • DO: хранить валидацию запроса на route-слое, а доменную обработку в service.
  • DON'T: вызывать SQLite напрямую из UI.
  • DON'T: переносить доменную логику в server.js.

Бизнес-логика

  • DO: для filters использовать только filterRulesStorage (app_filter_rules).
  • DO: для BGP-reference использовать только evobgpClient.
  • DON'T: писать domains/asns/ip-ranges в blobs.

State management (frontend)

  • DO: network-state через React Query.
  • DO: optimistic updates + rollback на error.
  • DO: invalidation query keys после мутаций.
  • DON'T: дублировать fetch/caching logic вне api.js/useApiQuery.js.

Доступ к БД

  • DO: через s3Service/blobStorage/filterRulesStorage.
  • DO: учитывать etag, lastModified, contentLength.
  • DON'T: менять ключевые object_key без миграции и impact map.

Изменения высокой опасности

  • Запрещено менять без полной цепочки рефакторинга:
    • форматы payload для /api/domains-new, /api/asns, /api/ip-ranges;
    • schema ключей blob-хранилища;
    • sendOk/sendError формат;
    • scheduler settings endpoints и их JSON-структуры;
    • semantics server-configs (только jumphost в листинге).

4. BUSINESS LOGIC SPECIFICATION

4.1 Процесс: BGP Reference Sync (domains/asns/ip-ranges)

  • Inputs: HTTP GET/POST, EvoBGP env (EVOBGP_API_URL, EVOBGP_API_TOKEN), payload массив.
  • Outputs: данные справочников + sendOk metadata.
  • States:
    • IDLE -> VALIDATE_INPUT -> CALL_EVOBGP -> NORMALIZE -> RESPOND_OK
    • ветка ошибки: VALIDATE_INPUT -> RESPOND_400 или CALL_EVOBGP -> RESPOND_5XX.
  • Errors: E_BAD_REQUEST, E_SCHEMA, E_EVOBGP, E_EVOBGP_NOT_CONFIGURED.
  • Side effects: запись в EvoBGP, обновление remote reference set.

4.2 Процесс: Filter Rules Replace (global/simple)

  • Inputs: scope, массив правил {community,gateway,...}.
  • Outputs: новый snapshot правил + meta (etag/lastModified).
  • States:
    • READ_SCOPE_META -> VALIDATE_ARRAY -> TX_BEGIN -> DELETE_SCOPE_ROWS -> INSERT_ROWS_ORDERED -> UPDATE_META_MTIME -> TX_COMMIT -> RESPOND_OK
    • rollback: TX_BEGIN -> ERROR -> TX_ROLLBACK.
  • Errors: E_BAD_REQUEST, E_SCHEMA, E_STORAGE.
  • Side effects: перезапись всех правил scope (full replace).

4.3 Процесс: Blob Object Write (legacy s3Service API)

  • Inputs: object_key, content.
  • Outputs: sendOk(meta).
  • States:
    • VALIDATE_KEY -> READ_EXISTING -> IF_VERSIONED_SAVE_OLD_VERSION -> UPSERT_BLOB -> TRIM_VERSIONS -> INVALIDATE_MEMORY_CACHE -> RESPOND_OK.
  • Errors: E_STORAGE.
  • Side effects: изменение blobs, опционально blob_versions.

4.4 Процесс: Server Config Management

  • Inputs: serverId, config text / filters json.
  • Outputs: per-server config/filter data.
  • States:
    • VALIDATE_SERVER_ID -> READ_OR_WRITE_BLOB_KEY -> RESPOND.
    • Для /api/server-configs list: READ_SERVERS -> FILTER_JUMPHOST -> MAP_ID_NAME -> RESPOND.
  • Errors: E_BAD_REQUEST, E_SCHEMA, E_S3/E_STORAGE.
  • Side effects: запись в filter-manager/config-*.txt и filter-manager/server-filters-*.json.

4.5 Процесс: Auto URLs Ingestion

  • Inputs: список URL + community.
  • Outputs: summary counters.
  • States:
    • LOAD_URLS -> FETCH_CONTENT -> PARSE_LINES -> CLASSIFY(IP/CIDR/DOMAIN) -> DEDUP_WITH_CURRENT -> SAVE_TO_EVOBGP -> RESPOND.
  • Errors: E_BAD_REQUEST, E_EVOBGP.
  • Side effects: расширение списков IP/domains в EvoBGP.

4.6 Процесс: Ping Services Cache Refresh

  • Inputs: UI settings (pingServicesSource, cache TTL), services list.
  • Outputs: { byId, history }.
  • States:
    • LOAD_UI_SETTINGS -> (ROUTER_MODE | WEB_MODE) -> MEASURE_RTT -> WRITE_CACHE -> APPEND_HISTORY -> RESPOND.
  • Errors: fallback на ms: null payload при деградации.
  • Side effects: запись в blob-ключи ping-services/cache_*, ping-services/history_*.

4.7 Процесс: History Rollback

  • Inputs: resource, versionId.
  • Outputs: sendOk(meta) после rollback.
  • States:
    • MAP_RESOURCE_TO_KEY -> VALIDATE_SUPPORT -> ROLLBACK_VERSION -> RESPOND.
  • Errors: E_RESOURCE, E_HISTORY_EV, E_HISTORY_FILTERS_SQL, E_STORAGE.
  • Side effects: восстановление blob из blob_versions.

5. API CONTRACTS (ФОРМАЛЬНЫЕ КОНТРАКТЫ)

5.1 Глобальные правила API

  • Base path: /api.
  • Auth level: явной auth-схемы нет (network-level trust, rate-limit, CORS, security headers).
  • Success write format: { ok, etag, lastModified, contentLength }.
  • Error format: { code, message, details, requestId }.
  • Конкурентность: If-None-Match для GET, If-Match/etag для отдельных write.

5.2 Контракты endpoint’ов

Route Method Auth Input schema (JSON) Output schema Side effects Таблицы/ключи Сервисы
/health GET public - {ok:true} none - -
/ready GET public - {ok:true} none - -
/metrics GET internal - Prometheus text none - prom-client
/api/version GET public - {version,gitSha,buildAt} none - env
/api/domains GET/POST public POST: {domains:[{domain,type}],etag?} GET std/raw list, POST sendOk remote write/read EvoBGP evobgpClient
/api/asns GET/POST public POST: {domains:[{domain,type}],etag?} GET/POST аналогично remote write/read EvoBGP evobgpClient
/api/domains-new GET/POST public POST: {domains:[{domain,community}],etag?} GET/POST аналогично remote write/read EvoBGP evobgpClient
/api/ip-ranges GET/POST public POST: {ipRanges:[{ipRange,community}],etag?} GET/POST аналогично remote write/read EvoBGP evobgpClient
/api/servers GET/POST public POST: {servers:[...],etag?} JSON list / sendOk persist servers blobs:servers.json serversRoutes,s3Service
/api/server-connections GET/POST public POST: {domains:[{from,to,tunnelType,...}]} list / sendOk persist graph links blob key server-connections.json jsonDataRoutes
/api/billing GET/POST public POST: {items:[...],etag?} (route expects domains in factory; adapters normalize) list / sendOk persist billing blob key servers-billing.json jsonDataRoutes
/api/filters GET/POST public POST: {domains:[{community,gateway,...}]} list / sendOk replace scope rules app_filter_rules(scope=global) filterRulesStorage
/api/simple-filters GET/POST public POST: {domains:[{community,gateway,...}]} list / sendOk replace scope rules app_filter_rules(scope=simple) filterRulesStorage
/api/network-config GET/POST public POST: {domains:{gateways?,tunnelInterfaces?,ipPools?}} object / sendOk persist network config blob key network-config.json jsonDataRoutes
/api/communities GET/POST public POST: {communities:[{value,name?,...}]} list / sendOk EvoBGP write EvoBGP communitiesRoutes
/api/communities/stats GET public - {stats:[{community,count}],total} none EvoBGP + app_filter_rules communitiesRoutes
/api/filters/generate-config GET public query params generated config none/write temp derived blobs filtersRoutes
/api/filters/export-config POST public export params file/content json write export derived blobs/fs filtersRoutes
/api/server-filters/generate-config POST public {serverId,...} generated config none per-server blobs filtersRoutes
/api/server-configs GET/POST public POST: {servers:[jumphost...]} jumphost list / sendOk rewrite servers subset servers.json serverConfigsRoutes
/api/server-configs/:serverId GET/POST/DELETE public POST: {config:string} {config} / sendOk write/delete server config filter-manager/config-<id>.txt serverConfigsRoutes
/api/server-configs/:serverId/complete DELETE public - {ok:true,...} delete config+filters filter-manager/config-*, server-filters-* serverConfigsRoutes
/api/server-filters/:serverId GET/POST public POST: {filters:[{community,gateway,...}],etag?} {filters} / sendOk write server filters filter-manager/server-filters-<id>.json serverConfigsRoutes
/api/locks/:resource GET/POST/DELETE public POST:{owner?,ttlSeconds?} lock status/result in-memory lock mutate RAM only lockManager
/api/history/:resource GET public query:countOnly,format versions list none blob_versions miscRoutes+s3Service
/api/history/:resource/rollback POST public {versionId} sendOk rollback snapshot blobs,blob_versions miscRoutes+s3Service
/api/s3/last-modified GET public - map metas none blobs/filter_rules miscRoutes
/api/auto-urls GET/POST public POST:{urls:[{url,community,...}]} list / sendOk EvoBGP write EvoBGP miscRoutes
/api/auto-urls/process POST public optional params process summary pulls URLs, writes lists EvoBGP miscRoutes
/api/servers/availability GET public query:ttlSeconds? {online,total,statuses} refresh memory cache RAM miscRoutes
/api/update-bgp/background POST public (rate limited) passthrough body upstream response outbound HTTP POST - miscRoutes
/api/ws/url GET public - {url} none bgp_data/rt_ui_settings.json miscRoutes
/api/ui-settings GET/POST public POST:{settings,etag?} settings / sendOk write ui settings bgp_data/rt_ui_settings.json miscRoutes
/api/ping-services-list GET public - {list:[...]} none ui settings miscRoutes
/api/ping-services GET public query:`refresh nocache` {byId,history} cache+history writes ping-services/cache_*,history_*
/api/ipsec-passwords GET/POST public POST DTO ipsec secret list / item / sendOk secret storage update blobs/config ipsecPasswordsRoutes
/api/ipsec-passwords/:id GET/PUT/DELETE public PUT DTO item / sendOk update/delete secret blobs/config ipsecPasswordsRoutes
/api/mikrotik/generate POST public generation payload config text/json none derived mikrotikConfigRoutes
/api/mikrotik/generate-interfaces GET public query generated config none derived mikrotikConfigRoutes
/api/mikrotik/generate-recursive-routes GET public query generated config none derived mikrotikConfigRoutes
/api/mikrotik/test-connection POST public connection payload test result network probe - mikrotikConfigRoutes
/api/mikrotik/ping GET/POST public POST:{serverId,gateway,target,...} health/ping result RouterOS ping - mikrotikConfigRoutes
/api/mikrotik/traceroute POST public traceroute payload trace result RouterOS command - mikrotikConfigRoutes
/api/mikrotik/speed-test POST public speed-test payload throughput metrics RouterOS command speed cache blobs mikrotikConfigRoutes
/api/mikrotik/apply POST public apply payload apply report config apply + backup fs+blobs mikrotikConfigRoutes
/api/mikrotik/run-script POST public script payload execution output RouterOS script execution - mikrotikConfigRoutes
/api/mikrotik/address-lists GET public query list data none EvoBGP/derived mikrotikConfigRoutes
/api/mikrotik/ospf-interface-templates GET public query templates none blobs/config mikrotikConfigRoutes
/api/mikrotik/ospf-interface-templates/apply POST public apply payload sendOk/report RouterOS mutation - mikrotikConfigRoutes
/api/mikrotik/address-lists/apply-summary POST public summary payload report RouterOS mutation - mikrotikConfigRoutes
/api/uptime/cache GET public query uptime snapshot none uptime cache blob mikrotikConfigRoutes
/api/uptime/check POST public check payload status report ping/http checks uptime cache blob mikrotikConfigRoutes
/api/traffic/interface-stats GET public query traffic stats optional cache update cache blobs trafficRoutes
/api/resources/stats GET public query cpu/ram/hdd stats optional cache update cache blobs resourceStatsRoutes
/api/alerts GET public query alerts aggregate none combines caches alertsRoutes
/api/mikrotik/backups GET/POST public POST backup payload list / backup result write/read .rsc local FS + metadata mikrotikBackupRoutes
/api/mikrotik/backups/item GET public query id/path backup item read FS local FS mikrotikBackupRoutes
/api/mikrotik/backups/diff POST public {from,to,...} diff result none local FS mikrotikBackupRoutes
/api/mikrotik/backups/run POST public optional run-now result scheduler trigger local FS mikrotikBackupRoutes
/api/network-map-cache GET public query cached map none cache blobs schedulerRoutes
/api/route-optimizer GET public query topology optimization result none derived/cache routeOptimizerRoutes
/api/scheduler/network-map/settings GET/PATCH public PATCH settings DTO settings/result update scheduler config blobs/ui settings schedulerRoutes
/api/scheduler/network-map/logs GET public query logs none blobs/logs schedulerRoutes
/api/scheduler/network-map/run-now POST public optional trigger result immediate job cache update schedulerRoutes
/api/scheduler/ping-services/settings GET/PATCH public PATCH settings DTO settings/result update scheduler config ui settings schedulerRoutes
/api/scheduler/ping-services/run-now POST public optional trigger result immediate cache refresh ping-services cache schedulerRoutes
/api/scheduler/uptime-monitor/settings GET/PATCH public PATCH settings DTO settings/result update scheduler config ui settings schedulerRoutes
/api/scheduler/uptime-monitor/run-now POST public optional trigger result immediate uptime job uptime cache schedulerRoutes
/api/mikrotik/validate POST public {config:string} validation report none - mikrotik-validator

6. DATABASE BEHAVIOR MODEL

6.1 Критичные таблицы

Таблица Назначение Критичность Можно менять?
blobs текущее состояние logical objects very high только через миграцию + compatibility layer
blob_versions история версий для rollback high нельзя удалять без замены rollback механизма
versioned_keys whitelist ключей с версионированием high расширять можно, удаление рискованно
app_filter_rules глобальные/simple фильтры very high менять с миграцией + route/service sync
app_meta meta timestamps/flags medium осторожно; используется для etag/mtime
cache_entries TTL-кеш medium можно расширять, не ломая purge logic
schema_migrations applied versions critical не редактировать вручную

6.2 Cascade/relations

  • blob_versions.object_key -> blobs.object_key ON DELETE CASCADE.
  • Удаление blob удаляет историю версий автоматически.

6.3 Transactional boundaries

  • blobStorage.writeBlobTx: атомарно сохраняет новую версию + snapshot old version + trim.
  • filterRulesStorage.replaceRules: атомарно DELETE scope + INSERT new set + update mtime.
  • Rollback версии выполняется внутри DB write flow.

6.4 Consistency rules

  • etag вычисляется по SHA-256 body; должен соответствовать текущему blob содержимому.
  • lastModified и contentLength обязательны для корректной cache-конкурентности UI/API.
  • app_filter_rules.position определяет порядок; запись всегда full-replace.
  • SQLITE_PATH должен быть persistent volume в production.
  • journal_mode=WAL обязателен для конкурентного I/O.

7. FRONTEND RULES (UI ENGINEERING RULESET)

Структура страниц

  • Все маршруты регистрируются централизованно в App.jsx.
  • Экран = manager/page компонент + общие UI-компоненты (components/*).

State management rules

  • Server-state: только React Query (useQuery/useMutation).
  • UI-state: local component state + Context (Language, Theme, Ping, Alerts).
  • Запрещено хранить API snapshot в произвольных singleton-объектах вне React Query.

Data fetching rules

  • Только через src/lib/api.js.
  • Для GET использовать If-None-Match/ETag-механику клиента.
  • Для write-путей с поддержкой ETag передавать If-Match/etag.

Caching strategy

  • React Query staleTime default 30s.
  • Axios in-memory response cache для GET.
  • Для /communities отключён условный GET (всегда fresh).

Routing dependencies

  • Навигация и route paths должны совпадать (sidebar/horizontal menu).
  • Любой новый route требует:
    • компонент страницы;
    • запись в nav categories;
    • route registration (оба layout блока).

Запрещённые паттерны

  • Прямой fetch в компонентах (мимо api.js).
  • Изменение queryClient политики точечно без общего обоснования.
  • UI-изменения, которые ломают optimistic rollback сценарии.

8. AI AGENT OPERATING PROTOCOL

8.1 Роли агентов

  • architect agent: проверяет архитектурные границы, планирует миграции/контракты.
  • backend agent: реализует route/service/storage изменения с сохранением backward compatibility.
  • frontend agent: реализует UI/state/data-fetch изменения по правилам React Query.
  • refactor agent: выполняет безопасные структурные изменения с impact map.
  • debug agent: локализует баги, подтверждает root cause, готовит минимальный fix.

8.2 Правила работы агентов

  • Перед правками читать: README.md, backend/server.js, целевой route/service, соответствующий frontend hook/page.
  • Изменения планировать от контракта к реализации: API -> service -> storage -> UI.
  • При любом endpoint-change проверять:
    • формат success/error;
    • ETag/headers;
    • влияние на React Query keys и optimistic updates.
  • Избегать конфликтов:
    • не менять shared utility без cross-feature impact check;
    • при рефакторинге route переносить логику в service, не наоборот.

8.3 SAFE EDITING RULE (обязательный)

Перед изменением кода агент обязан:

  1. Найти все зависимости (routes/services/hooks/components/schedulers).
  2. Проверить влияние на API (input/output, status codes, headers).
  3. Проверить влияние на DB (таблицы, ключи blobs, миграции, транзакции).
  4. Проверить UI impact (query keys, route path, optimistic update behavior).
  5. Сформировать plan diff (что меняется, что не меняется, как верифицируется).

9. CHANGE MANAGEMENT PROTOCOL

STEP 1 — ANALYZE

  • Определить feature/bug scope.
  • Идентифицировать owner-слой (frontend/backend/storage/external).
  • Собрать baseline контрактов.

STEP 2 — IMPACT MAP

  • Построить карту зависимостей:
    • endpoint -> service -> storage/external;
    • endpoint -> frontend hooks -> pages/components.
  • Классифицировать риск: low/medium/high.

STEP 3 — IMPLEMENT PLAN

  • Реализовать минимально-инвазивные изменения.
  • Сохранять backward-compatible payload где возможно.
  • Для high-risk сначала добавить адаптерный слой, потом migration.

STEP 4 — APPLY PATCH

  • Вносить правки атомарными логическими блоками.
  • Не смешивать функциональные и косметические изменения.
  • Фиксировать invariants в комментариях только при необходимости.

STEP 5 — VERIFY CONSISTENCY

  • Проверить lint/type/build.
  • Проверить ключевые API сценарии (read/write/etag/error).
  • Проверить UI critical path (list load -> edit -> save -> refresh).
  • Проверить scheduler/side effect пути, если затронуты.

10. DEBUGGING & RECOVERY RULES

Диагностика ошибок

  • Backend:
    • проверять structured logs (pino-http) с requestId;
    • проверять метрики (http_errors_total, http_request_duration_seconds);
    • валидировать env для EvoBGP/MikroTik.
  • Frontend:
    • проверять network ошибки через apiErrorHandler + notify payload;
    • проверять retry/noRetry и cache behavior.

Откат изменений

  • Код: откат через VCS commit revert.
  • Данные:
    • blob keys: /api/history/:resource/rollback (если поддерживается).
    • filters/evobgp resources: rollback через локальный history API не поддерживается; нужен внешний restore plan.

Изоляция багов

  • Сначала локализовать слой (UI/API/Service/Storage/External).
  • Воспроизвести минимальный сценарий.
  • Проверить контракт на границе слоя перед deep refactor.

Логирование проблем

  • Каждый баг-репорт должен включать:
    • requestId/endpoint;
    • входной payload (без секретов);
    • фактический vs ожидаемый ответ;
    • impacted таблицы/ключи.

11. EXTENSION GUIDE

Добавление новой фичи (общий шаблон)

  1. Добавить/расширить service (доменная логика).
  2. Добавить route с валидацией и contract-consistent ответом.
  3. Добавить frontend hook в useApiQuery.js или отдельный data hook.
  4. Подключить UI page/component + route entry.
  5. Добавить проверку impact на ETag/cache/retry.

Расширение API

  • Предпочитать additive changes (новые поля/роуты) вместо breaking.
  • Для breaking change:
    • ввести transitional endpoint или feature flag;
    • обновить frontend и consumers синхронно;
    • подготовить rollback plan.

Добавление новой таблицы

  • Только новой миграцией 00X_*.sql.
  • Определить:
    • primary key + indexes;
    • relation/cascade policy;
    • transaction boundaries;
    • read/write service API.

Как не ломать текущую систему

  • Не удалять legacy aliases без full usage audit.
  • Не менять ключи объектов в blobs без map миграции.
  • Не менять sendError/sendOk contract.
  • Не обходить evobgpClient для BGP-reference данных.

OPERATIONAL CHECKLIST FOR LLM AGENTS

  • Прочитан README.md и целевые route/service/frontend файлы.
  • Сформирован plan diff и impact map.
  • Проверены API contract invariants (status/errors/headers).
  • Проверены DB invariants (transactions/etag/versioning).
  • Проверен UI flow (query cache + optimistic updates).
  • Выполнены lint/build/ручная smoke-валидация критических сценариев.