- api_settings: убраны реальные API-ключи из кода (env/файл) — 1.1
- verify: промт ИИ для проверки реквизитов больше не ссылается на 187-ФЗ
как на закон о ПДн («юрист по ПДн (187-ФЗ)» → специалист по реквизитам)
- ui: дата ПП РФ №127 исправлена 08.02.2019 → 08.02.2018 (3 места)
- help_docs: группа B переименована «187-ФЗ (персональные данные)» →
«187-ФЗ (критическая информационная инфраструктура)»
- generator: убран дубль хвоста параграфа в _highlight_unmatched
- importer: «магия дат» (числа 10001-79999 → дата Excel) теперь только
для полей-дат (as_date), финансовые поля не ломаются
- ui (_collect_is): убраны дубли пар маппинга attacker_level/attacker_types
- ui (импорт): убрано наследие 152-ФЗ ispdnPosition/ispdnFio из маппинга
- test_generator: переписан под модель 187-ФЗ (category/sphere/object_type
вместо pd_count/threat_type/defence_level)
- criteria_justifications: п.9 для здравоохранения согласован с кодом
(убран «критерий неприменим» — противоречие с «применим ко всем»)
- criteria_applicability: Транспорт (добавлены п.1, п.2; убран п.10),
Банковская сфера (добавлены п.8, п.9) — требуется экспертная сверка
- ui: Бусредн вынесен в константу DEFAULT_BUDGET_AVG (данные Минфина,
обновлять ежегодно); автозаполнение п.9 унифицировано с авторасчётом
(ΔБ = ΔНП+ΔНДПИ+ΔДИВ+ΔВСО+ΔНС)
- ui: п.8 — предупреждение при неполных данных (менее 5 лет доходов)
- models: поля ndpi/div/vso/ns для п.9; комментарий income_loss уточнён
- .gitignore: api_settings.json/.env не попадают в git
- проверка категории через regex с границей слова: «Категория значимости: I»
была подстрокой «…III», из-за чего III выбиралась как I
- если расчёт не удался (в result «Заполните…») — ничего не применяется
и не пишется в обоснование
Вместо тесной двухколоночной раскладки — ряд подвкладок:
1) Основные данные — модель нарушителя (категория, уровень Н1-Н4, виды)
+ кнопки «⚡ Автозаполнить» и «🤖 Проверить безопасность через ИИ»
2) Угрозы — панель действий (⬇️ ФСТЭК / ⚙️ программа / 🤖 ИИ / ⚖️ сравнить)
+ большой список угроз на всю ширину
3) Инциденты и критерии — инциденты, показатели критериев,
кнопка «📋 ПП № 127», обоснование
4) Орг. и тех. меры — оба списка с нормальной высотой
Все виджеты и маппинги сохранены (is_*_listbox/combo на месте)
Проблемы:
1. Окно уходило на задний план при сдвиге — не было grab_set/lift,
родитель указывал на главное окно вместо диалога ПП 127
2. В показателе 8 не вводились данные — из-за потери фокуса
3. В показателе 9 кнопка «Рассчитать» не была видна — окно 720x560
не вмещало все поля (прибыль/налог/ΔДоходов/бюджет/НДПИ/ДИВ/ВСО/НС +
результат), кнопки уезжали за край
Исправлено:
- родитель окна — dialog (ПП 127), а не root
- w.transient(dialog) + w.lift() + w.grab_set() + w.focus_force()
- тело окна в Canvas + вертикальный Scrollbar (все поля доступны)
- кнопки «🧮 Рассчитать / ✔️ Применить / Отмена» вне скролла — всегда видны
- при закрытии — grab_release()
- prompts/suggest_object_params.json: жёсткие правила подбора характеристик —
выбирать ТОЛЬКО из предоставленных списков (сферы/типы/архитектуры/
типовые объекты), ничего не выдумывать; назначение строго по форме
«Объект предназначен для … с целью …»; типовой объект — дословно из 360-р
- prompts/suggest_threats.json, check_security.json, check_company.json,
declension.json — промты для остальных ИИ-кнопок
- verify.py: _load_prompt() + подключение промтов в suggest_object_params_ai,
suggest_threats_ai, check_security_ai; ИИ получает полные списки
(spheres/object_types/architectures) и выбирает из них
- ui.py: окно рекомендаций ИИ — галочки у каждого поля, применяются
только отмеченные (ИИ может ошибаться в архитектуре — оператор решает)
Кнопки command=_auto_fill_criteria и lambda _open_calc_dialog создавались
ДО определения этих функций внутри _open_criteria_127_dialog — Python
бросал UnboundLocalError/NameError при нажатии. Определения функций
перенесены выше мест использования (проверено: def < кнопка для всех).
- verify.py: get_company_finance_dadata(inn, token) — findById/party,
возвращает finance (последний отчётный год) + finance_history (по годам)
- ui.py: кнопка «🌐 Загрузить доходы из DaData (по ИНН)» в блоке
«Доходы за 5 лет (показатель 8)» — по ИНН организации подтягивает
доходы за последние 5 лет и заполняет income_year_1..5
- если в тарифе DaData нет финансовой отчётности — понятное сообщение,
доходы заполняются вручную
В _open_calc_dialog использовался _num2 (определён только в
_auto_fill_criteria) — tkinter молча глотал исключение, кнопки
«молчали». Заменено на _num (определён внутри _open_calc_dialog).
Дополнительно isys определён в начале диалога ПП 127 для
авторасчёта (доходы/ущерб/балансовая стоимость объекта).
- dictionaries/okved_187.json: 78 кодов ОКВЭД из Распоряжения ПРФ № 360-р
(виды деятельности субъектов КИИ по типовым отраслевым объектам)
- okved.json: добавлен недостающий код 09.90 (всего 267)
- ui.py: _load_okved_187_codes/_is_okved_187 — проверка по коду/подкоду
- окно выбора основного ОКВЭД: радио-кнопки с пометкой «★ ...»
- окно выбора доп. ОКВЭД: display_map со звёздочками (в значение
звёздочка не попадает), легенда «★ — код подходит под 187-ФЗ»
- при применении сохраняется чистый код без ★ (импорт/документы не ломаются)
- models: income_year_1..5 (доход за 5 лет назад ... за прошлый год),
income_loss (суммарный экономический ущерб от нарушения критических
процессов) — понятные названия без ΔДоходов
- вкладка «Организация» → «Финансовые показатели»: 6 новых полей
- авторасчёт п. 8: берёт доходы за 5 лет и ущерб из полей,
считает №8 = ущерб / средний доход за 5 лет × 100% (проверено
на примере методички: 33% → I категория)
- импорт из опросника: incomeYear1..5 / incomeLoss
- переменные шаблонов: {{company_income_year_1..5}},
{{company_income_loss}}
- после автозаполнения категория пересчитывается сразу (по наивысшей
из выбранных)
- подсказка для ΔДоходов: балансовая стоимость объекта как ориентир
- итоговое сообщение показывает, какие показатели остались незаполненными
(нет данных для расчёта) — оператор видит, что именно добить вручную
Кнопка «⚡ Заполнить автоматически (по данным)» в окне ПП 127:
- п. 8 (ущерб субъекту КИИ): если организация не госкорпорация/ГУП/
госкомпания/стратегическое АО (Указ № 1009) — автоматически «не
применим» + обоснование
- п. 9 (ущерб бюджетам): подставляет прибыль и налог из данных
организации, оператор вводит ΔДоходов → расчёт КНП → ΔНП →
№9 = ΔБ/Бусредн×100% → рекомендация категории (пороги ПП 127),
расчёт добавляется в обоснование
- остальные применимые показатели — оператор заполняет вручную
- результаты как рекомендация, всё подтверждается пользователем
- detect_sphere(): автоопределение сферы по ключевым словам названия/
назначения/описания объекта (здравоохранение, наука, транспорт, связь,
энергетика, банки, ТЭК, атомная, ОПК, ракетно-космическая, горная,
металлургия, химия)
- suggest_typical_object_program: фильтр по сфере в приоритете —
1) сфера из комбобокса, 2) сфера объекта (isys.sphere), 3) автодетект,
4) иначе все сферы. ОПК-объекту НЕ подбираются объекты из
здравоохранения и других сфер
- если в своей сфере совпадений нет — возвращается пусто, оператор
выбирает сферу вручную
Выпадающий список применимого показателя: пусто / «—» (применим,
категория не присвоена) / «не применим» / III / II / I.
У неприменимых к сфере — только «не применим» + кнопка 🔓.
Вкладка «Основное», кнопки под полем типового объекта:
- ⚙️ «Подобрать типовой объект (программа)»: скоринг по совпадению
значимых слов названия/назначения объекта с перечнем 392 типовых
отраслевых объектов (Распоряжение 360-р), IDF-веса (редкие слова
важнее общих) → окно с вариантами, оператор выбирает и применяет
(заполняет сферу + типовой объект)
- 🤖 «Подобрать характеристики (ИИ)»: DeepSeek предлагает назначение,
сферу, тип, архитектуру и типовой объект (из перечня 360-р) как
рекомендацию → окно с полями, оператор подтверждает/правит
Примеры: СКУД → «ИС, АСУ, ИТКС, обеспечивающие контроль и управление
доступом на территорию»; 1С:УПП → «ИС для ведения бухгалтерского учета»
- применимый показатель: пусто / «—» (применим, категория не присвоена)
/ III / II / I категория
- неприменимый к сфере: в списке ТОЛЬКО «не применим», выбран
автоматически, заблокирован, авто-обоснование из словаря сферы
- кнопка «🔓» разблокирует конкретный показатель и возвращает
полный список (категории + прочерк)
- options показателя: пусто / «—» (показатель применим, но категория
не присвоена) / «не применим» / III / II / I
- _selected различает «прочерк» и «не применим» (оба не влияют
на категорию, но сохраняются в список показателей)
- список показателей: «применим, категория не присвоена (—)» /
«не применим»
- авто-обоснование: прочерк — «применим, категория не присвоена»,
не применим — текст из словаря сферы
- criteria_applicability.json: ОПК — применимы 8 (ущерб субъекту КИИ),
9 (ущерб бюджету), 13 (гособоронзаказ) — обязательные для ОПК
- окно ПП 127: неприменимые для сферы показатели автоматически
выбирают «не применим» и блокируются (серым), НО у каждого есть
кнопка «🔓» — разблокировать конкретный показатель, если оператор
считает его применимым (вернётся выбор категории)
- «не применим» сохраняется в список показателей и обоснование,
не влияет на категорию
- dictionaries/criteria_justifications.json: тексты обоснований для сферы
здравоохранения (показатели 1-7) — дословно из примера заказчика
- окно ПП 127: при выборе «не применим» обоснование из словаря сферы
автоматически подставляется в поле «Обоснование»
- авто-обоснование при сохранении: категория + выбранные показатели +
неприменимые показатели с текстами обоснований; если все показатели
неприменимы — «Категория значимости: не присвоена»
В окне ПП 127 у каждого показателя теперь 5 вариантов: пусто,
«не применим», 3 категория, 2 категория, 1 категория.
«Не применим» не влияет на расчёт категории, но сохраняется
в список показателей как «Показатель N. ... — не применим».
После импорта данных (опросник/JSON) программа сама прогоняет логику
по каждому объекту КИИ: нарушитель (по интернету), уровень Н1/Н2,
виды нарушителей, угрозы (скоринг), инциденты (из угроз),
орг./тех. меры (базовые + по СЗИ объекта). Оператор добивает
остальное вручную. Лог: «⚡ Автозаполнение безопасности».
Новая кнопка «⚡ Автозаполнить» в панели действий — заполняет пустые поля
логически, без выдумок:
- категория нарушителя: есть интернет → внешний, нет → внутренний
- уровень возможностей: Н1 (внутренний) / Н2 (внешний)
- виды нарушителей: по категории из словаря attacker_types.json
- угрозы: подбор программой (скоринг по характеристикам объекта)
- инциденты: выводятся из подобранных угроз по ключевым словам
- орг. меры: базовый набор (контролируемая зона, доступ, документы,
ответственные, обучение, инциденты, перечень лиц)
- тех. меры: базовые + доп. по средствам защиты объекта (СЗИ:
межсетевой экран → МЭ, антивирус, СОВ, СКЗИ, виртуализация)
Незаполненное пользователем не перезаписывает.
Проблемы:
1. Подбор программой возвращал 193 из 227 угроз (весь перечень) —
теперь скоринг по ключевым словам объекта (тип, интернет, нарушитель,
сеть), отсев нерелевантных: 72-82 угрозы вместо 193
2. Сравнение программа↔ИИ не подсвечивало совпадения: ИИ возвращает
«1. УБИ.001 …» / с лишними пробелами — сравнение шло по точной строке.
Теперь ключ сравнения — код УБИ (regex), иначе нормализованный текст;
добавлена статистика «Совпало / только программа / только ИИ»
Причина: результат писался только в панель «Проверка данных» на вкладке
«Организация», а пользователь смотрит вкладку «Безопасность» — замечания
были не видны. Теперь после ответа ИИ открывается отдельное окно
«🤖 Проверка безопасности — результат ИИ» с оценкой, замечаниями
и предложениями.
- dictionaries/criteria_applicability.json: для каждой сферы перечень применимых
показателей ПП РФ № 127, построен из признаков значимости Распоряжения ПРФ
№ 360-р (например: ОПК → только 13 оборонзаказ, показатель 1 «ущерб жизни
и здоровью» не применим; банки → только 10; связь → только 4)
- окно ПП 127: неприменимые для сферы показатели блокируются и помечаются
серым «(не применим для сферы)», исключаются из расчёта категории;
если применимых показателей для сферы нет — категория «без категории»
- dictionaries/typical_industry_objects.json: 392 типовых отраслевых объекта
по 14 сферам (здравоохранение 12, наука 9, транспорт 62, связь 12,
энергетика 12, регистрация прав 1, банки 20, ТЭК 11, атомная 16,
оборонная 39, ракетно-космическая 72, горнодобывающая 38,
металлургическая 53, химическая 35), с процессами и ОКВЭД
- ui.py: логика привязки — при выборе сферы объекта КИИ список типовых
отраслевых объектов заполняется из словаря этой сферы (360-р),
иначе — общий словарь typical_objects.json
- _on_sphere_changed/_update_typical_objects_by_sphere; вызов при загрузке объекта
- dictionaries/fstek_offices.json: 7 управлений ФСТЭК по федеральным округам
с адресами (из официальных реестров) и списками городов/регионов:
ЦФО (Москва, Севастопольский пр-т 56/40), СЗФО (СПб, Исаакиевская пл. 11),
ЮФО+СКФО (Ростов-на-Дону, ул. Ярослава Галана 1Е/25), ПФО (Н.Новгород,
пр-т Гагарина 60 к11), УрФО (Екатеринбург, ул. Гагарина 28Б), СФО
(Новосибирск, Красный пр-т 41), ДФО (Хабаровск, ул. Ленина 37)
- variables.py: _find_fstek_office(address) — определяет управление по городу/
региону из адреса организации (с нормализацией сокращений обл./респ./г.о.)
- новые переменные: {{fstek_recipient_address}} (адрес управления для отправки),
{{fstek_district}} (наименование управления)
- логика: адрес организации → управление ФСТЭК → адрес подставляется в документ
- criteria_127.json переписан точно по Постановлению Правительства РФ
от 08.02.2019 № 127 (приложение): 5 критериев (социальная, политическая,
экономическая, экологическая, значимость для обороны страны), 30 показателей
(1-14 с подпунктами а/б/в/г), значения сразу привязаны к категориям III/II/I
- окно 980x700 со скроллом: у каждого показателя выбор значения из документа
(«III категория: …», «II категория: …», «I категория: …»)
- категория значимости по наивысшей выбранной: I→1-я, II→2-я, III→3-я, иначе без категории
- обоснование: автогенерация текста с перечнем выбранных показателей,
если поле пустое; кнопки «Рассчитать категорию» и «Сохранить»
- категория сразу подставляется в поле категории значимости объекта
- модели: Company.profit (сумма прибыли), Company.profit_tax (налог с прибыли),
InformationSystem.balance_value (балансовая стоимость объекта КИИ)
- импорт из опросника: «Сумма прибыли за предыдущий год» и «Сумма налога с прибыли»
(Общие сведения) → profit/profitTax; «Балансовая стоимость объекта КИИ в рублях»
(каждый ОБЪЕКТ-лист) → balanceValue, больше не падает в описание
- UI: блок «Финансовые показатели» во вкладке «Организация»; поле
«Балансовая стоимость (руб.)» в объекте КИИ; маппинги collect/select/copy/import
- генератор: {{company_profit}}, {{company_profit_tax}}, {{item.balance_value}}
- в окнах выбора из словаря инцидентов, угроз, критериев, мер,
пользователей, СЗИ и ОКВЭД кнопка больше не показывается
- параметр allow_refine: включается только у hw_sw/os_sw/app_sw
(там «уточнить модель» и количество действительно нужны)
- threat_rules: по умолчанию актуальны ВСЕ угрозы БДУ ФСТЭК, исключаются
заведомо неактуальные: нет интернета → убраны удалённый доступ/веб/почта/
беспроводные/DDoS/облачные/грид; АСУ → убраны BIOS/грид/виртуализация/браузер
(теперь 170-200 угроз на объект вместо 15 «самых похожих»)
- _has_internet уточнён: «Отсутствует» у оператора / «изолирован» / «не требуется»
→ внешней сети нет; сеть общего пользования или реальный оператор → есть
- verify.suggest_threats_ai: свежий перечень ФСТЭК (227 угроз) передаётся в промт,
ИИ выбирает из него, а не из устаревших знаний; + человекочитаемая сводка объекта
- ui: кнопки программа/ИИ без лимита 20; после подбора угрозы сохраняются в модель
(_collect_is) — при открытии словаря галочки выбранных угроз стоят
- models.from_dict: фильтрация неизвестных полей вложенных объектов — старые файлы
с удалёнными полями (attacker_characteristics) больше не падают
- _sec_row: новый параметр allow_add — ручное добавление показывается
даже при наличии словаря
- орг. и тех. меры: allow_add=True (может пригодиться), остальные словарные
списки (угрозы, инциденты, критерии) — по-прежнему только из словаря
- убрано из вкладки «Безопасность» (UI), модели InformationSystem,
маппингов _collect_is/_on_is_select, _copy_is, _apply_imported_data,
variables.py и данных для ИИ-проверки
- «Категория нарушителя» остаётся (из варианта 3 Кости)
- кнопка «📋 Заполнить по таблице ПП № 127» в вкладке «Безопасность»
- окно 860x640 со скроллом: 5 критериев (социальная, политическая,
экономическая, экологическая, оборонная), 12 показателей,
у каждого выбор значения 1-4 с описанием шкалы
- объединены показатели и обоснование в одном окне (общее поле)
- «🧮 Рассчитать категорию»: по максимальному баллу → 1/2/3/без категории
(4→1-я, 3→2-я, 2→3-я), результат пишется в категорию значимости объекта
- «💾 Сохранить»: заполняет список показателей и обоснование
- словарь criteria_127.json (формулировки можно править файлом)
- если в ячейке ФИО несколько человек (через запятую/точку с запятой/
перевод строки или просто подряд) — остаётся первое полное ФИО
- применяется к должностным лицам (chief/ответственный/админ),
комиссии и сотрудникам при импорте из опросника
- то же при открытии сохранённого файла (from_dict):
«Коростелев Павел Сергеевич Хрящев Сергей Владимирович …» → «Коростелев Павел Сергеевич»
- кнопка «✏️ Уточнить модель/кол-во» теперь всегда в окне выбора из словаря
- для позиций без маркера (Windows 10 Pro и т.п.) запрашивает количество:
вводишь 5 → «Windows 10 Pro 5 шт.»
- для позиций с «(уточнить …)» вычищает маркер из названия и дописывает модель + количество
- формат: «Позиция Модель N шт.» (без запятой)