Files
Deal/.superpowers/sdd/deal-scaffold/task-7-report.md
T
Rustam Khalimov 27c7831910
ci / build-test (push) Canceled after 0s
Deal — единая кодовая база
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 зелёные.
2026-09-11 23:56:47 +03:00

92 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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)`, `Name` max 200 / required.
- `src/core/Deal.Infrastructure/Persistence/DealDbDesignTimeFactory.cs``IDesignTimeDbContextFactory<DealDbContext>`; строка из env `DEAL_PG_CONNECTION`, fallback `Host=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.Design` 10.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.EntityFrameworkCore` **10.0.11**
- `Microsoft.EntityFrameworkCore.Design` **10.0.11** (PrivateAssets=all, добавлен `dotnet add` автоматически)
- `Microsoft.EntityFrameworkCore.Relational` **10.0.11** (см. Concern 1 — добавлен сверх списка плана)
- `Npgsql.EntityFrameworkCore.PostgreSQL` **10.0.3**
- (ранее, Task 6) `Microsoft.Extensions.Configuration.Abstractions` 10.0.11
Deal.Api:
- `Microsoft.EntityFrameworkCore.Design` **10.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 / заметки
1. **`Microsoft.EntityFrameworkCore.Relational` 10.0.11 добавлен явно (сверх 3 пакетов плана).** Причина: пакет `Microsoft.EntityFrameworkCore` 10.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`. Явная ссылка `Relational` 10.0.11 в Infrastructure (транзитивно утекает в Api) выравнивает все EF-сборки на 10.0.11. MSB3277 — MSBuild-warning (не C#), поэтому TreatWarningsAsErrors его не превращал в error, но требование «0 warnings» нарушалось.
2. **`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).
3. **Тест скорректирован (единственное отступление от 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-строке недостижимо.
4. `appsettings.Development.json` уже существовал (Logging-блок); `ConnectionStrings` добавлены merge-правкой — стандартный шаблонный блок сохранён.
5. `.editorconfig`/`Directory.Build.props` не редактировались. Генерённые миграционные файлы (`.Designer.cs`, Snapshot) предупреждений при сборке не дают.
6. Проект не является git-репозиторием: коммиты/ветки не создавались (как и во всех предыдущих задачах).