diff --git a/docs/scrum4me-architecture.md b/docs/scrum4me-architecture.md index bc1234d..5d3c373 100644 --- a/docs/scrum4me-architecture.md +++ b/docs/scrum4me-architecture.md @@ -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. diff --git a/prisma/migrations/20260501110000_sync_task_status_from_claude_job/migration.sql b/prisma/migrations/20260501110000_sync_task_status_from_claude_job/migration.sql new file mode 100644 index 0000000..5a2b8fa --- /dev/null +++ b/prisma/migrations/20260501110000_sync_task_status_from_claude_job/migration.sql @@ -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();