feat(milestone): SSE live-updating progress bars #14
Reference in New Issue
Block a user
Delete Branch "milestone-sse"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implements milestone 34 — push every milestone progress bar over SSE so open/closed counts and the completion bar move live, no refresh. Closes #10, #11, #12 (and the #9 scope).
Design
Mirrors the shipped project-board SSE feature (#7 + the #8 detach-ctx fix). New package
services/milestone_eventswith the same shape: typed payloads, non-blockingPublish*helpers, publish-time permission filter, broadcast/connectedUIDs seams for testability.repo-milestones.{repo_id}— one channel per repo (the milestone-list page watches many milestones at once; per-repo channel + dispatch-by-milestone_id in the payload avoids N subscriptions). Payloads:milestone.progress {repo_id, milestone_id, open_issues, closed_issues, completeness, session_tag},milestone.deleted {repo_id, milestone_id}.UpdateMilestoneCounters.models/issuescannot importservices/*(real import cycle), so — exactly as project_events did — publish calls live at the service layer:services/issue/{milestone,status,issue}.go(assign/reopen/close/create/delete) + milestone CRUD routers. Documented gap: the cron stats-repair path (models/repo.go) runs in models+cron and can't publish; acceptable (rare repair job; project_events has the same limitation).graceful.GetManager().ShutdownContext()(NOT the request ctx — the exact bug fixed in #8). Session tag resolved synchronously before the goroutine; milestone re-fetched inside the goroutine on the detached ctx.WithSessionTag/SessionTagFromContextextracted out ofproject_eventsinto a new tinymodules/sessiontagpackage somilestone_eventsandproject_eventsboth depend on it without cross-importing.project_eventstests still green after the extraction.web_src/js/features/repo-milestone-sse.tspatches the bar on all four render sites (repo milestone list, user-dashboard milestone list, single-milestone view, with sharedpatchMilestoneCard); templates gaineddata-milestone-id/data-repo-id+ CSS hook classes; init wired in repo-legacy.ts + dashboard.ts.Tests
services/milestone_events15 unit tests (mirror project_events).go build,go vet, project_events tests (post-sessiontag-extraction),tsc --noEmit,vite buildall green. No new REST endpoints (swagger unchanged by this branch).