fix(teched): render both directions of Devtoberfest↔TechEd cross-links (#2312) - #2423
Merged
Merged
Conversation
…nks (#2312) Two defects left the #2312 cross-links invisible on PROD despite the concept links being populated: 1. Forward (Devtoberfest -> TechEd) feed was always empty. The forward map was keyed by the KG DevtoberfestSessions.ID (a freshly-minted uuid) but the feed attached by the planner-facade Session.ID — two distinct UUID namespaces, so every lookup missed and every relatedTechEdSessions came back []. Re-key both sides on SESSIONCODE, the one identifier copied verbatim into the KG row (shared dtfSessionKey normalizer). Reverse (TechEd -> DTF) already keyed on the shared slug, which is why only the forward direction was broken. 2. Reverse (TechEd -> DTF) block never rendered on /teched/. The island preferred the baked #teched-data blob over the live /build/teched feed, and relatedDevtoberfestSessions is a request-time field that is always empty in the bake. Flip loadFeed to fetch-first; the blob is now a fallback used only when the fetch fails (offline / CAP down). Tests: added a seam-crossing assembleFeed test (distinct facade ID vs sessionCode key) + a regression guard that a facade-ID-keyed map yields [] — the existing unit test masked the bug by hardcoding map key == session ID. Rewrote the island load tests for the fetch-first contract (prefers live feed, falls back to blob on fetch failure). Backend 13/13, island 90/90. Note: hugo-apps does not declare @vue/test-utils; it resolves from a parent node_modules, which crashes the suite in a fresh worktree. Not fixed here (out of scope) but worth a follow-up devDep declaration. Generated with Claude Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
#2312 shipped the Devtoberfest↔TechEd concept cross-links, but on PROD neither direction rendered despite the concept-link tables being populated and warm (verified:
/build/techedcarries 215/349 sessions with matches). Two independent defects:1. Forward (Devtoberfest → TechEd) — feed always empty
/api/devtoberfest/schedulereturnedrelatedTechEdSessions: []for every session. The forward map was keyed by the KGDevtoberfestSessions.ID(a freshly-minted uuid from the fetch job) butdevtoberfest-feed.jsattached by the planner-facadeSession.ID— two distinct UUID namespaces, so every lookup missed.Fix: re-key both sides on
SESSIONCODE, the one identifier copied verbatim into the KG row. ShareddtfSessionKey()normalizer (trim + uppercase). The reverse direction already keyed on the sharedslug, which is why only forward was broken.2. Reverse (TechEd → Devtoberfest) — block never rendered on
/teched/The
teched-sessions-gridisland preferred the baked#teched-datablob over the live/build/techedfeed.relatedDevtoberfestSessionsis computed per request, so it's always empty in the bake — the page shipped stale-empty related arrays.Fix:
loadFeed()now fetches the live feed first; the baked blob is a fallback used only when the fetch fails (offline / CAP down). Durable — no rebuild needed, and it can't go stale again.Why tests missed it
The existing unit test hardcoded the crosslink map key equal to the session ID (
's1' == sessions[0].ID), forcing the two namespaces equal so the mismatch couldn't surface. Added:assembleFeedtest with a facadeIDdistinct fromSESSIONCODE.[](the old keying can't sneak back).Verification
test/unit/teched-devtoberfest-crosslink.test.js)hugo-apps/src/teched-sessions-grid/)Follow-up (not in this PR)
hugo-apps/package.jsondoes not declare@vue/test-utils— it resolves from a parentnode_modules, which crashes the island suite in a fresh worktree. Worth a devDep declaration.Deploy note
Both directions are gated by
TECHED_DEVTOBERFEST_CROSSLINK_ENABLED(already ON on PROD) + the KG session-link jobs (already warm). Once merged to DEV and promoted, the forward feed lights up immediately; the reverse/teched/cards render on next load (fetch-first, no rebuild).Generated with Claude Code