refactor: simplify data connections from many-to-many site assignment to direct site ownership

Replace SiteDataConnectionAssignment join table with a direct SiteId FK on DataConnection,
simplifying the data model, repositories, UI, CLI, and deployment service.
This commit is contained in:
Joseph Doherty
2026-03-21 21:07:10 -04:00
parent cd6efeea90
commit 970d0a5cb3
25 changed files with 1543 additions and 490 deletions

View File

@@ -27,17 +27,18 @@ public class CentralUiRepository : ICentralUiRepository
public async Task<IReadOnlyList<DataConnection>> GetDataConnectionsBySiteIdAsync(int siteId, CancellationToken cancellationToken = default)
{
return await _context.SiteDataConnectionAssignments
return await _context.DataConnections
.AsNoTracking()
.Where(a => a.SiteId == siteId)
.Join(_context.DataConnections, a => a.DataConnectionId, d => d.Id, (_, d) => d)
.Where(d => d.SiteId == siteId)
.OrderBy(d => d.Name)
.ToListAsync(cancellationToken);
}
public async Task<IReadOnlyList<SiteDataConnectionAssignment>> GetAllSiteDataConnectionAssignmentsAsync(CancellationToken cancellationToken = default)
public async Task<IReadOnlyList<DataConnection>> GetAllDataConnectionsAsync(CancellationToken cancellationToken = default)
{
return await _context.SiteDataConnectionAssignments
return await _context.DataConnections
.AsNoTracking()
.OrderBy(d => d.Name)
.ToListAsync(cancellationToken);
}

View File

@@ -76,13 +76,8 @@ public class SiteRepository : ISiteRepository
public async Task<IReadOnlyList<DataConnection>> GetDataConnectionsBySiteIdAsync(int siteId, CancellationToken cancellationToken = default)
{
var connectionIds = await _dbContext.SiteDataConnectionAssignments
.Where(a => a.SiteId == siteId)
.Select(a => a.DataConnectionId)
.ToListAsync(cancellationToken);
return await _dbContext.DataConnections
.Where(c => connectionIds.Contains(c.Id))
.Where(c => c.SiteId == siteId)
.OrderBy(c => c.Name)
.ToListAsync(cancellationToken);
}
@@ -107,43 +102,13 @@ public class SiteRepository : ISiteRepository
}
else
{
var stub = new DataConnection("stub", "stub") { Id = id };
var stub = new DataConnection("stub", "stub", 0) { Id = id };
_dbContext.DataConnections.Attach(stub);
_dbContext.DataConnections.Remove(stub);
}
return Task.CompletedTask;
}
// --- Site-Connection Assignments ---
public async Task<SiteDataConnectionAssignment?> GetSiteDataConnectionAssignmentAsync(
int siteId, int dataConnectionId, CancellationToken cancellationToken = default)
{
return await _dbContext.SiteDataConnectionAssignments
.FirstOrDefaultAsync(a => a.SiteId == siteId && a.DataConnectionId == dataConnectionId, cancellationToken);
}
public async Task AddSiteDataConnectionAssignmentAsync(SiteDataConnectionAssignment assignment, CancellationToken cancellationToken = default)
{
await _dbContext.SiteDataConnectionAssignments.AddAsync(assignment, cancellationToken);
}
public Task DeleteSiteDataConnectionAssignmentAsync(int id, CancellationToken cancellationToken = default)
{
var entity = _dbContext.SiteDataConnectionAssignments.Local.FirstOrDefault(a => a.Id == id);
if (entity != null)
{
_dbContext.SiteDataConnectionAssignments.Remove(entity);
}
else
{
var stub = new SiteDataConnectionAssignment { Id = id };
_dbContext.SiteDataConnectionAssignments.Attach(stub);
_dbContext.SiteDataConnectionAssignments.Remove(stub);
}
return Task.CompletedTask;
}
// --- Instances (for deletion constraint checks) ---
public async Task<IReadOnlyList<Instance>> GetInstancesBySiteIdAsync(int siteId, CancellationToken cancellationToken = default)