Services

Trans-Atlas-Backend: Sprint 0

Der Plan, die Demo-SPA in eine Anwendung mit serverseitiger Quelle der Wahrheit zu verwandeln: Firmenkonten, persistente Angebote, Referenzdaten in der Datenbank, ein Ereignisprotokoll.

Dies ist eine Spezifikation und ein Protokoll bereits durchgeführter Artefaktprüfungen, kein angebundenes Backend: index.html bleibt eine einzelne Datei ohne Build-Schritt, ohne PostgreSQL, ohne NestJS-Server und ohne echte API. Der Abschnitt „Geplante Frontend-Änderungen“ beschreibt den nächsten Schritt, nicht das bereits Angewendete - LISTINGS, der localStorage-Login und test-data/ funktionieren weiterhin genau wie vor dieser Seite.

Umfang von Sprint 0

  • PostgreSQL 18 + PostGIS: схема, міграції, довідники з реєстрів SPA
  • Автентифікація: реєстрація компанії, вхід, ротація refresh-токенів, підтвердження email, ролі
  • CRUD заявок і стрічка з фільтрами, що повторюють filteredListings()
  • Імпорт наявних 10 773 демо- і тестових заявок у БД без втрати даних
  • Append-only журнал подій
  • Розгортання, міграції, бекапи, моніторинг

Bewusst außerhalb des Umfangs

Was Warum Verschoben nach
Модуль SEARCH (маршрути, магістраль→фідери, POST_DRONE)Власний REST-контракт і власний CIОкремий етап
Верифікація контрагента (KYB, реєстри, дельта-моніторинг)Напрям A плануТижні 3–7
Ingest-агентНапрям B плануТижні 4–8
SSE-стрічка, push, PWAНапрям C плануТижні 6–10
Ставки, торг, ескроу, розрахункиМежа модулів A.1.3 рамкового ТЗПісля перших угод

Stack und Umgebung

Komponente Entscheidung Warum
МоваTypeScript, Node.js 24 LTSОдна мова від схеми до інтерфейсу
КаркасNestJSМодульність, DI, готова інтеграція валідації та OpenAPI
БДPostgreSQL 18 + PostGIS 3.6PostGIS потрібен уже зараз для країн і відстаней
Кеш і чергаRedis 7Ідемпотентність, ліміти запитів, надалі шина подій стрічки
Міграціїnode-pg-migrate або Flyway, тільки впередЗастосовність до продової бази без ручних кроків
ПоштаSMTP із SPF/DKIM/DMARCПідтвердження email і скидання пароля
СпостережуваністьJSON-логи, /api/v1/health, PrometheusМінімум, без якого продакшн не запускається

Wichtige Invarianten auf Datenbankebene

Invariante Mechanismus
mode='multi' ⇒ components містить ≥ 2 плеча, лише базові видиCHECK listings_components_rule
mode<>'multi' ⇒ components IS NULLтой самий CHECK
mode='drone' ⇔ існує рядок у listing_drone_detailsвідкладений CONSTRAINT TRIGGER
Місто відправлення ≠ місто призначенняCHECK listings_origin_ne_destination
is_cross_border не редагується вручнуGENERATED ALWAYS AS ... STORED
Рівень верифікації вище L0 неможливий без дати перевіркиCHECK companies_verified_needs_date
У компанії рівно один власникчастковий UNIQUE INDEX по role='owner'
Email унікальний без урахування регіструтип citext
Журнал подій не редагується застосункомREVOKE UPDATE, DELETE для ролі застосунку

Parität der API-/SPA-Filter

GET /api/v1/listings muss dasselbe Ergebnis liefern wie das heutige filteredListings().

SPA state.filters API-Parameter
state.filters.modemode
state.filters.multiModescomponents
state.filters.fromorigin_city_id
state.filters.todestination_city_id
state.filters.fromCountryorigin_country
state.filters.toCountrydestination_country
state.filters.borderScopeborder_scope
state.filters.currencycurrency

Authentifizierung und Sicherheit

Anforderung Wert
Хешування пароляargon2id, m=64 MiB, t=3, p=1
Мінімальна довжина пароля10 символів; перевірка за списком скомпрометованих
Access-токенJWT, 15 хв, EdDSA, kid для ротації ключів
Refresh-токен30 днів, лише SHA-256; ротація з родиною, повторне використання вбиває всі сесії
Блокування10 невдалих спроб → блок на 15 хвилин
Підтвердження emailОдноразовий токен, 24 години; до підтвердження - перегляд без публікації
Роліowner, manager, viewer; редагувати заявку може лише її компанія

Nichtfunktionale Anforderungen

Kennzahl Ziel
Стрічка з фільтрами, p95≤ 200 мс на 100 тис. заявок
Публікація заявки, p95≤ 300 мс
Доступність99.5% на місяць
БекапЩодоби повний, WAL безперервно, відновлення - щомісяця
МіграціїТільки вперед, без ручних кроків

Tatsächliche Testläufe

Lauf Was geprüft wurde Ergebnis
tools/extract_registries.pyВитягування реєстрів із index.html175 міст, 9 вантажів, 32 валюти, порожніх полів немає
ci/check_backend_contract.py8 груп перевірок артефактів15 із 15 пройдено
ci/acceptance_db.pyЖива PostgreSQL 18.6 + PostGIS 3.625 із 25 пройдено

Geplante Frontend-Änderungen

Der nächste Schritt, sobald ein echtes Backend existiert - in dieser Demo nicht angewendet:

  • LISTINGS перестає бути літералом і стає результатом GET /api/v1/listings; loadExternalListings() і LISTINGS_FEED замінюються курсорною пагінацією
  • getUsers(), setUsers(), saveUser() видаляються. localStorage лишається лише для мови, вибраного виду транспорту та інших втрачуваних станів UI
  • Форма модального вікна отримує третій режим — публікацію заявки
  • Помилки показуються з problem+json, поле в помилці підсвічується за JSON Pointer
  • Перемикач API_BASE: за відсутності бекенду сайт чесно повідомляє про це, як уже роблять вкладки погоди й кордонів

CI-Gates: erforderliche Prüfungen

Zwölf erforderliche Prüfungen aus drei Pipelines; jede Pipeline hat einen eigenen Gate-Job, der fehlschlägt, wenn ein Job, von dem er abhängt, fehlschlägt.

Pipeline Job Prüfung im Regelwerk
.github/workflows/contract.yml schema Схема і сценарії T16-T27
i18n Валютні та мовні сценарії C1-C13, L1-L12
proto Контракт proto модуля SEARCH
ui UI-сценарії U1-U8 вибору виду транспорту
contract-gate contract-gate
.github/workflows/backend.yml backend-contract Контракт бекенду Спринту 0
backend-db Приймальні тести БД Спринту 0
verification-contract Контракт модуля верифікації
verification-db Інваріанти верифікації
backend-gate backend-gate
.github/workflows/web3.yml web3-tests web3-sprint0-tests
blockchain-gate blockchain-gate

Dies ist eine angewendete Konfiguration, kein Entwurf: Das Regelwerk des main-Branches verlangt alle zwölf in der Tabelle oben genannten Prüfungen, und `.github/workflows/` enthält drei erforderliche Pipelines - `contract.yml`, `backend.yml` und `web3.yml` - sowie das nicht blockierende `source-probe.yml`. Die von der Backend-Pipeline aufgerufenen `sprint-0-backend/ci/*`-Skripte liegen im Repository und laufen gegen eine echte PostgreSQL mit PostGIS: Im Lauf auf main gingen Migration, Registerbefüllung, der Import von 10773 Angeboten und die negativen Invariantentests durch - insgesamt 42 Prüfungen auf einer echten Datenbank. `ci/check_live_ruleset.py` vergleicht die Regelwerksdatei mit dem Live-GitHub und meldet auf dem aktuellen main Übereinstimmung: 12 Prüfungen in der Datei, 12 auf GitHub. Der Konsistenzprüfer `ci/check_ruleset.py` läuft ebenfalls: 14 Regeln, 35 von 35 Mutationen erkannt. Was weiterhin nicht angewendet ist: Diese Seite selbst bleibt eine einzelne Datei ohne Backend - die Pipelines prüfen Verträge und die Datenbank, sie bedienen index.html nicht.

Modelldateien