Commit graph

2 commits

Author SHA1 Message Date
nns 76e956ea6c feat(platform): IEmailSender + MailKit + PlatformSettingsController
Пункт 2 + 3 пакета SMTP-настроек.

Backend:
- IEmailSender (Application/Common/Email) — общий интерфейс отправки
  одного письма; EmailNotConfiguredException — для контроллеров чтобы
  ловить и отдавать понятный 400 вместо 500.
- MailKitEmailSender (Infrastructure/Email) — реализация:
  · регистрируется Singleton, на каждой отправке открывает scope для
    свежего AppDbContext (конфиг перечитывается без рестарта);
  · читает PlatformSettings из БД, расшифровывает пароль через
    IDataProtector("foodmarket.smtp");
  · поддержка SmtpUseSsl (implicit TLS / 465) и SmtpStartTls (587);
    оба false → открытое соединение (для dev/MailHog);
  · бросает EmailNotConfiguredException если host или from-email пусты,
    или если расшифровка пароля падает (ключ DataProtection ротировался).

API:
- PlatformSettingsController:
  GET /api/super-admin/platform-settings — все поля КРОМЕ пароля
    (только has-password флаг + updatedAt).
  PUT — принимает Reason (≥10) + все поля + опциональный
    NewSmtpPassword. Спец-значение "__clear__" снимает пароль.
    Пароль шифруется через DataProtection при записи. Audit-log.
  POST /test-send — реальная отправка через текущие настройки;
    ловит EmailNotConfiguredException → 400, остальные → 500
    с message (SuperAdmin-only, diagnostic-info нужна).

DI:
- AddSingleton<IEmailSender, MailKitEmailSender>;
- AddDataProtection (default file-system key store ASP.NET Core).

Пакеты:
- MailKit 4.10.0 (4.8 имел moderate-severity advisory).
- Microsoft.AspNetCore.DataProtection 8.0.11 (transitive в API уже
  был через OpenIddict, но Infrastructure нужен явный reference).
2026-05-06 12:39:18 +05:00
nns fd2f5ae4f3 Phase 0: project scaffolding and end-to-end auth
- .NET 8 LTS solution with 7 projects (domain/application/infrastructure/api/shared/pos.core/pos[WPF])
- Central package management (Directory.Packages.props), .editorconfig, global.json pin to 8.0.417
- PostgreSQL 14 dev DB via existing brew service; food_market database created
- ASP.NET Identity + OpenIddict 5 (password + refresh token flows) with ephemeral dev keys
- EF Core 8 + Npgsql; multi-tenant query filter via reflection over ITenantEntity
- Initial migration: 13 tables (Identity + OpenIddict + organizations)
- AuthorizationController implements /connect/token; seeders create demo org + admin
- Protected /api/me endpoint returns current user + org claims
- React 19 + Vite 8 + Tailwind v4 SPA with TanStack Query, React Router 7
- Login flow with dev-admin placeholder, bearer interceptor + refresh token fallback
- docs/architecture.md, CLAUDE.md, README.md

Verified end-to-end: health check, password grant issues JWT with org_id,
web app builds successfully (310 kB gzipped).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 13:59:13 +05:00