feat(db): trigger sync_task_status_from_claude_job promote task naar DONE

Postgres AFTER-trigger op claude_jobs.status zet de bijbehorende
task automatisch op DONE zodra de job DONE wordt — werkt ongeacht
welke client de update doet (MCP-server, Server Action, raw SQL).

Idempotent: WHERE status <> 'DONE' voorkomt no-op updates die de
bestaande notify_task_change-trigger zouden doen vuren. Die laatste
verzorgt de pg_notify naar /api/realtime/solo zodat de UI synct.

- migration: prisma/migrations/20260501110000_sync_task_status_from_claude_job
- doc: nieuwe sectie 'Auto-promote task naar DONE' in architecture.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Janpeter Visser 2026-05-01 11:13:06 +02:00
parent 0605838b99
commit 36874a19dc
2 changed files with 40 additions and 0 deletions

View file

@ -1161,6 +1161,10 @@ UI klikt 'Voer uit'
`enqueueClaudeJobAction` weigert een tweede enqueue als er al een job bestaat met `status IN (QUEUED, CLAIMED, RUNNING)`. Teruggestuurde fout bevat het bestaande `jobId` zodat de UI ernaar kan linken.
### Auto-promote task naar DONE
Wanneer een `claude_job` op `DONE` komt, vuurt de Postgres-trigger `claude_job_status_to_task` (zie `prisma/migrations/20260501110000_sync_task_status_from_claude_job`) en zet de bijbehorende task ook op `DONE`. Werkt voor INSERT (direct als DONE aangemaakt) en UPDATE (transitie naar DONE). Idempotent: skip wanneer de task al DONE is. De bestaande `notify_task_change`-trigger op `tasks` vuurt dan automatisch de pg_notify zodat de Solo-paneel-UI synct — geen extra plumbing in de SSE-handler nodig.
### Hybride-ready
De huidige implementatie verwacht een lokale Claude Code-sessie die `wait_for_job` aanroept vanuit `madhura68/scrum4me-mcp`. Toekomstige uitbreiding naar Vercel Sandbox (serverless agent) vereist alleen een nieuw claim-endpoint — het datamodel en SSE-flow zijn ongewijzigd.

View file

@ -0,0 +1,36 @@
-- Sync task.status to DONE wanneer een ClaudeJob afgerond wordt.
--
-- Wanneer de agent (via MCP `update_job_status('done')` of een Server
-- Action) een ClaudeJob op DONE zet, willen we dat de bijbehorende
-- Task automatisch óók op DONE komt. Anders blijft de kaart in de
-- "Te doen"-kolom staan terwijl de job-badge "Klaar" toont.
--
-- We doen dit op DB-niveau zodat het werkt ongeacht welke client de
-- update doet (MCP-server, Server Action, raw SQL). De bestaande
-- notify_task_change-trigger vuurt automatisch op de task-UPDATE en
-- stuurt de pg_notify naar /api/realtime/solo, dus de UI synct
-- zonder extra plumbing.
--
-- Idempotent: WHERE-clause voorkomt no-op updates die de task-trigger
-- onnodig doen vuren.
CREATE OR REPLACE FUNCTION sync_task_status_from_claude_job() RETURNS trigger AS $$
BEGIN
IF NEW.status = 'DONE' THEN
IF (TG_OP = 'INSERT')
OR (TG_OP = 'UPDATE' AND OLD.status IS DISTINCT FROM 'DONE')
THEN
UPDATE tasks
SET status = 'DONE', updated_at = now()
WHERE id = NEW.task_id AND status <> 'DONE';
END IF;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS claude_job_status_to_task ON claude_jobs;
CREATE TRIGGER claude_job_status_to_task
AFTER INSERT OR UPDATE OF status ON claude_jobs
FOR EACH ROW
EXECUTE FUNCTION sync_task_status_from_claude_job();