geek.moscowдокументация

Эмулятор реестра ФСП

fsp-mock/ — сервис, моделирующий реестр достижений Федерации спортивного программирования. По проектным материалам у команды нет производственного доступа к реальному реестру для хакатона, поэтому определён собственный контракт и создан заменяемый источник данных. Это контракт команды, а не опубликованная спецификация реального API ФСП.

Источники: документация эмулятора, сущности, API, план, каталог публичных источников, seed, сценарии интерфейса. Репозиторий: https://gitlab.geek.moscow/geek.moscow/fsp-mock.

Место в продукте

Продуктовый сценарий состоит из поиска записи человека, подтверждения владения и импорта достижений. Привязкой владеет Candidates. Он создаёт фоновое задание через outbox, worker обращается к реестру через адаптер. В архитектурных материалах порт называется FspGateway, реализация для эмулятора — FspMockAdapter; фактический HTTP-адаптер также рассматривается в спецификации seed.

Каждый импортированный факт сохраняет источник, внешний идентификатор и время обновления. Повторная синхронизация должна обновлять существующий факт, включая исправление или отзыв результата. Продуктовый frontend не вызывает эмулятор напрямую. При недоступности ФСП профиль продолжает работать с последними полученными данными и видимым временем синхронизации.

Подтверждение владения кодом — проектная гипотеза о возможном механизме связи с реестром. Наличие такого механизма у настоящей ФСП не подтверждено. Для подключения реального источника потребуется согласовать контракт и заменить либо адаптировать интеграционный слой.

Реализация

Сервис написан на NestJS 11. База данных не используется: JSON-наборы загружаются в память при старте. Модули: Seed, Auth, Dictionaries, Competitions, Persons, Dossier, Ownership, Health. OpenAPI 3 выдаётся самим приложением.

Глобальная проверка bearer-токена защищает /v1/*; /health и /openapi.json открыты. Токен хранится в creds-store под именем FSP_MOCK_BEARER_TOKEN, пространство project/geek.moscow. Глобальный фильтр ошибок возвращает {code, message} с кодами person_not_found, unauthorized, not_found, bad_request, internal_error.

API

Метод Путь Назначение
GET /health Проверка работоспособности, {status: "ok"}
GET /openapi.json Описание OpenAPI
GET /v1/persons Поиск по fsp_person_id либо full_name и birth_date; необязательный regional_branch_code; результат unique, ambiguous или 404
GET /v1/persons/{id}/dossier Досье, необязательный курсор since; поля history, summary, participations, results, ranks, national_teams
POST /v1/persons/{id}/ownership-challenges Создание проверки владения; 202 с challenge_id и замаскированным каналом
POST /v1/persons/{id}/ownership-challenges/{challengeId}/confirm Проверка {code}; 200 с fsp_person_id либо 401
GET /v1/disciplines Дисциплины
GET /v1/competitions, /v1/competitions/{id} Соревнования; фильтры discipline_code, year
GET /v1/dictionaries/{levels,series,ranks,roles,categories,age-groups,branches} Семь справочников

Коды подтверждения хранятся в памяти. Обновление выполняется периодическим запросом досье с since; webhook в контракте эмулятора отсутствует.

Набор данных

Набор генерируется скриптом scripts/generate-seed.mjs из спецификации seed. Приведённые количества описывают зафиксированный набор, а не реальную численность участников ФСП.

Сущность Записей
Люди 50
Участия 135
Результаты 129
Спортивные разряды 80
Соревнования 38
Команды 20
Сборные 6
Региональные отделения 89
Дисциплины 5

Пять дисциплин: алгоритмическое программирование, продуктовое программирование и хакатоны, беспилотники, робототехника, информационная безопасность. Справочники содержат 5 уровней, 6 серий, 8 разрядов, 5 ролей, 3 категории и 8 возрастных групп.

Специальные примеры включают две пары полных тёзок для неоднозначного поиска, людей без истории соревнований, исправленный и отозванный результаты, участника сборной и идентификатор с гарантированным 404. Эти случаи нужны для контрактных тестов и демонстрации пограничных состояний. Синтетические записи с датами после даты подготовки стенда не являются утверждением о реально состоявшихся достижениях.

Исследовательский интерфейс

fsp-mock/frontend/ — React-приложение для разработчиков, QA и демонстраций. Оно использует Vite, React Router, TanStack Query и дизайн-систему проекта. Позволяет искать человека, просматривать карточку и досье, проходить сценарий подтверждения владения, исследовать соревнования и справочники.

Адрес API и bearer-токен сохраняются локально в исследовательском интерфейсе. Его сценарии проверяются с MSW. По текущему обзору этот интерфейс является локальным инструментом и не развёрнут в кластерах; опубликованный API эмулятора не означает публикацию explorer.

Проверки и упаковка

HTTP-контракт покрыт набором jest/supertest. Dockerfile выполняет двухэтапную сборку на node:22-alpine, запускает приложение непривилегированным пользователем и открывает порт 3000. При подготовке русской документации тесты сервиса повторно не запускались.

Размещение

Окружение Адрес Кластер и образ
Внутренний стенд Служебный доступ namespace fsp-mock, сертификат внутреннего CA, образ из локальной сборки
Публичный API fsp.geek.moscow Тот же публичный узел, что и платформа; namespace fsp-mock, Let's Encrypt; образ fsp-mock:f5788d1a

Манифесты находятся в infra/k3s/fsp-mock/; infra/k3s/fsp-mock-yc/ описывает прежнее размещение в Yandex Cloud. Оба развёртывания используют /health для проб. Публичная доступность адреса не отменяет bearer-защиту /v1/*; токен на сайте документации не публикуется.

Известное ограничение интеграции

В документе о seed backend зафиксировано, что FspHttpAdapter.fetchDossier ожидает плоское поле achievements, а эмулятор возвращает history, summary, participations, results, ranks, national_teams. Кроме того, требуется полное согласованное отображение исправленных и отозванных фактов на состояния достижений backend.

Поэтому сквозной импорт ФСП нельзя объявить рабочим только на основании доступности API или ответа с нулём записей. Нужны преобразование формата и проверка семантики состояний. Демонстрационные достижения, добавленные локальными фикстурами, должны быть явно помечены fixture-only и не выдаваться за результат реального импорта. Менять внешний контракт эмулятора только ради сокрытия несовпадения не следует.


Административный контур · Все разделы · Экраны и макеты

Обновлено 2026-10-10 Команда nubble · ЛЦТ-2026, трек ФСП Все разделы