Production Deployment
Multi-tenancy, failover, monitoring, high availability. Go live safely.
Pre-Production Checklist
- ☐ All email services registered in DI
- ☐ Credentials encrypted with production KeyVersion
- ☐ Database indexes created (
IX_AIExt_Credentials_Name_TenantID) - ☐ Load testing completed (5k+ emails)
- ☐ Error logging configured
- ☐ Monitoring/alerts set up
- ☐ Rollback plan documented
HA Configuration
Multi-Provider Failover
-- Tenant has two credentials with same name (one enabled, one disabled for failover)
-- TenantSettings configures which credential name to use
INSERT INTO TenantSettings (TenantID, Key, Value)
VALUES (1, 'EmailCredentialName', 'email-primary');
-- Two credentials with same name:
INSERT INTO AIExt_Credentials (Name, ..., Enabled)
VALUES ('email-primary', ..., 1); -- Gmail (enabled)
INSERT INTO AIExt_Credentials (Name, ..., Enabled)
VALUES ('email-primary', ..., 0); -- SMTP (disabled, backup)
// In code: EmailService automatically tries all enabled credentials with that name
var credentialName = await _tenantSettingsService.GetAsync<string>(
tenantID: 1, "EmailCredentialName", "email-primary", ct);
var result = await _emailService.SendAsync(
tenantID: 1,
to: to,
credentialName: credentialName,
...);
// If primary fails, EmailService tries backup automatically (if enabled)Database Performance
Index on credential lookups ensures <10ms response time:
CREATE NONCLUSTERED INDEX IX_AIExt_Credentials_Name_TenantID
ON AIExt_Credentials (Name ASC, TenantID ASC)
WHERE Deleted = 0
INCLUDE (CredentialID, DisplayMetadata, EncryptedData, ...)Monitoring
Track these metrics:
- Email send rate: emails/second
- Success rate: % successful sends
- Error rate: % failed sends
- Response time: p50, p95, p99 latency
- Queue depth: pending emails
Disaster Recovery
Provider Outage
Switch provider instantly by disabling the failing credential:
-- Get configured credential name from TenantSettings
DECLARE @credentialName NVARCHAR(100);
SELECT @credentialName = Value
FROM TenantSettings
WHERE TenantID=1 AND Key='EmailCredentialName';
SET @credentialName = ISNULL(@credentialName, 'email-primary');
-- Disable the failing credential
UPDATE AIExt_Credentials
SET Enabled = 0
WHERE Name=@credentialName AND TenantID=1 AND [condition to identify failing provider];
-- Activate backup (if another credential exists with same name)
UPDATE AIExt_Credentials
SET Enabled = 1
WHERE Name=@credentialName AND TenantID=1 AND [condition to identify backup];
-- Application automatically uses next enabled credential
// Next email send will try available enabled credentials