actions: idea-job triggers + cancel (M12 T-497)
actions/ideas.ts:
- startGrillJobAction(id) — DRAFT/GRILLED/GRILL_FAILED/PLAN_READY → GRILLING;
validates product+repo_url, idempotency check (active job 409),
worker-count check (15s freshness), atomic $transaction creates ClaudeJob
+ flips idea.status + IdeaLog{JOB_EVENT}, manual pg_notify
- startMakePlanJobAction(id) — GRILLED/PLAN_FAILED/PLAN_READY → PLANNING;
same shape via shared startIdeaJob helper
- cancelIdeaJobAction(id) — finds active QUEUED|CLAIMED|RUNNING job for idea,
reverts status: grill→DRAFT/GRILLED based on grill_md presence;
plan→GRILLED/PLAN_READY based on plan_md presence
Tests: 31 cases incl. happy path, demo-403, no-product/no-repo-422,
no-worker-422, idempotency-409, status-mismatch-422, cancel revert paths,
404 no-active-job.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>