From 86f0ee1137d95e3e2c49a18790413398ef0d0244 Mon Sep 17 00:00:00 2001 From: codex Date: Thu, 8 Oct 2026 15:05:33 +0300 Subject: [PATCH] fix: normalize K1 reference checksum for clean Linux checkouts --- .gitattributes | 2 ++ README.md | 6 ++++-- app/data/k1_specialties.json | 3 ++- app/version.py | 6 +++--- pyproject.toml | 2 +- scripts/extract_k1_journals.py | 2 +- scripts/extract_k1_specialties.py | 4 ++-- tests/test_api.py | 2 +- tests/test_council.py | 4 ++-- tests/test_extract_k1_specialties.py | 31 ++++++++++++++++++++++++++++ 10 files changed, 49 insertions(+), 13 deletions(-) diff --git a/.gitattributes b/.gitattributes index 3858263..89f67ab 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,4 @@ app/data/council_articles.csv text eol=lf app/data/council_articles.json text eol=lf +app/data/k1_journals.json text eol=lf +app/data/k1_specialties.json text eol=lf diff --git a/README.md b/README.md index cc2cdfb..b8061a4 100644 --- a/README.md +++ b/README.md @@ -155,7 +155,7 @@ node --check app/static/admin.js Тесты с данными используют временную SQLite; отдельные API smoke-тесты запускают приложение с его текущей конфигурацией. Браузерная проверка: `pip install playwright`, `python -m playwright install chromium`, затем `python tests/browser_admin.py`. Она проверяет реальный рендеринг страниц, клавиатуру, диалог, фильтры и восстановление прогресса после ошибки. Скриншоты сохраняются во временную папку; путь выводится в конце. -Версия сервиса: `0.15.3`. Админка всегда показывает версии backend и frontend в footer. +Версия сервиса: `0.15.4`. Админка всегда показывает версии backend и frontend в footer. ## Разовый импорт публикаций @@ -196,7 +196,9 @@ python scripts/extract_k1_specialties.py "app/data/ВАК Перечень.pdf" Скрипт проверяет последовательность всех 3231 строк. Проверенные различия названий сохранены в `scripts/k1_specialty_matches.json`; каждое сопоставление проверяется по номеру строки и точному исходному названию. Нечёткий поиск не применяется. -Сервис читает готовый JSON и не требует PDF или `pdfplumber` при запуске. +Сервис читает готовый JSON и не требует PDF или `pdfplumber` при запуске. Хеш +`k1_source_sha256` рассчитывается для исходного JSON с окончаниями строк LF; оба +JSON-справочника записываются с LF для воспроизводимости на Windows и Linux. ### Подготовка публикаций для портала diff --git a/app/data/k1_specialties.json b/app/data/k1_specialties.json index b7124f8..8553634 100644 --- a/app/data/k1_specialties.json +++ b/app/data/k1_specialties.json @@ -3,7 +3,8 @@ "source": "ВАК Перечень.pdf", "source_sha256": "d16ab69668fb4c4cab80eb75809928cca63b447df5ee246e4f9d56cae4d3273d", "as_of": "2026-09-15", - "k1_source_sha256": "ae6c18ae283d89b7703264bd0047f0466207fd535b59c8c50288f0315c546392", + "k1_source_sha256": "f0f4514b132e486e821ae64c92cc23dccc55b641d590946de53bc7199e6f4caa", + "k1_source_hash_eol": "LF", "source_rows": 3231, "specialties": [ { diff --git a/app/version.py b/app/version.py index 2d0ed8b..48136a6 100644 --- a/app/version.py +++ b/app/version.py @@ -1,3 +1,3 @@ -APP_VERSION = "0.15.3" -FRONTEND_VERSION = "0.15.3" -BACKEND_VERSION = "0.15.3" +APP_VERSION = "0.15.4" +FRONTEND_VERSION = "0.15.4" +BACKEND_VERSION = "0.15.4" diff --git a/pyproject.toml b/pyproject.toml index 6db66dc..0363dad 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "miem-workers" -version = "0.15.3" +version = "0.15.4" description = "MIEM employees parser, admin API, and web admin" requires-python = ">=3.11" dependencies = [ diff --git a/scripts/extract_k1_journals.py b/scripts/extract_k1_journals.py index 7de0793..cccaaa5 100644 --- a/scripts/extract_k1_journals.py +++ b/scripts/extract_k1_journals.py @@ -54,5 +54,5 @@ if __name__ == "__main__": parser.add_argument("--output", type=Path, default=Path("app/data/k1_journals.json")) args = parser.parse_args() result = extract(args.source) - args.output.write_text(json.dumps(result, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") + args.output.write_text(json.dumps(result, ensure_ascii=False, indent=2) + "\n", encoding="utf-8", newline="\n") print(f"Saved {len(result['journals'])} K1 journals; verified {result['source_rows']} source rows") diff --git a/scripts/extract_k1_specialties.py b/scripts/extract_k1_specialties.py index 1ccbc6f..9b73ebc 100644 --- a/scripts/extract_k1_specialties.py +++ b/scripts/extract_k1_specialties.py @@ -169,8 +169,8 @@ if __name__ == "__main__": entries = build_reference(journals, k1, json.loads(args.matches.read_text(encoding="utf-8")), args.as_of) result = {"schema_version": 1, "source": args.source.name, "source_sha256": hashlib.sha256(args.source.read_bytes()).hexdigest(), "as_of": args.as_of, - "k1_source_sha256": hashlib.sha256(args.k1.read_bytes()).hexdigest(), "source_rows": len(journals), + "k1_source_sha256": hashlib.sha256(args.k1.read_bytes().replace(b"\r\n", b"\n")).hexdigest(), "k1_source_hash_eol": "LF", "source_rows": len(journals), "specialties": [{"code": code, "name": name} for code, name in SPECIALTIES], "journals": entries} - args.output.write_text(json.dumps(result, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") + args.output.write_text(json.dumps(result, ensure_ascii=False, indent=2) + "\n", encoding="utf-8", newline="\n") from collections import Counter print(len(entries), dict(Counter(j['status'] for j in entries))) diff --git a/tests/test_api.py b/tests/test_api.py index 3bbde7e..7e91173 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -18,7 +18,7 @@ def test_health_returns_versions(): response = TestClient(app).get("/api/health") assert response.status_code == 200 - assert response.json()["backend_version"] == "0.15.3" + assert response.json()["backend_version"] == "0.15.4" def test_api_employees_and_stats_require_admin_session(): diff --git a/tests/test_council.py b/tests/test_council.py index fb583b2..7ae4f23 100644 --- a/tests/test_council.py +++ b/tests/test_council.py @@ -215,7 +215,7 @@ def test_public_page_data_minimization_and_safe_links(db_session, export): assert "<script>" in response.text and "