Paslaugos

Technology stack

The language and technology choices for a production rewrite of Trans-Atlas as an exchange covering six transport modes: a server-side database as the single source of truth, PostgreSQL + PostGIS, contracts via JSON Schema.

This is a decision record, not a deployed stack: none of the listed services (Next.js, NestJS, Go, Kafka, ClickHouse, Kubernetes) actually run in this project. index.html stays the same single-page file it always was. "Backend: Sprint 0" is the first executed and tested slice of this broader plan.

Decisions by layer

Layer Choice Language Why
FrontendNext.js (App Router) + React + TypeScriptTypeScriptSSR/ISR для SEO-розділів біржі, клієнтські таблиці заявок, один тип-контракт із бекендом
UI-шарTailwind CSS + Radix UI + TanStack Table/QueryTypeScriptЩільні табличні інтерфейси біржі, доступність, серверний кеш замість localStorage
Основний backendNestJS на Node.js 24 LTSTypeScriptОдна мова з фронтендом, модульність під розділи транспорту, зрілі валідація/DI/OpenAPI
ORM / доступ до данихPrisma для CRUD + чистий SQL (pg) для геозапитівTypeScript / SQLPostGIS-функції та ранжування пишуться SQL-ом, не ORM-абстракцією
Пошук маршрутів (SEARCH)окремий сервіс на GoGoОбхід графа магістраль→фідери, POST_DRONE; передбачувана латентність і паралелізм
Геодані та відстаніPostgreSQL 18 + PostGIS; OSRM або ValhallaSQL / C++Радіусний пошук для дрон-плеча, реальні дорожні відстані замість «по прямій»
СУБДPostgreSQL 18 (Patroni або керований кластер)SQLТранзакційна цілісність угод, ставок, ескроу; JSONB для шаблонів заявок
Кеш і черги коротких задачRedis 7—Вимога A.4/A.11; кеш конекторів погоди та кордонів
Шина подійKafka (або Redpanda)—Ставки, статуси угод, аудит, вебхуки партнерам; ordered log під фінансові події
Повнотекстовий пошукPostgreSQL FTS на MVP → OpenSearch за потребиSQLНе вводити ще один кластер, поки Postgres тримає навантаження
Реальний час (ставки, чат)WebSocket (Socket.IO або ws) + Redis pub/subTypeScriptОнлайн-стрічка заявок і ставок
Платежі, валюти, ескроуокремий сервіс settlement, decimal-арифметикаTypeScript + SQLВалюта ціни ≠ валюта оплати: ставка, договір, платіж, курс, комісія — окремі поля
Web3-шар (опційний)Solidity + Foundry, EVM L2, стейблкоїн-виплатиSolidityСмартконтрактне ескроу як додатковий шар, а не заміна фіатної бухгалтерії
Аналітика та BIClickHouse (події) + Metabase/Power BISQLОперативна аналітика без навантаження на OLTP
ML / прогноз ставокPython (FastAPI, pandas, scikit-learn/LightGBM)PythonОкремий сервіс, викликається API; не змішується з доменним бекендом
ІнфраструктураDocker + Kubernetes (керований) або Nomad; TerraformHCL / YAMLОдин спосіб опису середовищ, узгоджений із наявним CI-підходом
CI/CD і контрактиGitHub Actions + JSON Schema + мутаційні тести + bash -euo pipefailYAML / PythonПродовження вже перевіреного контрактного CI проєкту TA
СпостережуваністьOpenTelemetry → Grafana (Loki, Tempo, Prometheus), Sentry—Трасування пошуку маршрутів і платіжних операцій end-to-end

Why these choices

TypeScript as the primary language: one type contract from database to UI, the largest hiring market for a web product of this class, and the existing demo prototype and local TA server carry over to production without a language change.

Go for the SEARCH module only: graph traversal for routing and bulk distance calculations give unstable latency under load in Node; goroutines and a single static binary make the parallel fan-out direct and predictable.

Deliberately not chosen

Rejected Reason
PHP/Laravel монолiтСлабший шлях до реального часу й до окремого високонавантаженого сервісу пошуку
Java/SpringПридатний і надійний, але дорожчий у наймі та повільніший в ітераціях для команди такого розміру
Python як основний backendЗалишено лише для ML і аналітики; для OLTP-домену з ескроу типізований TypeScript зручніший у контрактному CI
MongoDB як основна базаУгоди, ставки, ескроу потребують транзакцій і обмежень цілісності
Vector DB на старті Q&AУ TA вже працює локальне retrieval по курованих wiki.json/outputs.json — цього достатньо для MVP
Повністю on-chain біржаЮридично значущі документи й фіатні платежі лишаються off-chain; блокчейн — опційний розрахунковий шар
localStorage як сховище предметних данихПряма заборона рамкового ТЗ; допустимий лише втрачуваний UI-стан

MVP service map

web (Next.js, TS)
  └─ api-gateway (NestJS, TS) ── OpenAPI + JSON Schema
       ├─ identity (KYB, тризрівневий онбординг, права на розділи транспорту)
       ├─ exchange (заявки, лоти, ставки, рейтинги)  ── Kafka
       ├─ settlement (валюта ціни / валюта оплати, курс + джерело курсу, комісія, ескроу)
       ├─ search (Go)  ── PostGIS, OSRM/Valhalla, Redis
       ├─ connectors (погода, кордони, довідники) ── Redis-кеш, деградація по джерелу
       └─ qa-portal (raw → wiki → outputs, цитати й статус перевірки)
PostgreSQL 18 + PostGIS · Redis · Kafka · ClickHouse · S3-сумісне сховище документів

Launch sequence

Stage What's included Technology added
Етап 1 (0–3 міс.)Заявки, ставки, профілі, права на розділи, UK/EN/PL/DE, платна реєстраціяNext.js, NestJS, PostgreSQL+PostGIS, Redis, GitHub Actions
Етап 2 (3–6 міс.)Модуль SEARCH, POST_DRONE, реальні дорожні відстаніGo-сервіс, OSRM/Valhalla, gRPC-контракт
Етап 3 (6–9 міс.)Мультивалютні угоди, ескроу, e-invoicing, локальні виплатиsettlement, decimal-арифметика, PSP-інтеграції
Етап 4 (9–12 міс.)Аналітика, рейтинги на даних, прогноз ставок, вебхуки партнерамClickHouse, Python-ML, Kafka Connect
Етап 5Смартконтрактне ескроу й оракули підтвердження доставкиSolidity + Foundry, L2

Acceptance criteria for the stack choice

  • Жоден предметний запис не зберігається у сховищі браузера; очищення браузера не втрачає даних учасника
  • Кожен публічний API-ендпойнт має JSON Schema, і мутація схеми валить CI
  • Контракт між api-gateway і search перевіряється окремим негативним pull request
  • Пошук повертає зібраний і ранжований набір варіантів, а не перший знайдений маршрут
  • Дрон-варіант додається як альтернатива останнього авто-плеча і не видаляє авто-варіант
  • У угоді ставка, договір, платіж, курс, джерело курсу, комісія та стан ескроу — окремі поля
  • Деградація одного зовнішнього конектора дає частковий результат, а не помилку всієї сторінки
  • Усі bash-кроки конвеєра виконуються з bash -euo pipefail

Model files