|
|
6fee0394c5
|
actions: materializeIdeaPlanAction + relinkIdeaPlanAction (M12 T-498)
actions/ideas.ts:
- materializeIdeaPlanAction(id):
- guard: status===PLAN_READY, plan_md present, product linked, demo-403
- parsePlanMd → 422 with line-info on fail
- Prisma.\$transaction:
- SELECT max(code) for PBI/Story/Task within product
- INSERT PBI with sort_order = lastPbi+1 within priority
- per story: INSERT (sequential ST-NNN), per task: INSERT (T-N)
- UPDATE idea SET pbi_id, status=PLANNED
- INSERT IdeaLog{PLAN_RESULT, metadata}
- returns 409 on P2002 (concurrent-materialize race)
- relinkIdeaPlanAction(id):
- guard: status===PLANNED && pbi_id===null (PBI manually deleted via SetNull FK)
- reverts to PLAN_READY + IdeaLog{NOTE}
Tests: 39 cases total (8 new for materialize + relink): happy creates entities,
status-mismatch-422, parse-fail-422 with details, demo-403, P2002→409,
relink happy + invalid-precondition guards.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-04 19:51:18 +02:00 |
|
|
|
33cbb6c2f4
|
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>
|
2026-05-04 19:49:27 +02:00 |
|
|
|
5f410d3b10
|
actions: ideas CRUD + grill_md/plan_md edit + download (M12 T-496)
actions/ideas.ts (strikt user_id-only, geen productAccessFilter):
- createIdeaAction(input) — atomic nextIdeaCode + idea.create in $transaction
- updateIdeaAction(id, input) — guards on isIdeaEditable
- archiveIdeaAction / unarchiveIdeaAction
- deleteIdeaAction — refuses when pbi_id linked
- updateGrillMdAction — only in GRILLED|PLAN_READY; logs IdeaLog{NOTE}
- updatePlanMdAction — only in PLAN_READY; runs parsePlanMd; 422 with details on fail
- downloadIdeaMdAction — read-only, demo allowed
Added rate-limit configs: create-idea, edit-idea-md, start-idea-job,
materialize-idea.
Tests: 19 cases covering auth (401), demo (403), zod (422), status guards
(422), 404 cross-user-scope, plan-md parse-fail with details.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-04 19:47:30 +02:00 |
|