From 06bd9f704e6372657e7e724b2b01a11e7f835d40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Sat, 1 Aug 2026 20:23:01 +0400 Subject: [PATCH] =?UTF-8?q?v0.5.1:=20=D1=81=D1=81=D1=8B=D0=BB=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=BD=D0=B0=20=D1=81=D1=82=D0=B5=D0=BD=D0=B4=D1=8B=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=B3=D0=BB=D0=B0=D0=B2=D0=BD=D0=BE=D0=B9=20+=20?= =?UTF-8?q?=D0=B2=20Swagger=20=D0=BE=D0=BF=D0=B8=D1=81=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- site/config/loader.py | 2 +- site/routes/openapi.py | 8 +++++- site/routes/root.py | 12 ++++++++ site/static/style.css | 60 +++++++++++++++++++++++++++++++++++++++ site/templates/index.html | 19 +++++++++++++ 5 files changed, 99 insertions(+), 2 deletions(-) diff --git a/site/config/loader.py b/site/config/loader.py index 06fb878..5c8538b 100644 --- a/site/config/loader.py +++ b/site/config/loader.py @@ -80,7 +80,7 @@ SERVICES = _DF["SERVICES"] OPS_INDEX = _DF["OPS_INDEX"] DELAY = float(os.getenv("MOCK_OP_DELAY", "0.1")) -VERSION = "0.5.0" +VERSION = "0.5.1" def get_services(stand_id): diff --git a/site/routes/openapi.py b/site/routes/openapi.py index 34bc181..56e144b 100644 --- a/site/routes/openapi.py +++ b/site/routes/openapi.py @@ -60,10 +60,16 @@ def _build_spec(): "Polygon полностью повторяет контракты реального API: сервисы, инстансы, " "операции, параметры, валидацию — но работает **без реальной инфраструктуры**, " "в памяти, с мгновенным откликом.\n\n" + "### Стенды\n" + "**3 изолированных стенда** — переключайте в выпадающем списке серверов выше:\n" + "- **dev** — 37 сервисов (разработка)\n" + "- **test** — 37 сервисов (тестирование)\n" + "- **prod** — 35 сервисов (продуктив)\n" + "У каждого стенда **свои инстансы, свои операции, своё состояние**.\n\n" "### Особенности\n" "- Все операции синхронные (настраиваемая задержка через `/_mock/delay`)\n" "- Состояние в памяти (1 gunicorn-воркер)\n" - "- Конфигурация сервисов из YAML (генерируется из STANDS)\n" + "- Конфигурация сервисов из YAML (генерируется из terraform)\n" "- Управляемый сброс через `/_mock/reset`\n" "- Симуляция ошибок через `/_mock/fail-next`\n\n" "### Авторизация\n" diff --git a/site/routes/root.py b/site/routes/root.py index 4c1d448..caaa03b 100644 --- a/site/routes/root.py +++ b/site/routes/root.py @@ -49,6 +49,16 @@ def index(): svc_count = len(_cfg.SERVICES) inst_count = len(state.instances) + # Список стендов + stands_list = [] + for sid in _cfg.list_stands(): + svc = _cfg.get_services(sid) + stands_list.append({ + "id": sid, + "count": len(svc), + }) + current_stand = g.stand_id + # Список сервисов для таблицы: name, id, кол-во операций svc_list = [] for sid, svc in sorted(_cfg.SERVICES.items(), key=lambda x: x[1].get("name", x[0])): @@ -69,6 +79,8 @@ def index(): inst_count=inst_count, delay=_cfg.DELAY, svc_list=svc_list, + stands_list=stands_list, + current_stand=current_stand, endpoint=_POLYGON_ENDPOINT, ) diff --git a/site/static/style.css b/site/static/style.css index 83a5769..f05bcfc 100644 --- a/site/static/style.css +++ b/site/static/style.css @@ -115,6 +115,66 @@ main { color: #fff; } +/* ── Stands cards ── */ +.card-stands .card-header { + display: flex; + align-items: baseline; + gap: 12px; +} + +.stands-grid { + display: flex; + gap: 12px; +} + +.stand-card { + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + gap: 6px; + padding: 16px 12px; + background: var(--brand-grey-light); + border: 2px solid var(--border); + border-radius: var(--radius); + text-decoration: none; + color: var(--text); + transition: all 0.15s; +} + +.stand-card:hover { + border-color: var(--brand-primary); + background: #eff6ff; +} + +.stand-active { + border-color: var(--brand-primary); + background: #eff6ff; +} + +.stand-name { + font-size: 18px; + font-weight: 700; + text-transform: uppercase; + color: var(--brand-primary); +} + +.stand-count { + font-size: 13px; + color: var(--text-muted); +} + +.stand-arrow { + font-size: 12px; + color: var(--brand-primary); + opacity: 0; + transition: opacity 0.15s; +} + +.stand-card:hover .stand-arrow { + opacity: 1; +} + /* ── Dots ── */ .dot { display: inline-block; diff --git a/site/templates/index.html b/site/templates/index.html index 4111c78..b0231c4 100644 --- a/site/templates/index.html +++ b/site/templates/index.html @@ -30,6 +30,25 @@
+ +{% if stands_list|length > 1 %} +
+
+

🖥 Стенды

+ Вы находитесь на стенде {{ current_stand }} +
+
+ {% for s in stands_list %} + + {{ s.id }} + {{ s.count }} сервисов + + + {% endfor %} +
+
+{% endif %} +