sdelay-sayt-proekt-lifemap-k/design-system/docs/PRODUCT_CONTRACT.md

94 lines
11 KiB
Markdown
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.

# Продуктовый контракт KT AI
Единый контракт, из которого собирается прототип. **Один источник, один рантайм.** Это ключевой механизм северной звезды (`GOAL.md`): *прототип === фронтенд продакшна*.
## Зачем
Раньше форма «входного контракта» дублировалась в четырёх местах и неизбежно дрейфовала:
`archive/kt_ai_atomic_product_system.md` (yaml) · JSON-конфиг в `kt-ai-app-shell.html` · `kt-ai-shadcn/.../kt-ai-product-input-contract.md` · вывод дизайнера Төре `[[APP]]`.
Теперь каноническая форма одна: **`product.schema.json`** (JSON Schema). Все остальные описания — производные от неё.
## Контур
```
Паспорт агента ─┐
├─► Төре (дизайнер [[APP]]) ──► product.config.json ──► kt-ai-app-shell.html ──► кликабельный прототип
Интервью Төре ──┘ выдаёт контракт ▲ проверяет потребляет контракт (владелец кликает, комментирует)
│
scripts/validate_product.py
(структура по схеме + lint правил ДС)
│
└──► handoff: тот же контракт читает kt-ai-prototype-handoff.md
```
- **Төре выдаёт** контракт по `product.schema.json` (Төре не трогаем — он уже эмитит эту форму).
- **`kt-ai-app-shell.html` потребляет** его из `<script id="kt-app-config">` — это рантайм, которым владеет ДС.
- **`validate_product.py` проверяет** — структуру и правила честности.
- **Handoff читает** тот же контракт: данные → mock-модуль, статусы → workflow, control → primary-действие.
## Поля (кратко; полная форма и все ограничения — в `product.schema.json`)
Ниже описаны **все 31 блок** схемы. Звёздочка — обязательное поле внутри блока.
| Блок | Назначение |
|---|---|
| `archetype` | форма экрана из открытого реестра (`queue` дефолт; см. `ARCHETYPES.md`). `layout` — deprecated-алиас |
| `product` | name (H1, 1-3 слова), purpose (scope ≤90), entity, primary_user, language, **view** (`operational`/`management`) |
| `user` | name, role владельца |
| `notifications` | лента уведомлений (text, time, unread) |
| `steps` | этапы мастера создания (items, current) — НЕ на главном списке |
| `nav` | разделы sidebar (3-5 на группу): {label, icon}; `group` → общий заголовок для идущих подряд пунктов (заголовок не пункт: в нумерации разделов не участвует, в полосе значков становится разделителем); `view:"documents"`+`docType` → секция-коллекция документов (по `_docs` строк) с кнопкой «Скачать» |
| `kpis` | тихая метрик-полоса; отвечают на работу пользователя, не на ROI продукта. Значение — всегда НОВОЕ (to-be) состояние: подпись «вместо X» не может стоять над значением X — сколько СТАЛО пишется в value, сколько БЫЛО остаётся в подписи или hint (валидатор ловит, DS-016). `hint` (≤40) — из чего считано; `note` (без потолка) — чем число НЕ является: оговорка о поле-источнике, стоит рядом с числом и не прячется под клик |
| `scenario` | один сквозной сценарий: headline, **control** (ровно один primary), reject, confirmText, approveTo/rejectTo, `aiSummary` (что сделал агент — 1-2 фразы для drawer) |
| `statuses` | словарь workflow-статусов: ключ → { label ≤4 слов, tone `ok/warn/risk/info`, `dim?` (гасит терминальные строки) } |
| `table` | columns + rows — главный объект экрана. Строка: `_flags` (признаки агента), `_docs` (выходные документы [{label,type,status,format}] — карточки со «Скачать») |
| `drawer` | детали объекта справа (titleKey, fields, flagsLabel) + секция «Документы» из `_docs` строки |
| `ai` | точка входа Төре (intro, suggestions, answers, fallback) |
| `banner` | системный баннер «что-почему-что делать» (text, tone). Стоит НАД числами: всё, что в него уходит, читают до первого числа |
| `search` | поиск в шапке: `placeholder`, `compact` (узкое поле 176px), `shortcut` (сочетание ⌘K/Ctrl+K вместе с бейджем — включаются и выключаются одним полем). В React-ките те же поля — в пропе `search` у `KTAIShell` |
| `conclusion` | вывод раздела (title, **text**) — последний блок экрана, после таблицы. Противовес баннера: баннер предупреждает ДО чисел, вывод объясняет ПОСЛЕ них. Пустая строка в `text` делит абзацы |
| `compare` | данные архетипа compare: aLabel, bLabel, pairs[{label,a,b}] |
| `sections` | данные архетипа custom: секции-карточки [{title, description?, body?, fields?}] |
| `chart` | сводный bar-chart над таблицей: title, total, unit, color, link; `groupBy` (бары из фильтрованных строк) или `bucket:"day"`+`dateKey` (раскатка по дням + универсальный фильтр диапазона) |
| `activity` | правый таймлайн-лог действий агента [{title, time, ago, tone, who, tags, summary, link}] — кнопка «Активность» в топбаре |
| `onboarding` | карусель первого входа [{icon, title, text}] — показ один раз + ссылка повторного показа в низу sidebar |
| `filterKeys` | какие поля строки дают вкладки-фильтры (string[]). Рантайм берёт **не более 4** + «Все» — закон Хика |
| `dashboard` | обзорный экран: `series*` (ряды графика), `range` (период), `breakdowns` (разборы под графиком: top-N, доли, мини-карточки) |
| `analytics` | аналитический экран: `charts*`, `findings*` (выводы словами), `summary`, `period` |
| `document` | документ с фрагментами: `title*`, `fragments*` (абзацы; помеченные агентом — с причиной), `source` |
| `artifact` | результат работы агента рядом с чатом: `type`, `title*`, `version`, `preview*`, `actions` (архетип copilot) |
| `wizard` | многошаговый процесс: `steps*` (номер, название, 1-строчное описание), `current` — вертикальный степпер слева |
| `inbox` | «список + чтение»: `bodyKey*` и ключи для заголовка/подписи/времени (`titleKey`, `subKey`, `timeKey`) |
| `calendar` | окна и брони: `events*`, `range`, `title` |
| `map` | география: `points*`, `lines`, `title` |
| `timeline` | хронология события: `events*`, `title` |
### Field-level data contract (что делает прототип правдивым)
Колонка таблицы несёт не только `key`/`label`/`type`, но и:
- `values` — допустимые значения для status/enum-колонок (из паспорта/интервью);
- `source` — откуда значение: SAP, Лотус, KTWorks, агент, человек;
- `align` / `sortable` — поведение.
Без этого слоя дизайнер выдумывает примеры, и владелец процесса ревьюит вымысел. С ним владелец видит **свои** поля, статусы и источники — первый прототип становится правдивым.
## Как проверить
```bash
python3 scripts/validate_product.py <ваш-конфиг>.json # черновая проверка (errors блокируют)
python3 scripts/validate_product.py <ваш-конфиг>.json --strict # ВОРОТА handoff/CI: warnings тоже блокируют
```
Правило: **прототип уходит в handoff/CI только при `--strict` без замечаний** (0 ошибок, 0 предупреждений). Без `--strict` проходят честностные warnings (ROI/FTE на operational, debug-язык, неизвестный архетип) — они допустимы на этапе черновика, но не на сдаче.
Валидатор — это seed `kt-ai-lint`. Он ловит:
- **ERROR** (блокирует): статус в ряду не объявлен в `statuses`; `scenario.approveTo/rejectTo` ссылается на несуществующий статус; `drawer.titleKey`/`fields` не из колонок; лишние/недостающие поля; tone вне `ok/warn/risk/info`; пустой `scenario.control`.
- **WARN** (правила честности ДС): ROI/FTE/экономия на операционном дашборде (`view=operational`); debug-язык в копирайте (`модель вернула`, `fallback`, `JSON`, `prompt`, `shell`); статус-лейбл > 4 слов; имя экрана/лейблы длиннее нормы; мало строк (< 5).
## Правило
Меняется форма контракта — меняется **только** `product.schema.json`, затем синхронизируются производные описания и проверяется `examples/`. Не плодить пятую копию контракта.