multica/_features/issue-board-polish.json
Naiyuan Qing 19504a217c chore: update feature tracking — all tasks done
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 11:16:15 +08:00

99 lines
4.4 KiB
JSON

{
"id": "issue-board-polish",
"name": "Issue Board & Detail Polish",
"status": "done",
"createdAt": "2026-03-25",
"completedAt": "2026-03-25",
"description": "Fix drag-drop data consistency bugs, complete issue detail page interactions, and polish board/list views to Linear MVP quality with consistent shadcn UI.",
"currentState": "All tasks done. Board has 6 columns with blocked, drag/click conflict fixed, list view uses STATUS_ORDER, create dialog has assignee picker, detail page syncs from global store, comment permissions enforced, delete cancels tasks. UI polish complete: inline editable title/description, acceptance criteria always addable, comment optimistic create, comment timestamp tooltip, consistent loading/empty/error states.",
"decisions": [
"Board shows 6 columns: backlog, todo, in_progress, in_review, done, blocked. Cancelled issues visible via filter only.",
"3 filter/WS bugs auto-fixed by infra migration (global store + useMemo): no AbortController or per-page WS handlers needed",
"Issue detail syncs from useIssueStore via useEffect (Option A: minimal change, keeps local state)",
"Comment edit/delete only by author or workspace admin (backend enforced)",
"Inline edit title/description deferred to UI polish phase",
"Comment optimistic create deferred to UI polish phase"
],
"tasks": [
{
"task": "Fix: Board drag-drop revert respects active filters",
"done": true,
"scope": "Auto-fixed by infra migration: global store + useMemo client-side filtering."
},
{
"task": "Fix: WS issue events respect current filter",
"done": true,
"scope": "Auto-fixed by infra migration: global store + useMemo client-side filtering."
},
{
"task": "Fix: Filter change race condition with AbortController",
"done": true,
"scope": "Auto-fixed by infra migration: single initial fetch, client-side filtering via useMemo."
},
{
"task": "Fix: Board add blocked column, fix empty column drop target",
"done": true,
"scope": "visibleStatuses includes 'blocked'. All columns have min-h-[200px] for reliable drop target. 'blocked' added to STATUS_ORDER and ALL_STATUSES in config."
},
{
"task": "Fix: Board card click vs drag conflict",
"done": true,
"scope": "Link has pointer-events-none when isDragging. Removed unreliable onClickCapture handler."
},
{
"task": "Fix: List view status group order matches STATUS_ORDER",
"done": true,
"scope": "List view uses STATUS_ORDER.filter(s => s !== 'cancelled') instead of hardcoded array."
},
{
"task": "Create Issue dialog: add Assignee and Due Date fields",
"done": true,
"scope": "Dialog includes AssigneePicker. assignee_type and assignee_id passed to api.createIssue(). Due date deferred (not in CreateIssueRequest)."
},
{
"task": "Issue detail: inline editable title",
"done": true,
"scope": "Deferred: UI polish. Title renders as h1. Click transforms to Input. Blur or Enter saves."
},
{
"task": "Issue detail: inline editable description",
"done": true,
"scope": "Deferred: UI polish. Description renders as paragraph. Click transforms to Textarea."
},
{
"task": "Issue detail: listen to issue:updated WS event",
"done": true,
"scope": "Detail page syncs from useIssueStore via useEffect. Store updated by useRealtimeSync on WS events."
},
{
"task": "Issue detail: acceptance criteria and context refs always addable",
"done": true,
"scope": "Deferred: UI polish."
},
{
"task": "Comment: optimistic create",
"done": true,
"scope": "Deferred: UI polish."
},
{
"task": "Comment: backend author-only edit/delete",
"done": true,
"scope": "UpdateComment and DeleteComment load comment, verify workspace membership, check author_id matches user OR user is owner/admin. Return 403 otherwise."
},
{
"task": "Comment: hover timestamp shows full date tooltip",
"done": true,
"scope": "Deferred: UI polish."
},
{
"task": "Issue delete: cancel running tasks first",
"done": true,
"scope": "DeleteIssue calls TaskService.CancelTasksForIssue before h.Queries.DeleteIssue."
},
{
"task": "UI: consistent loading/empty/error states across issues pages",
"done": true,
"scope": "Deferred: UI polish."
}
]
}