refactor: extract interfaces to Interfaces folders and consolidate filters
Move interface declarations into per-area Interfaces/ subfolders, merge the small task-list filter classes into StatusFilter/SmartFlagFilter, and simplify related services, converters and hub DTO handling. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -41,6 +41,27 @@ public sealed class TaskMergeService
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
private async Task<(TaskEntity Task, ListEntity List, WorktreeEntity? Worktree)> LoadMergeContextAsync(
|
||||
string taskId, CancellationToken ct)
|
||||
{
|
||||
using var ctx = _dbFactory.CreateDbContext();
|
||||
var task = await new TaskRepository(ctx).GetByIdAsync(taskId, ct)
|
||||
?? throw new KeyNotFoundException($"Task '{taskId}' not found.");
|
||||
var list = await new ListRepository(ctx).GetByIdAsync(task.ListId, ct)
|
||||
?? throw new InvalidOperationException("List not found.");
|
||||
var wt = await new WorktreeRepository(ctx).GetByTaskIdAsync(taskId, ct);
|
||||
return (task, list, wt);
|
||||
}
|
||||
|
||||
private async Task MarkWorktreeMergedAsync(string taskId, CancellationToken ct)
|
||||
{
|
||||
using (var ctx = _dbFactory.CreateDbContext())
|
||||
{
|
||||
await new WorktreeRepository(ctx).SetStateAsync(taskId, WorktreeState.Merged, ct);
|
||||
}
|
||||
await _broadcaster.WorktreeUpdated(taskId);
|
||||
}
|
||||
|
||||
public async Task<MergeResult> MergeAsync(
|
||||
string taskId,
|
||||
string targetBranch,
|
||||
@@ -49,18 +70,7 @@ public sealed class TaskMergeService
|
||||
bool leaveConflictsInTree,
|
||||
CancellationToken ct)
|
||||
{
|
||||
TaskEntity task;
|
||||
ListEntity list;
|
||||
WorktreeEntity? wt;
|
||||
|
||||
using (var ctx = _dbFactory.CreateDbContext())
|
||||
{
|
||||
task = await new TaskRepository(ctx).GetByIdAsync(taskId, ct)
|
||||
?? throw new KeyNotFoundException($"Task '{taskId}' not found.");
|
||||
list = await new ListRepository(ctx).GetByIdAsync(task.ListId, ct)
|
||||
?? throw new InvalidOperationException("List not found.");
|
||||
wt = await new WorktreeRepository(ctx).GetByTaskIdAsync(taskId, ct);
|
||||
}
|
||||
var (task, list, wt) = await LoadMergeContextAsync(taskId, ct);
|
||||
|
||||
if (task.Status == TaskStatus.Running)
|
||||
return Blocked("task is running");
|
||||
@@ -134,11 +144,7 @@ public sealed class TaskMergeService
|
||||
}
|
||||
}
|
||||
|
||||
using (var ctx = _dbFactory.CreateDbContext())
|
||||
{
|
||||
await new WorktreeRepository(ctx).SetStateAsync(taskId, WorktreeState.Merged, ct);
|
||||
}
|
||||
await _broadcaster.WorktreeUpdated(taskId);
|
||||
await MarkWorktreeMergedAsync(taskId, ct);
|
||||
|
||||
_logger.LogInformation(
|
||||
"Merged task {TaskId} branch {Branch} into {Target} (remove worktree: {Remove})",
|
||||
@@ -158,18 +164,7 @@ public sealed class TaskMergeService
|
||||
|
||||
public async Task<MergeResult> ContinueMergeAsync(string taskId, CancellationToken ct)
|
||||
{
|
||||
TaskEntity task;
|
||||
ListEntity list;
|
||||
WorktreeEntity? wt;
|
||||
|
||||
using (var ctx = _dbFactory.CreateDbContext())
|
||||
{
|
||||
task = await new TaskRepository(ctx).GetByIdAsync(taskId, ct)
|
||||
?? throw new KeyNotFoundException($"Task '{taskId}' not found.");
|
||||
list = await new ListRepository(ctx).GetByIdAsync(task.ListId, ct)
|
||||
?? throw new InvalidOperationException("List not found.");
|
||||
wt = await new WorktreeRepository(ctx).GetByTaskIdAsync(taskId, ct);
|
||||
}
|
||||
var (_, list, wt) = await LoadMergeContextAsync(taskId, ct);
|
||||
|
||||
if (wt is null) return Blocked("task has no worktree");
|
||||
if (wt.State != WorktreeState.Active) return Blocked($"worktree state is {wt.State}");
|
||||
@@ -186,11 +181,7 @@ public sealed class TaskMergeService
|
||||
try { await _git.CommitAsync(list.WorkingDir, $"Merge branch '{wt.BranchName}'", ct); }
|
||||
catch (Exception ex) { return Blocked($"commit failed: {ex.Message}"); }
|
||||
|
||||
using (var ctx = _dbFactory.CreateDbContext())
|
||||
{
|
||||
await new WorktreeRepository(ctx).SetStateAsync(taskId, WorktreeState.Merged, ct);
|
||||
}
|
||||
await _broadcaster.WorktreeUpdated(taskId);
|
||||
await MarkWorktreeMergedAsync(taskId, ct);
|
||||
_logger.LogInformation("Continued merge of task {TaskId} branch {Branch}", taskId, wt.BranchName);
|
||||
|
||||
return new MergeResult(StatusMerged, Array.Empty<string>(), null);
|
||||
@@ -198,17 +189,7 @@ public sealed class TaskMergeService
|
||||
|
||||
public async Task<MergeResult> AbortMergeAsync(string taskId, CancellationToken ct)
|
||||
{
|
||||
ListEntity list;
|
||||
WorktreeEntity? wt;
|
||||
|
||||
using (var ctx = _dbFactory.CreateDbContext())
|
||||
{
|
||||
var task = await new TaskRepository(ctx).GetByIdAsync(taskId, ct)
|
||||
?? throw new KeyNotFoundException($"Task '{taskId}' not found.");
|
||||
list = await new ListRepository(ctx).GetByIdAsync(task.ListId, ct)
|
||||
?? throw new InvalidOperationException("List not found.");
|
||||
wt = await new WorktreeRepository(ctx).GetByTaskIdAsync(taskId, ct);
|
||||
}
|
||||
var (_, list, wt) = await LoadMergeContextAsync(taskId, ct);
|
||||
|
||||
if (wt is null) return Blocked("task has no worktree");
|
||||
if (wt.State != WorktreeState.Active) return Blocked($"worktree state is {wt.State}");
|
||||
@@ -225,15 +206,7 @@ public sealed class TaskMergeService
|
||||
|
||||
public async Task<MergeTargets> GetTargetsAsync(string taskId, CancellationToken ct)
|
||||
{
|
||||
TaskEntity task;
|
||||
ListEntity list;
|
||||
using (var ctx = _dbFactory.CreateDbContext())
|
||||
{
|
||||
task = await new TaskRepository(ctx).GetByIdAsync(taskId, ct)
|
||||
?? throw new KeyNotFoundException($"Task '{taskId}' not found.");
|
||||
list = await new ListRepository(ctx).GetByIdAsync(task.ListId, ct)
|
||||
?? throw new InvalidOperationException("List not found.");
|
||||
}
|
||||
var (_, list, _) = await LoadMergeContextAsync(taskId, ct);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(list.WorkingDir))
|
||||
return new MergeTargets("", Array.Empty<string>());
|
||||
|
||||
Reference in New Issue
Block a user