feat(refine): wire RefineTask hub method, broadcaster events, and DI

This commit is contained in:
mika kuns
2026-06-04 23:14:00 +02:00
parent 0460d7bea5
commit e523ed85eb
6 changed files with 29 additions and 5 deletions

View File

@@ -1,10 +1,11 @@
using ClaudeDo.Data.Models;
using ClaudeDo.Worker.Prime;
using ClaudeDo.Worker.Refine;
using Microsoft.AspNetCore.SignalR;
namespace ClaudeDo.Worker.Hub;
public sealed class HubBroadcaster : IPrimeBroadcaster
public sealed class HubBroadcaster : IPrimeBroadcaster, IRefineBroadcaster
{
private readonly IHubContext<WorkerHub> _hub;
@@ -62,4 +63,12 @@ public sealed class HubBroadcaster : IPrimeBroadcaster
Task IPrimeBroadcaster.PrepStartedAsync() => PrepStarted();
Task IPrimeBroadcaster.PrepLineAsync(string line) => PrepLine(line);
Task IPrimeBroadcaster.PrepFinishedAsync(bool success) => PrepFinished(success);
public Task RefineStarted(string taskId) => _hub.Clients.All.SendAsync("RefineStarted", taskId);
public Task RefineFinished(string taskId, bool success, string? error) =>
_hub.Clients.All.SendAsync("RefineFinished", taskId, success, error);
Task IRefineBroadcaster.RefineStartedAsync(string taskId) => RefineStarted(taskId);
Task IRefineBroadcaster.RefineFinishedAsync(string taskId, bool success, string? error) =>
RefineFinished(taskId, success, error);
}

View File

@@ -8,6 +8,7 @@ using ClaudeDo.Worker.Lifecycle;
using ClaudeDo.Worker.Planning;
using ClaudeDo.Worker.Prime;
using ClaudeDo.Worker.Queue;
using ClaudeDo.Worker.Refine;
using ClaudeDo.Worker.Report;
using ClaudeDo.Worker.Report.Interfaces;
using ClaudeDo.Worker.State;
@@ -83,6 +84,7 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub
private readonly IPrimeRunner _primeRunner;
private readonly ITaskStateService _state;
private readonly IWeekReportService _report;
private readonly IRefineRunner _refineRunner;
public WorkerHub(
QueueService queue,
@@ -102,7 +104,8 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub
IPrimeScheduleSignal primeSignal,
IPrimeRunner primeRunner,
ITaskStateService state,
IWeekReportService report)
IWeekReportService report,
IRefineRunner refineRunner)
{
_queue = queue;
_waker = waker;
@@ -122,6 +125,7 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub
_primeRunner = primeRunner;
_state = state;
_report = report;
_refineRunner = refineRunner;
}
// Maps the two exceptions service methods throw into client-facing HubExceptions:
@@ -541,6 +545,12 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub
_primeSignal.Signal();
}
public Task RefineTask(string taskId)
{
_ = _refineRunner.RefineAsync(taskId, CancellationToken.None);
return Task.CompletedTask;
}
public async Task<bool> RunDailyPrepNow()
{
var schedule = new PrimeScheduleDto(Guid.Empty, 0, TimeSpan.Zero, true, null, null);

View File

@@ -12,6 +12,7 @@ using ClaudeDo.Worker.Queue;
using ClaudeDo.Worker.Runner;
using ClaudeDo.Worker.State;
using ClaudeDo.Worker.Prime;
using ClaudeDo.Worker.Refine;
using ClaudeDo.Worker.Report;
using ClaudeDo.Worker.Report.Interfaces;
using ClaudeDo.Worker.Worktrees;
@@ -108,6 +109,10 @@ builder.Services.AddSingleton(PrimeSchedulerOptions.Default);
builder.Services.AddSingleton<IPrimeBroadcaster>(sp => sp.GetRequiredService<HubBroadcaster>());
builder.Services.AddHostedService<PrimeScheduler>();
// Refine
builder.Services.AddSingleton<IRefineRunner, RefineRunner>();
builder.Services.AddSingleton<IRefineBroadcaster>(sp => sp.GetRequiredService<HubBroadcaster>());
// QueueService: singleton + hosted service (same instance).
builder.Services.AddSingleton<QueueService>();
builder.Services.AddHostedService(sp => sp.GetRequiredService<QueueService>());

View File

@@ -19,7 +19,7 @@ public sealed class ClearMyDayHubTests : IDisposable
var broadcaster = new HubBroadcaster(new CapturingHubContext());
var hub = new WorkerHub(
null!, null!, null!, null!, broadcaster, _db.CreateFactory(),
null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!);
null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!);
hub.Clients = new FakeHubCallerClients(new RecordingClientProxy());
hub.Context = new FakeHubCallerContext();
return hub;

View File

@@ -55,7 +55,7 @@ public sealed class PlanningHubTests : IDisposable
{
var hub = new WorkerHub(
null!, null!, null!, null!, null!, null!, null!, null!, null!,
_planning, _launcher, null!, null!, null!, null!, null!, null!, null!);
_planning, _launcher, null!, null!, null!, null!, null!, null!, null!, null!);
hub.Clients = new FakeHubCallerClients(_proxy);
hub.Context = new FakeHubCallerContext();
return hub;

View File

@@ -19,7 +19,7 @@ public sealed class WorktreeStateHubTests : IDisposable
var broadcaster = new HubBroadcaster(new CapturingHubContext());
var hub = new WorkerHub(
null!, null!, null!, null!, broadcaster, _db.CreateFactory(),
null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!);
null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!);
hub.Clients = new FakeHubCallerClients(new RecordingClientProxy());
hub.Context = new FakeHubCallerContext();
return hub;