docs: архитектурный анализ + History + gitignore (2026-06-27)

This commit is contained in:
“Naeel”
2026-06-27 13:00:18 +04:00
parent 4a21d77f51
commit 82c5c075f1
154 changed files with 4789 additions and 1443 deletions
@@ -0,0 +1,103 @@
# Ответ Опуса — isolated training page / feedback storage
Дата: 26.06.2026 | Ответ на вопросы по отдельной странице "обучения" для проекта «Сверка договоров».
## Контекст
- Стек: Lucee/CFML 6.0, файловая маршрутизация (`teach.cfm``/teach`), PostgreSQL `baza`.
- Рабочий compare-пайплайн не трогаем: новая фича должна жить полностью изолированно.
- Цель: отдельная страница с тем же UI-скелетом, что и compare results, но с возможностью оставлять замечания по строкам таблицы операций и сохранять их в БД для дальнейшего анализа агентом.
## 1. Минимальная схема `feedback`
Для MVP достаточно плоских колонок для агрегации и `JSONB` для значений:
```sql
CREATE TABLE IF NOT EXISTS feedback (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
created_at TIMESTAMPTZ DEFAULT now(),
contract_id UUID,
supplement_id UUID,
event_seq INTEGER, -- NULL для missed/document
scope TEXT NOT NULL, -- 'row' | 'missed' | 'document'
verdict TEXT NOT NULL, -- 'correct' | 'error'
error_type TEXT, -- wrong_price|wrong_qty|wrong_name|wrong_date|extra_row|missed_row|wrong_action|wrong_mode
field TEXT, -- price|qty|sum|name|date_start|action|mode
service_name TEXT,
llm_value JSONB,
correct_value JSONB,
prompt_version TEXT,
doc_mode TEXT, -- partial | full_replace
comment TEXT
);
CREATE INDEX IF NOT EXISTS idx_feedback_error ON feedback(error_type);
CREATE INDEX IF NOT EXISTS idx_feedback_prompt ON feedback(prompt_version);
```
Рекомендуемый фиксированный набор `error_type`:
`wrong_price, wrong_qty, wrong_name, wrong_date, extra_row, missed_row, wrong_action, wrong_mode`.
## 2. UI первой версии vs отложить
### В MVP
- Колонка `⚠` у каждой строки таблицы операций с мини-формой: выбор `error_type` + опционально правильное значение + комментарий.
- Кнопка `[✓ всё верно]` на карточке ДС для положительного сигнала (`scope=document, verdict=correct`).
- Кнопка `[➕ пропущена позиция]` для случая, когда позиция была пропущена (`scope=missed`).
### Отложить
- Инлайн-редактирование значений прямо в ячейках.
- Статистика и дашборды на самой странице.
- Модерация замечаний, роли, удаление чужих записей.
- Разбор новых загрузок на этой странице; работать только по уже разобранным документам из БД.
## 3. Связь с исходной операцией
Правильная связь — логическая, без FK и без вмешательства в рабочий pipeline: `(contract_id, supplement_id, event_seq)`.
Почему так:
- `spec_events` уже хранит операции как `spec_events(contract_id, supplement_id, seq, action, new_values, ...)`.
- `feedback` просто повторяет эти значения как обычные поля.
- Без FK исключается риск связать feedback с жизненным циклом боевых событий или сломать вставки при повторном разборе.
Если `event_seq` когда-то переедет из-за пересборки данных, в `llm_value` / `correct_value` нужно сохранять снимок операции (`action` + `new_values`), чтобы замечание оставалось интерпретируемым.
## 4. `prompt_version`
Версию промпта хранить нужно, иначе нельзя считать регрессию между изменениями.
Но сейчас результат разбора не штампуется версией промпта, поэтому для MVP предлагается практический компромисс:
- `/teach` при сохранении замечания пишет текущую активную версию промпта из БД.
- Это честно помечается как версия на момент проверки, а не на момент исходного разбора.
- Правильная фиксация `prompt_version` в результате разбора — отдельная задача основного pipeline, не часть isolated feedback flow.
## 5. Что исключить
### PII / обезличивание
- Не хранить название/ИНН клиента, номер договора, ФИО, подписантов, реквизиты, email, телефоны.
- Не хранить оригинальный текст документа и байты файла.
### Изоляция рабочих данных
- Не использовать `ALTER` существующих таблиц.
- Не добавлять FK, триггеры или write-логики в `spec_events`, `spec_current`, `contracts`, `supplements`.
- `/teach` должен писать только в `feedback` через отдельный параметризованный endpoint.
## Итог
Опус подтвердил, что MVP должен быть:
1. Отдельной страницей с тем же UX-скелетом, что и compare results.
2. Отдельным write endpoint и отдельной таблицей `feedback`.
3. Полностью изолированным от рабочего compare-пайплайна.
4. Приспособленным для SQL-аналитики агентом через плоские колонки + `JSONB`.
Главный принцип: это не online-training, а сбор структурированного feedback для последующего анализа и планирования изменений.