1631786ce2
Add push contracts, provider delivery and channel diagnostics. Link email channels to services and document migration and validation. Ref: IT-1074
80 lines
4.9 KiB
Markdown
80 lines
4.9 KiB
Markdown
# Email channels: stable service association
|
|
|
|
Email channels reference `services.id` (UUID) through required `email_channels.service_id`.
|
|
The `(service_id, priority)` index supports channel selection; the service FK uses RESTRICT,
|
|
so service deletion cannot remove channels or their usage. Service names in channel reads
|
|
come from the related service, not a copied string. Create/Edit select an existing service;
|
|
Edit can reassign a channel without changing its identity or statistics.
|
|
|
|
## Migration
|
|
|
|
`LinkEmailChannelsToServices` validates every legacy channel name before replacing the
|
|
string column. An exact, case-sensitive service-name match is accepted. The owner-approved
|
|
legacy mapping `StoreMate-Prod` → `Invemory-Prod` is also accepted; the existing staging
|
|
name `Invemory.Staging.Sandbox` uses an exact match. Every channel must have exactly one
|
|
candidate service. Missing names or ambiguity (for example both legacy and renamed
|
|
services existing) abort the migration. No service is guessed, created, renamed or deleted.
|
|
|
|
The migration runs in an EF transaction and locks services/channels while checking and
|
|
backfilling. Failure rolls back schema and data. Channel IDs, SMTP settings (including
|
|
secrets and sender settings), priority, quotas, warning threshold, active state, timestamps
|
|
and usage records remain unchanged. No SMTP settings are logged by the migration.
|
|
Downgrade reconstructs the current service names; historical names are not restored.
|
|
|
|
Before a separately authorized rollout, audit unmatched/ambiguous names and resolve them
|
|
with the owner, take the normal backup, and coordinate Web/Worker downtime with migration:
|
|
old binaries use the removed `service_name` column. Administrative POST/PUT clients must
|
|
send `serviceId`; name-only writes are no longer supported. RabbitMQ producers retain
|
|
their existing `ServiceName` wire field and must send the current service name. The
|
|
approved legacy mapping applies only during migration, never as a runtime fallback.
|
|
|
|
## Verification
|
|
|
|
### Local database update on Windows
|
|
|
|
Run from any directory, without arguments or environment setup:
|
|
|
|
```bat
|
|
C:\projects\HrynCo\hrynco-notification-service\HrynCo.NotificationService.DAL.EF\update-development-database.bat
|
|
```
|
|
|
|
The script resolves its directory through %~dp0, reads the existing Web
|
|
`appsettings.Development.json`, builds the EF project in Release and applies pending
|
|
migrations. It requires dotnet-ef and Windows PowerShell. It validates a loopback host and a nonempty database name before invoking EF.
|
|
The port and database come from the Development configuration without hardcoded overrides.
|
|
A remote host is rejected; this script is specifically for the local development database. It never installs, recreates or restarts containers.
|
|
|
|
The connection is passed only through the child process's `App__ConnectionString`;
|
|
the design-time factory reads it. Credentials are neither echoed nor passed as CLI
|
|
arguments, and inherited connection overrides are replaced with the verified Development
|
|
configuration. The script returns EF's exit code (or a nonzero code for configuration
|
|
failure). Restart local Web/Worker after a schema change to use matching binaries.
|
|
|
|
### Tests
|
|
|
|
PostgreSQL integration tests exercise exact and approved-alias backfill, preserved channel
|
|
settings/limits/usage, downgrade, missing/ambiguous-name rollback, FK enforcement, service
|
|
rename, API validation, editable reassignment with a blank password, and service deletion
|
|
after reassignment. Worker tests verify name-to-ID channel resolution and sending/usage.
|
|
All migration rehearsals use disposable local databases; they do not alter production.
|
|
|
|
On 2026-10-24, the Release solution build, 54 service/worker tests and 145 integration
|
|
tests passed. A follow-up check explicitly verified both invalid update IDs reach the
|
|
service-existence validator (2/2 passed). Rider inspected the changed production methods;
|
|
remaining findings were existing/style suggestions. Cognitive complexity was reviewed
|
|
structurally against the limit of 10; no numeric score was produced by the inspection.
|
|
|
|
After separate owner authorization, the existing local container database was backed up
|
|
and updated with the already-built Migrator. Its two pending migrations were
|
|
`20261023223753_AddPushDeliveries` and `20261024073202_LinkEmailChannelsToServices`.
|
|
No email channels or usage records existed in this local database before the update;
|
|
their unchanged empty state and the installed RESTRICT FK were verified afterwards.
|
|
The development batch script was then executed from its own folder and another working
|
|
directory: both returned 0 and reported no pending migrations. An isolated fake EF
|
|
failure verified exit-code propagation (37). The current local Web at port 5188 rendered
|
|
the dropdown with the existing service catalog. Disposable test containers were removed.
|
|
Production was not accessed or migrated.
|
|
|
|
The existing private-network administration access model is unchanged. This change does
|
|
not configure Firebase or resume the paused push-channel architecture.
|