- Use AsNoTracking() on all EmailChannelRepository read methods to prevent
EF identity conflict when Update() attaches a new entity with same key
- Move test modal to @section Scripts rendered at end of <body> so
bootstrap.Modal is available and modal is not nested inside card DOM
- Add @RenderSection('Scripts') forwarding in _EditorLayout to bubble
child scripts sections up to _Layout
- Switch Test button to programmatic bootstrap.Modal() open instead of
data-bs-toggle (more reliable across layout section boundaries)
Ref: IT-628
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Rename Template -> EmailTemplate, Provider -> EmailChannel,
ProviderSettings -> EmailChannelSettings, ProviderType -> EmailChannelType,
ProviderUsage -> EmailChannelUsage throughout all layers
- Add Undefined = 0 to EmailChannelType enum for safe default handling
- Remove SaveChangesAsync from EfRepository methods — repositories now only stage changes
- Add SaveChangesAsync to IUnitOfWork and EfUnitOfWork
- Add TransactionBehavior MediatR pipeline: wraps every handler in a transaction,
saves and commits on success, rolls back on exception
- Add MediatR package reference to Services project
Ref: IT-628
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Directory.Packages.props and Directory.Build.props for central package management
- TemplateEntity, ProviderEntity, ProviderUsageEntity (internal to DAL.EF)
- TemplateEntityConfiguration: composite unique index (service_name, key, language_code), Variables as JSON column
- ProviderEntityConfiguration: settings stored as jsonb, index on (service_name, priority)
- ProviderUsageEntityConfiguration: composite unique index (provider_id, date)
- All entities map Id column explicitly as 'id' (snake_case)
- NotificationDbContext with ApplyConfigurationsFromAssembly
Ref: IT-628
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>