model: v5.15 — индексы osv_entry(parent_entry_id, recognition_job_id), stored_file(current_recognition_job_id) (I-1, OQ-117)
- data-model-v5.15.dbml: обычные индексы osv_entry (parent_entry_id), osv_entry (recognition_job_id), stored_file (current_recognition_job_id) с note; п. 4 changelog v5.15 — индексы для удаления файла и обхода дерева строк; замер: DELETE документа 1000 строк 8,6 с → 16 мс на 200 тыс. строк. - entities-v5.15.md: строка 4 в «Что изменилось в v5.15». - 07-open-questions: OQ-117 закрыт в v5.15 (v5.16 и миграция 0004 не понадобились). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
This commit is contained in:
parent
8c73fe941c
commit
e3d3c2a9eb
@ -122,7 +122,7 @@
|
||||
| OQ-114 | `EntryOut` (API строк ОСВ) не отдаёт `is_modified`/`original_*`: панели правки подсреза 2d нужен признак правки аналитика (инвариант «первичка не мутируется»: правка — рядом, с аудитом). Добавить поля в схему и контракт API при проектировании 2d | arm-core Срез 2c: Task 9 (T9.7) | подсрез 2d | открыт: в 2c строк не правят, `is_modified = false` у всех |
|
||||
| OQ-115 | Автозамена: если новый файл содержит лишь часть документов прежнего (прежний — ОСВ 60 и 51, новый — только 60), прежний уходит в `SUPERSEDED` **целиком**, документ 51 пропадает из списка файлов; в `FILE_REPLACE.description` о нём ничего нет. Подтвердить «замена файлом целиком» (OQ-06) для этого случая или заменять по документам | arm-core Срез 2c: Task 8 (T8.4) | Срез 2d (список файлов), Срез 4 (комплект документов) | допущение принято: замена файлом целиком, документы заменённого файла сохраняются в БД |
|
||||
| OQ-116 | ОСВ Q2–Q4, признанная нарастающей по данным Q1 (сальдо на начало корня равно сальдо Q1, §1.5), получает предупреждение маппинга и поэтому остаётся `NEEDS_CHECK`, а не `RECOGNIZED` (буквально D-7/D-9 спеки: `RECOGNIZED` только без предупреждений). Верно ли, что аналитик подтверждает такие документы вручную, или нарастающая по данным — штатный случай без предупреждения (OQ-02, OQ-05) | arm-core Срез 2c: Task 7 (R-17, design №30) | Срез 2d (нагрузка на аналитика), §9.3 | допущение принято: `NEEDS_CHECK`; снять предупреждение — одна правка в `result_mapping.py` и правило статуса |
|
||||
| OQ-117 | Индексы `osv_entry(parent_entry_id)`, `osv_entry(recognition_job_id)`, `stored_file(current_recognition_job_id)`: `DELETE /files/{id}` (и очистка файла при повторном маппинге) делает seq scan на проверке self-FK — на временной таблице 200 тыс. строк удаление документа в 1000 строк 8,6 с без индекса и 16 мс с индексом (замер в psql на временной таблице, final review); при ~3 млн строк DELETE ≈ 2 мин → HTTP-таймаут и долгое удержание блокировок. Требуется DBML v5.16 + миграция 0004. Решает владелец (источник истины — DBML) | arm-core Срез 2c: final review (I-1, R-24, design №51) | `DELETE /files/{id}`, повторный маппинг; подсрез 2d (UI удаления), прод | открыт, **блокер: до прода / до подсреза 2d (UI удаления)**; в 2c индексов нет |
|
||||
| OQ-117 | Индексы `osv_entry(parent_entry_id)`, `osv_entry(recognition_job_id)`, `stored_file(current_recognition_job_id)`: `DELETE /files/{id}` (и очистка файла при повторном маппинге) делает seq scan на проверке self-FK — на временной таблице 200 тыс. строк удаление документа в 1000 строк 8,6 с без индекса и 16 мс с индексом (замер в psql на временной таблице, final review); при ~3 млн строк DELETE ≈ 2 мин → HTTP-таймаут и долгое удержание блокировок. Требуется DBML v5.16 + миграция 0004. Решает владелец (источник истины — DBML) | arm-core Срез 2c: final review (I-1, R-24, design №51) | `DELETE /files/{id}`, повторный маппинг; подсрез 2d (UI удаления), прод | **закрыт в v5.15 (06.10.2026):** индексы добавлены в DBML v5.15 (п. 4 changelog) и миграцию `0003_dbml_v5_15` arm-core — `ix_osv_entry_parent_entry_id`, `ix_osv_entry_recognition_job_id`, `ix_stored_file_current_recognition_job_id`; v5.16 и миграция 0004 не понадобились (v5.15 ещё не слит) |
|
||||
|
||||
Служебные идентификаторы в DBML/аналитике: `ANL-nnn` — замечания аналитика к макету; `ARCH-nnn` — архитектурные решения;
|
||||
`DECISION-n` — решения по модели; `FIX-nn` — исправления дефектов v4.
|
||||
|
||||
@ -12,6 +12,9 @@
|
||||
// 3. Без изменений структуры, уточнение семантики: stored_file.status — PROCESSING ставится inbox'ом по ack сервиса,
|
||||
// PROCESSED/ERROR — циклом маппинга результата (OQ-67); маппинг выполняется отдельно от inbox (OQ-69);
|
||||
// recognition_job.group_schema заполняет маппер; «Итого» в osv_entry не хранится (OQ-01).
|
||||
// 4. Индексы для удаления файла и обхода дерева строк: osv_entry (parent_entry_id), osv_entry (recognition_job_id),
|
||||
// stored_file (current_recognition_job_id) — проверки FK при DELETE документа/файла и очистке перед повторным
|
||||
// маппингом шли seq scan'ом (OQ-117). Замер: DELETE документа 1000 строк 8,6 с → 16 мс на 200 тыс. строк.
|
||||
//
|
||||
// v5.14 (Срез 1, решения владельца 04.10.2026):
|
||||
// 1. ЮЛ может состоять ОДНОВРЕМЕННО в одной ГСК и одной ГСЗ (но только в одной группе каждого вида) — отменяет
|
||||
@ -696,7 +699,10 @@ Table stored_file {
|
||||
uploaded_by uuid [ref: > app_user.id]
|
||||
uploaded_at timestamptz
|
||||
updated_at timestamptz
|
||||
Indexes { (legal_entity_id, status) }
|
||||
Indexes {
|
||||
(legal_entity_id, status)
|
||||
current_recognition_job_id [note: 'v5.15: проверка FK при удалении recognition_job / файла (OQ-117)']
|
||||
}
|
||||
Note: 'v5.13: физический файл одной загрузки (S3 — только ссылка). Что внутри — document (1:N). Первичка не редактируется. Удаление физическое запрещено после INITIATED — только SUPERSEDED (ANL-020)'
|
||||
}
|
||||
|
||||
@ -806,6 +812,8 @@ Table osv_entry {
|
||||
Indexes {
|
||||
(document_id, row_number) [unique]
|
||||
(owner_legal_entity_id, account_id, counterparty_id)
|
||||
parent_entry_id [note: 'v5.15: обход дерева строк и проверка self-FK при удалении документа (OQ-117)']
|
||||
recognition_job_id [note: 'v5.15: проверка FK при удалении recognition_job / файла (OQ-117)']
|
||||
}
|
||||
Note: 'Строка ОСВ. Правки сумм аналитиком — original_values/modified_by + audit_event(RECOGNIZED_DATA_EDIT, before/after)'
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# АРМ КА — описание сущностей модели данных v5.15
|
||||
|
||||
Источник истины по структуре — `data-model-v5.15.dbml` (полный). Диаграммы по частям — `diagrams/` (part01…09 svg/png; отрисованы по v5.13: v5.14 меняет только `related_group_member` — колонку `kind` и индекс, v5.15 — одно значение enum, — диаграммы не перерисовывались). Здесь — что каждая таблица значит для бизнеса, как связана с соседями и откуда взялась.
|
||||
Источник истины по структуре — `data-model-v5.15.dbml` (полный). Диаграммы по частям — `diagrams/` (part01…09 svg/png; отрисованы по v5.13: v5.14 меняет только `related_group_member` — колонку `kind` и индекс, v5.15 — одно значение enum и три индекса, — диаграммы не перерисовывались). Здесь — что каждая таблица значит для бизнеса, как связана с соседями и откуда взялась.
|
||||
|
||||
## Что изменилось в v5.15 (Срез 2c, решения владельца 05.10.2026)
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
| 1 | `osv_data_type` + `NU` (после `BU`) | Строки налогового учёта из ОСВ «БУ, НУ» хранятся в `osv_entry` как есть (OQ-45); контракт результата допускал `NU` с v1.0, ядро раньше такой строки принять не могло |
|
||||
| 2 | `app_user.email` — в нижнем регистре | Без изменения структуры: нормализация при записи (seed, администрирование), поиск по `lower(email)` сохраняется, уникальность — существующий UNIQUE по `email` (OQ-59). Expression-индекс `lower(email)` не вводится: сверка ORM↔DBML не умеет expression-индексы. Миграция `0003` приводит существующие email к нижнему регистру (при дублях по регистру — падает, слияние решает человек) |
|
||||
| 3 | Семантика `stored_file.status`, `recognition_job.group_schema` | Без изменения структуры: `PROCESSING` ставит inbox по ack сервиса, `PROCESSED`/`ERROR` — цикл маппинга результата (OQ-67); маппинг выполняется отдельно от inbox (OQ-69); `group_schema` заполняет маппер; «Итого» в `osv_entry` не хранится (OQ-01) |
|
||||
| 4 | Индексы `osv_entry (parent_entry_id)`, `osv_entry (recognition_job_id)`, `stored_file (current_recognition_job_id)` | Индексы для удаления файла и обхода дерева строк: без них проверки FK (в том числе self-FK `parent_entry_id`) при `DELETE /files/{id}` и очистке файла перед повторным маппингом шли seq scan'ом. Замер: DELETE документа 1000 строк 8,6 с → 16 мс на 200 тыс. строк. Обычные (не unique) индексы; закрывает OQ-117 (I-1 финального ревью Среза 2c) |
|
||||
|
||||
Остальные таблицы и enum — как в v5.14 (43 таблицы, 27 enum). Реализация — миграция `0003` в `arm-core`.
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user