На публичной странице /admin/council добавлена кнопка «Скачать XLSX». Она выгружает всех сотрудников, соответствующих текущему поиску, в выбранном порядке, включая записи на других страницах. Используются текущие значения полей формы; экспорт доступен без авторизации по /admin/council/export.xlsx.
Файл содержит три листа: «Сотрудники» (ФИО, степени, три счётчика, статус, ссылка на профиль и неоднозначность ФИО), «Публикации» (общий перечень без дублей, тип материала, источники, критерии, участие в счётчиках, DOI, ссылка и строки CSV), «Параметры» (период, поиск, сортировка, количество сотрудников, условия отбора и ограничения предварительного счётчика CSV). Заголовки закреплены, предусмотрены автофильтры, ширины колонок и перенос текста. Отбор по докторской степени, сопоставление источников, дедупликация и сортировка переиспользуются из council_candidates; пагинация отключается только для экспорта.
Для записи XLSX добавлен openpyxl в оба списка зависимостей. Строки из профиля/CSV записываются текстом, включая строки с начальным '=' и коды ошибок Excel; управляющие символы, недопустимые в XLSX, удаляются. Превышение лимита текста ячейки возвращает ошибку вместо незаметного обрезания. Ошибка экспорта показывает понятное сообщение, контакты и служебные данные в файл не включаются. Версии frontend/backend/package: 0.13.1.
Проверки: pytest — 98 passed, 10 skipped (PostgreSQL integration tests без тестовой БД). Проверены экспорт более 25 сотрудников, фильтрация, порядок, одинаковые работы из CSV/БД, содержимое трёх листов, числовые счётчики, отсутствие приватных полей, пустой результат, формулы как текст, управляющие символы и отказ при слишком длинной ячейке. Playwright browser_council.py — passed: реальное скачивание с корректным именем файла, выгрузка полного списка из второй страницы, фильтрованный файл, поиск/сортировка и отсутствие переполнения 320–1440 px. node --check, sh -n обоих backup-скриптов, git diff --check — passed; детектор Impeccable не сообщил находок.
Заполнение XLSX не вычисляет границы листа после каждой строки: текстовый тип выставляется в существующем единственном проходе форматирования перед сохранением. Добавлен�� регрессионная проверка, запрещающая обращения к max_row/max_column при добавлении 1000 строк. Локальное сравнение полного формирования и сохранения файла на синтетических данных: 1000 публикаций — 0,354 → 0,158 с; 2000 — 1,098 → 0,300 с. Полученные XLSX успешно открыты обратно; время production не измерялось.
Локальные артефакты на синтетических данных: council-export-example.xlsx, xlsx-desktop.png, xlsx-mobile.png в корне проекта. Ожидается независимое ревью в отдельной сессии. Production не изменён; changelog обновляется отдельным шагом после готовности PR по установленному порядку.
На публичной странице /admin/council добавлена кнопка «Скачать XLSX». Она выгружает всех сотрудников, соответствующих текущему поиску, в выбранном порядке, включая записи на других страницах. Используются текущие значения полей формы; экспорт доступен без авторизации по /admin/council/export.xlsx.
Файл содержит три листа: «Сотрудники» (ФИО, степени, три счётчика, статус, ссылка на профиль и неоднозначность ФИО), «Публикации» (общий перечень без дублей, тип материала, источники, критерии, участие в счётчиках, DOI, ссылка и строки CSV), «Параметры» (период, поиск, сортировка, количество сотрудников, условия отбора и ограничения предварительного счётчика CSV). Заголовки закреплены, предусмотрены автофильтры, ширины колонок и перенос текста. Отбор по докторской степени, сопоставление источников, дедупликация и сортировка переиспользуются из council_candidates; пагинация отключается только для экспорта.
Для записи XLSX добавлен openpyxl в оба списка зависимостей. Строки из профиля/CSV записываются текстом, включая строки с начальным '=' и коды ошибок Excel; управляющие символы, недопустимые в XLSX, удаляются. Превышение лимита текста ячейки возвращает ошибку вместо незаметного обрезания. Ошибка экспорта показывает понятное сообщение, контакты и служебные данные в файл не включаются. Версии frontend/backend/package: 0.13.1.
Проверки: pytest — 98 passed, 10 skipped (PostgreSQL integration tests без тестовой БД). Проверены экспорт более 25 сотрудников, фильтрация, порядок, одинаковые работы из CSV/БД, содержимое трёх листов, числовые счётчики, отсутствие приватных полей, пустой результат, формулы как текст, управляющие символы и отказ при слишком длинной ячейке. Playwright browser_council.py — passed: реальное скачивание с корректным именем файла, выгрузка полного списка из второй страницы, фильтрованный файл, поиск/сортировка и отсутствие переполнения 320–1440 px. node --check, sh -n обоих backup-скриптов, git diff --check — passed; детектор Impeccable не сообщил находок.
Заполнение XLSX не вычисляет границы листа после каждой строки: текстовый тип выставляется в существующем единственном проходе форматирования перед сохранением. Добавлен�� регрессионная проверка, запрещающая обращения к max_row/max_column при добавлении 1000 строк. Локальное сравнение полного формирования и сохранения файла на синтетических данных: 1000 публикаций — 0,354 → 0,158 с; 2000 — 1,098 → 0,300 с. Полученные XLSX успешно открыты обратно; время production не измерялось.
Локальные артефакты на синтетических данных: council-export-example.xlsx, xlsx-desktop.png, xlsx-mobile.png в корне проекта. Ожидается независимое ревью в отдельной сессии. Production не изменён; changelog обновляется отдельным шагом после готовности PR по установленному порядку.
Независимое ревью коммита 4aeb26abe9 завершено: одно замечание P2 по квадратичному заполнению XLSX (см. комментарий к _append). Рекомендую исправить перед слиянием.
Подтверждены соответствие origin репозиторию PR и независимость Gitea-аккаунта reviewer agent (id 7) от автора PR и коммита codex (id 6). Получены коммиты через git fetch origin. Изучены все 11 изменённых файлов, общий отбор/дедупликация/сортировка, маршрут экспорта, шаблон, footer и тестовые сценарии. Экспорт полного списка, фильтрация, явная запись строк как текста, числовые счётчики, исключение приватных полей и версии 0.13.0 согласованы по коду.
git diff --check прошёл. CI / test на проверенном SHA остаётся pending (Waiting to run). Локальные тесты, браузер и нагрузочные измерения не запускались: reviewer-сессия ограничена fetch/read/diff/comment/approval. Результаты тестов из описания PR независимо запуском не подтверждались. Код не изменялся, push и merge не выполнялись.
Независимое ревью коммита 4aeb26abe99ea4b51bf38ac94f198367101e15b4 завершено: одно замечание P2 по квадратичному заполнению XLSX (см. комментарий к _append). Рекомендую исправить перед слиянием.
Подтверждены соответствие origin репозиторию PR и независимость Gitea-аккаунта reviewer agent (id 7) от автора PR и коммита codex (id 6). Получены коммиты через git fetch origin. Изучены все 11 изменённых файлов, общий отбор/дедупликация/сортировка, маршрут экспорта, шаблон, footer и тестовые сценарии. Экспорт полного списка, фильтрация, явная запись строк как текста, числовые счётчики, исключение приватных полей и версии 0.13.0 согласованы по коду.
git diff --check прошёл. CI / test на проверенном SHA остаётся pending (Waiting to run). Локальные тесты, браузер и нагрузочные измерения не запускались: reviewer-сессия ограничена fetch/read/diff/comment/approval. Результаты тестов из описания PR независимо запуском не подтверждались. Код не изменялся, push и merge не выполнялись.
[P2] Уберите повторный обход всего листа при добавлении каждой строки.
После sheet.append(values) выражение sheet[sheet.max_row] вычисляет max_row обходом всех уже созданных ячеек; получение строки по числовому индексу дополнительно вычисляет max_column ещё одним обходом. В результате N строк листа «Публикации» заполняются за O(N²), хотя экспорт намеренно включает все публикации всех найденных сотрудников без пагинации. Например, 10 000 строк по 12 колонок дают порядка 1,2 млрд посещений координат только на эти два повторных обхода, до форматирования и сохранения. Большой полный экспорт поэтому создаёт лишнюю CPU-нагрузку и задержку ответа публичного маршрута; новые тесты с 28 публикациями этого не выявляют.
Записывайте текстовый data_type без поиска последней строки: например, создавайте Cell с явным data_type="s" для строк и передавайте готовые ячейки в append, либо выставляйте типы за один проход после заполнения листа. Защиту от формул и обрезания строк необходимо сохранить. Поведение max_row, max_column и getitem подтверждено по опубликованным исходникам openpyxl: https://openpyxl.readthedocs.io/en/stable/_modules/openpyxl/worksheet/worksheet.html . Фактическое время на production не измерялось.
[P2] Уберите повторный обход всего листа при добавлении каждой строки.
После sheet.append(values) выражение sheet[sheet.max_row] вычисляет max_row обходом всех уже созданных ячеек; получение строки по числовому индексу дополнительно вычисляет max_column ещё одним обходом. В результате N строк листа «Публикации» заполняются за O(N²), хотя экспорт намеренно включает все публикации всех найденных сотрудников без пагинации. Например, 10 000 строк по 12 колонок дают порядка 1,2 млрд посещений координат только на эти два повторных обхода, до форматирования и сохранения. Большой полный экспорт поэтому создаёт лишнюю CPU-нагрузку и задержку ответа публичного маршрута; новые тесты с 28 публикациями этого не выявляют.
Записывайте текстовый data_type без поиска последней строки: например, создавайте Cell с явным data_type="s" для строк и передавайте готовые ячейки в append, либо выставляйте типы за один проход после заполнения листа. Защиту от формул и обрезания строк необходимо сохранить. Поведение max_row, max_column и __getitem__ подтверждено по опубликованным исходникам openpyxl: https://openpyxl.readthedocs.io/en/stable/_modules/openpyxl/worksheet/worksheet.html . Фактическое время на production не измерялось.
Повторное независимое ревью коммита 339dd71f63: замечание P2 устранено, новых замечаний, требующих исправления, не обнаружено.
В _append удалено обращение sheet[sheet.max_row]. Установка строкового data_type перенесена в существующий единственный проход форматирования перед workbook.save; повторных обходов растущего листа при добавлении строк больше нет. Защита от формул и кодов ошибок Excel сохранена: все строковые значения получают data_type="s" до сериализации. Очистка недопустимых управляющих символов и отказ при длине более 32767 символов сохранены, числовые и календарные значения не преобразуются в текст.
Прочитаны все изменения после предыдущего ревью и итоговый сервис экспорта. Добавленная регрессионная проверка запрещает обращения к max_row/max_column при добавлении 1000 строк; прежний тест проверяет текстовый тип формул/ошибок, отсутствие XML-формул и отказ от незаметного обрезания. Версии приложения/frontend/backend/package согласованы на 0.13.1. git diff --check для полного PR прошёл.
Повторно подтверждены совпадение origin с репозиторием PR и независимость reviewer agent (id 7) от автора PR и нового коммита codex (id 6); выполнен fetch, head перепроверен перед публикацией. CI / test для нового SHA пока pending (Waiting to run); успешное прохождение CI этим одобрением не подтверждается. Локальные тесты, браузер и бенчмарки не запускались в рамках ограничений reviewer-сессии, результаты из описания PR независимо запуском не подтверждались. Код не изменялся, push и merge не выполнялись.
Повторное независимое ревью коммита 339dd71f6342251e4d55aeac3f7e45f3d85ef4b2: замечание P2 устранено, новых замечаний, требующих исправления, не обнаружено.
В _append удалено обращение sheet[sheet.max_row]. Установка строкового data_type перенесена в существующий единственный проход форматирования перед workbook.save; повторных обходов растущего листа при добавлении строк больше нет. Защита от формул и кодов ошибок Excel сохранена: все строковые значения получают data_type="s" до сериализации. Очистка недопустимых управляющих символов и отказ при длине более 32767 символов сохранены, числовые и календарные значения не преобразуются в текст.
Прочитаны все изменения после предыдущего ревью и итоговый сервис экспорта. Добавленная регрессионная проверка запрещает обращения к max_row/max_column при добавлении 1000 строк; прежний тест проверяет текстовый тип формул/ошибок, отсутствие XML-формул и отказ от незаметного обрезания. Версии приложения/frontend/backend/package согласованы на 0.13.1. git diff --check для полного PR прошёл.
Повторно подтверждены совпадение origin с репозиторием PR и независимость reviewer agent (id 7) от автора PR и нового коммита codex (id 6); выполнен fetch, head перепроверен перед публикацией. CI / test для нового SHA пока pending (Waiting to run); успешное прохождение CI этим одобрением не подтверждается. Локальные тесты, браузер и бенчмарки не запускались в рамках ограничений reviewer-сессии, результаты из описания PR независимо запуском не подтверждались. Код не изменялся, push и merge не выполнялись.
Замечание P2 устранено в 339dd71f63. Новых замечаний нет. Подробности и ограничения проверки приведены в тексте ревью; CI нового SHA пока pending.
Замечание P2 устранено в 339dd71f6342251e4d55aeac3f7e45f3d85ef4b2. Новых замечаний нет. Подробности и ограничения проверки приведены в тексте ревью; CI нового SHA пока pending.
Детали повторного ревью 339dd71: _append больше не обращается к sheet.max_row или sheet.max_column после добавления каждой строки. Текстовый data_type выставляется в единственном существующем проходе форматирования перед сохранением, поэтому защита от формул и кодов ошибок Excel сохранена. Очистка управляющих символов и проверка предельной длины не изменены. Прочитаны все изменения нового коммита, итоговый сервис и регрессионный тест на 1000 строк. Версии согласованы на 0.13.1; git diff --check полного PR прошёл.
Origin совпадает с репозиторием PR. Reviewer agent (id 7) независим от автора PR и коммита codex (id 6); выполнен fetch и перепроверен head. CI нового SHA пока pending. Локальные тесты, браузер и бенчмарки не запускались в рамках ограничений reviewer-сессии; результаты автора независимо запуском не подтверждались. Замечание P2 устранено, опубликовано APPROVED. Код не изменялся, push и merge не выполнялись.
Детали повторного ревью 339dd71: _append больше не обращается к sheet.max_row или sheet.max_column после добавления каждой строки. Текстовый data_type выставляется в единственном существующем проходе форматирования перед сохранением, поэтому защита от формул и кодов ошибок Excel сохранена. Очистка управляющих символов и проверка предельной длины не изменены. Прочитаны все изменения нового коммита, итоговый сервис и регрессионный тест на 1000 строк. Версии согласованы на 0.13.1; git diff --check полного PR прошёл.
Origin совпадает с репозиторием PR. Reviewer agent (id 7) независим от автора PR и коммита codex (id 6); выполнен fetch и перепроверен head. CI нового SHA пока pending. Локальные тесты, браузер и бенчмарки не запускались в рамках ограничений reviewer-сессии; результаты автора независимо запуском не подтверждались. Замечание P2 устранено, опубликовано APPROVED. Код не изменялся, push и merge не выполнялись.
admin
merged commit 2dc63098e4 into main2026-10-08 07:50:42 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
На публичной странице /admin/council добавлена кнопка «Скачать XLSX». Она выгружает всех сотрудников, соответствующих текущему поиску, в выбранном порядке, включая записи на других страницах. Используются текущие значения полей формы; экспорт доступен без авторизации по /admin/council/export.xlsx.
Файл содержит три листа: «Сотрудники» (ФИО, степени, три счётчика, статус, ссылка на профиль и неоднозначность ФИО), «Публикации» (общий перечень без дублей, тип материала, источники, критерии, участие в счётчиках, DOI, ссылка и строки CSV), «Параметры» (период, поиск, сортировка, количество сотрудников, условия отбора и ограничения предварительного счётчика CSV). Заголовки закреплены, предусмотрены автофильтры, ширины колонок и перенос текста. Отбор по докторской степени, сопоставление источников, дедупликация и сортировка переиспользуются из council_candidates; пагинация отключается только для экспорта.
Для записи XLSX добавлен openpyxl в оба списка зависимостей. Строки из профиля/CSV записываются текстом, включая строки с начальным '=' и коды ошибок Excel; управляющие символы, недопустимые в XLSX, удаляются. Превышение лимита текста ячейки возвращает ошибку вместо незаметного обрезания. Ошибка экспорта показывает понятное сообщение, контакты и служебные данные в файл не включаются. Версии frontend/backend/package: 0.13.1.
Проверки: pytest — 98 passed, 10 skipped (PostgreSQL integration tests без тестовой БД). Проверены экспорт более 25 сотрудников, фильтрация, порядок, одинаковые работы из CSV/БД, содержимое трёх листов, числовые счётчики, отсутствие приватных полей, пустой результат, формулы как текст, управляющие символы и отказ при слишком длинной ячейке. Playwright browser_council.py — passed: реальное скачивание с корректным именем файла, выгрузка полного списка из второй страницы, фильтрованный файл, поиск/сортировка и отсутствие переполнения 320–1440 px. node --check, sh -n обоих backup-скриптов, git diff --check — passed; детектор Impeccable не сообщил находок.
Заполнение XLSX не вычисляет границы листа после каждой строки: текстовый тип выставляется в существующем единственном проходе форматирования перед сохранением. Добавлен�� регрессионная проверка, запрещающая обращения к max_row/max_column при добавлении 1000 строк. Локальное сравнение полного формирования и сохранения файла на синтетических данных: 1000 публикаций — 0,354 → 0,158 с; 2000 — 1,098 → 0,300 с. Полученные XLSX успешно открыты обратно; время production не измерялось.
Локальные артефакты на синтетических данных: council-export-example.xlsx, xlsx-desktop.png, xlsx-mobile.png в корне проекта. Ожидается независимое ревью в отдельной сессии. Production не изменён; changelog обновляется отдельным шагом после готовности PR по установленному порядку.
Независимое ревью коммита
4aeb26abe9завершено: одно замечание P2 по квадратичному заполнению XLSX (см. комментарий к _append). Рекомендую исправить перед слиянием.Подтверждены соответствие origin репозиторию PR и независимость Gitea-аккаунта reviewer agent (id 7) от автора PR и коммита codex (id 6). Получены коммиты через git fetch origin. Изучены все 11 изменённых файлов, общий отбор/дедупликация/сортировка, маршрут экспорта, шаблон, footer и тестовые сценарии. Экспорт полного списка, фильтрация, явная запись строк как текста, числовые счётчики, исключение приватных полей и версии 0.13.0 согласованы по коду.
git diff --check прошёл. CI / test на проверенном SHA остаётся pending (Waiting to run). Локальные тесты, браузер и нагрузочные измерения не запускались: reviewer-сессия ограничена fetch/read/diff/comment/approval. Результаты тестов из описания PR независимо запуском не подтверждались. Код не изменялся, push и merge не выполнялись.
@@ -0,0 +13,4 @@if any(isinstance(value, str) and len(value) > 32767 for value in values):raise ValueError("Text exceeds Excel cell limit")sheet.append(values)for cell in sheet[sheet.max_row]:[P2] Уберите повторный обход всего листа при добавлении каждой строки.
После sheet.append(values) выражение sheet[sheet.max_row] вычисляет max_row обходом всех уже созданных ячеек; получение строки по числовому индексу дополнительно вычисляет max_column ещё одним обходом. В результате N строк листа «Публикации» заполняются за O(N²), хотя экспорт намеренно включает все публикации всех найденных сотрудников без пагинации. Например, 10 000 строк по 12 колонок дают порядка 1,2 млрд посещений координат только на эти два повторных обхода, до форматирования и сохранения. Большой полный экспорт поэтому создаёт лишнюю CPU-нагрузку и задержку ответа публичного маршрута; новые тесты с 28 публикациями этого не выявляют.
Записывайте текстовый data_type без поиска последней строки: например, создавайте Cell с явным data_type="s" для строк и передавайте готовые ячейки в append, либо выставляйте типы за один проход после заполнения листа. Защиту от формул и обрезания строк необходимо сохранить. Поведение max_row, max_column и getitem подтверждено по опубликованным исходникам openpyxl: https://openpyxl.readthedocs.io/en/stable/_modules/openpyxl/worksheet/worksheet.html . Фактическое время на production не измерялось.
Повторное независимое ревью коммита
339dd71f63: замечание P2 устранено, новых замечаний, требующих исправления, не обнаружено.В _append удалено обращение sheet[sheet.max_row]. Установка строкового data_type перенесена в существующий единственный проход форматирования перед workbook.save; повторных обходов растущего листа при добавлении строк больше нет. Защита от формул и кодов ошибок Excel сохранена: все строковые значения получают data_type="s" до сериализации. Очистка недопустимых управляющих символов и отказ при длине более 32767 символов сохранены, числовые и календарные значения не преобразуются в текст.
Прочитаны все изменения после предыдущего ревью и итоговый сервис экспорта. Добавленная регрессионная проверка запрещает обращения к max_row/max_column при добавлении 1000 строк; прежний тест проверяет текстовый тип формул/ошибок, отсутствие XML-формул и отказ от незаметного обрезания. Версии приложения/frontend/backend/package согласованы на 0.13.1. git diff --check для полного PR прошёл.
Повторно подтверждены совпадение origin с репозиторием PR и независимость reviewer agent (id 7) от автора PR и нового коммита codex (id 6); выполнен fetch, head перепроверен перед публикацией. CI / test для нового SHA пока pending (Waiting to run); успешное прохождение CI этим одобрением не подтверждается. Локальные тесты, браузер и бенчмарки не запускались в рамках ограничений reviewer-сессии, результаты из описания PR независимо запуском не подтверждались. Код не изменялся, push и merge не выполнялись.
Замечание P2 устранено в
339dd71f63. Новых замечаний нет. Подробности и ограничения проверки приведены в тексте ревью; CI нового SHA пока pending.Детали повторного ревью
339dd71: _append больше не обращается к sheet.max_row или sheet.max_column после добавления каждой строки. Текстовый data_type выставляется в единственном существующем проходе форматирования перед сохранением, поэтому защита от формул и кодов ошибок Excel сохранена. Очистка управляющих символов и проверка предельной длины не изменены. Прочитаны все изменения нового коммита, итоговый сервис и регрессионный тест на 1000 строк. Версии согласованы на 0.13.1; git diff --check полного PR прошёл.Origin совпадает с репозиторием PR. Reviewer agent (id 7) независим от автора PR и коммита codex (id 6); выполнен fetch и перепроверен head. CI нового SHA пока pending. Локальные тесты, браузер и бенчмарки не запускались в рамках ограничений reviewer-сессии; результаты автора независимо запуском не подтверждались. Замечание P2 устранено, опубликовано APPROVED. Код не изменялся, push и merge не выполнялись.