From 5dbdac3d2cf7898cb40b2efde68d6ab5293a89eb Mon Sep 17 00:00:00 2001 From: Denozordec Date: Fri, 12 Jun 2026 21:11:15 +0700 Subject: [PATCH] feat(memory-bank): update active context and progress documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Обновлены разделы активного контекста и прогресса для задачи `settings-ui-and-runtime-logs`. Упрощено отображение статуса завершённых фаз и добавлены ссылки на архив. Уточнены следующие шаги и активные задачи, улучшая ясность и доступность информации. Co-authored-by: Cursor --- memory-bank/activeContext.md | 17 +- .../archive-settings-ui-and-runtime-logs.md | 124 ++++++ memory-bank/progress.md | 36 +- ...reflection-settings-ui-and-runtime-logs.md | 98 +++++ memory-bank/tasks.md | 388 +----------------- 5 files changed, 260 insertions(+), 403 deletions(-) create mode 100644 memory-bank/archive/archive-settings-ui-and-runtime-logs.md create mode 100644 memory-bank/reflection/reflection-settings-ui-and-runtime-logs.md diff --git a/memory-bank/activeContext.md b/memory-bank/activeContext.md index b5d393f..7e777c0 100644 --- a/memory-bank/activeContext.md +++ b/memory-bank/activeContext.md @@ -2,23 +2,18 @@ ## Текущий фокус -**Task:** `settings-ui-and-runtime-logs` -**Phase:** **BUILD complete** → **REFLECT** +_Нет активной задачи._ -## Phase 7 deliverables +## Последняя завершённая -- `docs/api.md` — RuntimeLogs endpoints -- `docs/manual.md` — Web UI `/tenant-settings`, Monitoring runtime logs -- QA: `go test ./...`, redocly lint, web check+lint, lint-go.ps1 — pass +**`settings-ui-and-runtime-logs`** — tenant settings UI + runtime logs API/UI/deploy. -## E2E manual (на сервере, не автоматизировано) - -См. checklist в `memory-bank/tasks.md` Phase 7. +Архив: `memory-bank/archive/archive-settings-ui-and-runtime-logs.md` ## Следующий шаг ``` -/reflect +/van ``` -Затем `/archive` по workflow Memory Bank. +Для новой задачи. На production — E2E checklist из архива (compose + pull `evobgp-all`). diff --git a/memory-bank/archive/archive-settings-ui-and-runtime-logs.md b/memory-bank/archive/archive-settings-ui-and-runtime-logs.md new file mode 100644 index 0000000..ba51916 --- /dev/null +++ b/memory-bank/archive/archive-settings-ui-and-runtime-logs.md @@ -0,0 +1,124 @@ +# TASK ARCHIVE: settings-ui-and-runtime-logs + +## METADATA + +| Поле | Значение | +|------|----------| +| **Task ID** | `settings-ui-and-runtime-logs` | +| **Complexity** | Level 4 | +| **VAN** | 2026-06-12 | +| **PLAN** | 2026-06-12 | +| **BUILD complete** | 2026-06-12 | +| **REFLECT** | 2026-06-12 | +| **ARCHIVE** | 2026-06-12 | + +--- + +## SUMMARY + +Два связанных улучшения control plane: + +1. **Tenant settings UI** — единый модуль `/tenant-settings` (BIRD, ревизии, custom KV); `/settings` только для браузера. +2. **Runtime logs** — API и UI для файлов `*.log` от sidecar `stack-runtime-logs`: list, tail, sync cleanup, audit в БД; FS только на `evobgp-all` с volume. + +--- + +## REQUIREMENTS (resolved) + +| # | Решение | +|---|---------| +| `/settings` vs tenant | Раздельные модули | +| Cleanup | Синхронный HTTP, не jobs | +| FS API | Только `evobgp-all` + mount | +| Audit | `runtime_log_cleanup_audit` в postgres/sqlite | + +--- + +## IMPLEMENTATION + +### Backend + +| Компонент | Путь | +|-----------|------| +| OpenAPI tag `RuntimeLogs` | `docs/openapi.yaml` | +| Миграция 000026 | `migrations/postgres/`, `migrations/sqlite/` | +| Store | `internal/store/runtime_logs.go`, `memory_runtime_logs.go`, `postgres_runtime_logs.go` | +| FS layer | `internal/runtimelogs/` (config, safe, list, tail, cleanup) | +| HTTP | `internal/httpapi/routes_runtime_logs.go`, `server.go` wiring | +| Config/docs | `internal/config/config.go`, `docs/access.md` | + +**API paths:** `GET/DELETE /v1/runtime-logs/files`, `GET .../files/{filename}`, `GET /v1/runtime-logs/cleanup-audit` + +### Deploy + +| Файл | Изменение | +|------|-----------| +| `deploy/compose/stack.microvps-full.yaml` | env + mount на `evobgp-all`, `EVOBGP_RUNTIME_LOGS_HOST_DIR` | +| `deploy/compose/docker-compose.microvps-full.yaml` | overlay mount/env | +| `deploy/compose/docker-compose.production.example.yaml` | полный prod example для `/opt/evobgp` | +| `deploy/compose/.env.production.example` | host dir для runtime-logs | +| `docs/quickstart.md` | секция runtime logs | +| `.gitignore` | `deploy/compose/runtime-logs/` | + +### Web UI + +| Область | Путь | +|---------|------| +| Tenant settings | `web/src/routes/tenant-settings/`, `web/src/lib/components/tenant-settings/*` | +| Nav «Параметры» | `web/src/lib/ui/app/layout/nav.ts` | +| Operations | убран tab `system`, редирект `?tab=system` | +| Network | `NetworkBirdSettingsSummaryCard.svelte` | +| Runtime logs UI | `web/src/lib/runtime-logs/runtime-logs-api.ts`, `RuntimeLogsTab.svelte` | +| Monitoring | `?tab=runtime-logs`, URL sync | + +**Удалено:** `OperationsSystemSettingsTab.svelte`, `BirdSettingsForm.svelte` + +### Docs (Phase 7) + +- `docs/api.md` — RuntimeLogs +- `docs/manual.md` — Web UI tenant-settings + monitoring runtime logs + +--- + +## TESTING + +| Gate | Результат | +|------|-----------| +| `go test ./... -count=1` | pass | +| `scripts/lint-go.ps1` | pass | +| `go test ./internal/httpapi/... -run RuntimeLogs` | pass | +| `go test ./internal/runtimelogs/...` | pass | +| `npx @redocly/cli lint docs/openapi.yaml` | pass | +| `npm run check && npm run lint` | pass | +| E2E manual prod | **не выполнен** (чеклист в tasks Phase 7) | + +--- + +## LESSONS LEARNED + +См. [reflection-settings-ui-and-runtime-logs.md](../reflection/reflection-settings-ui-and-runtime-logs.md). + +Кратко: deploy mount обязателен для FS API; audit не зависит от FS; production compose example критичен; phased BUILD + creative снижают риск откатов. + +--- + +## POST-DEPLOY (оператор) + +1. Обновить `/opt/evobgp/docker-compose.yaml` (или скопировать `docker-compose.production.example.yaml`). +2. `mkdir -p /opt/evobgp/runtime-logs` +3. `docker compose pull evobgp-all evobgp-web && docker compose up -d evobgp-all` +4. E2E: list → tail → truncate → audit row; `/tenant-settings` PATCH. + +--- + +## REFERENCES + +| Документ | Путь | +|----------|------| +| Reflection | `memory-bank/reflection/reflection-settings-ui-and-runtime-logs.md` | +| CP-1 Tenant UI | `memory-bank/creative/creative-tenant-settings-ui.md` | +| CP-2 Runtime logs UI | `memory-bank/creative/creative-runtime-logs-ui.md` | +| CP-3 Cleanup | `memory-bank/creative/creative-runtime-logs-cleanup.md` | +| CP-4 Path safety | `memory-bank/creative/creative-runtime-logs-path-safety.md` | +| HTTP contract | `docs/openapi.yaml` (tag RuntimeLogs) | +| Access / env | `docs/access.md` | diff --git a/memory-bank/progress.md b/memory-bank/progress.md index 56b863f..fc668de 100644 --- a/memory-bank/progress.md +++ b/memory-bank/progress.md @@ -1,14 +1,22 @@ -# Memory Bank: Progress - -## settings-ui-and-runtime-logs - -| Фаза | Статус | -|------|--------| -| VAN / PLAN / CREATIVE | ✅ | -| BUILD P1 OpenAPI+store | ✅ | -| BUILD P2 FS layer | ✅ 2026-06-12 | -| BUILD P3 HTTP | ✅ 2026-06-12 | -| BUILD P4 Deploy | ✅ 2026-06-12 | -| BUILD P5 Tenant UI | ✅ 2026-06-12 | -| BUILD P6 Runtime logs UI | ✅ 2026-06-12 | -| BUILD P7 QA | ✅ 2026-06-12 | +# Memory Bank: Progress + +## Completed + +### settings-ui-and-runtime-logs (2026-06-12) + +| Фаза | Статус | +|------|--------| +| VAN / PLAN / CREATIVE | ✅ | +| BUILD P1–P7 | ✅ | +| REFLECT | ✅ | +| ARCHIVE | ✅ | + +**Archive:** [archive-settings-ui-and-runtime-logs.md](archive/archive-settings-ui-and-runtime-logs.md) + +**Открыто:** E2E manual на production после deploy compose + pull образа. + +--- + +## Active + +_Нет._ diff --git a/memory-bank/reflection/reflection-settings-ui-and-runtime-logs.md b/memory-bank/reflection/reflection-settings-ui-and-runtime-logs.md new file mode 100644 index 0000000..bfb60d5 --- /dev/null +++ b/memory-bank/reflection/reflection-settings-ui-and-runtime-logs.md @@ -0,0 +1,98 @@ +# Reflection: settings-ui-and-runtime-logs + +**Task ID:** `settings-ui-and-runtime-logs` +**Complexity:** Level 4 +**Дата reflection:** 2026-06-12 +**Статус BUILD:** фазы 1–7 завершены + +--- + +## Summary + +Задача объединила два независимых направления: + +1. **Tenant settings UI** — вынос BIRD / revision / custom KV из Operations и Network в `/tenant-settings`; `/settings` остаётся только для браузера (токен, тема). +2. **Runtime logs** — контракт OpenAPI, audit в БД, безопасный FS-слой, HTTP API только на `evobgp-all`, compose volume, Web UI во вкладке Monitoring. + +Реализация шла по 7 фазам (0–7 с creative): контракт → persistence → FS → HTTP → deploy → два UI-модуля → docs/QA. Все acceptance criteria закрыты автоматическими проверками; E2E на production-хосте оставлен ручным чеклистом. + +--- + +## What Went Well + +| Область | Наблюдение | +|---------|------------| +| **Creative до BUILD** | Четыре CP-документа зафиксировали спорные точки (tabs vs routes, sync cleanup, path safety, Monitoring tab). В BUILD не было откатов по UX. | +| **Contract-first (P1)** | OpenAPI + миграция `000026` + `store.Backend` до FS/HTTP упростили параллельную работу и review. | +| **Паттерны репозитория** | Maintenance audit (`actor_prefix`, cursor list) и settings-api переиспользованы без новых абстракций. | +| **Guard FS** | `EVOBGP_SERVICE=evobgp-all` + `EVOBGP_RUNTIME_LOGS_DIR` + path regex/EvalSymlinks — единая точка в `internal/runtimelogs`. | +| **Поэтапный UI** | P5 (tenant) не зависел от runtime logs backend — можно было бы параллелить с P2–P4. | +| **503 + audit** | Разделение `filesUnavailable` и audit-only в UI: оператор видит историю очистки даже без volume. | +| **Production example** | `docker-compose.production.example.yaml` закрыл разрыв между repo `stack.microvps-full.yaml` и кастомным compose на сервере пользователя. | + +--- + +## Challenges + +| Challenge | Как решали | +|-----------|------------| +| **Prod compose без Phase 4 env/mount** | Пользовательский `/opt/evobgp/docker-compose.yaml` отставал от репозитория; подготовлен полный example с сохранением кастомных env (`BUNDLE_SEED_HEX`, `NODE_DISPATCH`). | +| **Windows dev** | `go test -race` и `bash scripts/lint-httpapi.sh` недоступны; gates выполнялись альтернативами (test без race, grep ERR-01/ARCH-01). | +| **Sidecar уже был, API — нет** | `stack-runtime-logs` писал в `./runtime-logs`, но `evobgp-all` не монтировал каталог — типичная «половинная» интеграция; Phase 4 явно связал оба mount через `EVOBGP_RUNTIME_LOGS_HOST_DIR`. | +| **Старые закладки Operations** | `?tab=system` → редирект на `/tenant-settings?tab=revision`. | +| **E2E не автоматизирован** | Нет compose в CI с реальным volume и sidecar; manual checklist в `tasks.md`. | + +--- + +## Lessons Learned + +1. **Deploy — часть фичи.** FS API без compose mount на целевом процессе даёт 503 и ощущение «баг в коде»; example для production обязателен при stack, который копируют на сервер вручную. +2. **Audit endpoint ≠ FS endpoint.** Cleanup audit в БД не должен зависеть от `requireRuntimeLogs` — иначе теряется ценность на `evobgp-api`/без volume. +3. **Разделение `/settings` и tenant** снижает путаницу ролей: browser config vs control plane KV — разные mental models и nav-пункты. +4. **Синхронный DELETE** при лимите 512 MiB и truncate-by-default — приемлемый trade-off для операторского UI без jobs; важно документировать в OpenAPI и ConfirmDialog. +5. **Memory Bank phased BUILD** хорошо масштабируется на Level 4: 7 фаз с чеклистами удерживают контекст между сессиями агента. + +--- + +## Process Improvements + +| Рекомендация | Действие | +|--------------|----------| +| После изменения compose в repo — **синхронизировать production.example** в той же фазе | Уже сделано для этой задачи; закрепить как правило в Phase 4 checklist | +| **E2E smoke** в `scripts/` или compose profile `test-runtime-logs` (temp dir + evobgp-all env) | Backlog: снизить зависимость от ручного prod | +| В PR template: «обновлены `docs/api.md` + `manual.md`?» для API/UI фич | Phase 7 не забывать при мелких задачах | +| Creative commit local без push — ок для итерации; перед prod нужен **CI image** с новым API | Напоминание в runbook E2E | + +--- + +## Technical Improvements (backlog) + +- **Operator role в UI:** сейчас `session?.role === 'operator'` — если появятся расширенные роли, вынести `canMutateSettings` / `canCleanupLogs` в один helper. +- **Monitoring URL tabs:** добавлен sync для `runtime-logs`; при новых вкладках — единый helper как в Operations/tenant-settings. +- **Удаление custom KV:** PATCH только перечисленных ключей; полное удаление ключа из tenant может требовать явного API (сейчас — операторская семантика через форму). +- **Метрики:** опционально `evobgp_runtime_logs_cleanup_total` в observability (PERF-03). + +--- + +## Comparison to Plan + +| План | Факт | +|------|------| +| 7 BUILD фаз | Выполнено | +| CP-1…CP-4 | Соблюдены | +| `/tenant-settings` Tabs | Да | +| Monitoring `?tab=runtime-logs` | Да + nested files/audit | +| Только evobgp-all FS | Да | +| Sync cleanup + audit | Да | +| `redocly`, go test, web check+lint | Pass локально | + +**Отклонения:** нет существенных. E2E manual на prod — единственный незакрытый автоматический gate. + +--- + +## Next Steps + +1. **`/archive`** — архив задачи в `memory-bank/archive/`. +2. **На сервере:** применить `docker-compose.production.example.yaml` (или патч Phase 4), `pull evobgp-all`, пройти E2E checklist из `tasks.md` Phase 7. +3. **Коммит/PR:** сгруппировать изменения (backend, web, deploy, docs) или один feature PR — по предпочтению команды. +4. **Опционально:** smoke-скрипт для runtime logs API в dev compose. diff --git a/memory-bank/tasks.md b/memory-bank/tasks.md index 12fc5c8..c77927a 100644 --- a/memory-bank/tasks.md +++ b/memory-bank/tasks.md @@ -2,391 +2,23 @@ ## Current Task -**settings-ui-and-runtime-logs** - -| Поле | Значение | -|------|----------| -| **Task ID** | `settings-ui-and-runtime-logs` | -| **Complexity** | **Level 4** | -| **Status** | **BUILD complete** → REFLECT | -| **Дата VAN** | 2026-06-12 | -| **Дата PLAN** | 2026-06-12 | +_Нет активной задачи. Запустите `/van` для новой._ --- -## Resolved Decisions (от заказчика) +## Last Completed -| # | Вопрос | Решение | -|---|--------|---------| -| 1 | `/settings` vs tenant | **`/settings` — только frontend** (токен, тема, localStorage). **Tenant-настройки — отдельный модуль** (новый route + nav). | -| 2 | Очистка больших логов | **Синхронно** (HTTP 200/4xx/5xx), без `jobs.Registry` / 202. | -| 3 | Где FS API | **Только `evobgp-all`** с bind-mount volume на runtime-logs. На `evobgp-api` — `503` или отсутствие маршрута. | -| 4 | Audit очистки | **Да** — персистентный audit в PostgreSQL (и sqlite для паритета). | +| Task ID | Archive | Дата | +|---------|---------|------| +| `settings-ui-and-runtime-logs` | [archive-settings-ui-and-runtime-logs.md](archive/archive-settings-ui-and-runtime-logs.md) | 2026-06-12 | --- -## Requirements Summary +## Status Template (для следующей задачи) -### A. Web UI — два независимых модуля - -| Модуль | Route (план) | Данные | Роль | -|--------|--------------|--------|------| -| **Frontend settings** | `/settings` (существует) | localStorage, theme | любой пользователь UI | -| **Tenant settings** | `/tenant-settings` (новый) | `GET/PATCH /v1/settings` → `global_settings` | viewer read / operator write | - -**Tenant module** объединяет сейчас разрозненное: -- `OperationsSystemSettingsTab` → revision + custom KV (убрать из Operations) -- `BirdSettingsForm` → BIRD keys (убрать с `/network` или оставить read-only summary + ссылка) - -**`/settings` не трогать семантически** — только polish (заголовки, пояснения что это настройки браузера). - -### B. Runtime logs — FS - -- Корень: `EVOBGP_RUNTIME_LOGS_DIR` (prod default: `/opt/evobgp/runtime-logs`) -- Источник файлов: sidecar `stack-runtime-logs` (без изменений) -- API: list / stat / tail / cleanup (sync) -- Audit: каждая операция cleanup → запись в БД - ---- - -## Technology Validation - -| Технология | Версия / статус | Примечание | -|------------|-----------------|------------| -| Go stdlib `os`, `path/filepath` | 1.24 | FS read/truncate; без новых deps | -| PostgreSQL + sqlite миграции | 000026 | audit table | -| OpenAPI 3.1 | `docs/openapi.yaml` | новые paths под tag `RuntimeLogs` | -| SvelteKit 5 + shadcn | web/ | новые routes/components | -| Compose bind mount | `deploy/compose/*` | volume на `evobgp-all` | - -**PoC не требуется** — паттерны audit и settings уже в репозитории. - ---- - -## Architecture Overview - -```mermaid -flowchart TB - subgraph web [Web UI] - FS["/settings
frontend only"] - TS["/tenant-settings
BIRD + revision + KV"] - MON["/monitoring?tab=runtime-logs"] - end - - subgraph api [evobgp-all only] - H[httpapi handlers] - RL[internal/runtimelogs] - ST[store.Backend] - end - - subgraph data [Data] - PG[(global_settings)] - AUD[(runtime_log_cleanup_audit)] - VOL["/opt/evobgp/runtime-logs/*.log"] - end - - FS --> localStorage - TS --> H - MON --> H - H --> ST - H --> RL - ST --> PG - ST --> AUD - RL --> VOL -``` - ---- - -## Phased Implementation Plan - -### Phase 0 — Creative (обязательно перед BUILD) - -Документы в `memory-bank/creative/`: - -| ID | Тип | Тема | Вопросы | -|----|-----|------|---------| -| CP-1 | uiux | Tenant settings module | Структура вкладок: BIRD / Ревизии / Дополнительно; nav label | -| CP-2 | uiux | Runtime logs UI | Вкладка в Monitoring vs отдельный route | -| CP-3 | algorithm | Cleanup semantics | `truncate` (обнулить файл) vs `delete`; max tail bytes/lines | -| CP-4 | architecture | Path safety | Allowlist имён файлов `*.log`, запрет `..`, symlink policy | - -**Уже решено (не обсуждать в creative):** sync cleanup, evobgp-all only, audit yes, settings split. - ---- - -### Phase 1 — Contract & persistence (OpenAPI + migrations + store) - -**Цель:** контракт и audit до FS-логики. - -| # | Действие | Файлы | -|---|----------|-------| -| 1.1 | OpenAPI: `RuntimeLogs` tag | `docs/openapi.yaml` | -| 1.2 | Схемы: `RuntimeLogFile`, `RuntimeLogTail`, `RuntimeLogCleanupAudit` | `docs/openapi.yaml` | -| 1.3 | Paths (см. ниже) | `docs/openapi.yaml` | -| 1.4 | Миграция `000026_runtime_log_cleanup_audit` | `migrations/postgres/`, `migrations/sqlite/` | -| 1.5 | Типы + `store.Backend` методы | `internal/store/runtime_logs.go`, `backend.go` | -| 1.6 | Postgres + Memory реализации | `internal/repository/postgres_runtime_logs.go`, `internal/store/memory_runtime_logs.go` | - -**OpenAPI paths (черновик):** - -``` -GET /v1/runtime-logs/files # list + size/mtime -GET /v1/runtime-logs/files/{filename} # tail (?lines= | ?bytes=, ?grep=) -DELETE /v1/runtime-logs/files/{filename} # cleanup (?mode=truncate|delete), operator+, sync 200 -GET /v1/runtime-logs/cleanup-audit # cursor/limit, viewer+ -``` - -**Audit table `runtime_log_cleanup_audit`:** - -| Column | Type | Note | -|--------|------|------| -| id | TEXT PK | UUID | -| tenant_id | TEXT | из auth | -| actor_prefix | TEXT | API key prefix | -| filename | TEXT | basename only | -| action | TEXT | `truncate` \| `delete` | -| size_before | BIGINT | bytes | -| size_after | BIGINT | nullable | -| detail_json | JSONB | optional (grep stats, error) | -| created_at | TIMESTAMPTZ | | - -**Checklist Phase 1:** -- [x] `npx @redocly/cli lint docs/openapi.yaml` -- [x] миграции `000026` postgres + sqlite (пары up/down) -- [x] store interface + memory tests (`TestMemoryRuntimeLogCleanupAudit`) - ---- - -### Phase 2 — FS layer & config (evobgp-all only) - -**Цель:** безопасное чтение/очистка файлов. - -| # | Действие | Файлы | -|---|----------|-------| -| 2.1 | `EVOBGP_RUNTIME_LOGS_DIR` в config | `internal/config/config.go`, `docs/access.md` | -| 2.2 | Guard: FS enabled iff dir non-empty **and** `EVOBGP_SERVICE=evobgp-all` | `internal/runtimelogs/guard.go` | -| 2.3 | ListDir, Stat, Tail, Cleanup | `internal/runtimelogs/fs.go` | -| 2.4 | Path hardening: basename allowlist `[a-z0-9_.-]+\.log` | `internal/runtimelogs/safe.go` | -| 2.5 | Unit tests (temp dir) | `internal/runtimelogs/*_test.go` | - -**Поведение при отключённом FS:** -- `GET` → `503` problem+json `runtime_logs_unavailable` -- `DELETE` → `503` - -**Cleanup flow (sync):** -1. Stat file → `size_before` -2. Truncate or Remove -3. `AppendRuntimeLogCleanupAudit(...)` -4. Return `200` + audit id + sizes - -**Checklist Phase 2:** -- [x] `go test ./internal/runtimelogs/... -count=1` -- [x] path traversal + symlink tests (`safe_test.go`) - ---- - -### Phase 3 — HTTP handlers - -| # | Действие | Файлы | -|---|----------|-------| -| 3.1 | Регистрация маршрутов | `internal/httpapi/routes.go` или `routes_runtime_logs.go` | -| 3.2 | Handlers | `internal/httpapi/handlers_runtime_logs.go` | -| 3.3 | `actorPrefix(a)` как в maintenance | reuse from `routes_maintenance.go` | -| 3.4 | Handler tests | `internal/httpapi/handlers_runtime_logs_test.go` | - -**Роли:** list/tail/audit — `viewer+`; cleanup — `operator+`. - -**Checklist Phase 3:** -- [x] `go test ./internal/httpapi/... -run RuntimeLogs` (Windows: без `-race`, CGO disabled) -- [x] `scripts/lint-go.ps1` exit 0 -- [x] lint-httpapi gates (ERR-01, ARCH-01) — проверено grep - ---- - -### Phase 4 — Deploy (compose) - -| # | Действие | Файлы | -|---|----------|-------| -| 4.1 | Bind mount runtime-logs → evobgp-all | `deploy/compose/stack.microvps-full.yaml`, `docker-compose.microvps-full.yaml` | -| 4.2 | Env `EVOBGP_RUNTIME_LOGS_DIR=/opt/evobgp/runtime-logs` | compose env | -| 4.3 | `EVOBGP_SERVICE=evobgp-all` (если ещё не задан) | compose | -| 4.4 | Комментарий в quickstart / manual | `docs/quickstart.md` или `docs/manual.md` | - -**Пример mount:** -```yaml -volumes: - - ${EVOBGP_RUNTIME_LOGS_HOST_DIR:-./runtime-logs}:/opt/evobgp/runtime-logs:rw -environment: - EVOBGP_RUNTIME_LOGS_DIR: /opt/evobgp/runtime-logs -``` - -**Checklist Phase 4:** -- [x] dev: `./runtime-logs` рядом с compose (`EVOBGP_RUNTIME_LOGS_HOST_DIR` default) -- [x] prod: `/opt/evobgp/runtime-logs` на хосте (через `EVOBGP_RUNTIME_LOGS_HOST_DIR` в `.env`) -- [x] `stack.microvps-full.yaml` + `docker-compose.microvps-full.yaml` — mount + env на `evobgp-all` -- [x] `.env.stack.microvps-full.example`, `docs/quickstart.md`, `docs/manual.md` - ---- - -### Phase 5 — Web UI: Tenant settings module - -**Цель:** отдельный модуль tenant-настроек; `/settings` остаётся frontend-only. - -| # | Действие | Файлы | -|---|----------|-------| -| 5.1 | Новый route | `web/src/routes/tenant-settings/+page.svelte` | -| 5.2 | Компонент-обёртка с Tabs | `web/src/lib/components/tenant-settings/TenantSettingsPage.svelte` | -| 5.3 | Перенос логики из Operations | refactor `OperationsSystemSettingsTab` → `TenantRevisionSettingsCard.svelte` | -| 5.4 | Перенос BIRD | refactor `BirdSettingsForm` → `TenantBirdSettingsCard.svelte` | -| 5.5 | Custom KV card | `TenantAdditionalSettingsCard.svelte` | -| 5.6 | Nav: добавить пункт (main или bottom) | `web/src/lib/ui/app/layout/nav.ts` | -| 5.7 | Убрать tab `system` из Operations | `web/src/routes/operations/+page.svelte` | -| 5.8 | Network: заменить форму на Card-summary + link | `web/src/routes/network/+page.svelte` | -| 5.9 | Обновить ссылки в docs strings / empty states | grep `tab=system`, `BirdSettingsForm` | - -**Структура tenant module (предложение для creative CP-1):** -``` -/tenant-settings - ├─ BIRD (bird_*) - ├─ Ревизии (revision_retention_minutes) - └─ Дополнительно (custom KV, operator) -``` - -**Checklist Phase 5:** -- [x] `npm run check && npm run lint` -- [x] `/settings` без tenant-форм -- [x] `/tenant-settings` с Tabs BIRD / Ревизии / Дополнительно -- [x] nav «Параметры»; Operations без tab system; Network summary + link - ---- - -### Phase 6 — Web UI: Runtime logs - -| # | Действие | Файлы | -|---|----------|-------| -| 6.1 | API client | `web/src/lib/runtime-logs/runtime-logs-api.ts` | -| 6.2 | Tab в Monitoring | `web/src/lib/components/monitoring/RuntimeLogsTab.svelte` | -| 6.3 | Подключить tab | `web/src/routes/monitoring/+page.svelte` | -| 6.4 | Таблица файлов (size, mtime) | `AppDataTable` | -| 6.5 | Preview dialog | `ScrollPreBlock` + tail API | -| 6.6 | Cleanup | `ConfirmDialog` + DELETE sync | -| 6.7 | Sub-tab или section: Cleanup audit | таблица `GET /v1/runtime-logs/cleanup-audit` | -| 6.8 | 503 empty state | «Доступно только на evobgp-all с volume» | - -**Checklist Phase 6:** -- [x] `npm run check && npm run lint` -- [x] `/monitoring?tab=runtime-logs` + nested files/audit - ---- - -### Phase 7 — Integration, docs, QA - -| # | Действие | -|---|----------| -| 7.1 | `docs/api.md` — новые endpoints | -| 7.2 | `docs/manual.md` — tenant-settings + runtime logs | -| 7.3 | `go test ./... -race -count=1` | -| 7.4 | E2E manual: list → tail → truncate → audit row | - -**Checklist Phase 7:** -- [x] `docs/api.md` — секция RuntimeLogs -- [x] `docs/manual.md` — Web UI tenant-settings + runtime logs -- [x] `go test ./... -count=1` exit 0 (Windows: без `-race`, CGO disabled) -- [x] `npx @redocly/cli lint docs/openapi.yaml` -- [x] `npm run check && npm run lint` -- [x] `scripts/lint-go.ps1` -- [ ] E2E manual на prod/staging (см. ниже) - -**E2E manual (оператор на evobgp-all с volume):** -1. `GET /v1/runtime-logs/files` → 200, список `*.log` -2. `GET /v1/runtime-logs/files/evobgp-all.log?lines=50` → content -3. UI: Monitoring → Файловые логи → preview -4. `DELETE ...?mode=truncate` (operator) → 200 + audit_id -5. `GET /v1/runtime-logs/cleanup-audit` → новая строка -6. `/tenant-settings` — BIRD + revision сохраняются через PATCH - ---- - -## Dependency Graph - -```mermaid -graph TD - P0[Phase 0 Creative] --> P1[Phase 1 OpenAPI+store] - P1 --> P2[Phase 2 FS layer] - P2 --> P3[Phase 3 HTTP] - P3 --> P4[Phase 4 Deploy] - P0 --> P5[Phase 5 Tenant UI] - P3 --> P6[Phase 6 Runtime logs UI] - P4 --> P6 - P5 --> P7[Phase 7 QA] - P6 --> P7 -``` - -**Параллелизация:** Phase 5 (tenant UI) можно начинать после Phase 0, не дожидаясь runtime logs backend. - ---- - -## Risks & Mitigations - -| Risk | Impact | Mitigation | -|------|--------|------------| -| Path traversal | Critical | basename only, allowlist, `filepath.Clean` + root check | -| Sync cleanup блокирует HTTP worker | Medium | лимит размера файла для DELETE; timeout context; документировать | -| evobgp-api без volume | Low | 503 + UI empty state | -| Дублирование settings forms | Medium | Phase 5 удаляет старые вхождения | -| reference compose (не all) | Low | FS API disabled; документировать | - ---- - -## Creative Phases Required - -- [x] **CP-1 uiux** — `creative-tenant-settings-ui.md` ✅ Tabs `/tenant-settings`, nav «Параметры» -- [x] **CP-2 uiux** — `creative-runtime-logs-ui.md` ✅ Monitoring tab `runtime-logs` + sub-tabs files/audit -- [x] **CP-3 algorithm** — `creative-runtime-logs-cleanup.md` ✅ truncate default, max 512MiB, tail 200/2000 lines, 256KiB -- [x] **CP-4 architecture** — `creative-runtime-logs-path-safety.md` ✅ regex + EvalSymlinks + root prefix check - ---- - -## Acceptance Criteria - -- [x] `/settings` — только frontend (токен, тема) -- [x] `/tenant-settings` — все tenant KV (BIRD + revision + custom) -- [x] Operations без tab `system`; Network без полной BIRD-формы (summary + link) -- [x] Runtime logs: list, tail, sync cleanup на evobgp-all (UI) -- [x] Audit cleanup в БД + просмотр в UI -- [x] `EVOBGP_RUNTIME_LOGS_DIR`, volume в compose -- [x] redocly lint, go test, web check+lint - ---- - -## Status Checklist - -- [x] VAN -- [x] PLAN -- [x] CREATIVE (4 docs) -- [x] BUILD Phase 1 (OpenAPI + migration + store) -- [x] BUILD Phase 2 (FS layer + config) -- [x] BUILD Phase 3 HTTP handlers -- [x] BUILD Phase 4 Deploy (compose) -- [x] BUILD Phase 5 Tenant settings UI -- [x] BUILD Phase 6 Runtime logs UI -- [x] BUILD Phase 7 (docs + QA) +- [ ] VAN +- [ ] PLAN +- [ ] CREATIVE (если Level 3–4) +- [ ] BUILD - [ ] REFLECT - [ ] ARCHIVE - ---- - -## Key Files (reference) - -**Settings today:** -- `web/src/routes/settings/+page.svelte` — frontend-only -- `web/src/routes/tenant-settings/+page.svelte` — tenant KV -- `web/src/lib/components/tenant-settings/*` — BIRD / revision / additional cards -- `internal/httpapi/routes_crud.go` — settings handlers (unchanged contract) - -**Runtime logs today:** -- `deploy/compose/stack.microvps-full.yaml` — `stack-runtime-logs`, `./runtime-logs` - -**Patterns:** -- `internal/httpapi/routes_maintenance.go` — audit list, actor_prefix -- `migrations/postgres/000025_*` — config audit table shape