MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-85

2.3 Issue create / edit (form + server actions)

Done
Description

The issue-mutation surface: a create-issue modal + a full edit form route, both following the 4-layer architecture (Server Action → service → repository → Prisma). Type + parent picker that surfaces 2.1.2's assertValidParent rule inline as a filtered combobox (illegal selections aren't constructible, not flagged after submit). A reusable MarkdownEditor primitive on top of the descriptionMd field 1.4 already ships, with paste/drop image upload via Vercel Blob. The edit form also resolves finding #46 by routing every status change through 2.2.4's gated updateStatus and removing the ungated status patch on updateWorkItem. Story also includes the previously-relocated delete-with-reassign flow for in-use statuses (2.3.1, with its own E2E in 2.3.2) — kept here because its E2E spans both the workflow-settings surface AND the work-item mutation pipeline, which is exactly this Story's seam.

Prerequisites: Story 1.4 already ships workItemsService.createWorkItem (atomic key allocation via the project counter, parentage gate via 2.1.2's assertValidParent, audit revisions) and updateWorkItem (patch-style updates for non-status fields). Story 2.1 ships the issue-type metadata (lib/issues/issueTypes.ts) + parent rules (lib/issues/parentRules.ts) the type+parent picker reads from. Story 2.2 ships transition validation on workItemsService.updateStatus (2.2.4) — the SINGLE gated path every status change in this Story routes through — plus initial-status seeding on create (also 2.2.4 + 2.2.2) and the workflow-management UI 2.3.1 extends. Issue-key assignment is NOT re-built here — Story 2.1.3 already verified the atomic monotonic-counter path; this Story just consumes createWorkItem as-is. All work follows motir-core/CLAUDE.md's 4-layer architecture (Route/Server-Action → Service → Repository → Prisma). Per finding #26, every new route + Server Action carries an explicit workspaceId gate at the application layer — RLS is defense-in-depth, not the sole gate (the dev/CI superuser bypasses RLS until the Epic-8 runtime cutover).

Verification

  • Pull the Story branch, pnpm install && pnpm prisma generate && pnpm prisma migrate dev against a fresh local DB.
  • pnpm test — Vitest covers: 2.3.1 delete-with-reassign matrix; 2.3.3 createIssue Server Action; 2.3.4 candidate-parents service + picker; 2.3.5 MarkdownEditor round-trip + render guard; 2.3.6 edit form + the finding #46 grep guard (no status in UpdateWorkItemInput) + stale-edit; 2.3.7 attachment service gates.
  • pnpm test:e2e — both E2E suites: 2.3.2 workflow-delete-reassign + 2.3.8 issue-create-edit-flow.
  • Manual UX check — create: sign in, project page, press "C", create a Story with title + Markdown description + a pasted image; assert the toast shows the PROD-N identifier, the linked detail/edit page renders the description with the image rendered inline.
  • Manual UX check — type+parent inline validation: open create modal; for every type, open the parent picker and confirm the candidate list matches 2.1.2's matrix (Epic→none, Story→Epic, Task→Story/Epic, Bug→Story/Task/Epic, Subtask→Story/Task/Bug); changing type after picking a parent clears the parent with the documented notice.
  • Manual UX check — edit + finding #46: open /projects/[key]/issues/[key]/edit; change title + status in one form, save; both succeed; activity tab shows two revisions; assert that mutating the row externally between page load + save surfaces the stale-edit banner.
  • Manual UX check — delete-with-reassign (2.3.1): as project admin, create a custom status, change 2–3 issues into it, delete it from /settings/project/[key]/workflow, confirm reassign modal + per-item migration + status row removal + per-item revision.
  • Cross-workspace check: sign in as a user with only workspace-A; visit a workspace-B issue URL → 404 (no leak of title/existence/key).
  • Findings-log update: append > Resolved: 2.3.6 to finding #46 in prodect_plan/PRODECT_FINDINGS.md.