{ "id": "issue-board-polish", "name": "Issue Board & Detail Polish", "status": "in_progress", "createdAt": "2026-03-25", "completedAt": null, "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": "Core 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. Remaining: inline edit title/description, comment optimistic create, comment timestamp tooltip, acceptance criteria UI, loading/empty states — all deferred as UI polish.", "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": false, "scope": "Deferred: UI polish. Title renders as h1. Click transforms to Input. Blur or Enter saves." }, { "task": "Issue detail: inline editable description", "done": false, "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": false, "scope": "Deferred: UI polish." }, { "task": "Comment: optimistic create", "done": false, "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": false, "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": false, "scope": "Deferred: UI polish." } ] }