docs(code-review): record SMS-feature review findings + reconcile NotificationService doc
Per-module code review of the SMS notifications feature (reviewed at d6ead8ae) following
code-reviews/REVIEW-PROCESS.md. 19 findings across 7 modules — 1 High, 5 Medium, 13 Low:
- ManagementService-024 (High): provider-config updates Admin-gated to match the UI.
- ConfigurationDatabase-025, CentralUI-034/035, ManagementService-025 (Medium): migration
data-safety guard, type-aware recipient badge, FromNumber-optional (Messaging-Service-only),
empty-token-clear guard.
- Remaining Low: secret-encryption + diff + dispatch + factory + contract tests, truncation,
ctor guard, reserved retry-field docs.
- Won't Fix: Transport-015/016 (shared repo-wide import patterns, not SMS-specific),
Commons-026 (breaking ergonomics-only change). Deferred: ConfigurationDatabase-027 (live-SQL
migration test).
All findings closed (0 pending). README.md regenerated; Component-NotificationService.md
updated for the FromNumber-optional + reserved-retry-fields outcomes.
This commit is contained in:
@@ -5,9 +5,9 @@
|
||||
| Module | `src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase` |
|
||||
| Design doc | `docs/requirements/Component-ConfigurationDatabase.md` |
|
||||
| Status | Reviewed |
|
||||
| Last reviewed | 2026-05-28 |
|
||||
| Last reviewed | 2026-06-19 |
|
||||
| Reviewer | claude-agent |
|
||||
| Commit reviewed | `1eb6e97` |
|
||||
| Commit reviewed | `d6ead8ae` |
|
||||
| Open findings | 0 |
|
||||
|
||||
## Summary
|
||||
@@ -1373,3 +1373,91 @@ later months. This pins down the resolution of CD-019. (2) Add a
|
||||
`DeploymentRecord`, clear the change tracker, call `DeleteDeploymentRecordAsync`,
|
||||
and assert the row is gone — pinning the resolution of CD-018. Both tests should be
|
||||
`[SkippableFact]` so the suite still passes when no MS SQL Server is available.
|
||||
|
||||
#### Re-review 2026-06-19 (commit `d6ead8ae`) — SMS notifications feature
|
||||
|
||||
Per-module review of the SMS (Twilio) notifications data layer: the `SmsConfiguration` EF mapping +
|
||||
encrypted `AuthToken`, the `AddSmsNotifications` migration, and the `NotificationRecipient` nullable
|
||||
contact change. The encryption wiring (`EncryptedStringConverter` on `AuthToken` via
|
||||
`ApplySecretColumnEncryption` + `GuardSecretWritesHaveAKeyRing`) mirrors `SmtpConfiguration.Credentials`
|
||||
and is correct. Two Medium findings (one data-safety, one test gap) and one Low test gap; the two
|
||||
Mediums are Resolved.
|
||||
|
||||
### ConfigurationDatabase-025 — `AddSmsNotifications.Down()` silently corrupts SMS-only recipients
|
||||
|
||||
| | |
|
||||
|--|--|
|
||||
| Severity | Medium |
|
||||
| Category | Correctness & logic bugs |
|
||||
| Status | Resolved |
|
||||
| Location | `src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/Migrations/20260619135543_AddSmsNotifications.cs:52-66` |
|
||||
|
||||
**Description**
|
||||
|
||||
The `Down()` migration drops the `PhoneNumber` column and backfills every NULL `EmailAddress` to `''`
|
||||
so the column can revert to NOT NULL. An SMS-only recipient (PhoneNumber set, EmailAddress
|
||||
legitimately NULL) is therefore corrupted on rollback: its phone is dropped and its email becomes an
|
||||
invalid empty string. In a database where SMS lists have been created, the rollback destroys contact data.
|
||||
|
||||
**Recommendation**
|
||||
|
||||
Before dropping `PhoneNumber`, guard the rollback: throw if any SMS-only recipient (PhoneNumber set,
|
||||
EmailAddress NULL) exists, so the operator must reassign/remove them first instead of losing data silently.
|
||||
|
||||
**Resolution**
|
||||
|
||||
Resolved 2026-06-19 (commit `cd8e4872`): `Down()` now runs a `THROW`-on-`IF EXISTS` guard for
|
||||
SMS-only recipients as its first statement (while `PhoneNumber` is still queryable), refusing the
|
||||
rollback instead of corrupting data. Comments document the invariant.
|
||||
|
||||
### ConfigurationDatabase-026 — No encryption-at-rest regression test for `SmsConfiguration.AuthToken`
|
||||
|
||||
| | |
|
||||
|--|--|
|
||||
| Severity | Medium |
|
||||
| Category | Testing coverage |
|
||||
| Status | Resolved |
|
||||
| Location | `tests/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests/SecretEncryptionTests.cs` |
|
||||
|
||||
**Description**
|
||||
|
||||
`SecretEncryptionTests` covered the database-connection, SMTP-credentials, and external-system secrets
|
||||
with "stored-encrypted / raw != plaintext / round-trips" tests, but had no parallel test for the
|
||||
Twilio `AuthToken`. A refactor dropping `SmsConfiguration` from `ApplySecretColumnEncryption` would go
|
||||
uncaught.
|
||||
|
||||
**Recommendation**
|
||||
|
||||
Add `SmsConfiguration_AuthToken_StoredEncrypted_RoundTrips` and a null-round-trip test mirroring the
|
||||
SMTP shape.
|
||||
|
||||
**Resolution**
|
||||
|
||||
Resolved 2026-06-19 (commit `a9393c89`): added both tests; the encrypted test also asserts the raw
|
||||
column is ciphertext and that `AccountSid` stays plaintext.
|
||||
|
||||
### ConfigurationDatabase-027 — No MS SQL migration integration test for `AddSmsNotifications`
|
||||
|
||||
| | |
|
||||
|--|--|
|
||||
| Severity | Low |
|
||||
| Category | Testing coverage |
|
||||
| Status | Deferred |
|
||||
| Location | `tests/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests/Migrations/` |
|
||||
|
||||
**Description**
|
||||
|
||||
Prior structural migrations have MS SQL integration tests asserting the resulting columns/types/nullability.
|
||||
`AddSmsNotifications` (and the follow-up `SmsFromNumberOptional`) have none, so the column shapes and the
|
||||
idempotency of the `ALTER COLUMN` statements are unverified against a real SQL Server.
|
||||
|
||||
**Recommendation**
|
||||
|
||||
Add an `AddSmsNotificationsMigrationTests` using the `MsSqlMigrationFixture` pattern.
|
||||
|
||||
**Resolution**
|
||||
|
||||
Deferred (2026-06-19): the migrations are standard idempotent `ALTER`/guarded-`CREATE` statements
|
||||
verified by the model snapshot and the build, and `AddSmsNotifications` was applied to the real
|
||||
docker MS SQL during the feature's integration pass. A live-SQL migration test is tracked for a
|
||||
future ConfigurationDatabase test-stability pass.
|
||||
|
||||
Reference in New Issue
Block a user