platform-boundaries

Межі Family Platform

Коротке рішення про поділ сервісів, доступ до спільних колекцій та передачу даних.

Реалізація

ЧастинаРепозиторійЗадачаМасштабування
00Contracts packagecontracts / @it-monkeys/contractsFrontend-safe interfaces, DTO, schemas та HTTP/RMQ contracts без backend-залежностейPackage, не deployable service
01Backend common packagebackend-common / @it-monkeys/backend-commonAuth middleware, RMQ, errors, logging, Mongo schemas і repositories без бізнес-модулівPackage, не deployable service
02StackstackЯк і зараз: login, users, roles і власні внутрішні модуліПоки без змін
03Family Application APIfamily-application-apiОдне HTTP API для нашого frontend та Electron; спільні серверні бізнес-модуліStateless, кілька instances у cluster
04Electronstack-electronУніверсальний workspace оператораОдна desktop-програма на operator
05Electron Runtime / Gatewaystack-electron-gatewayПідключення Electron, socket sessions і передача команд та подійStateful process; спочатку один instance
06Family-сервісинові family-*Partner API clients, session/auth, типізовані Family responses та справді специфічні operations/workersКожна Family масштабується окремо

stack-commons залишається legacy package на час міграції. Нові contracts та backend primitives туди не додаємо; після переходу всіх споживачів package архівується.

Frontend і Electron routes лежать в одному family-application-api, бо мають однаковий stateless runtime та спільні бізнес-модулі. stack-electron-gateway залишається окремим через довгі socket-з’єднання і state операторів.

family-application-api обслуговує наш frontend та Electron. Поточний prototype electron-api у stack-electron-gateway переноситься сюди; у Gateway залишається socket runtime.

HTTP

RouteСервісДоступ
Поточні routesstack і legacy Family-сервісиЯк зараз
/v2/*family-application-apiНаш frontend та Electron
Без публічного routefamily-*RMQ та внутрішня Docker network

JSON API зберігає HTTP 200. Реальний результат передається в body через code:

{ "success": true, "code": 200, "data": {} }
{ "success": false, "code": 401, "data": null, "message": "Invalid or expired token" }

Stack залишається issuer токенів. family-application-api перевіряє чинний Bearer JWT тим самим secret і записує payload у request.user. Family-сервіси Stack token secret не отримують.

Схема

Сервіси та RMQ

flowchart LR
    Front["Наш frontend"] --> Stack["stack<br/>auth · users · roles"]
    Front --> PlatformAPI["family-application-api cluster<br/>frontend · Electron API"]
    Electron["Electron"] --> Gateway["Electron Gateway<br/>connect · socket sessions"]
    Electron --> PlatformAPI

    Stack <--> RMQ{{"RMQ<br/>команди · події"}}
    PlatformAPI <--> RMQ
    Gateway <--> RMQ

    RMQ <--> Families["Нові Family-сервіси<br/>Golden · Prime · Chathouse · Udate"]
    Families -->|"HTTP / GraphQL"| Partners["Партнерські API<br/>Golden · Prime · Chathouse · Udate"]

Великі дані для фронту

flowchart LR
    Partners["Партнерські API"] -->|"raw data"| Families["Family-сервіси"]
    Families -->|"типізований Family response"| PlatformAPI["family-application-api"]
    PlatformAPI -->|"canonical adapter + business flow"| Storage[("Mongo / ClickHouse")]
    Storage -->|"repository read"| PlatformAPI
    PlatformAPI --> Front["Наш frontend"]

RMQ є каналом керування: запустити sync, виконати коротку дію або повідомити про зміну. Mongo і ClickHouse є каналом даних. У поточному Admin/TU vertical slice Family-сервіс не пише TU: він парсить partner response, family-application-api нормалізує його та виконує canonical business flow. Для майбутніх workers writer визначається окремо для кожної collection.

Колекції

  • Спільні schemas, indexes і repositories описуються один раз у @it-monkeys/backend-common.
  • Сервіси можуть напряму читати спільну БД через repository.
  • Для кожної колекції окремо фіксуємо writer-ів, reader-ів і Family scope.
  • Спочатку scope контролює repository; окремі Mongo users/roles можна додати пізніше.
  • Перенесення колекції або БД змінює repository/config, а не бізнес-логіку споживачів.
  • Під час міграції legacy-сервіс читає canonical schema тільки через один compatibility repository; старий Mongoose model не направляємо на нову collection.
  • Owner визначається для capability/поля. Два сервіси не виконують одну partner mutation або зміну одного assignment паралельно.
  • Завершена capability не має постійного dual-write у legacy і canonical collections.

Обмін даними

КаналДля чого
Mongo / ClickHouseCanonical data, великі вибірки й агрегати
RMQКоманди та події з невеликим payload
RedisPartner sessions, online, locks і cache

Великі списки не повертаємо через RMQ: Family-сервіс записує нормалізовані дані у спільну collection, а споживач читає їх напряму.