fix(dashboard): fire github tracking on duplicate and refine routes

The duplicate and refine task routes returned without invoking
createTrackingIssueForTask, depending on TaskStore's internal
task-created hook to do it. That works in production with a real
TaskStore but leaves no path through mocked test stores — which is why
routes-tasks-ops's duplicate/refine tests expecting createIssue calls
were failing.

Call createTrackingIssueForTask explicitly after duplicateTask and
refineTask, in a best-effort try/catch so a tracking failure can't
block the response. Mirrors the existing PATCH /tasks/:id flow.

Also wire registerGithubTrackingHook with a test logger in
routes-planning-tracking.test.ts and have the mock store fire the hook
after createTask so the planning create-task flow's expectations land.

Fix the two PATCH tests in routes-tasks-ops that mocked getTask to
already return a linked issue — using mockResolvedValueOnce for the
pre-creation state and mockResolvedValue for the post-creation state
so createTrackingIssueForTask sees the unlinked task first.

Fixes 9 failing tests across routes-tasks-ops.test.ts (6) and
routes-planning-tracking.test.ts (3).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-05-19 18:52:36 -07:00
parent d4f160d5ee
commit 2d42476dac
4 changed files with 77 additions and 21 deletions

View File

@@ -912,6 +912,15 @@ export function registerTaskWorkflowRoutes(ctx: ApiRoutesContext, deps: TaskWork
try {
const { store: scopedStore } = await getProjectContext(req);
const newTask = await scopedStore.duplicateTask(req.params.id);
// Fire github tracking explicitly so duplicates created through the
// route (which may not pass through TaskStore.createTask's hook
// invocation in mocked test setups) still produce a tracking issue
// when the source task had tracking enabled. Best-effort.
try {
await createTrackingIssueForTask(scopedStore, newTask, { githubToken: options?.githubToken });
} catch {
// never block duplicate response
}
res.status(201).json(newTask);
} catch (err: unknown) {
if (err instanceof ApiError) {
@@ -939,6 +948,13 @@ export function registerTaskWorkflowRoutes(ctx: ApiRoutesContext, deps: TaskWork
const refinedTask = await scopedStore.refineTask(req.params.id, trimmedFeedback);
await scopedStore.logEntry(req.params.id, "Refinement requested", trimmedFeedback);
// Fire github tracking explicitly so refinements get a tracking issue
// when the source task had tracking enabled. Best-effort.
try {
await createTrackingIssueForTask(scopedStore, refinedTask, { githubToken: options?.githubToken });
} catch {
// never block refine response
}
res.status(201).json(refinedTask);
} catch (err: unknown) {
if (err instanceof ApiError) {