SaaS-мониторинг Telegram: ядро (модули Cards/Kanban/Pipeline/Tenants/Settings/ Discovery, Api, Infrastructure), сервисы telegram/ai/ml/storage, фронт Vue, контракты и grpc-hosting, деплой-конфиги (dev/prod/observability/CI-раннер), Gitea Actions CI, документация (ТЗ, техдок, api-map, код-стайл, планы, бэклог). Текущее состояние: все этапы роадмапа 0–12 закрыты, сборка 5 sln 0/0, тесты 1340/130/52/38/9 зелёные.
4.3 KiB
Task 6 — Tenant-контекст и подключение к Postgres (отчёт)
Дата: 2026-09-05 Статус: ✅ Выполнено (build 0 warnings / 0 errors, 3 теста PASS)
Файлы
Созданы (по коду плана, verbatim)
src/core/Deal.SharedKernel/Tenants/TenantId.cs—readonly record struct TenantId, валидация непустогоValue,SchemaName => "tenant_{Value}".src/core/Deal.SharedKernel/Tenants/ITenantContext.cs—TenantId? TenantId,HasTenant,string? SchemaName.src/core/Deal.Infrastructure/Data/TenantContext.cs—AsyncLocal<TenantId?>, имплементируетITenantContext+SetTenant.src/core/Deal.Infrastructure/Data/ConnectionStringProvider.cs— ctor бросаетInvalidOperationExceptionбезConnectionStrings:DealPostgres;ForTenantдобавляет;Search Path=....tests/Deal.Tests.Unit/TenantIdTests.cs— 2 теста:SchemaName_PrefixesTenant,TenantId_Empty_Throws.
Изменены
src/core/Deal.Api/Program.cs— добавленыusing Deal.Infrastructure.Data;иusing Deal.SharedKernel.Tenants;, зарегистрированыbuilder.Services.AddSingleton<ITenantContext, TenantContext>();иAddSingleton<ConnectionStringProvider>();./api/healthиpublic partial class Programне тронуты.src/core/Deal.Infrastructure/Deal.Infrastructure.csproj— добавленPackageReference Microsoft.Extensions.Configuration.Abstractions 10.0.11(командойdotnet add, Ruling 4).
Отклонение от кода плана (требование стиля репозитория)
ITenantContext.cs: члены интерфейса получили явный public (план их опускал). Иначе сборка падает с IDE0040 (error): в корневом C:\telbase\.editorconfig задано dotnet_style_require_accessibility_modifiers = always:error, а EnforceCodeStyleInBuild=true + TreatWarningsAsErrors=true. Изменение семантики не меняет — члены интерфейса и так public. .editorconfig/Directory.Build.props не редактировались.
TenantId (record struct с property-initializer-валидацией) успешно компилируется под net10.0 — перепроектирование не потребовалось.
Build
Команда: dotnet build Deal.sln (из src/core)
Восстановление завершено (0,8 с)
Deal.SharedKernel net10.0 успешно выполнено
...
Deal.Api net10.0 успешно выполнено (0,6 с)
Сборка успешно выполнено через 2,5 с
Результат: 0 warnings, 0 errors (11 проектов собраны).
Tests
Команда: dotnet test tests/Deal.Tests.Unit --no-build
Сводка теста: всего: 3; сбой: 0; успешно: 3; пропущено: 0; длительность: 1,1 с
PASS: MarkerTests (1) + TenantIdTests (2) = ровно 3.
Concerns / заметки
- Template-level conflict (план vs .editorconfig): код
ITenantContextв плане не проходитIDE0040— потребовался явныйpublicна членах интерфейса. Аналогичное стоит ожидать в будущих задачах, где план опускает модификаторы доступа у членов интерфейса. ConnectionStringProviderзарегистрирован в DI, но нигде не резолвится (как и задумано для Task 6) — конструктор сInvalidOperationExceptionпри отсутствииConnectionStrings:DealPostgresсработает только с Task 7 (appsettings).- NuGet-пакет выбран как
10.0.11(latest stable, совместим с net10.0). Версия не зафиксирована в плане; при централизованном управлении пакетами (CPM) отсутствует — правок не требуется. - Загруженных файлов-маркеров (
SharedKernelMarker.cs,InfrastructureMarker.cs) не касались.