Services
Technologie-Stack
Die Sprach- und Technologieentscheidungen für eine Produktions-Neuentwicklung von Trans-Atlas als Börse für sechs Transportarten: eine serverseitige Datenbank als einzige Quelle der Wahrheit, PostgreSQL + PostGIS, Verträge über JSON Schema.
Dies ist ein Entscheidungsprotokoll, kein bereitgestellter Stack: Keiner der genannten Dienste (Next.js, NestJS, Go, Kafka, ClickHouse, Kubernetes) läuft tatsächlich in diesem Projekt. index.html bleibt dieselbe einzelne Datei wie zuvor. „Backend: Sprint 0“ ist der erste umgesetzte und getestete Teil dieses umfassenderen Plans.
Entscheidungen nach Schicht
| Schicht | Wahl | Sprache | Warum |
|---|---|---|---|
| Frontend | Next.js (App Router) + React + TypeScript | TypeScript | SSR/ISR для SEO-розділів біржі, клієнтські таблиці заявок, один тип-контракт із бекендом |
| UI-шар | Tailwind CSS + Radix UI + TanStack Table/Query | TypeScript | Щільні табличні інтерфейси біржі, доступність, серверний кеш замість localStorage |
| Основний backend | NestJS на Node.js 24 LTS | TypeScript | Одна мова з фронтендом, модульність під розділи транспорту, зрілі валідація/DI/OpenAPI |
| ORM / доступ до даних | Prisma для CRUD + чистий SQL (pg) для геозапитів | TypeScript / SQL | PostGIS-функції та ранжування пишуться SQL-ом, не ORM-абстракцією |
| Пошук маршрутів (SEARCH) | окремий сервіс на Go | Go | Обхід графа магістраль→фідери, POST_DRONE; передбачувана латентність і паралелізм |
| Геодані та відстані | PostgreSQL 18 + PostGIS; OSRM або Valhalla | SQL / 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/sub | TypeScript | Онлайн-стрічка заявок і ставок |
| Платежі, валюти, ескроу | окремий сервіс settlement, decimal-арифметика | TypeScript + SQL | Валюта ціни ≠ валюта оплати: ставка, договір, платіж, курс, комісія — окремі поля |
| Web3-шар (опційний) | Solidity + Foundry, EVM L2, стейблкоїн-виплати | Solidity | Смартконтрактне ескроу як додатковий шар, а не заміна фіатної бухгалтерії |
| Аналітика та BI | ClickHouse (події) + Metabase/Power BI | SQL | Оперативна аналітика без навантаження на OLTP |
| ML / прогноз ставок | Python (FastAPI, pandas, scikit-learn/LightGBM) | Python | Окремий сервіс, викликається API; не змішується з доменним бекендом |
| Інфраструктура | Docker + Kubernetes (керований) або Nomad; Terraform | HCL / YAML | Один спосіб опису середовищ, узгоджений із наявним CI-підходом |
| CI/CD і контракти | GitHub Actions + JSON Schema + мутаційні тести + bash -euo pipefail | YAML / Python | Продовження вже перевіреного контрактного CI проєкту TA |
| Спостережуваність | OpenTelemetry → Grafana (Loki, Tempo, Prometheus), Sentry | — | Трасування пошуку маршрутів і платіжних операцій end-to-end |
Warum diese Wahl
TypeScript als Hauptsprache: ein Typvertrag von der Datenbank bis zur Oberfläche, der größte Einstellungsmarkt für ein Webprodukt dieser Klasse, und der vorhandene Demo-Prototyp sowie der lokale TA-Server lassen sich ohne Sprachwechsel in die Produktion übernehmen.
Go nur für das SEARCH-Modul: Graphdurchlauf für Routing und Massenberechnungen von Entfernungen führen in Node unter Last zu instabiler Latenz; Goroutinen und eine einzelne statische Binärdatei machen den parallelen Fan-out direkt und vorhersehbar.
Bewusst nicht gewählt
| Abgelehnt | Grund |
|---|---|
| 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-Servicekarte
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-сумісне сховище документівStartreihenfolge
| Phase | Umfang | Technologiezuwachs |
|---|---|---|
| Етап 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 |
Abnahmekriterien für die Stack-Wahl
- Жоден предметний запис не зберігається у сховищі браузера; очищення браузера не втрачає даних учасника
- Кожен публічний API-ендпойнт має JSON Schema, і мутація схеми валить CI
- Контракт між api-gateway і search перевіряється окремим негативним pull request
- Пошук повертає зібраний і ранжований набір варіантів, а не перший знайдений маршрут
- Дрон-варіант додається як альтернатива останнього авто-плеча і не видаляє авто-варіант
- У угоді ставка, договір, платіж, курс, джерело курсу, комісія та стан ескроу — окремі поля
- Деградація одного зовнішнього конектора дає частковий результат, а не помилку всієї сторінки
- Усі bash-кроки конвеєра виконуються з bash -euo pipefail