v0.5.1: ссылки на стенды на главной + в Swagger описании

This commit is contained in:
2026-08-01 20:23:01 +04:00
parent edecf13493
commit 06bd9f704e
5 changed files with 99 additions and 2 deletions
+1 -1
View File
@@ -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):
+7 -1
View File
@@ -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"
+12
View File
@@ -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,
)
+60
View File
@@ -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;
+19
View File
@@ -30,6 +30,25 @@
<main>
<!-- ── Стенды ── -->
{% if stands_list|length > 1 %}
<section class="card card-stands">
<div class="card-header">
<h2>🖥 Стенды</h2>
<span class="muted">Вы находитесь на стенде <strong>{{ current_stand }}</strong></span>
</div>
<div class="card-body stands-grid">
{% for s in stands_list %}
<a href="/{{ s.id }}/" class="stand-card {% if s.id == current_stand %}stand-active{% endif %}">
<span class="stand-name">{{ s.id }}</span>
<span class="stand-count">{{ s.count }} сервисов</span>
<span class="stand-arrow"></span>
</a>
{% endfor %}
</div>
</section>
{% endif %}
<!-- ── Что такое Polygon ── -->
<section class="card">
<div class="card-header">