From 4b5ae562c7cbfd9b1e2bbda7aee16704d2d9c625 Mon Sep 17 00:00:00 2001 From: Oliver Kieselbach Date: Tue, 1 Sep 2026 22:55:54 +0200 Subject: [PATCH] fix(web): drop retired /docs, /roadmap and /changelog from sitemap lastmod generator The generator still listed the removed docs sections, roadmap and changelog (all moved to docs.autopilotmonitor.com / retired), and lacked /get-started, which the sitemap emits -- so that entry got "now" as lastmod on every build. - PAGE_MAP now matches exactly the URLs app/sitemap.ts emits - generator fails on a missing source file instead of using the deleted file's last commit date - sitemap throws at build time for a URL without a lastmod entry - fix stale comment: the /docs redirects live in staticwebapp.config.json Co-Authored-By: Claude Fable 5.1 --- src/Web/autopilot-monitor-web/app/sitemap.ts | 13 +++++++--- .../scripts/generate-lastmod.js | 25 +++++++------------ .../utils/page-lastmod.generated.ts | 16 ++---------- 3 files changed, 21 insertions(+), 33 deletions(-) diff --git a/src/Web/autopilot-monitor-web/app/sitemap.ts b/src/Web/autopilot-monitor-web/app/sitemap.ts index 2f8d6409..2259ee21 100644 --- a/src/Web/autopilot-monitor-web/app/sitemap.ts +++ b/src/Web/autopilot-monitor-web/app/sitemap.ts @@ -7,13 +7,20 @@ import { SITE_URL } from "@/utils/config"; const BASE_URL = SITE_URL; +// Build-time only (static export): a URL missing from PAGE_LASTMOD means +// scripts/generate-lastmod.js drifted from this list -- fail the build rather +// than emit "now" as lastmod on every deploy. function lastmod(urlPath: string): Date { const iso = PAGE_LASTMOD[urlPath]; - return iso ? new Date(iso) : new Date(); + if (!iso) { + throw new Error(`sitemap: no lastmod entry for ${urlPath} (add it to scripts/generate-lastmod.js PAGE_MAP)`); + } + return new Date(iso); } -// Documentation lives at docs.autopilotmonitor.com (GitBook) and is indexed -// there; the old /docs/* URLs permanently redirect (see next.config.ts). +// Documentation and the changelog live at docs.autopilotmonitor.com (GitBook) +// and are indexed there; the old /docs/* and /changelog URLs permanently +// redirect (see staticwebapp.config.json). export default function sitemap(): MetadataRoute.Sitemap { return [ { diff --git a/src/Web/autopilot-monitor-web/scripts/generate-lastmod.js b/src/Web/autopilot-monitor-web/scripts/generate-lastmod.js index 1c4dd600..70a40bff 100644 --- a/src/Web/autopilot-monitor-web/scripts/generate-lastmod.js +++ b/src/Web/autopilot-monitor-web/scripts/generate-lastmod.js @@ -13,33 +13,26 @@ const path = require("path"); const WEB_ROOT = path.resolve(__dirname, ".."); const OUTPUT_FILE = path.join(WEB_ROOT, "utils/page-lastmod.generated.ts"); -// URL path -> source file(s) relative to WEB_ROOT -// For docs sections, we check the section component file +// URL path -> source file(s) relative to WEB_ROOT. +// Must list exactly the public pages emitted by app/sitemap.ts; the sitemap +// fails the build for any URL missing here. Documentation and the changelog +// live on docs.autopilotmonitor.com (GitBook) and are not part of this site. const PAGE_MAP = { "/": ["app/page.tsx"], "/about": ["app/about/page.tsx"], + "/get-started": ["app/get-started/page.tsx"], + "/plans": ["app/plans/page.tsx", "components/plans/planData.ts"], "/buy": ["app/buy/page.tsx"], "/help": ["app/help/page.tsx"], - "/plans": ["app/plans/page.tsx", "components/plans/planData.ts"], - "/roadmap": ["app/roadmap/page.tsx"], - "/changelog": ["app/changelog/page.tsx"], "/privacy": ["app/privacy/page.tsx"], "/terms": ["app/terms/page.tsx"], - "/docs": ["app/docs/docsNavSections.ts", "app/docs/[section]/page.tsx"], - "/docs/private-preview": ["app/docs/sections/SectionPrivatePreview.tsx"], - "/docs/overview": ["app/docs/sections/SectionOverview.tsx"], - "/docs/general": ["app/docs/sections/SectionGeneral.tsx"], - "/docs/setup": ["app/docs/sections/SectionSetup.tsx"], - "/docs/agent": ["app/docs/sections/SectionAgent.tsx"], - "/docs/agent-setup": ["app/docs/sections/SectionAgentSetup.tsx"], - "/docs/settings": ["app/docs/sections/SectionSettings.tsx"], - "/docs/gather-rules": ["app/docs/sections/SectionGatherRules.tsx"], - "/docs/analyze-rules": ["app/docs/sections/SectionAnalyzeRules.tsx"], - "/docs/ime-log-patterns": ["app/docs/sections/SectionImeLogPatterns.tsx"], }; function getLastCommitDate(filePath) { const absolutePath = path.join(WEB_ROOT, filePath); + if (!fs.existsSync(absolutePath)) { + throw new Error(`generate-lastmod: source file not found: ${filePath}`); + } try { const date = execSync( `git log -1 --format=%aI -- "${absolutePath}"`, diff --git a/src/Web/autopilot-monitor-web/utils/page-lastmod.generated.ts b/src/Web/autopilot-monitor-web/utils/page-lastmod.generated.ts index 4fb2c61b..1e86108f 100644 --- a/src/Web/autopilot-monitor-web/utils/page-lastmod.generated.ts +++ b/src/Web/autopilot-monitor-web/utils/page-lastmod.generated.ts @@ -5,22 +5,10 @@ export const PAGE_LASTMOD: Record = { "/": "2026-07-30T22:21:18+02:00", "/about": "2026-08-23T02:47:52+02:00", + "/get-started": "2026-08-22T19:46:44+02:00", + "/plans": "2026-08-22T19:46:44+02:00", "/buy": "2026-08-31T18:15:28+02:00", "/help": "2026-08-22T18:12:09+02:00", - "/plans": "2026-08-22T19:46:44+02:00", - "/roadmap": "2026-07-06T18:31:00+02:00", - "/changelog": "2026-07-06T18:12:31+02:00", "/privacy": "2026-08-29T11:07:31+02:00", "/terms": "2026-08-29T11:07:31+02:00", - "/docs": "2026-07-06T18:12:31+02:00", - "/docs/private-preview": "2026-07-06T18:12:31+02:00", - "/docs/overview": "2026-07-06T18:12:31+02:00", - "/docs/general": "2026-07-06T18:12:31+02:00", - "/docs/setup": "2026-07-06T18:12:31+02:00", - "/docs/agent": "2026-07-06T18:12:31+02:00", - "/docs/agent-setup": "2026-07-06T18:12:31+02:00", - "/docs/settings": "2026-07-06T18:12:31+02:00", - "/docs/gather-rules": "2026-07-06T18:12:31+02:00", - "/docs/analyze-rules": "2026-07-06T18:12:31+02:00", - "/docs/ime-log-patterns": "2026-07-06T18:12:31+02:00", };