Initial Commit
This commit is contained in:
138
openspec/changes/enterprise-browser-react-kanban/tasks.md
Normal file
138
openspec/changes/enterprise-browser-react-kanban/tasks.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# Tasks: enterprise-browser-react-kanban
|
||||
|
||||
**Change ID**: enterprise-browser-react-kanban
|
||||
**Package**: `@suaveplan/react-kanban`
|
||||
**Target path**: `browser/react/react-kanban`
|
||||
**Prerequisite packages on Verdaccio**: `@suaveplan/error`, `@suaveplan/schema-registry`
|
||||
|
||||
---
|
||||
|
||||
## 0. Pre-flight (non-negotiable)
|
||||
|
||||
- [ ] 0.1 Confirm clean working tree (`git status` reports nothing) and no in-flight worktrees with uncommitted work (`git worktree list` then `git status` in each)
|
||||
- [ ] 0.2 If any worktrees exist under `.claude/worktrees/`, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (`git worktree remove`) before opening a new one — code that has been lost twice on main is the failure mode this guards against.
|
||||
- [ ] 0.3 Confirm the package set in `MANIFEST.md` matches `find packages -maxdepth 3 -name package.json` count. Drift here means a prior change archived without regenerating the manifest.
|
||||
|
||||
## 1. Scaffold
|
||||
|
||||
- [ ] Create directory tree per `proposal.md`.
|
||||
- [ ] `package.json` v0.0.0, `"sideEffects": false`.
|
||||
- `dependencies`: `@suaveplan/error workspace:^`, `@suaveplan/logger workspace:^`, `@suaveplan/schema-registry workspace:^`, `zod catalog:forms`, `@opentelemetry/api catalog:observability`, `tslib catalog:build`, `react catalog:react`
|
||||
- `peerDependencies`: `react`, `react-dom`
|
||||
- `devDependencies`: `vitest catalog:testing`, `@vitest/coverage-istanbul catalog:testing`, `happy-dom catalog:testing`, `@testing-library/react catalog:testing`, `@suaveplan/testing workspace:^`, `@suaveplan/testing-dom workspace:^`
|
||||
- Subpath exports: `"."`, `"./core/board/board"`, `"./core/column/column"`, `"./core/card/card"`, `"./utils/drag-drop"`, `"./components/board"`
|
||||
- [ ] `tsconfig.json`, `vitest.config.ts` (pool: forks, happy-dom environment).
|
||||
|
||||
---
|
||||
|
||||
## 2. Error codes
|
||||
|
||||
- [ ] `WIP_LIMIT_EXCEEDED`, `INVALID_MOVE`, `CARD_NOT_FOUND`.
|
||||
- [ ] `registerKanbanErrorCodes()` — call eagerly.
|
||||
|
||||
---
|
||||
|
||||
## 3. Types (`src/types/common.ts`)
|
||||
|
||||
- [ ] `KanbanBoard`, `KanbanColumn`, `KanbanCard`, `KanbanConfig`, `KanbanState`, `KanbanActions`, `DragSource`, `DropTarget`, `MoveResult`, `KanbanSwimlane`.
|
||||
- [ ] Write `common.md`.
|
||||
|
||||
---
|
||||
|
||||
## 4. WIP sub-module (`src/core/board/wip.ts`)
|
||||
|
||||
- [ ] `isColumnAtWipLimit(column)`, `enforceWipLimit(board, dest)` — throw `WIP_LIMIT_EXCEEDED`.
|
||||
- [ ] Write `wip.test.ts`. Write docs inline (part of `board.md`).
|
||||
|
||||
---
|
||||
|
||||
## 5. Moves sub-module (`src/core/board/moves.ts`)
|
||||
|
||||
- [ ] `moveCardInBoard(board, src, dst)`, `moveColumnInBoard(board, from, to)`, `validateMove(board, src, dst)`.
|
||||
- [ ] `findCardColumn(board, cardId)` — throw `CARD_NOT_FOUND` when absent.
|
||||
- [ ] Write `moves.test.ts`.
|
||||
|
||||
---
|
||||
|
||||
## 6. Swimlanes sub-module (`src/core/board/swimlanes.ts`)
|
||||
|
||||
- [ ] `groupBySwimlane(board, keyFn)` returning `Map<string, KanbanSwimlane>`.
|
||||
- [ ] Write `swimlanes.test.ts`.
|
||||
|
||||
---
|
||||
|
||||
## 7. `useKanban` hook (`src/core/board/board.ts`)
|
||||
|
||||
- [ ] Hook composing moves + wip + swimlanes; keyboard-drag support (ArrowLeft/Right/Up/Down).
|
||||
- [ ] Wire OTel counters + histogram.
|
||||
- [ ] Write `board.test.ts` (≤500 lines). Write `board.md`.
|
||||
|
||||
---
|
||||
|
||||
## 8. Column module (`src/core/column/`)
|
||||
|
||||
- [ ] `column.ts` — column type helpers: `addCard`, `removeCard`, `reorderCards`.
|
||||
- [ ] Write `column.test.ts`, `column.md`.
|
||||
|
||||
---
|
||||
|
||||
## 9. Card module (`src/core/card/`)
|
||||
|
||||
- [ ] `card.ts` — card type helpers: `updateCard`, `cardMatches`.
|
||||
- [ ] Write `card.test.ts`, `card.md`.
|
||||
|
||||
---
|
||||
|
||||
## 10. Drag-drop utilities (`src/utils/drag-drop/`)
|
||||
|
||||
- [ ] `drag-drop.ts` — `DragSource`, `DropTarget` helpers; drag-handle type utilities.
|
||||
- [ ] Write `drag-drop.test.ts`, `drag-drop.md`.
|
||||
|
||||
---
|
||||
|
||||
## 11. Board schemas (`src/schema/board-schema/`)
|
||||
|
||||
- [ ] `board-schema.ts` — `KanbanBoardSchema`, `KanbanColumnSchema`, `KanbanCardSchema`; `registerKanbanSchemas()`.
|
||||
- [ ] Write `board-schema.md`.
|
||||
|
||||
---
|
||||
|
||||
## 12. Reference `Card` component (`src/components/card/`)
|
||||
|
||||
- [ ] `card.tsx` — draggable card with keyboard support; `card.stories.tsx` (default, variants). Axe-core clean.
|
||||
- [ ] Write `card.test.tsx`, `card.md`.
|
||||
|
||||
---
|
||||
|
||||
## 13. Reference `Column` component (`src/components/column/`)
|
||||
|
||||
- [ ] `column.tsx` — drop-target column showing WIP badge; `column.stories.tsx`. Axe-core clean.
|
||||
- [ ] Write `column.test.tsx`, `column.md`.
|
||||
|
||||
---
|
||||
|
||||
## 14. Reference `Board` component (`src/components/board/`)
|
||||
|
||||
- [ ] `board.tsx` — full board composing `Column` + `Card`; `board.stories.tsx` (default, playground, WIP-enforcement, swimlanes).
|
||||
- [ ] Write `board.test.tsx`, `board.md`.
|
||||
|
||||
---
|
||||
|
||||
## 15. Integration test (`tests/integration.test.ts`)
|
||||
|
||||
- [ ] Full round-trip: render board, drag card, assert state, verify WIP rejection.
|
||||
- [ ] Keyboard-drag round-trip (arrow keys).
|
||||
|
||||
---
|
||||
|
||||
## 16. Docs + verify
|
||||
|
||||
- [ ] Write `.md` per module (≥200 words, API reference, examples).
|
||||
- [ ] Write `README.md` with subpath table, hook API, WIP-limit guide, a11y notes.
|
||||
- [ ] `bunx turbo lint typecheck test --filter=@suaveplan/react-kanban` — green.
|
||||
- [ ] `bunx turbo test:coverage` — 100%.
|
||||
- [ ] No `@ts-expect-error` in `src/` or tests. No `react-dom` in runtime deps.
|
||||
- [ ] All subpath exports resolve to real source files.
|
||||
- [ ] Reference components pass axe-core.
|
||||
- [ ] `bun scripts/publish.ts --package @suaveplan/react-kanban`.
|
||||
- [ ] Archive to `openspec/archive/2026-04-24-enterprise-browser-react-kanban/`.
|
||||
Reference in New Issue
Block a user