From 1027e96706a16a53a487c613081e416d7b775bde Mon Sep 17 00:00:00 2001 From: Sinduri Guntupalli Date: Thu, 27 Aug 2026 16:44:42 +0200 Subject: [PATCH] fix(sync): auto-register challenge tag routes in ROUTES_WITHOUT_FULL_COVERAGE When a new adventure is synced, its level topics generate /challenges// routes that the route-coverage drift gate (route-coverage.spec.ts) requires to be acknowledged in ROUTES_WITHOUT_FULL_COVERAGE. The script now upserts a GENERATED block per adventure alongside the existing smoke and a11y blocks. Signed-off-by: Sinduri Guntupalli --- scripts/sync-adventure.mjs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/scripts/sync-adventure.mjs b/scripts/sync-adventure.mjs index b090720e3..2821c7868 100644 --- a/scripts/sync-adventure.mjs +++ b/scripts/sync-adventure.mjs @@ -581,6 +581,32 @@ async function main() { routesSrc = upsertRoutesBlock(routesSrc, smokeBlockStart, smokeBlockEnd, smokeBlock, "\n};", "export const SMOKE_ROUTES", routesPath); routesSrc = upsertRoutesBlock(routesSrc, a11yBlockStart, a11yBlockEnd, a11yBlock, "\n];", "export const A11Y_PAGES", routesPath); + + // Each unique tag generates a /challenges// route. The drift gate in + // route-coverage.spec.ts requires every built route to be acknowledged in + // ROUTES_WITHOUT_FULL_COVERAGE (or fully covered). We upsert a GENERATED block + // so new tags are automatically registered; duplicates with the manual list or + // other adventure blocks are harmless (Set-deduplicated at test time). + const tagToSlug = (tag) => + tag.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, ""); + const allAdventureTags = [ + ...new Set( + allLiveLevels + .flatMap((l) => (l.topics ?? []).map((t) => (typeof t === "string" ? t : (t.name ?? "")))) + .filter(Boolean), + ), + ]; + if (allAdventureTags.length > 0) { + const challengeBlockStart = ` // GENERATED:${slug}-challenges`; + const challengeBlockEnd = ` // /GENERATED:${slug}-challenges`; + const challengeBlock = [ + challengeBlockStart, + ...allAdventureTags.map((tag) => ` "/challenges/${tagToSlug(tag)}/",`), + challengeBlockEnd, + ].join("\n"); + routesSrc = upsertRoutesBlock(routesSrc, challengeBlockStart, challengeBlockEnd, challengeBlock, "\n];", "export const ROUTES_WITHOUT_FULL_COVERAGE", routesPath); + } + writeFileSync(routesPath, routesSrc); console.log(`Updated e2e/routes.ts with routes for ${slug}`);