feat: bounty board, task lifecycle, AI work performer flow, notifications (phase 8)
- whitelist HTML sanitizer (stdlib tokenizer) with XSS vector tests - developer board: pool-scoped visibility, customer/search/minBounty/sort filters, stale-task age badges, competing-claims visibility setting, saved filters in profile extras - claims: request/withdraw (developer), approve/decline (consultant) with notifications to winners and losers; unassign/abandon back to board - work tracking: start, sanitized comments with @mention notifications, time logging, submit for review - review queue + review with per-AC checklist stored on the timeline; approve writes the immutable bountyAwards row (human assignees only) - assign-to-AI: §5.2 job submission, HMAC-verified callback endpoint, idempotent by jobId, artifacts downloaded into GridFS, failure path keeps the task assigned with timeline + notification - notifications API + bell with unread badge, dropdown, page, WS toasts - pages: bounty board, my-tasks kanban, task detail (role-driven actions, review dialog, AI dialog), review queue, developer pool Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -155,6 +155,33 @@ table.list th { color: var(--muted); font-size: 0.875rem; }
|
||||
.toast.err { border-left-color: var(--err); }
|
||||
.toast.ok { border-left-color: var(--ok); }
|
||||
|
||||
/* kanban */
|
||||
.kanban { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
|
||||
.kanban-col {
|
||||
background: var(--surface2); border: 1px solid var(--border);
|
||||
border-radius: var(--radius); padding: 16px; min-height: 200px;
|
||||
}
|
||||
.kanban-col h2 { font-size: 0.9rem; text-transform: uppercase; color: var(--muted); }
|
||||
|
||||
/* notification bell */
|
||||
.bell-badge {
|
||||
position: absolute; top: -4px; right: -4px;
|
||||
background: var(--err); color: #fff;
|
||||
font-size: 0.65rem; font-weight: 700;
|
||||
padding: 1px 5px; border-radius: var(--radius);
|
||||
}
|
||||
.notif-panel {
|
||||
position: absolute; right: 0; top: 36px; z-index: 50;
|
||||
width: 320px; max-height: 420px; overflow: auto;
|
||||
background: var(--surface); border: 1px solid var(--border);
|
||||
border-radius: var(--radius); padding: 12px;
|
||||
box-shadow: 0 4px 16px rgba(0,0,0,0.2);
|
||||
}
|
||||
.notif-list { list-style: none; margin: 0 0 8px; padding: 0; }
|
||||
.notif-list li { padding: 8px 0; border-bottom: 1px solid var(--border); }
|
||||
.notif-list a { color: var(--text); text-decoration: none; }
|
||||
.notif-list a:hover { text-decoration: none; opacity: 0.85; }
|
||||
|
||||
/* atomizing progress shimmer */
|
||||
.shimmer {
|
||||
position: relative;
|
||||
|
||||
Reference in New Issue
Block a user