feat(worker,ui): wire EF Core into DI and update all consumers to IDbContextFactory

Worker and App Program.cs: replace SqliteConnectionFactory+SchemaInitializer
with AddDbContextFactory<ClaudeDoDbContext> + Database.Migrate(). Repos
changed from AddSingleton to AddScoped.

All singleton services (QueueService, StaleTaskRecovery, WorktreeManager,
TaskRunner) and singleton ViewModels (MainWindowViewModel, TaskDetailViewModel,
TaskListViewModel, TaskEditorViewModel) now take IDbContextFactory<ClaudeDoDbContext>
and create short-lived contexts per operation.

Test infrastructure: DbFixture now uses EF migrations instead of SchemaInitializer;
all test classes create contexts via DbFixture.CreateContext().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
mika kuns
2026-04-16 08:59:24 +02:00
parent b7be52a623
commit 36484ed45a
18 changed files with 479 additions and 232 deletions

View File

@@ -1,7 +1,9 @@
using ClaudeDo.Data;
using ClaudeDo.Data.Git;
using ClaudeDo.Data.Models;
using ClaudeDo.Data.Repositories;
using ClaudeDo.Worker.Config;
using Microsoft.EntityFrameworkCore;
namespace ClaudeDo.Worker.Runner;
@@ -10,14 +12,14 @@ public sealed record WorktreeContext(string WorktreePath, string BranchName, str
public sealed class WorktreeManager
{
private readonly GitService _git;
private readonly WorktreeRepository _wtRepo;
private readonly IDbContextFactory<ClaudeDoDbContext> _dbFactory;
private readonly WorkerConfig _cfg;
private readonly ILogger<WorktreeManager> _logger;
public WorktreeManager(GitService git, WorktreeRepository wtRepo, WorkerConfig cfg, ILogger<WorktreeManager> logger)
public WorktreeManager(GitService git, IDbContextFactory<ClaudeDoDbContext> dbFactory, WorkerConfig cfg, ILogger<WorktreeManager> logger)
{
_git = git;
_wtRepo = wtRepo;
_dbFactory = dbFactory;
_cfg = cfg;
_logger = logger;
}
@@ -50,7 +52,9 @@ public sealed class WorktreeManager
await _git.WorktreeAddAsync(workingDir, branchName, worktreePath, baseCommit, ct);
// Insert worktrees row AFTER git succeeds — if git throws, no row is created.
await _wtRepo.AddAsync(new WorktreeEntity
using var context = _dbFactory.CreateDbContext();
var wtRepo = new WorktreeRepository(context);
await wtRepo.AddAsync(new WorktreeEntity
{
TaskId = task.Id,
Path = worktreePath,
@@ -87,7 +91,9 @@ public sealed class WorktreeManager
var head = await _git.RevParseHeadAsync(ctx.WorktreePath, ct);
var diffStat = await _git.DiffStatAsync(ctx.WorktreePath, ctx.BaseCommit, head, ct);
await _wtRepo.UpdateHeadAsync(task.Id, head, diffStat, ct);
using var context = _dbFactory.CreateDbContext();
var wtRepo = new WorktreeRepository(context);
await wtRepo.UpdateHeadAsync(task.Id, head, diffStat, ct);
_logger.LogInformation("Committed changes for task {TaskId}: {Head}", task.Id, head);
return true;