Files
portal/web/index.html
T
Дмитрий 4ffc19a7d2 docs(narrative): v8.4 → v8.5 — реализация 27 решений аудита C
Завершает блок реализации v8.5 после schema-коммита 038a884.

Переименования:
- docs/CRM_bp-gr_Инструкция_v8_4.md → _v8_5.md
- docs/README_АРХИВ_v8_4.md → _v8_5.md

Новые подразделы narrative (in-place):
- §10.8: Антифрод дублей (Биз-19), routing (Биз-17, CTO-16), scoring
  (Биз-22), регион (Биз-23), эскалация (OPEN-И-25), call-recordings
  задел (OPEN-И-26)
- §12.5.5: TTFR-SLA (Биз-18), UTM-когорты (CTO-14)
- §14.8: Append-only audit hash chain (OPEN-И-15), report_jobs export
  trigger (OPEN-И-20)
- §17.9: Telegram-бот (Биз-20), эскалация-нотификации (OPEN-И-25),
  late waiting_payment alert (Биз-24)
- §19.10.11–12: DNS-rebinding pin-IP (OPEN-И-18),
  marketing.conversion event (Биз-21)
- §22.13: SSO Yandex 360 + JIT + break-glass (OPEN-И-13), SET LOCAL
  test plan (CTO-13), RLS WITH CHECK + REVOKE (OPEN-И-14), Sentry
  PII whitelist+regex (OPEN-И-16), anti-DDoS Nginx+SmartCaptcha+
  blacklist (OPEN-И-21), TTL secrets 365d (OPEN-И-17/19),
  two-person impersonation (CTO-15+Ю-9), audit hash chain link
- §23.10.11: SSO login UI, break-glass dashboard, two-person UI,
  152-ФЗ ст.21 hard-block UI
- §7.1: метрики обновлены 53→54/86→91/33→34/3→4/12 триггеров/4 функции

Прил. И Часть Г (новая) — 9 операционных процедур:
- Г.1 RLS smoke-test через PgBouncer (CTO-13, BLOCKER для фазы 1)
- Г.2 Cron audit:verify-chain (OPEN-И-15)
- Г.3 Cron secrets:notify-expiring (OPEN-И-17)
- Г.4 Anti-DDoS (Nginx + Yandex SmartCaptcha + disposable-blacklist)
- Г.5 Per-tenant DEK + crypto-shred (OPEN-И-22)
- Г.6 pg_anonymizer для staging (OPEN-И-24)
- Г.7 Yandex 360 SSO setup (OPEN-И-13)
- Г.8 Cron leads:escalate-stale (OPEN-И-25)
- Г.9 Cron payments:notify-stale (Биз-24)

Кросс-ссылки обновлены: CLAUDE.md, README.md, web/index.html,
README архива (переименован v8_4→v8_5). Schema.sql v8.5 шапка
указывает на narrative v8_5.md.

cspell-words.txt: +SPE, +gethostbyname.

Lint+spell чистые. Архитектурно фаза 1 (composer create-project)
разблокирована — требуется только Г.1 (e2e-тест RLS) в спринте 1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:09:22 +03:00

235 lines
10 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Прил. Л — Прототипы Лидпоток</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap&subset=cyrillic" rel="stylesheet" />
<style>
:root {
--teal-900: #04342C;
--teal-600: #0F6E56;
--teal-200: #5DCAA5;
--teal-50: #E1F5EE;
--gray-900: #1A1A1A;
--gray-700: #444441;
--gray-500: #888780;
--gray-200: #D3D1C7;
--gray-100: #F1EFE8;
--gray-50: #FAFAF8;
}
* { box-sizing: border-box; }
body {
margin: 0;
font-family: Inter, sans-serif;
background: var(--gray-100);
color: var(--gray-900);
line-height: 1.6;
}
.container { max-width: 880px; margin: 0 auto; padding: 64px 24px; }
.header {
display: flex; align-items: center; gap: 16px;
padding-bottom: 24px; border-bottom: 1px solid var(--gray-200); margin-bottom: 32px;
}
.header-mark {
display: flex; align-items: center; gap: 4px;
}
.header-mark span {
display: block; border-radius: 50%;
}
.header-mark span:nth-child(1) { width: 8px; height: 8px; background: var(--teal-600); opacity: 0.6; }
.header-mark span:nth-child(2) { width: 14px; height: 14px; background: var(--teal-600); opacity: 0.8; }
.header-mark span:nth-child(3) { width: 20px; height: 20px; background: var(--teal-600); }
.header-title { font-size: 22px; font-weight: 600; margin: 0; letter-spacing: -0.01em; }
.header-sub { font-size: 13px; color: var(--gray-500); margin-top: 2px; }
h1 { font-size: 32px; font-weight: 700; letter-spacing: -0.02em; margin: 0 0 8px; }
h1 + p { font-size: 16px; color: var(--gray-700); margin: 0 0 32px; max-width: 640px; }
.meta {
background: var(--teal-50); border: 1px solid var(--teal-200);
border-radius: 12px; padding: 16px 20px; margin-bottom: 40px;
font-size: 13px; color: var(--teal-900);
}
.meta strong { color: var(--teal-900); }
.screens { list-style: none; padding: 0; margin: 0; display: grid; gap: 12px; }
.screen {
display: flex; align-items: center; gap: 20px;
padding: 20px 24px; background: white;
border: 1px solid var(--gray-200); border-radius: 12px;
transition: border-color .15s ease, transform .05s ease;
text-decoration: none; color: inherit;
}
.screen:hover { border-color: var(--teal-600); }
.screen:active { transform: translateY(1px); }
.screen[aria-disabled="true"] {
opacity: 0.5; pointer-events: none;
background: var(--gray-50);
}
.screen-num {
flex: 0 0 40px; height: 40px;
border-radius: 8px;
background: var(--teal-50); color: var(--teal-600);
display: flex; align-items: center; justify-content: center;
font-weight: 600; font-size: 14px;
}
.screen[aria-disabled="true"] .screen-num { background: var(--gray-100); color: var(--gray-500); }
.screen-body { flex: 1; min-width: 0; }
.screen-title { font-size: 15px; font-weight: 500; margin: 0 0 2px; }
.screen-desc { font-size: 13px; color: var(--gray-500); margin: 0; }
.screen-status {
flex: 0 0 auto; font-size: 12px; font-weight: 500;
padding: 4px 10px; border-radius: 999px;
}
.screen-status.is-ready {
background: var(--teal-50); color: var(--teal-600);
}
.screen-status.is-pending {
background: var(--gray-100); color: var(--gray-500);
}
.screen-arrow { color: var(--gray-300); flex: 0 0 auto; }
.screen:hover .screen-arrow { color: var(--teal-600); }
.footer {
margin-top: 48px; padding-top: 24px;
border-top: 1px solid var(--gray-200);
font-size: 12px; color: var(--gray-500);
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<div class="header-mark" aria-hidden="true">
<span></span><span></span><span></span>
</div>
<div>
<p class="header-title">Лидпоток</p>
<p class="header-sub">Прил. Л — HTML-прототипы 8 экранов</p>
</div>
</div>
<h1>Прототипы клиентского приложения и админки SaaS</h1>
<p>HTML/CSS/JS-прототипы 8 ключевых экранов для дизайнера (Диз-1) и frontend-разработчика. Каждый файл самодостаточен — открывается двойным кликом, без сборки. Источник истины по визуалу — <code>brandbook.md</code> v1.1, по поведению — narrative v8.3.1.</p>
<div class="meta">
<strong>Версия:</strong> v0.2 от 06.05.2026 ·
<strong>Готовность:</strong> 3 / 8 экранов (01 + 02 + 03) ·
<strong>Создаётся итеративно:</strong> по одному экрану за сессию ·
<strong>Назначение:</strong> референс для Figma-макетов (Диз-1) и для frontend-команды на старте спринтов 1, 4, 5, 8, 14
</div>
<ul class="screens">
<li>
<a class="screen" href="01-login.html">
<div class="screen-num">01</div>
<div class="screen-body">
<p class="screen-title">Логин · Регистрация · 2FA · Recovery</p>
<p class="screen-desc">Email + пароль, регистрация с zxcvbn, TOTP с 6-значным кодом, 8 резервных кодов</p>
</div>
<span class="screen-status is-ready">Готово</span>
<svg class="screen-arrow" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/>
</svg>
</a>
</li>
<li>
<a class="screen" href="02-dashboard.html">
<div class="screen-num">02</div>
<div class="screen-body">
<p class="screen-title">Дашборд</p>
<p class="screen-desc">5 KPI-карточек, 2 графика (ApexCharts), последние сделки, баланс</p>
</div>
<span class="screen-status is-ready">Готово</span>
<svg class="screen-arrow" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/>
</svg>
</a>
</li>
<li>
<a class="screen" href="03-deals.html">
<div class="screen-num">03</div>
<div class="screen-body">
<p class="screen-title">Список сделок</p>
<p class="screen-desc">Таблица с фильтрами, 14 цветных статусов, массовые операции, пагинация, low-balance баннер</p>
</div>
<span class="screen-status is-ready">Готово</span>
<svg class="screen-arrow" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/>
</svg>
</a>
</li>
<li>
<a class="screen" aria-disabled="true">
<div class="screen-num">04</div>
<div class="screen-body">
<p class="screen-title">Карточка сделки</p>
<p class="screen-desc">Модалка/страница: статусы, теги, комментарии, напоминания, история</p>
</div>
<span class="screen-status is-pending">В очереди</span>
<span></span>
</a>
</li>
<li>
<a class="screen" aria-disabled="true">
<div class="screen-num">05</div>
<div class="screen-body">
<p class="screen-title">Канбан-доска</p>
<p class="screen-desc">Drag-and-drop по 14 статусам, optimistic UI, виртуализация колонок</p>
</div>
<span class="screen-status is-pending">В очереди</span>
<span></span>
</a>
</li>
<li>
<a class="screen" aria-disabled="true">
<div class="screen-num">06</div>
<div class="screen-body">
<p class="screen-title">Биллинг и тарифы</p>
<p class="screen-desc">Кошелёк, история операций, выбор тарифа, пополнение, счета и УПД</p>
</div>
<span class="screen-status is-pending">В очереди</span>
<span></span>
</a>
</li>
<li>
<a class="screen" aria-disabled="true">
<div class="screen-num">07</div>
<div class="screen-body">
<p class="screen-title">Настройки тенанта</p>
<p class="screen-desc">Профиль, проекты, токены API, интеграции, тихие часы, активные сессии</p>
</div>
<span class="screen-status is-pending">В очереди</span>
<span></span>
</a>
</li>
<li>
<a class="screen" aria-disabled="true">
<div class="screen-num">08</div>
<div class="screen-body">
<p class="screen-title">Админка SaaS</p>
<p class="screen-desc">Список тенантов, карточка тенанта, биллинг, impersonation, журналы</p>
</div>
<span class="screen-status is-pending">В очереди</span>
<span></span>
</a>
</li>
</ul>
<p class="footer">
Прил. Л v0.1 · Источник истины по визуалу: <code>brandbook.md</code> v1.1 ·
По поведению: <code>CRM_bp-gr_Инструкция_v8_5.md</code> §1–28 + Прил. Г для №08
</p>
</div>
</body>
</html>