Merge main into council specialty selection
CI / test (pull_request) Failing after 4m45s
CI / Fingerprint diagnostics (production deployment temporarily disabled) (pull_request) Has been skipped

This commit is contained in:
codex committed 2026-10-08 12:41:34 +03:00
commit 7eaed9aa8a
3 files changed
+21 -8

No files matched your search

+4
View File
@@ -6,6 +6,10 @@
- Добавлен справочник связей всех 773 журналов К1 со специальностями из Перечня ВАК на 15.09.2026, с ISSN, страницами, строками источника и датами назначений. Исключены истёкшие назначения; одинаковое название «Нефтегазовое дело» для двух ISSN помечено как неоднозначное и не используется в автоматическом подборе.
- Добавлен воспроизводимый скрипт извлечения и проверенные варианты названий. Сервис читает готовый JSON без обработки PDF при запросах.
## 0.14.3
- Из XLSX диссертационного совета удалён столбец «Статус». Колонка «В БД» переименована в «Страница ВШЭ» на листах «Сотрудники» и «Публикации»; расчёт значений сохранён.
## 0.14.2
- Исправлено сопоставление К1 для переименованного журнала: действующее и явно указанное в исходном PDF прежнее название распознаются как один журнал. Административное примечание хранится отдельно от названия; конфликтующие алиасы не присваиваются автоматически.
+9 -8
View File
@@ -22,15 +22,15 @@ def council_xlsx(result: dict) -> bytes:
employees.title = "Сотрудники"
publications = workbook.create_sheet("Публикации")
parameters = workbook.create_sheet("Параметры")
_append(employees, ["№", "ФИО", "Учёная степень", "Q1", "Q2", "К1", "ВСЕГО", "В БД", "Все публикации",
"Статус", "Профиль ВШЭ", "Примечание"])
_append(employees, ["№", "ФИО", "Учёная степень", "Q1", "Q2", "К1", "ВСЕГО", "Страница ВШЭ", "Все публикации",
"Профиль ВШЭ", "Примечание"])
_append(publications, ["№ сотрудника", "ФИО", "Название публикации", "Год", "Тип материала", "Источники",
"Критерии", "Q1", "Q2", "К1", "В ВСЕГО", "В БД", "DOI", "Ссылка на сайте", "Строки CSV"])
"Критерии", "Q1", "Q2", "К1", "В ВСЕГО", "Страница ВШЭ", "DOI", "Ссылка на сайте", "Строки CSV"])
for number, candidate in enumerate(result["candidates"], 1):
note = "Совпадение ФИО: публикации CSV не присвоены автоматически" if candidate["ambiguous"] else ""
_append(employees, [number, candidate["name"], candidate["degree"], candidate["q1_count"], candidate["q2_count"],
candidate["k1_count"], candidate["total_count"],
candidate["db_count"], candidate["count"], "Уволен" if candidate["dismissed"] else "Не отмечен как уволенный",
candidate["db_count"], candidate["count"],
candidate["profile_url"], note])
for article in candidate["articles"]:
_append(publications, [number, candidate["name"], article["title"], article["year"], article["type_label"],
@@ -43,7 +43,7 @@ def council_xlsx(result: dict) -> bytes:
["Подбор по специальности", "Хотя бы одна публикация за пять лет в релевантном журнале К1 по Перечню ВАК на 15.09.2026; содержание статьи и исторические специальности не проверяются."],
["Начало периода", result["start"]], ["Конец периода", result["end"]], ["Поиск по ФИО", result["q"]],
["Сортировать по", {"full_name": "ФИО", "q1_count": "Q1", "q2_count": "Q2", "k1_count": "К1",
"total_count": "ВСЕГО", "db_count": "В БД", "count": "Все публикации"}[result["sort"]]],
"total_count": "ВСЕГО", "db_count": "Страница ВШЭ", "count": "Все публикации"}[result["sort"]]],
["Направление", "По возрастанию" if result["direction"] == "asc" else "По убыванию"],
["Сотрудников в выгрузке", result["matched"]], ["Всего сотрудников в списке", result["total"]],
["Отбор по степени", "Доктор наук в профиле; достаточно хотя бы одной публикации из CSV или БД"],
@@ -53,11 +53,12 @@ def council_xlsx(result: dict) -> bytes:
"в справочнике из ВАК категории.pdf; историческая категория не подтверждается. "
"Без названия журнала К1 не подтверждён."],
["ВСЕГО", "Уникальные публикации, входящие в Q1 ИЛИ Q2 ИЛИ К1; пересечения учитываются один раз."],
["В БД / Все публикации", "Все годы и категории; общий перечень объединяет CSV и БД без дублей."],
["Страница ВШЭ / Все публикации", "Все годы и категории; общий перечень объединяет CSV и БД без дублей. "
"Страница ВШЭ учитывает сохранённые публикации, включая импортированные из CSV; источник указан на листе Публикации."],
]:
_append(parameters, values)
for sheet, widths in [(employees, [7, 34, 40, 10, 10, 10, 12, 12, 22, 30, 45, 55]),
(publications, [16, 34, 65, 12, 40, 45, 65, 10, 10, 10, 12, 12, 45, 45, 22]),
for sheet, widths in [(employees, [7, 34, 40, 10, 10, 10, 12, 20, 22, 45, 55]),
(publications, [16, 34, 65, 12, 40, 45, 65, 10, 10, 10, 12, 20, 45, 45, 22]),
(parameters, [32, 95])]:
sheet.freeze_panes = "A2"
sheet.auto_filter.ref = sheet.dimensions
+8
View File
@@ -254,6 +254,14 @@ def test_xlsx_exports_all_filtered_workers_in_order_and_deduplicated_evidence(db
book = load_workbook(BytesIO(response.content))
assert book.sheetnames == ["Сотрудники", "Публикации", "Параметры"]
people, works = book["Сотрудники"], book["Публикации"]
assert [cell.value for cell in people[1]] == [
"№", "ФИО", "Учёная степень", "Q1", "Q2", "К1", "ВСЕГО", "Страница ВШЭ", "Все публикации",
"Профиль ВШЭ", "Примечание"
]
assert people["J2"].value == "https://www.hse.ru/staff/test"
assert people["K2"].value is None
assert people.max_column == 11
assert works["L1"].value == "Страница ВШЭ"
assert people.max_row == 29 and works.max_row == 29
assert people["B2"].value == "Петров 27" and people["B29"].value == "Петров 00"
assert [people.cell(2, n).value for n in [4, 5, 6, 7, 8, 9]] == [1, 1, 0, 1, 1, 1]