- Создал(а) Миронов Юрий Владимирович, редактировал(а) Бурахин Сергей Александрович июл 30, 2025

## Состав релиза

- Релизные скрипты:
- Элементы дистрибутива:
- Docker-образы:
- Конфигурационные изменения:
- Helm чарты:

## Зависимые релизы

## Укажите зависимые релизы, если такие имеются

## Порядок установки релиза

| Последовательность установки
--- | ---
| Последовательность установки
1 | Скрипты БД
2 | Топики кафка
3 | Компоненты
4 | Балансировщики

## Список изменений

- Изменения, специфичные для этого релиза. Например, изменения конфигурационных файлов, обновления версий ПО, изменения в самой инфраструктуре и т.д. Заполняется командами разработки до фиксации плана релиза
- Для изменений конфигурации следует указывать конфигурационные элементы - см. configuration в distr.xml или configuration/ervu

Включено в план установки (заполняется релиз- инженером) | Тикет разработки | Тикет на подготовку инфраструктуры в продуктиве (с подтверждением по срокам), подтверждение
о согласовании с эксплуатацией.

Изменение (название раздела плана установки)

Ответственный

Проверено
в UAT (да, DESCOPED) ФИО

Комментарий

Включено в план установки (заполняется релиз- инженером) | Тикет разработки | Тикет на подготовку инфраструктуры в продуктиве (с подтверждением по срокам), подтверждение
о согласовании с эксплуатацией.

Изменение (название раздела плана установки)

Ответственный

Проверено
в UAT (да, DESCOPED) ФИО

Комментарий

## 1. Сборка и запуск ervu-journal-service

1. Для подключения сервиса к slave (readonly) ноде установить значения переменных PG_USER_RO, PG_PASSWORD_RO, PG_HOST_RO, PG_PORT_RO, PG_DATABASE_RO

2. Выполнить скрипты на добавление колонки и индекса

   ?

   `ALTER TABLE object_versions` `ADD COLUMN IF NOT EXISTS source_last_update INTEGER;` `CREATE INDEX` `if` `not exists object_versions_recruit_update_idx` `` `ON object_versions (id)` `` `INCLUDE (recruitment_id)`
   `` `WHERE object_type =` `'Recruit'` `AND source_last_update =` `1``;`
   `CREATE INDEX` `if` `not exists object_history_version_update_idx`
   `` `ON object_history (version_id)`
   `` `WHERE operation_type =` `'UPDATE'``;`

   ?

   `SET timezone =` `'UTC'``;` `ALTER TABLE auth_journal` `` `ALTER time_created TYPE timestamptz;` `ALTER TABLE import_events_journal` `` `ALTER event_time TYPE timestamptz;`
   `ALTER TABLE import_journal_finish`
   `` `ALTER start_time TYPE timestamptz;`
   `ALTER TABLE import_journal_finish`
   `` `ALTER finish_time TYPE timestamptz;`
   `ALTER TABLE import_journal_start`
   `` `ALTER start_time TYPE timestamptz;`
   `ALTER TABLE import_journal_start`
   `` `ALTER finish_time TYPE timestamptz;`
   `ALTER TABLE import_results`
   `` `ALTER created_date TYPE timestamptz;`
   `ALTER TABLE journal`
   `` `ALTER time_created TYPE timestamptz;`
   `ALTER TABLE object_history`
   `` `ALTER time_created TYPE timestamptz;`
   `ALTER TABLE object_versions`
   `` `ALTER time_created TYPE timestamptz;`
   `ALTER TABLE uploaded_files`
   `` `ALTER start_time TYPE timestamptz;`
   `ALTER TABLE uploaded_files`
   `` `ALTER finish_time TYPE timestamptz;`
   `ALTER TABLE ui_action_journal`
   `` `ALTER event_time TYPE timestamptz;`

3. Собрать и запустить сервис стандартным образом через helm, убрав риднеспробы

4. После установки сервиса необходимо

5. Выполнить скрипт на обновление историчных записей - в скрипте несколько операций, необходимо выполнить каждую в указанном порядке. После каждого шага прошу сохранять тайминг выполнения а так же скрин результата выполнения шага. Отправлять в чат сопровождения Express или напрямую в личку Воронин Андрей Сергеевич
   Внимание! на тестовом стенде скрипт выполнялся 1 минуту при 353000 записях. На продуктиве расчётное время выполнения > 4 часов. Не ожидать завершения выполнения, после запуска скрипта перейти на следующий шаг.

   ?

   `-- После установки новой версии ervu-journal` `-- Убрать констрейн с историй (потом вернём)` `ALTER TABLE object_history DROP CONSTRAINT object_history_version_id_fkey;` `-- Создать новую таблицу` `CREATE TABLE object_versions_new (LIKE object_versions INCLUDING ALL);`
   `-- Наполнить новую таблицу`
   `INSERT INTO object_versions_new (id, object_id, version, time_created, object, object_type, user_id, main_vk_id, event_trace_id, recruitment_id, previous_version_id, next_version_id, source_last_update)`
   `SELECT id, object_id, version, time_created, object, object_type, user_id, main_vk_id, event_trace_id, recruitment_id, previous_version_id, next_version_id,`
   `` `(convert_from(object,` `'UTF8'``)::json->>``'sourceLastUpdate'``)::``int`
   `FROM object_versions ORDER BY time_created desc;`
   `-- Проверить новую таблицу`
   `-- Переименовать таблицы`
   `ALTER TABLE object_versions RENAME TO object_versions_old;`
   `ALTER TABLE object_versions_new RENAME TO object_versions;`
   `-- Добавить констрейнты`
   `ALTER TABLE object_versions ADD CONSTRAINT object_versions_previous_version_id_fkey FOREIGN KEY (previous_version_id) REFERENCES object_versions(id);`
   `ALTER TABLE object_versions ADD CONSTRAINT object_versions_next_version_id_fkey FOREIGN KEY (next_version_id) REFERENCES object_versions(id);`
   `-- Вернуть констрейнты`
   `ALTER TABLE object_history ADD CONSTRAINT object_history_version_id_fkey FOREIGN KEY (version_id) REFERENCES object_versions(id);`
   `-- Проверить, что существует индекс object_versions_recruit_update_idx на object_versions, если его нет, создать`
   `CREATE INDEX` `if` `not exists object_versions_recruit_update_idx`
   `` `ON object_versions (id)`
   `` `INCLUDE (recruitment_id)`
   `` `WHERE object_type =` `'Recruit'` `AND source_last_update =` `1``;`
   `-- Перепроверить, удалить старую таблицу`
   `DROP TABLE object_versions_old;`
   `-- Анализ`
   `ANALYZE object_versions;`

## 2. Выполнение скриптов создания materialized view

Выполнение следующих пунктов создания view можно выполнять параллельно

1. Выполнить запрос создания materialize view бд ervu_person_registry

   ?

   `CREATE MATERIALIZED VIEW IF NOT EXISTS ervu_person_registry_count AS` `WITH` `` `REG_OVER_18 as (SELECT coalesce(current_recruitment_id, target_recruitment_id) recruitment, count(*) reg_over_18_count from recruits` `` `where vu_current_info ->>` `'recruitmentConversion'` `=` `'false'` `and recruits.system_pgs_status notnull and`
   `` `(target_recruitment_id notnull and current_recruitment_id is` `null``) and`
   `` `(birth_date <= make_date ( date_part(``'year'``, NOW())::``int` `-` `18``,` `12``,` `31``))`
   `` `group by recruitment),`
   `` `MILITARY_REGISTRATION as (select rpf.requested_recruitment_id recruitment, count(*) military_registration_count from recruit_private_file rpf where rpf.recruit_private_file_status_id =` `'e9e58951-4efa-4952-b7ae-6977ee751b25'`
   `` `and rpf.requested_recruitment_id =` `'9703f108-761a-467a-aad3-89617e5539ed'`
   `` `AND NOT EXISTS( select *`
   `` `from system_document_dto sd`
   `` `where sd.recruit_id = rpf.recruit_id AND sd.status =` `'formed'` `AND sd.type =` `'7'`
   `` `)`
   `` `AND NOT EXISTS( SELECT *`
   `` `from decision dec`
   `` `where dec.recruit_id = rpf.recruit_id AND dec.status ->>` `'code'` `=` `'1'` `AND dec.type ->>` `'code'` `=` `'7'``)`
   `` `group by rpf.requested_recruitment_id),`
   `` `REMOVED as (SELECT current_recruitment_id recruitment, count(*) removed_count from recruits`
   `` `where vu_current_info ->>` `'removeRegInProgress'` `=` `'true'` `and current_recruitment_id notnull`
   `` `group by current_recruitment_id ),`
   `` `PERSONAL_FILE as (select rpf.sending_recruitment_id recruitment, count(*) person_file_count from recruit_private_file rpf`
   `` `inner join` `public``.recruit_private_file_status pfst on pfst.id = rpf.recruit_private_file_status_id`
   `` `inner join recruits r on r.id = rpf.recruit_id`
   `` `inner join recruits_info ri on r.id = ri.recruit_id`
   `` `left join documents doc`
   `` `ON r.id = doc.recruit_id`
   `` `inner join recruitment rec_sending_pf on rec_sending_pf.id = rpf.sending_recruitment_id`
   `` `inner join recruitment rec_requested_pf on rec_requested_pf.id = rpf.requested_recruitment_id`
   `` `where rpf.recruit_private_file_status_id not in (``'aa94451f-5611-4a9e-bbe3-425a41110baa'``)`
   `` `group by rpf.sending_recruitment_id),`
   `` `BATCH_SIGNING as (with find_decision as (`
   `` `select d.recruit_id as find_recruit_id,`
   `` `d.recruitment_id as recruitment_id`
   `` `from decision d`
   `` `where not exists (`
   `` `select` `1` `from subpoena_dto sabp`
   `` `where sabp.recruit_id = d.recruit_id and (sabp.status ->>` `'code'` `=``'3.7'` `or sabp.status ->>` `'code'` `=` `'3.13'``)`
   `` `)`
   `` `and d.status ->>` `'code'` `=` `'1'`
   `` `union all`
   `` `select sd.recruit_id as find_recruit_id,`
   `` `sd.recruitment_id as recruitment_id`
   `` `from system_document_dto sd left join subpoena_dto sabp on sabp.recruit_id = sd.recruit_id and (sabp.status ->>` `'code'` `=``'3.7'` `or sabp.status ->>` `'code'` `=` `'3.13'``)`
   `` `where not exists (`
   `` `select` `1` `from subpoena_dto sabp`
   `` `where sabp.recruit_id = sd.recruit_id and (sabp.status ->>` `'code'` `=``'3.7'` `or sabp.status ->>` `'code'` `=` `'3.13'``)`
   `` `) and sd.status =` `'formed'``)`
   `` `SELECT`
   `` `fd.recruitment_id recruitment,`
   `` `count(distinct rec.id) batch_signing_count`
   `` `from recruits rec`
   `` `inner join find_decision fd on fd.find_recruit_id = rec.id`
   `` `group by fd.recruitment_id),`
   `` `CONVERSION_LOG as (SELECT target_recruitment_id recruitment, count(*) conversion_log_count from recruits`
   `` `where system_pgs_status in (``'12'``,` `'12.13'``,` `'12.14'``,` `'12.15'``,` `'12.17'``) group by target_recruitment_id ),`
   `` `CONVERSION_MANUAL as (SELECT coalesce(target_recruitment_id, current_recruitment_id) recruitment, count(*) conversion_manual_count`
   `` `from recruits where system_pgs_status in (``'12.2'``,` `'12.5'``,` `'12.7'``,` `'12.8'``)`
   `` `group by target_recruitment_id, current_recruitment_id),`
   `` `CONVERSION_ERROR as (select rec.id recruitment, count(*) convertion_error_count from recruit_association ass`
   `` `inner join recruit_association_status stat on stat.id = ass.recruit_association_status_id`
   `` `left join recruitment rec on ass.vk_code = rec.code`
   `` `where stat.code !=` `'processed'` `group by rec.id),`
   `` `CONSCRIPTION as (SELECT current_recruitment_id recruitment, count(*) conscription_count from recruits`
   `` `where conscription is` `true` `and system_pgs_status not in (``'1.2'``,` `'1.3'``)`
   `` `group by current_recruitment_id ),`
   `` `INITIAL_MIL_REG_17 as (SELECT target_recruitment_id recruitment, count(*) initial_mil_reg_17_count from recruits`
   `` `where ( birth_date > make_date ( date_part(``'year'``, NOW())::``int` `-` `18``,` `12``,` `31``))`
   `` `and system_pgs_status in (``'1'``,` `'8.3'``) group by target_recruitment_id ),`
   `` `RECRUITS_FOR_LIST as (SELECT coalesce(current_recruitment_id, target_recruitment_id) recruitment, count(*) recruits_for_list_count from recruits`
   `` `WHERE system_id_ern IS NOT NULL`
   `` `and (birth_date <= make_date ( date_part(``'year'``, NOW())::``int` `-` `18``,` `12``,` `31``))`
   `` `and system_pgs_status = any (``'{1, 1.2, 15}'``)`
   `` `group by recruitment),`
   `` `DEFERMENT as (SELECT coalesce(current_recruitment_id, target_recruitment_id) recruitment, count(*) deferment_count`
   `` `from recruits r`
   `` `inner join decision_deferment_dto dec on dec.recruit_id = r.id and dec.hidden =` `false`
   `` `where system_pgs_status NOT IN (``'1.3'``,` `'1.4'``) group by recruitment ),`
   `` `DEFERMENT_EXPECTED as (SELECT coalesce(current_recruitment_id, target_recruitment_id) recruitment,`
   `` `count(*) deferment_expected_count`
   `` `from recruits r`
   `` `inner join recruits_deferment rd on rd.recruit_id = r.id and rd.hidden =` `false`
   `` `where system_pgs_status NOT IN (``'1.3'``,` `'1.4'``)`
   `` `group by recruitment)`
   `select coalesce(ro18.recruitment, milr.recruitment, rem.recruitment, pf.recruitment, bs.recruitment) recruitment,`
   `` `coalesce(ro18.reg_over_18_count,` `0``) reg_over_18_count,`
   `` `coalesce(milr.military_registration_count,` `0``) military_registration_count,`
   `` `coalesce(rem.removed_count,` `0``) removed_count,`
   `` `coalesce(pf.person_file_count,` `0``) person_file_count,`
   `` `coalesce(bs.batch_signing_count,` `0``) batch_signing_count,`
   `` `coalesce(cl.conversion_log_count,` `0``) conversion_log_count,`
   `` `coalesce(cm.conversion_manual_count,` `0``) conversion_manual_count,`
   `` `coalesce(ce.convertion_error_count,` `0``) convertion_error_count,`
   `` `coalesce(co.conscription_count,` `0``) conscription_count,`
   `` `coalesce(mr.initial_mil_reg_17_count,` `0``) initial_mil_reg_17_count,`
   `` `coalesce(rfl.recruits_for_list_count,` `0``) recruits_for_list_count,`
   `` `coalesce(def.deferment_count,` `0``) deferment_count,`
   `` `coalesce(de.deferment_expected_count,` `0``) deferment_expected_count`
   `from REG_OVER_18 ro18`
   `` `full join MILITARY_REGISTRATION milr on ro18.recruitment = milr.recruitment`
   `` `full join REMOVED rem on ro18.recruitment = rem.recruitment`
   `` `full join PERSONAL_FILE pf on ro18.recruitment = pf.recruitment`
   `` `full join BATCH_SIGNING bs on ro18.recruitment = bs.recruitment`
   `` `full join CONVERSION_LOG cl on ro18.recruitment = cl.recruitment`
   `` `full join CONVERSION_MANUAL cm on ro18.recruitment = cm.recruitment`
   `` `full join CONVERSION_ERROR ce on ro18.recruitment = ce.recruitment`
   `` `full join CONSCRIPTION co on ro18.recruitment = co.recruitment`
   `` `full join INITIAL_MIL_REG_17 mr on ro18.recruitment = mr.recruitment`
   `` `full join RECRUITS_FOR_LIST rfl on ro18.recruitment = rfl.recruitment`
   `` `full join DEFERMENT def on ro18.recruitment = def.recruitment`
   `` `full join DEFERMENT_EXPECTED de on ro18.recruitment = de.recruitment;`
   `COMMENT ON COLUMN ervu_person_registry_count.reg_over_18_count IS` `'Количество граждан для раздела первоначальная постановка старше 18'``;`
   `COMMENT ON COLUMN ervu_person_registry_count.military_registration_count IS` `'Количество граждан для раздела состоящие на учете'``;`
   `COMMENT ON COLUMN ervu_person_registry_count.removed_count IS` `'Количество граждан для раздела снятых с учета'``;`
   `COMMENT ON COLUMN ervu_person_registry_count.person_file_count IS` `'Количество граждан для раздела запросы личных дел'``;`
   `COMMENT ON COLUMN ervu_person_registry_count.batch_signing_count IS` `'Количество граждан для раздела запросы пакетное подписание решения'``;`
   `COMMENT ON COLUMN ervu_person_registry_count.conversion_log_count IS` `'Количество граждан для раздела задания на конвертацию'``;`
   `COMMENT ON COLUMN ervu_person_registry_count.conversion_manual_count IS` `'Количество граждан для раздела ручная конвертация'``;`
   `COMMENT ON COLUMN ervu_person_registry_count.convertion_error_count IS` `'Количество граждан для раздела ошибки конвертации'``;`
   `COMMENT ON COLUMN ervu_person_registry_count.conscription_count IS` `'Количество граждан для раздела граждане подлежащие вызову'``;`
   `COMMENT ON COLUMN ervu_person_registry_count.initial_mil_reg_17_count IS` `'Количество граждан для раздела первоначальная 17 лет'``;`
   `COMMENT ON COLUMN ervu_person_registry_count.recruits_for_list_count IS` `'Количество граждан для раздела списки на вызов'``;`
   `COMMENT ON COLUMN ervu_person_registry_count.deferment_count IS` `'Количество граждан для раздела отсрочка / освобождение'``;`
   `COMMENT ON COLUMN ervu_person_registry_count.deferment_expected_count IS` `'Количество граждан для раздела имеющие право на отсрочку'``;`

2. Выполнить запрос создания materialize view бд ervu_subpoena_registry

   ?

   `CREATE MATERIALIZED VIEW IF NOT EXISTS v_subpoena_count AS` `with subpoenas as (SELECT s.department_id, count(*) count_subpoena` `` `from subpoena s` `` `left join recruit_block_list rbl ON rbl.recruit_id = s.recruit_id` `` `WHERE rbl.id is` `null`
   `` `group by s.department_id),`
   `` `batch_signing as (SELECT s.department_id, count(*) count_batch_signing`
   `` `from subpoena s`
   `` `left join recruit_block_list rbl ON rbl.recruit_id = s.recruit_id`
   `` `join subpoena_status ss on s.status_id = ss.id`
   `` `WHERE rbl.id is` `null`
   `` `AND ss.code in (``'3.7'``,` `'3.13'``)`
   `` `AND summon_list_id is` `null`
   `` `AND extra_info ->>` `'signBlocked'` `!=` `'true'`
   `` `group by s.department_id)`
   `select coalesce(sb.department_id, bs.department_id) as department_id, coalesce(count_subpoena,` `0``) count_subpoena, coalesce(count_batch_signing,` `0``) count_batch_signing`
   `from subpoenas sb`
   `` `full join batch_signing bs on sb.department_id = bs.department_id;`
   `COMMENT ON COLUMN v_subpoena_count.count_subpoena IS` `'Количество повесток'``;`
   `COMMENT ON COLUMN v_subpoena_count.count_batch_signing IS` `'Количество повесток для пакетного подписания'``;`

3. Выполнить запрос создания materialize view бд ervu_summon_list_registry

   ?

   `CREATE MATERIALIZED VIEW IF NOT EXISTS v_summon_list_count AS` `with list as (SELECT department_id, summon_objective =` `'301'` `as mobilization_flag, count(*) count_list` `` `from summon_list sl` `` `group by department_id, mobilization_flag)` `select department_id, mobilization_flag, coalesce(count_list,` `0``) count_list`
   `from list;`
   `COMMENT ON COLUMN v_summon_list_count.count_list IS` `'Количество списков на вызов'``;`

4. Выполнить запрос создания materialize view бд ervu_incidents

   ?

   `CREATE MATERIALIZED VIEW IF NOT EXISTS incident_count AS` `with archive_incidents as (SELECT coalesce(current_recruitment_id, target_recruitment_id) recruitment, count(*) count_archive` `` `from incident` `` `left join recruit_block_list rbl ON rbl.recruit_id = incident.recruit_id`
   `` `left join incidents_error_code iec on incident.error_code_id = iec.id`
   `` `left join recruits r on incident.recruit_id = r.id`
   `` `WHERE rbl.id is` `null`
   `` `AND status in (``'5'``,` `'6'``,` `'7'``,` `'1000'``)`
   `` `AND iec.type !=` `'1'`
   `` `AND iec.type !=` `'2'`
   `` `group by recruitment),`
   `` `active_incidents as (SELECT coalesce(current_recruitment_id, target_recruitment_id) recruitment, count(*) count_active`
   `` `from incident`
   `` `left join recruit_block_list rbl ON rbl.recruit_id = incident.recruit_id`
   `` `left join incidents_error_code iec on incident.error_code_id = iec.id`
   `` `left join recruits r on incident.recruit_id = r.id`
   `` `WHERE rbl.id is` `null`
   `` `AND status not in (``'5'``,` `'6'``,` `'7'``,` `'1000'``)`
   `` `AND iec.type !=` `'1'`
   `` `AND iec.type !=` `'2'`
   `` `group by recruitment)`
   `select coalesce(aci.recruitment, ari.recruitment) recruitment, coalesce(count_active,` `0``) count_active, coalesce(count_archive,` `0``) count_archive`
   `from active_incidents aci`
   `` `full join archive_incidents ari on aci.recruitment = ari.recruitment;`
   `COMMENT ON COLUMN incident_count.count_active IS` `'Количество инцидентов в статусе "активный"'``;`
   `COMMENT ON COLUMN incident_count.count_archive IS` `'Количество инцидентов в статусе "архивный"'``;`

5. Перед запуском на бд ervu_geps_notifications применить скрипт для view
   ?

   `CREATE MATERIALIZED VIEW IF NOT EXISTS geps_notifications_count AS` `SELECT` `` `vk_id recruitment,` `` `coalesce(count(*),` `0``) geps_count` `FROM notifications`
   `where not exists (select` `1` `from recruit_block_list rbl where rbl.recruit_id = notifications.recruit_id)`
   `group by recruitment;`
   `COMMENT ON COLUMN geps_notifications_count.geps_count IS` `'Количество уведомлений'``;`

## 3.Сборка и запуск ervu-person-registry

1. Перед запуском на бд ervu_person_registry применить скрипт для создания индекса

   ?

   `CREATE EXTENSION IF NOT EXISTS pg_trgm;` `CREATE INDEX` `if` `not exists recruits_addresses_reg_upper_gist_idx ON recruits` `` `USING gin ((addresses ->` `0` `->>` `'reg'``) gin_trgm_ops);` `--``1``)` `CREATE INDEX IF NOT EXISTS recruits_vu_current_info_waservumilitaryregistered_idx`
   `` `ON recruits((vu_current_info ->>` `'wasErvuMilitaryRegistered'``))`
   `` `WITH (deduplicate_items=True);`
   `analyze recruits;`
   `--``2``)`
   `CREATE INDEX IF NOT EXISTS recruits_system_doc_id_date_idx`
   `` `ON recruits(system_doc_id_date)`
   `` `WITH (deduplicate_items=True);`
   `--``3``)`
   `CREATE INDEX IF NOT EXISTS recruits_vu_unset_date_idx`
   `` `ON recruits(vu_unset_date)`
   `` `WITH (deduplicate_items=True);`
   `-``4``)`
   `alter table` `if` `exists recruits`
   `` `add column IF NOT EXISTS reject_recruitment_id uuid;`
   `alter table` `if` `exists recruits`
   `` `add foreign key (reject_recruitment_id) references recruitment (id)`
   `` `on update cascade;`
   `ALTER TABLE` `if` `exists recruits`
   `` `ADD COLUMN` `if` `not exists reject_name_vk varchar;`
   `COMMENT on column recruits.reject_recruitment_id is` `'ИД отклонившего ВК'``;`
   `COMMENT on column recruits.reject_name_vk is` `'Наименование отклонившего ВК'``;`
   `CREATE INDEX IF NOT EXISTS recruit_reject_name_vk_upper_idx ON recruits using btree(UPPER(reject_name_vk) varchar_pattern_ops)`
   `` `WITH (deduplicate_items=True);`
   `CREATE INDEX IF NOT EXISTS recruit_reject_recruitment_id_idx ON recruits using btree(reject_recruitment_id)`
   `` `WITH (deduplicate_items=True);`
   `CREATE INDEX IF NOT EXISTS recruit_reject_name_vk_upper_idx ON recruits (UPPER(reject_name_vk) varchar_pattern_ops);`
   `CREATE INDEX IF NOT EXISTS recruits_convertation_reserved_date_time_idx`
   `` `ON recruits(convertation_reserved_date_time)`
   `` `WITH (deduplicate_items=True);`
   `create index` `if` `not exists recruit_xml_export_list_s3url_upper_idx on recruit_xml_export_list`
   `` `using btree(upper(s3url) varchar_pattern_ops)`
   `` `WITH (deduplicate_items=True);`
   `CREATE INDEX` `if` `not exists recruit_xml_export_list_s3Url_gin_idx ON recruit_xml_export_list`
   `` `USING gin (upper(s3url) gin_trgm_ops);`
   `` `analyze recruits;`
   `analyze recruit_xml_export_list;`

2. Выполнить скрипт на бд ervu_person_registry исправляющий записи в истории, для которых некорректно указан источник изменений

   ?

   `-- Все записи с event =` `'При конвертации поступили сведения о смене ВК'` `WITH conversion_events AS (` `` `select recruit_id, date_time AS conv_date_time` `` `FROM recruits_history` `` `WHERE event in (``'При конвертации поступили сведения о смене ВК'``,` `'Запись обновлена сведениями ГИР'``)`
   `),`
   `-- Все записи с status =` `'1.1'` `AND source =` `'2'`
   `source_status_events AS (`
   `` `SELECT *`
   `` `FROM recruits_history`
   `` `WHERE status =` `'1.1'` `AND source =` `'2'`
   `),`
   `-- Некорректные записи`
   `incorrect_events AS (`
   `` `SELECT sse.*`
   `` `FROM source_status_events sse`
   `` `JOIN conversion_events ce ON ce.recruit_id = sse.recruit_id AND ce.conv_date_time < sse.date_time -- проверяем для одного recruit_id, что запись с event наступила раньше чем запись со status =` `'1.1'` `и source =` `'2'`
   `` `WHERE NOT EXISTS ( -- проверяем, что нет других записей с между двумя нашими, у которых статус` `1.1` `и source =` `2`
   `` `SELECT` `1`
   `` `FROM recruits_history rh`
   `` `where rh.recruit_id = sse.recruit_id`
   `` `AND rh.date_time > ce.conv_date_time`
   `` `AND rh.date_time < sse.date_time`
   `` `AND rh.status =` `'1.1'` `AND rh.source =` `'2'`
   `` `)`
   `)`
   `update recruits_history set source =` `'1'` `where id in (select id from incorrect_events);`

3. Прошу выполнить скрипт на бд ervu_person_registry для проставления rejectRecruitmentId рекрутам отклоненным ВК по задаче _Конвертация_Массовый возврат записей в ВК. Не дожидаясь отработки скрипта, перейти к следующему шагу.

   ?

   `WITH find_recruits AS (` `` `SELECT id AS rec_id` `` `FROM recruits` `` `WHERE recruits.reject_recruitment_id IS NULL` `` `AND recruits.system_pgs_status =` `'12.2'`
   `),`
   `` `latest_history AS (`
   `` `SELECT`
   `` `h.recruit_id AS history_recruit_id,`
   `` `h.target_recruitment_id,`
   `` `ROW_NUMBER() OVER (`
   `` `PARTITION BY h.recruit_id`
   `` `ORDER BY h.date_time DESC`
   `` `) AS date_rank`
   `` `FROM recruits_history h`
   `` `WHERE`
   `` `h.recruit_id IN (SELECT rec_id FROM find_recruits)`
   `` `AND h.status =` `'12.2'`
   `` `AND h.event =` `'Отклонено включение сведений в реестр'`
   `` `)`
   `UPDATE recruits`
   `SET`
   `` `reject_recruitment_id = lh.target_recruitment_id,`
   `` `reject_name_vk = rec.name`
   `FROM (`
   `` `SELECT`
   `` `lh.history_recruit_id,`
   `` `lh.target_recruitment_id`
   `` `FROM latest_history lh`
   `` `WHERE lh.date_rank =` `1`
   `` `) lh`
   `` `LEFT JOIN recruitment rec ON rec.id = lh.target_recruitment_id`
   `WHERE`
   `` `recruits.id = lh.history_recruit_id`
   `` `AND recruits.reject_recruitment_id IS NULL;`

## 4.Сборка и запуск ervu-extract-from-registry-provider

1. Собрать и запустить сервис стандартным образом через helm

## 5.Сборка и запуск stat-report-scheduler

1. Собрать и запустить сервис стандартным образом через helm
2. Скопировать данные из бд ervu_person_registry таблицы report в таблицу report базы stat_report_scheduler
3. Выполнить скрипт на базе stat_report_scheduler

?

`update report set status =` `'FAILED'` `where status not in (``'FINISHED'``,` `'FAILED'``,` `'FINISHED_WITHOUT_DATA'``) and EXTRACT(MINUTE FROM (now() - created_at)) >` `5``;` `update report set finished_at = now() where finished_at is` `null``;` `ALTER TABLE report ALTER COLUMN status SET DEFAULT` `'NEW'``;`

## 6.Установка сервисов Микорд

Перед началом установки выполнить скрипт в БД endpoints_access_info

?

`INSERT INTO access_info (id, app_name, pkg, method, ingress_path, path, rules, manual, modified_by)` `VALUES (uuid_generate_v4(),` `'ervu-account-applications-backend'``,` `'Manual'``,` `'Get'``,` `'/service/account-applications'``,` `'/**'``,` `'{"perms": ["responsible_for_information_security","responsible_for_internal_control","security_administrator"]}'``,` `true``,` `'Manual'``);`
`INSERT INTO access_info (id, app_name, pkg, method, ingress_path, path, rules, manual, modified_by)`
`VALUES (uuid_generate_v4(),` `'ervu-account-applications-backend'``,` `'Manual'``,` `'Post'``,` `'/service/account-applications'``,` `'/**'``,` `'{"perms": ["responsible_for_information_security","responsible_for_internal_control","security_administrator"]}'``,` `true``,` `'Manual'``);`
`INSERT INTO access_info (id, app_name, pkg, method, ingress_path, path, rules, manual, modified_by)`
`VALUES (uuid_generate_v4(),` `'ervu-account-applications-backend'``,` `'Manual'``,` `'Put'``,` `'/service/account-applications'``,` `'/**'``,` `'{"perms": ["responsible_for_information_security","responsible_for_internal_control","security_administrator"]}'``,` `true``,` `'Manual'``);`
`INSERT INTO access_info (id, app_name, pkg, method, ingress_path, path, rules, manual, modified_by)`
`VALUES (uuid_generate_v4(),` `'ervu-account-applications-backend'``,` `'Manual'``,` `'Delete'``,` `'/service/account-applications'``,` `'/**'``,` `'{"perms": ["responsible_for_information_security","responsible_for_internal_control","security_administrator"]}'``,` `true``,` `'Manual'``);`
`INSERT INTO access_info (id, app_name, pkg, method, ingress_path, path, rules, manual, modified_by)`
`VALUES (uuid_generate_v4(),` `'ervu-account-applications-backend'``,` `'Manual'``,` `'Patch'``,` `'/service/account-applications'``,` `'/**'``,` `'{"perms": ["responsible_for_information_security","responsible_for_internal_control","security_administrator"]}'``,` `true``,` `'Manual'``);`
`INSERT INTO access_info (id, app_name, pkg, method, ingress_path, path, rules, manual, modified_by)`
`VALUES (uuid_generate_v4(),` `'ervu-dashboard-backend'``,` `'Manual'``,` `'Get'``,` `'/service/dashboard'``,` `'/**'``,` `'{"perms": ["gomu_specialist","gomu_observer","military_district_observer","military_commissar","military_commissariat_observer"]}'``,` `true``,` `'Manual'``);`
`INSERT INTO access_info (id, app_name, pkg, method, ingress_path, path, rules, manual, modified_by)`
`VALUES (uuid_generate_v4(),` `'ervu-dashboard-backend'``,` `'Manual'``,` `'Post'``,` `'/service/dashboard'``,` `'/**'``,` `'{"perms": ["gomu_specialist","gomu_observer","military_district_observer","military_commissar","military_commissariat_observer"]}'``,` `true``,` `'Manual'``);`
`INSERT INTO access_info (id, app_name, pkg, method, ingress_path, path, rules, manual, modified_by)`
`VALUES (uuid_generate_v4(),` `'ervu-dashboard-backend'``,` `'Manual'``,` `'Put'``,` `'/service/dashboard'``,` `'/**'``,` `'{"perms": ["gomu_specialist","gomu_observer","military_district_observer","military_commissar","military_commissariat_observer"]}'``,` `true``,` `'Manual'``);`
`INSERT INTO access_info (id, app_name, pkg, method, ingress_path, path, rules, manual, modified_by)`
`VALUES (uuid_generate_v4(),` `'ervu-dashboard-backend'``,` `'Manual'``,` `'Delete'``,` `'/service/dashboard'``,` `'/**'``,` `'{"perms": ["gomu_specialist","gomu_observer","military_district_observer","military_commissar","military_commissariat_observer"]}'``,` `true``,` `'Manual'``);`
`INSERT INTO access_info (id, app_name, pkg, method, ingress_path, path, rules, manual, modified_by)`
`VALUES (uuid_generate_v4(),` `'ervu-dashboard-backend'``,` `'Manual'``,` `'Patch'``,` `'/service/dashboard'``,` `'/**'``,` `'{"perms": ["gomu_specialist","gomu_observer","military_district_observer","military_commissar","military_commissariat_observer"]}'``,` `true``,` `'Manual'``);`
`INSERT INTO access_info (id, app_name, pkg, method, ingress_path, path, rules, manual, modified_by)`
`VALUES (uuid_generate_v4(),` `'ervu-business-metrics-backend'``,` `'Manual'``,` `'Get'``,` `'/service/business-metrics'``,` `'/**'``,` `'{"perms": ["gomu_specialist","gomu_observer","military_district_observer","military_commissar","military_commissariat_observer"]}'``,` `true``,` `'Manual'``);`
`INSERT INTO access_info (id, app_name, pkg, method, ingress_path, path, rules, manual, modified_by)`
`VALUES (uuid_generate_v4(),` `'ervu-business-metrics-backend'``,` `'Manual'``,` `'Post'``,` `'/service/business-metrics'``,` `'/**'``,` `'{"perms": ["gomu_specialist","gomu_observer","military_district_observer","military_commissar","military_commissariat_observer"]}'``,` `true``,` `'Manual'``);`
`INSERT INTO access_info (id, app_name, pkg, method, ingress_path, path, rules, manual, modified_by)`
`VALUES (uuid_generate_v4(),` `'ervu-business-metrics-backend'``,` `'Manual'``,` `'Put'``,` `'/service/business-metrics'``,` `'/**'``,` `'{"perms": ["gomu_specialist","gomu_observer","military_district_observer","military_commissar","military_commissariat_observer"]}'``,` `true``,` `'Manual'``);`
`INSERT INTO access_info (id, app_name, pkg, method, ingress_path, path, rules, manual, modified_by)`
`VALUES (uuid_generate_v4(),` `'ervu-business-metrics-backend'``,` `'Manual'``,` `'Delete'``,` `'/service/business-metrics'``,` `'/**'``,` `'{"perms": ["gomu_specialist","gomu_observer","military_district_observer","military_commissar","military_commissariat_observer"]}'``,` `true``,` `'Manual'``);`
`INSERT INTO access_info (id, app_name, pkg, method, ingress_path, path, rules, manual, modified_by)`
`VALUES (uuid_generate_v4(),` `'ervu-business-metrics-backend'``,` `'Manual'``,` `'Patch'``,` `'/service/business-metrics'``,` `'/**'``,` `'{"perms": ["gomu_specialist","gomu_observer","military_district_observer","military_commissar","military_commissariat_observer"]}'``,` `true``,` `'Manual'``);`

1. Собрать и запустить стандартным образом через helm

## 7.Сборка и запуск ervu-dashboard-etl

1. Остановить сервис ervu-dashboard-etl

2. Удалить индексы в БД ervu_dashboard:

   ?

   `DROP INDEX IF EXISTS idx_citizen_recruitment_id;` `DROP INDEX IF EXISTS idx_citizen_target_recruitment_id;` `DROP INDEX IF EXISTS idx_citizen_marital_status;` `DROP INDEX IF EXISTS idx_citizen_gender;` `DROP INDEX IF EXISTS citizen_recruit_id_idx;`
   `DROP INDEX IF EXISTS citizen_recruitment_id_idx;`
   `DROP INDEX IF EXISTS citizen_age_residence_full_name_idx;`
   `DROP INDEX IF EXISTS recruitment_idm_id_idx;`
   `DROP INDEX IF EXISTS recruitment_shortname_idx;`
   `DROP INDEX IF EXISTS citizen_complex_filters_recruit_id_idx;`
   `DROP INDEX IF EXISTS citizen_education_diplomas_received_recruit_id_idx;`
   `DROP INDEX IF EXISTS citizen_guardianship_recruit_id_idx;`
   `DROP INDEX IF EXISTS citizen_sports_categories_recruit_id_idx;`
   `DROP INDEX IF EXISTS citizen_spouse_recruit_id_idx;`
   `DROP INDEX IF EXISTS citizen_work_activity_recruit_id_idx;`
   `DROP INDEX IF EXISTS citizenship_recruit_id_idx;`
   `DROP INDEX IF EXISTS citizenship_foreign_recruit_id_idx;`
   `DROP INDEX IF EXISTS deputy_recruit_id_idx;`
   `DROP INDEX IF EXISTS disability_recruit_id_idx;`
   `DROP INDEX IF EXISTS disease_recruit_id_idx;`
   `DROP INDEX IF EXISTS drivers_licence_recruit_id_idx;`
   `DROP INDEX IF EXISTS medical_authorities_recruit_id_idx;`
   `DROP INDEX IF EXISTS passport_recruit_id_idx;`
   `DROP INDEX IF EXISTS property_recruit_id_idx;`
   `DROP INDEX IF EXISTS prosecution_recruit_id_idx;`
   `DROP INDEX IF EXISTS punishment_recruit_id_idx;`
   `DROP INDEX IF EXISTS subpoena_recruit_id_idx;`
   `DROP INDEX IF EXISTS temporary_measures_recruit_id_idx;`
   `DROP INDEX IF EXISTS idx_edu_code_spec_doc_rus_trgm;`
   `DROP INDEX IF EXISTS idx_edu_form_study_trgm;`
   `DROP INDEX IF EXISTS idx_edu_obtaining_vus_trgm;`
   `DROP INDEX IF EXISTS idx_edu_code_profession_trgm;`
   `DROP INDEX IF EXISTS idx_edu_women_obtaining_prof_trgm;`
   `DROP INDEX IF EXISTS idx_edu_info_vus_doc_rus_trgm;`
   `DROP INDEX IF EXISTS idx_edu_code_spec_doc_foreign_trgm;`
   `DROP INDEX IF EXISTS idx_edu_name_spec_doc_foreign_trgm;`
   `DROP INDEX IF EXISTS idx_edu_obtaining_vus_doc_foreign_trgm;`
   `DROP INDEX IF EXISTS idx_edu_inn;`
   `DROP INDEX IF EXISTS idx_edu_ogrn;`
   `DROP INDEX IF EXISTS idx_edu_kpp;`
   `DROP INDEX IF EXISTS idx_edu_order_number;`
   `DROP INDEX IF EXISTS idx_edu_order_number_deduction;`
   `DROP INDEX IF EXISTS idx_edu_order_number_restore;`
   `DROP INDEX IF EXISTS idx_edu_reg_number_doc_rus;`
   `DROP INDEX IF EXISTS idx_edu_series_number_doc_foreign;`
   `DROP INDEX IF EXISTS idx_edu_start_date_edu;`
   `DROP INDEX IF EXISTS idx_edu_receipt_date;`
   `DROP INDEX IF EXISTS idx_edu_planned_graduation_date;`
   `DROP INDEX IF EXISTS idx_edu_order_date;`
   `DROP INDEX IF EXISTS idx_edu_date_deduction;`
   `DROP INDEX IF EXISTS idx_edu_completion_date;`
   `DROP INDEX IF EXISTS idx_edu_restore_date;`
   `DROP INDEX IF EXISTS idx_edu_start_date_training;`
   `DROP INDEX IF EXISTS idx_edu_start_date_academic;`
   `DROP INDEX IF EXISTS idx_edu_end_date_academic;`
   `DROP INDEX IF EXISTS idx_edu_start_date_maternity;`
   `DROP INDEX IF EXISTS idx_edu_end_date_maternity;`
   `DROP INDEX IF EXISTS idx_edu_start_date_military_center;`
   `DROP INDEX IF EXISTS idx_edu_end_date_military_center;`
   `DROP INDEX IF EXISTS idx_edu_start_date_mil_department;`
   `DROP INDEX IF EXISTS idx_edu_end_date_mil_department;`
   `DROP INDEX IF EXISTS idx_edu_date_issue_doc_rus;`
   `DROP INDEX IF EXISTS idx_edu_date_doc_foreign;`
   `DROP INDEX IF EXISTS idx_edu_student_status;`
   `DROP INDEX IF EXISTS idx_edu_education_level_student;`
   `DROP INDEX IF EXISTS idx_edu_receiving_education_first_time;`
   `DROP INDEX IF EXISTS idx_edu_successful_mil_dep;`
   `DROP INDEX IF EXISTS idx_edu_name_edu_organization_trgm;`
   `DROP INDEX IF EXISTS idx_edu_name_education_program_trgm;`
   `DROP INDEX IF EXISTS idx_edu_name_profession_trgm;`
   `DROP INDEX IF EXISTS idx_edu_name_edu_org_doc_rus_trgm;`
   `DROP INDEX IF EXISTS idx_edu_name_spec_doc_rus_trgm;`
   `DROP INDEX IF EXISTS idx_edu_name_edu_org_doc_foreign_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_work_job_title_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_work_org_name_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_work_place_work_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_work_employer_cat_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_work_org_address_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_work_inn;`
   `DROP INDEX IF EXISTS idx_citizen_work_ogrn;`
   `DROP INDEX IF EXISTS idx_citizen_work_kpp;`
   `DROP INDEX IF EXISTS idx_citizen_work_ogrn_ip;`
   `DROP INDEX IF EXISTS idx_citizen_work_date_hr_event;`
   `DROP INDEX IF EXISTS idx_citizen_work_start_parental_leave;`
   `DROP INDEX IF EXISTS idx_citizen_work_end_parental_leave;`
   `DROP INDEX IF EXISTS idx_citizen_work_date_reg_ip;`
   `DROP INDEX IF EXISTS idx_citizen_work_date_dereg_ip;`
   `DROP INDEX IF EXISTS idx_citizen_work_date_term_reg_ip;`
   `DROP INDEX IF EXISTS idx_citizen_work_date_reg_self;`
   `DROP INDEX IF EXISTS idx_citizen_work_date_dereg_self;`
   `DROP INDEX IF EXISTS idx_citizen_work_employer_status;`
   `DROP INDEX IF EXISTS idx_citizen_work_type_separate_division;`
   `DROP INDEX IF EXISTS idx_citizen_work_type_hr_event;`
   `DROP INDEX IF EXISTS idx_citizen_last_name_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_first_name_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_middle_name_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_snils_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_inn_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_id_ern_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_phone_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_email_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_birth_place_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_residence_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_address_place_stay_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_type_place_stay_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_address_actual_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_driver_license_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_right_deferment;`
   `DROP INDEX IF EXISTS idx_citizen_took_break;`
   `DROP INDEX IF EXISTS idx_citizen_medic;`
   `DROP INDEX IF EXISTS idx_citizen_sports_category;`
   `DROP INDEX IF EXISTS idx_citizen_tractor_license;`
   `DROP INDEX IF EXISTS idx_citizen_is_wanted;`
   `DROP INDEX IF EXISTS idx_citizen_is_in_prison;`
   `DROP INDEX IF EXISTS idx_citizen_acquired_citizenship;`
   `DROP INDEX IF EXISTS idx_citizen_urgent_service;`
   `DROP INDEX IF EXISTS idx_citizen_contract_service;`
   `DROP INDEX IF EXISTS idx_citizen_mobilization;`
   `DROP INDEX IF EXISTS idx_citizen_personal_data;`
   `DROP INDEX IF EXISTS idx_citizen_sign_deferred_release;`
   `DROP INDEX IF EXISTS idx_citizen_having_sport_title;`
   `DROP INDEX IF EXISTS idx_citizen_employed;`
   `DROP INDEX IF EXISTS idx_citizen_active_reg_ip;`
   `DROP INDEX IF EXISTS idx_citizen_active_parental_leave;`
   `DROP INDEX IF EXISTS idx_citizen_self_employed;`
   `DROP INDEX IF EXISTS idx_citizen_has_disease;`
   `DROP INDEX IF EXISTS idx_citizen_has_vich;`
   `DROP INDEX IF EXISTS idx_citizen_registered_in_pnd;`
   `DROP INDEX IF EXISTS idx_citizen_has_disability;`
   `DROP INDEX IF EXISTS idx_citizen_is_incompetent;`
   `DROP INDEX IF EXISTS idx_citizen_has_deferment;`
   `DROP INDEX IF EXISTS idx_citizen_has_deferment_right;`
   `DROP INDEX IF EXISTS idx_citizen_has_exemption;`
   `DROP INDEX IF EXISTS idx_citizen_is_guardian;`
   `DROP INDEX IF EXISTS idx_citizen_birth_date;`
   `DROP INDEX IF EXISTS idx_citizen_issue_date;`
   `DROP INDEX IF EXISTS idx_citizen_died_date;`
   `DROP INDEX IF EXISTS idx_citizen_start_date_residence;`
   `DROP INDEX IF EXISTS idx_citizen_end_date_residence;`
   `DROP INDEX IF EXISTS idx_citizen_start_date_place_stay;`
   `DROP INDEX IF EXISTS idx_citizen_end_date_place_stay;`
   `DROP INDEX IF EXISTS idx_citizen_date_info_actual;`
   `DROP INDEX IF EXISTS idx_citizen_date_loss_info_actual;`
   `DROP INDEX IF EXISTS idx_citizen_update_date;`
   `DROP INDEX IF EXISTS idx_citizen_date_registration;`
   `DROP INDEX IF EXISTS idx_citizen_date_deregistration;`
   `DROP INDEX IF EXISTS idx_citizen_start_date_right;`
   `DROP INDEX IF EXISTS idx_citizen_end_date_right;`
   `DROP INDEX IF EXISTS idx_citizen_start_date_decision;`
   `DROP INDEX IF EXISTS idx_citizen_end_date_decision;`
   `DROP INDEX IF EXISTS idx_citizen_age;`
   `DROP INDEX IF EXISTS idx_citizen_number_children;`
   `DROP INDEX IF EXISTS idx_citizen_number_children_18_old;`
   `DROP INDEX IF EXISTS idx_citizen_is_registered;`
   `DROP INDEX IF EXISTS idx_citizen_passport_series;`
   `DROP INDEX IF EXISTS idx_citizen_passport_number;`
   `DROP INDEX IF EXISTS idx_citizen_medical_requirements;`
   `DROP INDEX IF EXISTS idx_citizen_deferment_liberation;`
   `DROP INDEX IF EXISTS idx_citizen_education;`
   `DROP INDEX IF EXISTS idx_citizen_employment;`
   `DROP INDEX IF EXISTS idx_citizen_reason_registration;`
   `DROP INDEX IF EXISTS idx_citizen_disability_group;`
   `DROP INDEX IF EXISTS idx_citizen_dispensary_registration_code;`
   `DROP INDEX IF EXISTS idx_citizen_region_birth;`
   `DROP INDEX IF EXISTS idx_citizen_city_birth;`
   `DROP INDEX IF EXISTS idx_citizen_source_info_actual;`
   `DROP INDEX IF EXISTS idx_citizen_country_birth;`
   `DROP INDEX IF EXISTS idx_citizen_fact_issuance_military_registration;`
   `DROP INDEX IF EXISTS idx_citizen_grounds_exemption;`
   `DROP INDEX IF EXISTS idx_citizen_decision_number;`
   `DROP INDEX IF EXISTS idx_citizen_defer_conscription;`
   `DROP INDEX IF EXISTS idx_citizen_deferment_decision_type;`
   `DROP INDEX IF EXISTS idx_citizen_system_pgs_status;`
   `DROP INDEX IF EXISTS idx_citizen_full_name_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_spouse_kinship_type_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_spouse_full_name_trgm;`
   `DROP INDEX IF EXISTS idx_citizen_spouse_birth_date;`
   `DROP INDEX IF EXISTS idx_citizen_spouse_death_date;`
   `DROP INDEX IF EXISTS idx_citizen_spouse_marriage_date;`
   `DROP INDEX IF EXISTS idx_citizen_spouse_divorce_date;`
   `DROP INDEX IF EXISTS idx_citizen_spouse_information_excluded;`
   `DROP INDEX IF EXISTS idx_citizen_spouse_death_az_number;`
   `DROP INDEX IF EXISTS idx_citizen_spouse_marriage_az_number;`
   `DROP INDEX IF EXISTS idx_citizen_spouse_divorce_az_number;`

3. Сборка и запуск сервиса ervu-dashboard-etl

   1. Внести правку в values.yaml сервиса ervu-dashboard-etl. Сменить значение переменных JOBS_ON_STARTUP и JOBS_CRON на:

   - name: JOBS_ ON_STARTUP
   value: 'predictive_metrics/predictive.hwf'

   - name: JOBS_CRON
   value: '0,30_*_*_*_*@job_general.hwf 0_0_1_1_*@predictive_metrics/ predictive.hwf 30_20_30_7_3@jobs_once_a_day/job_info_recruits_once.hwf'

   !!!ВАЖНО. ОБРАТИТЕ ВНИМАНИЕ!!!

   В переменной JOBS_CRON прописано крон выражение для одноразового запуска джобы копирования рекрутов:

   (30_20_30_7_3@jobs_once_a_day/job_info_recruits_once.hwf).

   В зависимости от даты и времени деплоя сервиса, данное выражение крона необходимо будет скорректировать.

   Описание:

   30 – во сколько минут (в нашем примере 30 минута) !!!!НЕОБХОДИМО ПОСТАВИТЬ ВРЕМЯ так, чтобы с момента деплоя прошло еще 15 минут. Т.е. если деплоим в нулевую минуту, то здесь прописываем 15.

   20 – во сколько часов (в нашем примере в 20часов, т.е. 8 вечера)

   30 – день месяца (в нашем примере 30го числа)

   7 – седьмого месяца (в нашем примере месяц июль)

   3 – день недели (в нашем примере среда)

   Т.е. в текущем примере джоба стартанет 30 июля в среду в 20:30.

   Корректировку крон выражения делаем только для данной джобы.

4. Передеплоить сервис

## 8. Запуск всех сервисов

## 9.Выполнение реконсиляции военкоматов для ervu_journal
Выполнить строго после установки сервиса ervu-journal-service и ervu-extract-from-registry-provider

1. Выполнить cURL, используя токен пользователя с ролью Администратор ПОИБ

   curl --location --request POST '<<host>>/service/idm/reconcile/domain/to/kafka/v1' \
   --header 'Authorization: Bearer <<токен Администратор ПОИБ>>' \
   --header 'Content-Type: application/json'

## 10.Выполнение реконсиляции рекрутов

1. Реконсилсяция запускается строго после выполнения пунктов

   1. Сборка и запуск ervu-subpoena-registry

   2. Сборка и запуск ervu-summon-list-registry

   3. Сборка и запуск ervu-incidents-service

   4. Сборка и запуск ervu-person-registry

2. Для запуска реконсиляции необходимо выполнить курл (время выполнения 5 минут):
   1. curl --location --request GET '{{ingress}}/service/ervu-person-registry/reconcile' \
      --header 'Content-Type: application/json' \
      --header 'Authorization: {{токен}}'
3. Через 10 минут после запуска курла из п.2 проверить топик ervu.recruit.reconcile, что туда пишутся записи и кол-во записей увеличивается (с паузами, не моментально). Результат в виде скрина скинуть в чат сопровождения
4. Через 30 минут после запуска курла из п.2 проверить в БД ervu_person_registry, в таблице reconcile_status столбец batch_num НЕ РАВЕН нулю и примерно каждые 30 секунд в нём увеличивается цифра. Результат в виде скрина скинуть в чат сопровождения

После установки каждого сервиса писать в чат "ЕРВУ сопровождение" в экспрессе о результате установки и скриншот, какая версия сервиса после установки, а также написать в момент запуска курла реконсиляции из п.2

## 11.Обновление bpmn

1. Скачать содержимое https://git.ervu.rt-sk.ru/ervu/source/ervu-bpmn/-/tree/release/ervu/1.11.3/processes

2. Распаковать скачанный zip-архив

3. Запустить curl для каждого процесса из списка под токеном пользователя у которого есть роль "Администратор ПОИБ", где:

<<host>> - host стенда,

<<токен Администратор ПОИБ>> - токен пользователя у которого есть роль "Администратор ПОИБ"

<<pathToFile>> - путь к файлу bpmn процесса

curl обновления процесса

`curl --location --request POST` `'<<host>>/service/wf/service/schema'` `\` `--header` `'Authorization: Bearer <<токен Администратор ПОИБ>>'` `\` `--form` `'files=@"<<pathToFile>>"'`

Список изменённых процессов:

    [
    "milBaseConvertationSingle",
    "milBaseMassInitCancelRegistration",
    "milBaseMeasuresInflictionCancel",
    "milBaseChangeRecruitmentOffice"
    ]

## 12.Выполнение проверок успешного выполнения скриптов

1.Проверка обновления исторических записей в ervu-journal-service (после полного выполнения п. 1 "Сборка и запуск ervu-journal-service)
После выполнения скрипта в консоли должно отобразиться

    NOTICE: Обновление завершено за (время выполнения)

Через 30 минут после запуска скрипта на обновление исторических записей проверить факт заполнения в таблице выполнив 2 скрипта и сравнив результат между собой, результат в виде скрина скинуть в чат сопровождения с тегом на Воронин Андрей Сергеевич :

?

`SELECT count(*) FROM object_versions WHERE object_type =` `'Recruit'` `` `AND convert_from(``"object"``,` `'UTF8'``)::json ->>` `'sourceLastUpdate'` `=` `'1'``;` `SELECT count(*) FROM object_versions WHERE object_type =` `'Recruit'` `` `AND source_last_update =` `1``;`

2. Проверка обновления исторических записей ervu_person_registry

?

`-- Все записи с event =` `'При конвертации поступили сведения о смене ВК'` `WITH conversion_events AS (` `` `select recruit_id, date_time AS conv_date_time` `` `FROM recruits_history` `` `WHERE event in (``'При конвертации поступили сведения о смене ВК'``,` `'Запись обновлена сведениями ГИР'``)`
`),`
``
`-- Все записи с status =` `'1.1'` `AND source =` `'2'`
`source_status_events AS (`
`` `SELECT *`
`` `FROM recruits_history`
`` `WHERE status =` `'1.1'` `AND source =` `'2'`
`),`
`-- Некорректные записи`
`incorrect_events AS (`
`` `SELECT sse.*`
`` `FROM source_status_events sse`
`` `JOIN conversion_events ce ON ce.recruit_id = sse.recruit_id AND ce.conv_date_time < sse.date_time -- проверяем для одного recruit_id, что запись с event наступила раньше чем запись со status =` `'1.1'` `и source =` `'2'`
`` `WHERE NOT EXISTS ( -- проверяем, что нет других записей с между двумя нашими, у которых статус` `1.1` `и source =` `2`
`` `SELECT` `1`
`` `FROM recruits_history rh`
`` `where rh.recruit_id = sse.recruit_id`
`` `AND rh.date_time > ce.conv_date_time`
`` `AND rh.date_time < sse.date_time`
`` `AND rh.status =` `'1.1'` `AND rh.source =` `'2'`
`` `)`
`)`
`select count(*) from recruits_history where id in (select id from incorrect_events);`

3. Проверка скрипт для проставления rejectRecruitmentId рекрутам отклоненным ВК по задаче _Конвертация_Массовый возврат записей в ВК.

?

`--должен вернуть` `0` `SELECT count(*) from recruits where recruits.reject_recruitment_id is` `null` `and recruits.system_pgs_status =` `'12.2'``;`

4. Проверка обновления записей в БД endpoints_access_info:

Проверка, что джоба запустилась:

- Формируем логи после запуска сервиса ervu-dashboard-etl

- Ищем строку лога содержащую текст: job_info_recruits_once - Start of workflow execution

1. !!! Через 1 час, для проверки наполнения данными, сделать sql запросы в БД:

   1. select count(*) from ervu_dashboard.citizen_guardianship;
   2. select count(*) from ervu_dashboard.citizen_child;
   3. select count(*) from ervu_dashboard.drivers_licence;
   4. select count(*) from ervu_dashboard.passport;
   5. select count(*) from ervu_dashboard.punishment;

5. Проверка реконсиляции военкоматов (после полного выполнения п. 32)

Через 10 минут после запуски курла проверить топик idmv2.domain.reconcilation, убедиться, что записи попали в топик

Через 30 минут после запуска курла проверить, что в БД ervu_journal и в БД ervu_extract_from_registry_provider в таблицах idm_domain заполнена колонка short_name

6. Проверка наличия записей в топике ervu.recruit.reconcile

Через 10 минут после запуска курла из п.2 проверить топик ervu.recruit.reconcile, что туда пишутся записи и кол-во записей увеличивается (с паузами, не моментально). Результат в виде скрина скинуть в чат сопровождения

7. Проверка наличия записей в БД ervu_person_registry

Через 30 минут после запуска курла из п.2 проверить в БД ervu_person_registry, в таблице reconcile_status столбец batch_num НЕ РАВЕН нулю и примерно каждые 30 секунд в нём увеличивается цифра. Результат в виде скрина скинуть в чат сопровождения

## План отката

- Связаться с разработчиками для корректного отката изменений БД
- Откатить обновленные файлы/образы приложений
- Откатить изменения конфигурации

Фильтровать данные таблицы Создать сводную таблицу Создать диаграмму
Configure buttons visibility
Нравится Станьте первыми кому понравится это

- Нет меток
- Редактировать метки

Написать комментарий...

Добавить комментарий

Обзор
Инструменты контента
{"serverDuration": 106, "requestCorrelationId": "172e6423e8f9a212"}
search
recentlyviewed
attachments
weblink
advanced
image-effects
image-attributes

- Абзац

- Жирный
- Курсив
- Подчеркнутый
- Cредство выбора цвета
  Дополнительные цвета
- Форматирование

- Маркированный список
- Нумерованный список

- Список задач

- Убрать отступ
- Сделать отступ

- Выровнить по левому краю
- Выровнить по центру
- Выровнить по правому краю

- Разметка страницы

- Ссылка

- Таблица

- Вставить

- Разметка страницы

- Отменить
- Восстановить

- Найти/Заменить

- Справка по быстрым ссылкам на клавиатуре

Подключение...