Единственная точка входа снаружи — API Gateway (KrakenD) на порту 8080.
Порты сервисов users, credit, account, wallet, notify, wishlist, caldron
наружу не публикуются:
они доступны только внутри compose-сети.
Так сделано намеренно. Сервисы определяют пользователя по заголовку
X-Authorized-Id, и этот заголовок проставляет только шлюз — из claim sub
проверенного JWT. Если открыть порт сервиса напрямую, любой сможет подставить
произвольный идентификатор и работать от имени чужого пользователя.
Веб-интерфейс поднимается вместе со стендом и доступен на http://localhost:3000 — это единственный сервис, чей порт публикуется наружу.
make up
curl http://localhost:8080/api/v1/register \
-d 'username=...&password=...&phone=+79001234567'Список целей сборки — make help.
ЕСИА, СБП, OZON и Wildberries в системе не подключены: каждая требует договора или заявки от юридического лица. Что именно нужно получить, как устроен протокол каждой, что писать в коде и чем это отлаживать — в EXTERNAL.md.
Стенд из docker-compose.yml — для машины разработчика. На сервер
выкатывается отдельный стек: deploy/compose.yml и deploy/deploy.sh,
образы из GHCR по тегу коммита, миграции отдельным шагом до подмены
образов, откат на предыдущий тег при неудачном дымовом сценарии.
Снаружи там виден только обратный прокси с TLS: сертификат он получает и продлевает сам, а шлюз, интерфейс, база и кэш наружу не смотрят.
Решения и их цена — в ADR 0008 и ADR 0009, порядок шагов и нужные секреты — в docs/ci-cd.md.
Проект целиком описан в одном PDF: назначение, архитектура, сервисы, внешний API, развёртывание, переменные окружения, требования, безопасность и принятые решения.
make docsДокумент собирается из исходников: текст, объясняющий решения, лежит
в docs/book/chapters, а списки эндпоинтов, переменных, требований
и сервисов генерируются из самого кода. Расхождение ловит CI —
make docs-check перегенерирует их и сравнивает с зафиксированными.
Маршруты шлюза описаны в config/krakend/krakend.tmpl. Кошелёк доступен только по gRPC внутри сети: KrakenD Community Edition не проксирует gRPC-бэкенды.
Провайдеров два, и они переключаются набором переменных в .env
(готовые значения — в .env.example, обоснование —
в ADR 0001). Точка переключения одна:
какой JWKS считает доверенным шлюз.
| Режим | Переменные | Запуск |
|---|---|---|
| Собственный на fosite (по умолчанию) | AUTH_HOST=http://users:51053 |
docker compose up |
| Keycloak | AUTH_HOST=http://keycloak:8080 |
docker compose --profile keycloak up |
Выбор библиотеки обоснован в ADR 0002.
Собственный провайдер поддерживает гранты authorization_code (с PKCE),
password и refresh_token, выдаёт RS256 JWT и публикует ключи
на /.well-known/jwks.json. Страница входа отдаётся на GET /auth.
- Реестр требований — что считается сделанным и по какому критерию. Источник истины о готовности.
- Архитектура — контекст, контейнеры, границы сервисов и владение данными.
- Решения (ADR) — принятые архитектурные решения с условиями пересмотра.
- Модель угроз — активы, границы доверия, нарушители и принятые риски.
- Производительность — измеренный baseline и условия измерения.
- CI/CD — что проверяется и как публикуются образы.
- Отчёт по репозиторию — разбор состояния кода.
- План работ и задачи.
- Научиться писать на
Go, запомнить синтаксис; - Научиться описывать микросервисную архитектуру;
- Научиться проводить функциональный анализ и анализ требований;
- Научиться выявлять угрозы внешние и внутренние;
- Научиться проводить оптимизацию системы (сервисов) для повышения скорости работы, отказоусточивости, качества кода;
- Научиться оптимальным образом выстраивать общение (сетевое) между
сервисами (
GRPC)
Ниже — исходная постановка. Разнесённый по идентификаторам список с критериями приёмки и фактическим статусом — в реестре требований.
GatewayAPI - Krakend
- Регистрация пользователя в системе (в том числе через социальные сети, ЕСИА, маркетплейсы?)
- Хранение профиля пользователя (аватарки - gravatar, мыло, телефон обязателен, пол);
- Пользователь имеет уникальный идентификатор
UUIDи по нему можно посмотреть профиль (отображается только аватар и что еще?) или провести операции в системе (дарение, перевод, котел и т.д.) - Формирование
JWTтокена и инфраструктурыOAuth2
Лучше использовать Keycloak.
От платежных сервисов нам надо:
- СБП для перевода средств напрямую пользователю или в систему (кошелек, котел)
- Вывод средств каким либо образом
Оповещать пользователя через телеграм (ботом), WebSocket, пулинг как в вк
Скорее всего, основная логика потребует заведение кошелька пользователя в системе (отдельный сервис);
- Пользователь создает список желаемых подарков на основе данных выбранных маркетплейсов (возможно выставить приоритеты элементам списка желаний);
- Пользователь совершающий дарение, просматривает список и выбирает что дарить;
- Выбранный подарок резервируется за пользователем и не доступен к просмотру другими пользователями;
- Одоряемый пользователь оповещается о том, что кто-то хочет ему вручить конкретный подарок и имеет возможность отклонить дарение или подтвердить;
- Если подарок подтвержден даритель его заказывает через маркетплейс и акцептирует (что приводит к изменению статуса в списке желаний);
- Одним из элементов списка желаний может быть денежные средства (которые могут быть пересланы напрямую зарегистрированному пользователю через СБП с комиссией);
- Если подарок отвергнут одоряемым, то меняется его статус и он не доступен для подарка;
- Элемент списка желаний может быть в следующих состояниях: виден, не виден, выбран, подтвержден, акцептован, отклонен;
Основная задача котла сбор и аккумулирование средств и дальнейшая их передача (перевод) зарегистрированному пользователю.
- Пользователь создает котел (объект, котлы могут быть разного типа с разным поведением);
- Создатель добавляет в котел зарегистрированных пользователей (у которых есть привязанные карты МИР для перевода на них средств или виртуальный кошелек);
- Создатель определяет сколько средств должно быть переведено каждым из участников (конкретно, индивидуально, диапазон);
- Котел находится в состоянии подготовка до тех пор, пока каждый из участников не перечислит средства - после этого состояние готов;
- Создатель котла может участвовать в скидывании средств или просто как арбитр (разные виды котлов);
- Котел может быть в любой момент отменен - средства возвращаются всем скинувшимся;
- Добавление участников возможно только создателем и только в состоянии подготовка, если котел готов - добавление невозможно;
- Все участники котла оповещаются о добавлении в котел, а также о смене статуса котла;
- Каждый участник котла формирует список подарков из 5 элементов сумма цен которых не превышает общую сумму котла;
- После того как котел готов, создатель запускает генератор случайных чисел или выбирает арбитра из числа участников который запускает генератор за него;
- Генератор случайных чисел выдает номер участника который выиграл;
- Автоматически запускается генератор случайных чисел, чтобы выбрать набор подарков из списка предоставленного пользователем;
Пример:
Создатель - Вася (я участвую и ставка 2500) Участник1 - Петя (2500) Участник2 - Витя (2500) Участник3 - Жора (2500)
Котел : 10000 Рандом: Участник2 Рандом: Тостер(3400), Брелок(1600), 5000 перевод на карту
- После того как котел готов, создатель запускает генератор случайных чисел или выбирает арбитра из числа участников который запускает генератор за него;
- Генератор случайных чисел выдает номер участника который выиграл;
- Выигрыш зачисляется победившему участнику;
- Организовывается список покупок;
- Задается сколько средств потратить;
- Рандомно выбираются из списка товары и заказываются на маркетплейсе;