From 2c34023af8593f305f7c81e672b4e179c0992cf3 Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Sun, 11 Oct 2026 11:18:40 +0300 Subject: [PATCH 1/3] docs: document stock screener --- README.md | 2 +- architecture/http-api.md | 11 +++++++++ domains/instruments/stocks.md | 44 ++++++++++++++++++++--------------- glossary.md | 8 +++++++ integrations/tbank.md | 6 +++++ overview.md | 2 +- 6 files changed, 52 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index c48ab8c..8bb90f6 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ WealthLedger помогает частному инвестору понимат | [Операции](domains/operations/overview.md) | Исполненные операции, фильтры и пагинация | | [Доход](domains/income/overview.md) | Полученные купоны и дивиденды, периоды и состав расчёта | | [Будущие выплаты](domains/income/upcoming-events.md) | Календарь по текущим позициям и ограничения прогноза | -| [Акции](domains/instruments/stocks.md) и [облигации](domains/instruments/bonds.md) | Поиск выпуска, рыночные показатели и личная история | +| [Скринер акций](domains/instruments/stocks.md) и [облигации](domains/instruments/bonds.md) | Подбор акций по параметрам, поиск выпуска, рыночные показатели и личная история | ## Найти материал по задаче diff --git a/architecture/http-api.md b/architecture/http-api.md index 6c53404..a1c9bf9 100644 --- a/architecture/http-api.md +++ b/architecture/http-api.md @@ -21,6 +21,17 @@ artifact у себя и проверяет соответствие generated ty API имеет prefix `/api/v1`; Swagger публикуется для локальной разработки по environment policy, а не используется frontend в runtime. +## Скринер акций + +`POST /api/v1/stocks/screener/search` всегда создаёт новый результат по +условиям скринера, включая пустой подтверждённый список. Ответ первой страницы +содержит непрозрачный `searchId`, время получения каталога и признак следующей +страницы. `GET /api/v1/stocks/screener/search/{searchId}?page=...` читает +последующую страницу того же результата, не запускает новый поиск и сохраняет +состав и время списка. Идентификатор результата принадлежит текущему пользователю +и его подключению; недоступный или чужой результат возвращает ошибку, а не +пустой список. Точные поля и статусы определяет backend-generated OpenAPI. + ## Инвестиционные данные и синхронизация Затронутые GET инвестиционных ресурсов возвращают сгенерированный contract diff --git a/domains/instruments/stocks.md b/domains/instruments/stocks.md index 8ae1ea3..e058cf6 100644 --- a/domains/instruments/stocks.md +++ b/domains/instruments/stocks.md @@ -28,24 +28,29 @@ на frontend. Общее для акций и облигаций восстановление справочных данных принадлежит [загрузке портфеля на backend](../portfolio/flows/portfolio-loading.md). -Раздел «Акции» в боковой и мобильной навигации ведёт на `/stocks`: поиск -по названию или тикеру через каталог Т-Банка, начиная с двух символов. -Результаты разных выпусков, включая обыкновенные и привилегированные акции, -имеют отдельные UID. Карточка результата показывает логотип, последнюю цену -с её временем, тип бумаги, площадку, код режима, ISIN и доступность торгов через -API. Поиск показывает одну карточку на нормализованный ISIN. До ограничения -в 30 результатов выбирается представитель выпуска: доступность через API, -точное совпадение тикера, затем режим TQBR; равные варианты упорядочены по UID. -Записи без ISIN сохраняются отдельно по UID. Обыкновенные и привилегированные -акции с разными ISIN не объединяются. Цена и ссылка принадлежат выбранному -UID; данные разных режимов не смешиваются. Прямые ссылки из портфеля сохраняют +Раздел «Акции» в боковой и мобильной навигации ведёт на `/stocks`: скринер +запускается кнопкой «Найти» с необязательным названием или тикером, сектором, +типом акции, валютой расчётов, площадкой, страной риска и максимальным размером +лота. Он использует полный полученный каталог и показывает только акции, для +которых каталог подтверждает доступность покупки и торговли через API. Это не +гарантирует, что конкретная заявка пользователя будет исполнена прямо сейчас. + +Скринер показывает одну карточку на выпуск с нормализованным ISIN, а выпуск +без ISIN остаётся отдельной карточкой точного UID. Обыкновенные и +привилегированные акции с разными ISIN не объединяются. После отбора карточки +упорядочены по тикеру и UID, разделены на страницы по 30 и показывают единое +время получения списка. Изменение условий не заменяет текущий список до +следующего нажатия «Найти». Повторный поиск получает новый каталог; страницы +одного результата не пересчитываются. Подтверждённый пустой результат отличается +от ошибки источника, для которой интерфейс предлагает повторить поиск. + +Ссылка карточки принадлежит выбранному UID; данные разных режимов не смешиваются. +Прямые ссылки из портфеля сохраняют исходный UID, даже если поиск выбрал другой режим этого выпуска; такая страница сохраняет UUID в адресе. Если один точный тикер относится к разным выпускам, -сервер возвращает `409 STOCK_TICKER_AMBIGUOUS`, а страница предлагает поиск. -Поиск тикера нечувствителен к регистру, но использует точное совпадение: -SBER не заменяется на SBERP. Однобуквенные тикеры также поддерживаются. +сервер возвращает `409 STOCK_TICKER_AMBIGUOUS`. Прямая ссылка не требует предварительного открытия портфеля. Хлебные крошки -«Акции → название» возвращают к поиску. +«Акции → название» возвращают к скринеру. ## Содержание и состояния @@ -144,10 +149,11 @@ TTM означает последние 12 месяцев, MRQ — послед ## Получение данных и ограничения Общие metadata, discovery, company, quotes, свечи и календари сохраняются -в SQLite. Поиск хранит подтверждённый набор UID для конкретного query; -успешный SBER не подтверждает пустой GAZP. Отсутствующее enrichment не -скрывает найденную бумагу. Сохранённые общие источники переиспользуются -между пользователями, но личные позиции и выплаты всегда проверяют доступ. +в SQLite. Скринер получает каталог online и показывает время его получения; +временная недоступность каталога не подтверждает отсутствие подходящих акций. +Отсутствующее enrichment не скрывает найденную бумагу. Сохранённые общие +источники переиспользуются между пользователями, но личные позиции и выплаты +всегда проверяют доступ. Обычное чтение не ждёт RPC; missing/stale зависимости запрашиваются в фоне через существующий T-Bank limiter. Минутная свежесть применяется к quotes diff --git a/glossary.md b/glossary.md index 728f2b5..866c22d 100644 --- a/glossary.md +++ b/glossary.md @@ -128,6 +128,14 @@ Instrument обогащают отображение Position или Event, но _Не использовать_: бумага, тикер, актив позиции. +## Скринер акций + +Подбор выпусков акций по заданным условиям из каталога T-Bank с указанием +времени получения списка. Скринер отличается от текстового поиска конкретного +инструмента, личного портфеля и подтверждения исполнимости сделки. + +_Не использовать_: гарантия покупки, личная проверка доступа к сделке. + ## Instrument Logo Имя файла бренда T-Bank для отображения Instrument в интерфейсе; diff --git a/integrations/tbank.md b/integrations/tbank.md index f274f81..dfd61f3 100644 --- a/integrations/tbank.md +++ b/integrations/tbank.md @@ -20,6 +20,12 @@ T-Bank определяет исходные данные и права token. B сессию, выбирает подключение её пользователя и устанавливает доступ к счёту. Наличие идентификатора счёта в URL этого доступа не подтверждает. +Скринер акций получает полный online-каталог акций T-Bank для каждого нового +поиска. В него входят только инструменты, для которых каталог подтверждает и +доступность покупки, и торговли через API. Эти признаки описывают полученный +снимок каталога: они не подтверждают личные права пользователя, состояние торгов +или исполнение будущей заявки. Скринер не использует личный портфель как каталог. + [MOEX](moex.md) и [НКР](nkr.md) дополняют публичные сведения об облигациях; они не заменяют брокера как источник личных позиций и исполненных выплат. Границы источников показаны в [контексте](../architecture/context.md), смысл дополнений — в diff --git a/overview.md b/overview.md index 479b29d..ede05cb 100644 --- a/overview.md +++ b/overview.md @@ -24,7 +24,7 @@ WealthLedger — локальное приложение для частного | Посчитать полученные выплаты | [Пассивный доход](domains/income/overview.md): исполненные купоны и дивиденды за календарный период | | Посмотреть ожидаемые события | [Будущие выплаты](domains/income/upcoming-events.md): купоны, дивиденды, погашения и оферты по текущим позициям | | Увидеть общий состав инвестиций | Режим [«Все счета»](domains/portfolio/all-accounts.md), сохраняющий принадлежность строк к счетам | -| Изучить конкретный инструмент | Поиск и страницы [акций](domains/instruments/stocks.md) и [облигаций](domains/instruments/bonds.md): рынок, личная позиция, история и события | +| Изучить конкретный инструмент | [Скринер акций](domains/instruments/stocks.md) по параметрам каталога, страницы акций и поиск [облигаций](domains/instruments/bonds.md): рынок, личная позиция, история и события | ## Как связаны представления -- 2.54.0 From 4caa5e92b7d2597e5c7725b2036007b71ece2abd Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Sun, 11 Oct 2026 11:24:57 +0300 Subject: [PATCH 2/3] ci: avoid duplicate PR checks --- .gitea/workflows/security.yml | 3 +-- .gitea/workflows/verify.yml | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/security.yml b/.gitea/workflows/security.yml index 876617f..81c6bae 100644 --- a/.gitea/workflows/security.yml +++ b/.gitea/workflows/security.yml @@ -2,8 +2,7 @@ name: Docs security on: push: - branches: - - '**' + branches: [develop, main] pull_request: schedule: - cron: '17 5 * * *' diff --git a/.gitea/workflows/verify.yml b/.gitea/workflows/verify.yml index 9981701..0ecd543 100644 --- a/.gitea/workflows/verify.yml +++ b/.gitea/workflows/verify.yml @@ -2,7 +2,7 @@ name: Docs verify on: push: - branches: ['**'] + branches: [develop, main] pull_request: jobs: -- 2.54.0 From e6fd4f64b81dd73b33959b845a1babcfac1891c8 Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Sun, 11 Oct 2026 11:36:51 +0300 Subject: [PATCH 3/3] ci: skip checks on PR metadata edits --- .gitea/workflows/commits.yml | 6 +++++- .gitea/workflows/security.yml | 5 +++++ .gitea/workflows/verify.yml | 5 +++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/commits.yml b/.gitea/workflows/commits.yml index 2372d2c..ab86bce 100644 --- a/.gitea/workflows/commits.yml +++ b/.gitea/workflows/commits.yml @@ -2,7 +2,11 @@ name: Conventional commits on: pull_request: - types: [opened, synchronize, reopened, edited] + types: [opened, synchronize, reopened] + +concurrency: + group: docs-commits-${{ gitea.event.pull_request.number }} + cancel-in-progress: true jobs: commits: diff --git a/.gitea/workflows/security.yml b/.gitea/workflows/security.yml index 81c6bae..633d952 100644 --- a/.gitea/workflows/security.yml +++ b/.gitea/workflows/security.yml @@ -4,9 +4,14 @@ on: push: branches: [develop, main] pull_request: + types: [opened, synchronize, reopened] schedule: - cron: '17 5 * * *' +concurrency: + group: docs-security-${{ gitea.event_name }}-${{ gitea.event.pull_request.number || gitea.ref }} + cancel-in-progress: true + jobs: security: runs-on: ubuntu-latest diff --git a/.gitea/workflows/verify.yml b/.gitea/workflows/verify.yml index 0ecd543..defd378 100644 --- a/.gitea/workflows/verify.yml +++ b/.gitea/workflows/verify.yml @@ -4,6 +4,11 @@ on: push: branches: [develop, main] pull_request: + types: [opened, synchronize, reopened] + +concurrency: + group: docs-verify-${{ gitea.event_name }}-${{ gitea.event.pull_request.number || gitea.ref }} + cancel-in-progress: true jobs: verify: -- 2.54.0