ci / build-test (push) Canceled after 0s
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 зелёные.
8.7 KiB
8.7 KiB
Task 7 — EF Core + миграции (public) (отчёт)
Дата: 2026-09-05
Статус: ✅ Выполнено (build 0 warnings / 0 errors; 4 теста PASS; миграция InitialPublic применена к public)
Файлы
Созданы (по коду плана, verbatim)
src/core/Deal.Infrastructure/Persistence/Entities/TenantEntity.cs—TenantEntity(Guid Id,Name = string.Empty,Status = "active",CreatedAt).src/core/Deal.Infrastructure/Persistence/DealDbContext.cs—DealDbContext+DbSet<TenantEntity> Tenants; вOnModelCreating:ToTable("tenants", "public"),HasKey(Id),Namemax 200 / required.src/core/Deal.Infrastructure/Persistence/DealDbDesignTimeFactory.cs—IDesignTimeDbContextFactory<DealDbContext>; строка из envDEAL_PG_CONNECTION, fallbackHost=localhost;Port=5433;Database=deal;Username=deal;Password=deal_dev_password(рабочий dev-Postgres Task 5).src/core/Deal.Infrastructure/Migrations/20260905190044_InitialPublic.cs+.Designer.cs+DealDbContextModelSnapshot.cs— сгенерированыdotnet ef migrations add InitialPublic.tests/Deal.Tests.Unit/TenantEntityTests.cs— тест дефолтов (см. Concern 3: строкаAssert.NotEqualиз плана скорректирована).
Изменены
src/core/Deal.Infrastructure/Deal.Infrastructure.csproj— добавлены пакеты (см. ниже).src/core/Deal.Api/Deal.Api.csproj— добавленMicrosoft.EntityFrameworkCore.Design10.0.11 сPrivateAssets=all(см. Concern 2).src/core/Deal.Api/Program.cs— добавленыusing Deal.Infrastructure.Persistence;иusing Microsoft.EntityFrameworkCore;; послеCreateBuilderдобавленыGetConnectionString("DealPostgres")с тем же fallback иbuilder.Services.AddDbContext<DealDbContext>(options => options.UseNpgsql(connectionString));. Существующие 2 singleton-регистрации,/api/healthиpublic partial class Programне тронуты.src/core/Deal.Api/appsettings.Development.json— файл уже существовал (стандартныйLoggingот шаблона); блокConnectionStrings:DealPostgresдобавлен к существующему содержимому (merge, а не замена).tests/Deal.Tests.Unit/Deal.Tests.Unit.csproj— добавлен ProjectReference наDeal.Infrastructure(Ruling 3, командойdotnet add).
Пакеты NuGet (версии, resolved latest stable для net10.0)
Deal.Infrastructure:
Microsoft.EntityFrameworkCore10.0.11Microsoft.EntityFrameworkCore.Design10.0.11 (PrivateAssets=all, добавленdotnet addавтоматически)Microsoft.EntityFrameworkCore.Relational10.0.11 (см. Concern 1 — добавлен сверх списка плана)Npgsql.EntityFrameworkCore.PostgreSQL10.0.3- (ранее, Task 6)
Microsoft.Extensions.Configuration.Abstractions10.0.11
Deal.Api:
Microsoft.EntityFrameworkCore.Design10.0.11 (PrivateAssets=all; см. Concern 2)
dotnet-ef: локальный tool
Глобально dotnet-ef не установлен (dotnet tool list --global: только dotnet-dump, ilspycmd). По Ruling 5 создан локальный манифест:
dotnet new tool-manifest→ SDK 10 создал манифест вsrc/core/dotnet-tools.json(не в.config/, как в документации SDK 8/9).dotnet tool install dotnet-ef→ dotnet-ef 10.0.11, запись добавлена вsrc/core/dotnet-tools.json(isRoot: true). Никакой манифест «выше» не найден —dotnet new tool-manifestсообщений о существующем не выдавал.
Миграция и БД
Команды (из src/core, локальный tool):
dotnet ef migrations add InitialPublic --project Deal.Infrastructure --startup-project Deal.Api
Build started... Build succeeded. Done.
dotnet ef database update --project Deal.Infrastructure --startup-project Deal.Api
Applying migration '20260905190044_InitialPublic'. Done.
Проверка (docker exec deal-postgres psql -U deal -d deal -c "\dt public.*"):
Schema | Name | Type | Owner
--------+-----------------------+-------+-------
public | __EFMigrationsHistory | table | deal
public | tenants | table | deal
(2 rows)
Дизайн-тайм фабрика использовала fallback-строку (env DEAL_PG_CONNECTION не задан).
Build
Команда: dotnet build Deal.sln (из src/core)
Deal.SharedKernel net10.0 успешно выполнено
...
Deal.Api net10.0 успешно выполнено (0,4 с)
Сборка успешно выполнено через 2,3 с
Результат: 0 warnings, 0 errors (11 проектов).
Tests
Команда: dotnet test tests/Deal.Tests.Unit
Сводка теста: всего: 4; сбой: 0; успешно: 4; пропущено: 0; длительность: 1,0 с
PASS: MarkerTests (1) + TenantIdTests (2) + TenantEntityTests (1) = ровно 4.
Concerns / заметки
Microsoft.EntityFrameworkCore.Relational10.0.11 добавлен явно (сверх 3 пакетов плана). Причина: пакетMicrosoft.EntityFrameworkCore10.0.11 НЕ зависит от Relational (его nuspec тянет только Abstractions/Analyzers/Caching.Memory/Logging). Единственным источником Relational в графеDeal.Apiоказывается Npgsql.EntityFrameworkCore.PostgreSQL 10.0.3 с диапазоном[10.0.4, 11.0.0); NuGet выбирает минимальную версию диапазона → Relational 10.0.4, тогда какDeal.Infrastructureсобирается против 10.0.11 (через Design 10.0.11 с PrivateAssets=all — виден только в собственном графе). Итог: MSB3277 (конфликт версий Relational) в сборкеDeal.Api. Явная ссылкаRelational10.0.11 в Infrastructure (транзитивно утекает в Api) выравнивает все EF-сборки на 10.0.11. MSB3277 — MSBuild-warning (не C#), поэтому TreatWarningsAsErrors его не превращал в error, но требование «0 warnings» нарушалось.Microsoft.EntityFrameworkCore.Designдобавлен вDeal.Api(PrivateAssets=all).dotnet efтребует Design-пакет в startup-проекте:Your startup project 'Deal.Api' doesn't reference Microsoft.EntityFrameworkCore.Design.... Ссылка в Infrastructure имеетPrivateAssets=allи в Api не утекает, поэтому первая попыткаmigrations addупала с этой ошибкой. После добавления в Api миграция создалась штатно (дизайн-тайм фабрика при этом по-прежнему из Infrastructure).- Тест скорректирован (единственное отступление от verbatim-кода плана). Строка плана
Assert.NotEqual(Guid.Empty, entity.Id == Guid.Empty ? Guid.Empty : entity.Id);невыполнима:TenantEntity.Id— автосвойствоGuidбез инициализатора → всегдаGuid.Empty, тернарник всегда возвращаетGuid.Empty, иNotEqual(Guid.Empty, Guid.Empty)падает (проверено: 1 FAIL на verbatim-версии). План под кодом сам разрешает правку: «тест проверяет дефолты; при необходимости скорректировать под реальную модель». Строка заменена на проверки реальных дефолтов:Status == "active",Name == string.Empty,CreatedAt == default(DateTimeOffset). Ожидание Task 13 (4 PASS) при verbatim-строке недостижимо. appsettings.Development.jsonуже существовал (Logging-блок);ConnectionStringsдобавлены merge-правкой — стандартный шаблонный блок сохранён..editorconfig/Directory.Build.propsне редактировались. Генерённые миграционные файлы (.Designer.cs, Snapshot) предупреждений при сборке не дают.- Проект не является git-репозиторием: коммиты/ветки не создавались (как и во всех предыдущих задачах).