Перевести входящий поток источников на generic-контракт

Добавлен sources.proto с PushSource; приём в ядре вынесен в SourceIngressGrpcService с SourceProtoMapper и ISourceIngestObserver, тенант определяется IngressTenantResolver. Из telegram.proto удалён PushMessage, telegram-сервис шлёт generic-записи, превью сохраняет TelegramSourceIngestObserver.
This commit is contained in:
Rustam Khalimov
2026-09-11 16:32:49 +03:00
parent 3327bf48b0
commit 6d074834a7
39 changed files with 1312 additions and 532 deletions
+4 -2
View File
@@ -8,8 +8,10 @@
> `SourceItem` (`SourceRef` + `SourceContent`, вложения — `DataRef` → общий Storage). Дашборды/канбан/конвейер
> больше не знают о Telegram; Telegram-специфика — только в тонком адаптере приёма. Tenant-миграции
> пересозданы с нуля (init). Добавлены extension-point `ISourceContentProvider`/`SourceContentResolver` и
> `GET /api/cards/{id}/source`. Ядро: build 4 sln 0/0, `Deal.Tests.Unit` **1280/1280 PASS**, фронт `build` +
> `lint:i18n` зелёные. Детали — `docs/superpowers/specs/2026-09-11-source-contract-design.md`.
> `GET /api/cards/{id}/source`. Входящий поток источников — generic (`sources.proto`/`PushSource`,
> `SourceIngressGrpcService`), `PushMessage` из telegram.proto удалён. Ядро: build 5 sln 0/0,
> `Deal.Tests.Unit` **1289/1289 PASS**, telegram **125/125**, фронт `build` + `lint:i18n` зелёные.
> Детали — `docs/superpowers/specs/2026-09-11-source-contract-design.md`.
> Осталось (в backlog): `GET /api/cards/{id}/source` + `ISourceContentProvider`, выгрузка вложений
> telegram-адаптером в Storage, `TelegramSourceContentProvider`, перенос оставшейся Telegram-специфики
> (`TelegramStore`, `Dialogs`/`TgMessages`, Discovery) в telegram-сервис.
@@ -165,7 +165,19 @@ API ядра: `GET /api/cards/{id}/source` → generic контент.
### Маппинг источника
- Адаптер Telegram (в ядре — тонкий край приёма): `Kind="telegram"`, `ExternalId=MsgId`,
- Telegram-адаптер (в ядре — тонкий край приёма): `Kind="telegram"`, `ExternalId=MsgId`,
`OriginRef=DialogId`, `DisplayName=ChannelName`, `Extra["hue"]=ChannelHue` (иначе дефолт),
`ReceivedAt=msgAt`, `Content.Text=Text`, `Content.Author=ChannelName`.
- Дашборды/карточки/конвейер работают только с `SourceRef`/`SourceContent`; Telegram-поля не проходят дальше адаптера.
### Входящий поток (generic, 2026-09-11)
- `src/contracts/sources.proto` → сервис `SourceIngressService.PushSource` с generic-типами
`SourceRefProto`/`SourceContentProto`/`DataRefProto`/`ContactRefProto`; вложения — ссылки на Storage.
- Ядро: `Deal.Api/Sources/SourceIngressGrpcService` (приём) + `SourceProtoMapper` (proto → домен) +
`ISourceIngestObserver` (вторичная обработка принятой записи, сбой наблюдателя не влияет на приём) +
`IngressTenantResolver` (тенант по metadata).
- Из `telegram.proto` удалён `IngressService.PushMessage` (остались `SyncDialogs`/`ReportStatus`);
telegram-сервис шлёт записи через `PushSource` (`kind="telegram"`). Превью каталога/TgMessages сохраняет
`TelegramSourceIngestObserver` (ядро, telegram-модуль — единственное место с telegram-спецификой приёма).
- Любой другой источник (whatsapp/avito/файл/excel) шлёт тот же `PushSource` со своим `source.kind`.