Период: 2026-05-26 ... 2026-06-01.
Источники: TASKS.md, .tasks/sprint9/*, .tasks/reports/S9-*, git history 530b219..HEAD.
| Задача | Статус | Что сделано |
|---|---|---|
| S9-1 | заблокировано | Подготовлен runbook переноса на клиентскую инфраструктуру. Cutover не выполнялся. |
| S9-2 | готово | Подключен метод Контур /results/{id}. |
| S9-3 | готово | Подключен ingestion API инвестпроектов. |
| S9-4 | готово | Добавлены официальные ссылки ЕИС/Госзакупки. |
| S9-5 | готово | Доля ошибок обработки снижена ниже 1%. |
| S9-6 | готово | Добавлен фильтр по дате публикации. |
| S9-7 | готово | Добавлен фильтр по ИНН заказчика для тендеров и проектов. |
| S9-8 | заблокировано | Multi-source слой есть; проверка Seldon/Контур отложена. |
| S9-9 | готово | Добавлена политика polling завершенных тендеров через /results. |
| S9-10 | готово | Уточнены подписи сумм в аналитике. |
| S9-11 | готово | Добавлены donut-графики по объектам/проектам. |
| S9-12 | готово | Добавлена цена поставки/маркер НМЦ в top-10. |
| S9-13 | готово | Добавлен серверный shared-password gate. |
| S9-14 | готово | Добавлен мониторинг участников/победителей после results_date. |
| S9-15 | готово | Добавлен виджет новых победителей. |
| S9-16 | готово | Добавлена региональная аналитика с провалом в реестр. |
| S9-17 | готово | Вместо ДКО-пресетов зафиксированы простые сценарии реестра. |
GET /external/v1/results/{id} стал основным источником участников, победителя и финальной суммы контракта.
- Добавлен
KonturClient.getResults(id). - Добавлен парсер
Protocols[].Participants[]иContracts[].Supplier[]. - В
tendersдобавлены snapshot-поля: победитель, сумма контракта, список/кол-во участников, статус/ошибка/время fetch, raw payload, retry state. - Добавлена CLI-команда
admin:kontur-results-refresh. - Ошибки
401,403,429, пустые и terminal-состояния сохраняются явно. - На prod подтвержден доступ: limit group
results, лимит 200/день, smoke/results/32615944057вернул 200. - Решение: не использовать Search как fallback для участников/победителей.
Коммиты: 0ed6e7c, 4a6761c, 236dbdb, c6b3f32.
Добавлен ежедневный capped polling после даты результатов.
- Основной predicate:
results_date is not null and results_date <= now. - Polling идет после fresh discovery, с cap/reserve.
- До дедлайна заявки polling не делаем, чтобы не жечь лимиты.
- При появлении победителя заполняется
current_winner_detected_at. - Пустые/ошибочные ответы получают явный статус и retry/terminal policy.
Коммиты: 4a6761c, 236dbdb.
Данные из /results выведены в dashboard.
- В карточке тендера показываются победитель, участники и статус fetch.
- В аналитике появились winner periods.
- Новый виджет считает победителей, найденных за 7/14/30 дней.
- Клик по виджету открывает реестр с фильтром
winnerDetectedFrom.
Коммиты: 0ed6e7c, 883f11b.
Подключен ingestion инвестпроектов.
- Adapter:
src/server/modules/investProjectsApi.ts. - Daily pipeline вызывает investment API ingest.
- Данные мапятся в source records, investment entries и canonical projects.
- Env boundary:
INVEST_PROJECTS_BASE_URL,INVEST_PROJECTS_EMAIL,INVEST_PROJECTS_PASSWORD. - Prod-проверка: последний run получил и сохранил 825 строк.
Основание: task docs S9-3 и readiness audit.
Добавлена официальная ссылка, отдельно от Контур/source URL.
- Нормализуются source-provided EIS links из Kontur payload.
eisUrlдоступен в registry API и detail API.- UI показывает ЕИС в реестре и карточке тендера.
- Export тендеров содержит ЕИС URL.
- Добавлен backfill path для старых тендеров.
- Решение: не генерировать фейковые zakupki.gov.ru ссылки, если route неизвестен.
Коммиты: 1ae9bf3, fba64e9, 3b4c432.
Цель S9-5 закрыта по prod-факту.
- Зафиксирован prod failed rate:
1 / 6843 = 0.01%. - Ошибки не скрываются fallback-логикой.
- Важные guardrails: selected-ID/dry-run guard, deterministic ordering, advisory reprocess lock.
Основание: readiness audit и task docs S9-5.
Добавлены пользовательские фильтры и URL/API propagation.
publishedFrom,publishedTo: фильтр по дате публикации с проверка и UTC day bounds.customerTaxId: фильтр по ИНН заказчика.- Кликабельные INN chips в таблицах тендеров и проектов.
- Manual
tradingHouse/ ДКО фильтр работает точным match поcurrent_trading_house/current_dko. - Export учитывает фильтры реестра.
Коммиты: fc054f1, 222111c, f31af68.
Финальное решение по S9-17: ДКО-пресеты не нужны.
- Региональный сценарий использует существующий
region. - Сценарий ключевых клиентов использует список
customerTaxId. customerTaxIdпринимает один или несколько ИНН через запятую, перенос строки или;.- Валидны только ИНН 10 или 12 цифр.
- Если хотя бы один элемент списка невалиден, весь фильтр отклоняется.
- Тендеры фильтруются по
current_customer_tax_ids. - Проекты фильтруются только по
current_customer_tax_id, без developer/investor.
Коммит: f31af68.
Важно: f31af68 на момент этого лога локальный, не в origin/main, не задеплоен.
Улучшена подача аналитики без изменения расчетной семантики.
- Primary label: стоимость потенциальной поставки.
- Бюджет строительства/проекта показывается вторичной строкой.
- Source breakdown показывает два SVG donut-графика: по стоимости поставки и по количеству.
- Добавлен top-3 + Other helper.
- Unknown buckets не скрываются.
Коммиты: e6219ad, 03686ed.
Исправлено отображение сумм в top-10.
- Тендеры:
displayAmount = deliveryCostRub ?? startingPriceRub. - Если используется fallback, UI помечает сумму как
НМЦ. - Проекты не fallback-ятся на полный строительный бюджет.
- Null-суммы сортируются в конец.
Коммиты: e6219ad, 03686ed.
Добавлен drilldown по регионам.
- Analytics payload содержит
regionBreakdown. - UI показывает региональную разбивку.
- Клик по региону открывает реестр тендеров с
regionURL filter. - Unknown region bucket сохраняется.
Коммиты: e6219ad, 03686ed.
Frontend-only auth заменен серверной проверкой.
- Main app проверяет
DASHBOARD_SHARED_PASSWORD. - HTML routes защищены до отдачи SPA.
- API data требует валидную session.
- Login UI просит только пароль.
- Static assets публичные.
- Пароль не попадает во frontend bundle.
Коммиты: d5107c9, 227a8a8, 78b1c2c, 5ad9a29.
Daily pipeline запускает analytics refresh после ingest.
- Dashboard analytics не остается stale после ежедневного сбора данных.
Коммит: d248436.
Покрыто частично.
tender_sourcesпринят как модель multi-source provenance.- Реестр умеет показывать source badges.
- Проверка Seldon/Контур отложена до практичного состояния квоты/auth.
tenders.sourceне переводили в array/json.
Основание: task docs S9-8 и readiness audit.
Подготовлено, но не выполнено.
- Подготовлен runbook/checklist.
- Блокеры: доступ к client VM, схема передачи secrets, cutover approval.
- Active prod остается Hakku VPS
tender-agent-v2.
Основание: task docs S9-1 и reports.
В Sprint 9 использовались:
bun run typecheckbun testbun run build- GitHub Actions deploy для
/resultscommit0ed6e7c - Prod health:
https://polyplastic.hakku.ai/v2/health/ready - Prod
/resultssmoke - Prod investment API ingest count
- Prod processing failed rate
f31af68 feat: support customer INN list filters4080f7c docs: record sprint 9 feature log
- S9-1: client infra cutover требует доступов и approval.
- S9-8: Seldon/Kontur проверка требует практичного состояния Seldon quota/auth.
- Массовый
/resultsrefresh исторических тендеров требует отдельного approval.