Skip to content

moooon

Motir

Vibe your whole project. Bring an idea — Motir's three AI layers plan it, track it, and ship it, end to end. You're looking at Motir, built in Motir.

  • Vibe Project
  • Open Source
  • AI Agent
  • AI Loop
1
requests
0
upvotes
145
planned
1,361
shipped

Motir · Work items

MOTIR-259Done

4.7.3 At-scale Scrum interaction + complete journey E2E — drag-as-transition · snap-back · swimlanes · cross-lane reassign · WIP · complete-sprint carry-over + report

Estimate: 25m · Depends on: 4.7.1, 4.5.2, 4.5.3, 4.4.3, 4.4.4, 4.4.6, 3.2.4, 3.3.5, 3.3.6

The Playwright spec (tests/e2e/board-scrum-at-scale.spec.ts, the interaction + lifecycle half) that proves the combined Scrum journey holds at scale — the deferral 4.4.7 / 4.5.4 send here. Every interaction runs on a card inside a virtualized, bounded, sprint-scoped board (4.7.1 seed), so it doubles as proof that the 3.8 load model + the 4.5.2 sprint scope do not break the 3.2/3.3 interaction contracts, and the closing complete-sprint step proves the 4.4 carry-over holds over a LARGE set.

Drag-as-transition deep in a virtualized sprint column. Scroll a tall sprint column, pick a card not in the initial window, drag it to another column → the workflow transition applies (optimistic, then reconciled to the returned BoardCardDto); re-fetch / quick-view shows the new status and the card stays in the sprint (status changed, sprintId unchanged); counts + the header point figures on both columns update. Proves drag survives virtualization + the sprint scope (3.2.5/3.8.3 + 4.5.2).

Illegal-move snap-back (409) at scale. An illegal cross-column move under the restricted workflow → the card snaps back to its origin column and the status is unchanged on re-fetch (the 3.1.5 IllegalBoardMoveError 409 contract), even from deep in the list.

Swimlanes re-lay at scale (sprint-scoped). Switch group-by to Assignee → the Scrum board re-lays into one lane per assignee-with-cards + the "No assignee" catch-all, each lane still bounded + virtualized with NO "Load more" (3.8.5) and still sprint-scoped; switch to Epic (grouped by ancestor epic) and Priority and back to None. Collapse a lane → its cards hide, header + aggregate count remain, and the collapse persists on reload.

Cross-lane reassign + diagonal. Drag a card into another assignee lane → the assignee is reassigned (confirmed via re-fetch / quick-view), status + sprint unchanged; into "No assignee" → unassigned. A diagonal drag (different column AND different lane) applies BOTH the transition and the field reassign, each with independent reconcile (3.3.5) — one rejection does not revert the other; the card stays in the sprint throughout.

WIP soft-warning is advisory, not blocking. Set a column's WIP limit below its sprint-scoped card count (the [⋯] menu, 3.3.6) → the header shows the n/limit over-limit warning (hue + icon/label, not colour-alone, finding #35); drag another card in → the drop still succeeds and the warning persists (soft = advisory; the 3.2.4 move contract is untouched). A column exactly at the limit (n === limit) is NOT warned (strictly greater).

Complete-sprint with a LARGE carry-over + report (the lifecycle at scale). With the large active sprint still holding many unfinished (non-done-category) issues, invoke Complete sprint (the 4.4.6 modal, from the backlog active-sprint container or the scrum header): the carry-over chooser offers Backlog and the seeded planned target sprint. Choose the planned sprint → confirm → the whole large set of unfinished issues moves into it in ONE bounded transaction (the 4.4.3 contract — assert none are left behind and the done issues stay on the completed sprint), and the sprint report (4.4.4) shows the completed/incomplete lists paginated (a bounded first page + a "view all" deep-link, NOT a dump of thousands — finding #57), the committed/completed/not-completed points + the scope-change count from aggregates (not page sums), and the freed one-active slot (a new sprint can now start). Re-run the Backlog branch on a fresh seed to assert carry-over to the backlog restores backlog_rank order over a large set.

Acceptance criteria

  • pnpm test:e2e --grep board-scrum-at-scale (this spec) is green: a drag-as-transition on a card scrolled into view deep in a virtualized sprint column applies + reconciles and keeps the card in the sprint; an illegal cross-column move snaps back (409) with status unchanged.
  • Switching group-by (Assignee/Epic-ancestor/Priority/None) re-lays the Scrum board into bounded, virtualized, sprint-scoped lanes + catch-all with NO "Load more"; a collapsed lane stays collapsed on reload; a cross-lane drag reassigns the grouped field (status + sprint unchanged) and a diagonal drag applies both writes with independent reconcile.
  • A column over its WIP limit shows the soft n/limit warning (not colour-alone) yet still ACCEPTS a dropped card (advisory, non-blocking); an at-limit column is not warned.
  • Completing the large active sprint moves the WHOLE unfinished set into the chosen planned sprint (or the backlog, rank restored) in one bounded transaction (none left behind, done issues retained), frees the one-active slot, and renders the sprint report with PAGINATED lists + aggregate committed/completed/not-completed points + the scope-change count (no load-all, finding #57).
  • Every interaction runs against the 4.7.1 sprint-shaped large seed (cards deep in virtualized, sprint-scoped lists), reuses the real-Postgres/Playwright harness + 4.7.1 helpers, and does NOT duplicate the single-surface journeys owned by 4.4.7 (focused lifecycle) / 4.5.4 (small-scale scrum) / 3.5.3 (Kanban interaction).

Context refs

  • Story 4.7.1 — the sprint-shaped large seed + at-scale helpers; Stories 4.4.7 / 4.5.4 / 3.5.3 — the single-surface journeys this extends to the at-scale Scrum case (do not duplicate)
  • app/(authed)/boards/_components/{BoardContainer,BoardColumn,BoardCard,SwimlaneBoard,LaneCell}.tsx (3.2.4 dnd-kit drag, 3.3.5 swimlanes, 3.3.6 WIP, 3.8.5 bounded swimlane render) + the complete-sprint modal + report view (4.4.6) — under test
  • lib/services/boardsService.ts (moveCard, scrum scope, swimlane projection, WIP) + lib/services/sprintsService.ts (completeSprint carry-over 4.4.3, getSprintReport 4.4.4) + lib/boards/errors.ts (IllegalBoardMoveError 409) + lib/sprints/errors.ts (InvalidCarryOverTargetError) — the move + reassign + complete contracts verified
  • tests/e2e/_helpers/board.ts (+ 4.7.1 additions) + tests/e2e/_helpers/workflow.ts; design/boards/{scrum,swimlanes-wip}.mock.html (4.5.1/3.3.1) + design/sprints/sprint-lifecycle.mock.html (4.4.1) — the drag/lane/WIP/complete design under test