Repository navigation
fix(display): count completions per track + decouple hero total - #2935
Conversation
Two regressions from the initial track-grouping change, both reported live:
1. Per-track bars counted DISTINCT USERS, not completions. computePathBuckets
deduped by (user, track), so 5 completions by one attendee read as 1.
→ count every TUTORIAL completion in a track (no user dedup).
2. The hero "total activity" counter summed bucket counts. Once buckets became
track-scoped, the hero collapsed from all window completions (~62) to only
track-member completions (3) — and double-counted tutorials shared across
tracks. → computePathBuckets now returns { buckets, totalCompletions };
totalCompletions = ALL window TUTORIAL completions, track-independent.
Frontend (event-stream.ts): totalCount is seeded from totalCompletions on fetch
(falls back to bucket sum for older servers) and bumped by a new per-completion
`completionTick` socket event — NOT by summing buckets. Track bars still driven
by `tutorialCompleted` (one per track). A completion outside every track ticks
the hero but adds no bar; a multi-track tutorial ticks the hero once (one tick
per active event) while lighting each of its track bars.
Backend socket emit (developer-service.js) now fires `completionTick` once per
active event for every completion, plus `tutorialCompleted` per matching track.
New `completionTick` event declared on both EventStreamService + DisplayService.
Checkpoints DEFERRED: probe of event 10000002 shows 0 window checkpoint
completions and all 7 checkpoint path items carry null taskLegacyId (no join
key) — counting them would be inert. The two prize-only Joule tracks reading 0
is dead-slot path data (11 null-legacyId tutorial items in the mission), a
content issue tracked separately, not a display bug.
Verified against PROD event 10000002: totalCompletions=62, ABAP=3 (was 2 under
user-dedup), Joule Studio=1.
…skLegacyId buildTrackMap matched completions to tracks using only CompletionPathItems. taskLegacyId. But manually-authored event content (#1866) populates the item's tutorial_ID FK (UUID) and leaves taskLegacyId NULL — the normal shape for the TechEd/DSAG event missions, not a data defect. Those FK-only items fell through entirely, so whole tracks with real tutorials AND real completions ("Joule Studio with N8N", "Keynote Demo", "Agent Extension", "Command Line", "Frontend") counted 0. Resolve FK-first, mirroring path-item-task-resolver.buildTaskMap: - direct TUTORIAL items: prefer tutorial_ID → Tutorials.legacyId, else taskLegacyId - GROUP children (GroupPathItems): resolve tutorial_ID → legacyId too - CHECKPOINT/PETOBERFEST unchanged (no FK column) All collected tutorial_ID UUIDs resolved to legacyId in one batch, then the map is keyed by legacyId (what TaskRecords.taskLegacyId carries). Verified against PROD event 10000002: previously-zero tracks now count — "Joule Studio with N8N"=1, "Joule Studio Keynote Demo"=1 (the two tracks the reporter completed), alongside "Joule Studio"=1, "ABAP"=3; totalCompletions=66. New unit test: Track Gamma fed by an FK-only path item (tutorial_ID set, taskLegacyId NULL) + a completion carrying the resolved legacyId → counts 1.
|
Added a third fix (commit 3b2ab68): resolve track path items by The reporter flagged that tracks they'd completed ("Joule Studio with N8N", "Keynote Demo") still showed 0. Root cause: Now FK-first (mirrors PROD probe event 10000002 after fix: "Joule Studio with N8N"=1, "Joule Studio Keynote Demo"=1 (both now appear), "Joule Studio"=1, "ABAP"=3, totalCompletions=66. New unit test covers an FK-only path item. |
Summary
Two regressions from the initial track-grouping fix (#2933), both reported on the live PROD display:
computePathBucketsdeduped by(user, track), so 5 completions by one attendee read as 1. → now counts every TUTORIAL completion in a track (no user dedup).computePathBucketsnow returns{ buckets, totalCompletions };totalCompletions= all window TUTORIAL completions, track-independent.Changes
srv/lib/event-path-buckets.js— count completions (not users); return{ buckets, totalCompletions }.srv/event-stream-service.{js,cds}— exposetotalCompletions; declare newcompletionTickevent.srv/display-service.{js,cds}— unpack.buckets(admin array contract unchanged); declarecompletionTick.srv/developer-service.js— socket now firescompletionTickonce per active event for every completion (drives hero), plustutorialCompletedper matching track (drives bars).app/display-app/src/event-stream.ts—totalCountseeded fromtotalCompletions(falls back to bucket sum for old servers), bumped bycompletionTick; no longer summed from buckets.Deferred (data issue, not display)
Checkpoints: probe of event 10000002 shows 0 window checkpoint completions and all 7 checkpoint path items have null
taskLegacyId(no join key) — counting them would be inert. The two prize-only Joule tracks reading 0 is dead-slot path data (11 null-legacyId tutorial items in the mission), tracked separately.Verification
totalCompletions=62,ABAP=3(was 2 under user-dedup),Joule Studio=1.Test plan