feat: wire site-local repos, remove config DB from Site, update artifact service

- SiteExternalSystemRepository and SiteNotificationRepository registered in Site DI
- Removed AddConfigurationDatabase from Site role in Program.cs
- Removed ConfigurationDb from appsettings.Site.json
- ArtifactDeploymentService collects all 6 artifact types including data connections and SMTP
This commit is contained in:
Joseph Doherty
2026-03-17 13:54:37 -04:00
parent 2f3e0ceecb
commit 3b22a8f0da
5 changed files with 92 additions and 12 deletions

View File

@@ -12,8 +12,8 @@ namespace ScadaLink.DeploymentManager;
/// <summary>
/// WP-7: System-wide artifact deployment.
/// Broadcasts artifacts (shared scripts, external systems, notification lists, DB connections)
/// to all sites with per-site tracking.
/// Broadcasts artifacts (shared scripts, external systems, notification lists, DB connections,
/// data connections, and SMTP configurations) to all sites with per-site tracking.
///
/// - Successful sites are NOT rolled back on other failures.
/// - Failed sites are retryable individually.
@@ -24,6 +24,9 @@ public class ArtifactDeploymentService
{
private readonly ISiteRepository _siteRepo;
private readonly IDeploymentManagerRepository _deploymentRepo;
private readonly ITemplateEngineRepository _templateRepo;
private readonly IExternalSystemRepository _externalSystemRepo;
private readonly INotificationRepository _notificationRepo;
private readonly CommunicationService _communicationService;
private readonly IAuditService _auditService;
private readonly DeploymentManagerOptions _options;
@@ -32,6 +35,9 @@ public class ArtifactDeploymentService
public ArtifactDeploymentService(
ISiteRepository siteRepo,
IDeploymentManagerRepository deploymentRepo,
ITemplateEngineRepository templateRepo,
IExternalSystemRepository externalSystemRepo,
INotificationRepository notificationRepo,
CommunicationService communicationService,
IAuditService auditService,
IOptions<DeploymentManagerOptions> options,
@@ -39,12 +45,80 @@ public class ArtifactDeploymentService
{
_siteRepo = siteRepo;
_deploymentRepo = deploymentRepo;
_templateRepo = templateRepo;
_externalSystemRepo = externalSystemRepo;
_notificationRepo = notificationRepo;
_communicationService = communicationService;
_auditService = auditService;
_options = options.Value;
_logger = logger;
}
/// <summary>
/// Collects all artifact types from repositories and builds a <see cref="DeployArtifactsCommand"/>.
/// </summary>
public async Task<DeployArtifactsCommand> BuildDeployArtifactsCommandAsync(
CancellationToken cancellationToken = default)
{
var sharedScripts = await _templateRepo.GetAllSharedScriptsAsync(cancellationToken);
var externalSystems = await _externalSystemRepo.GetAllExternalSystemsAsync(cancellationToken);
var dbConnections = await _externalSystemRepo.GetAllDatabaseConnectionsAsync(cancellationToken);
var notificationLists = await _notificationRepo.GetAllNotificationListsAsync(cancellationToken);
var dataConnections = await _siteRepo.GetAllDataConnectionsAsync(cancellationToken);
var smtpConfigurations = await _notificationRepo.GetAllSmtpConfigurationsAsync(cancellationToken);
// Map shared scripts
var scriptArtifacts = sharedScripts.Select(s =>
new SharedScriptArtifact(s.Name, s.Code, s.ParameterDefinitions, s.ReturnDefinition)).ToList();
// Map external systems (serialize methods per system)
var externalSystemArtifacts = new List<ExternalSystemArtifact>();
foreach (var es in externalSystems)
{
var methods = await _externalSystemRepo.GetMethodsByExternalSystemIdAsync(es.Id, cancellationToken);
var methodsJson = methods.Count > 0
? JsonSerializer.Serialize(methods.Select(m => new
{
m.Name,
m.HttpMethod,
m.Path,
m.ParameterDefinitions,
m.ReturnDefinition
}))
: null;
externalSystemArtifacts.Add(new ExternalSystemArtifact(
es.Name, es.EndpointUrl, es.AuthType, es.AuthConfiguration, methodsJson));
}
// Map database connections
var dbConnectionArtifacts = dbConnections.Select(d =>
new DatabaseConnectionArtifact(d.Name, d.ConnectionString, d.MaxRetries, d.RetryDelay)).ToList();
// Map notification lists
var notificationListArtifacts = notificationLists.Select(nl =>
new NotificationListArtifact(nl.Name, nl.Recipients.Select(r => r.EmailAddress).ToList())).ToList();
// Map data connections
var dataConnectionArtifacts = dataConnections.Select(dc =>
new DataConnectionArtifact(dc.Name, dc.Protocol, dc.Configuration)).ToList();
// Map SMTP configurations — use Host as the artifact name (matches SQLite PK on site)
var smtpArtifacts = smtpConfigurations.Select(smtp =>
new SmtpConfigurationArtifact(
$"{smtp.Host}:{smtp.Port}", smtp.Host, smtp.Port, smtp.AuthType, smtp.FromAddress,
smtp.Credentials, null, smtp.TlsMode)).ToList();
return new DeployArtifactsCommand(
Guid.NewGuid().ToString("N"),
scriptArtifacts,
externalSystemArtifacts,
dbConnectionArtifacts,
notificationListArtifacts,
dataConnectionArtifacts,
smtpArtifacts,
DateTimeOffset.UtcNow);
}
/// <summary>
/// Deploys artifacts to all sites. Returns per-site result matrix.
/// </summary>