From bf0dc1cca9ffcfa9dc05846cf90d9f66db111bd9 Mon Sep 17 00:00:00 2001 From: William Zujkowski Date: Tue, 31 Mar 2026 21:51:08 -0400 Subject: [PATCH] feat: add RSS feed for recent US Code updates (#132) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - /feed.xml endpoint using @astrojs/rss - Shows 50 most recently updated sections - Title format: "N U.S.C. § M — Section name" - Feed autodiscovery link in BaseLayout head - Enables RSS readers and monitoring tools to track changes Closes #132 Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/web/package.json | 3 ++- apps/web/src/layouts/BaseLayout.astro | 1 + apps/web/src/pages/feed.xml.ts | 29 +++++++++++++++++++++++++++ pnpm-lock.yaml | 12 +++++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 apps/web/src/pages/feed.xml.ts diff --git a/apps/web/package.json b/apps/web/package.json index 708aeda..9b7dabd 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -12,8 +12,9 @@ "test": "vitest run" }, "dependencies": { - "@civic-source/types": "workspace:*", + "@astrojs/rss": "^4.0.18", "@astrojs/svelte": "^8.0.4", + "@civic-source/types": "workspace:*", "@octokit/rest": "^22.0.1", "@tailwindcss/typography": "^0.5.19", "@tailwindcss/vite": "^4.2.2", diff --git a/apps/web/src/layouts/BaseLayout.astro b/apps/web/src/layouts/BaseLayout.astro index a2fdcc1..1b02698 100644 --- a/apps/web/src/layouts/BaseLayout.astro +++ b/apps/web/src/layouts/BaseLayout.astro @@ -38,6 +38,7 @@ const titleEntries = Object.entries(TITLE_NAMES) + diff --git a/apps/web/src/pages/feed.xml.ts b/apps/web/src/pages/feed.xml.ts new file mode 100644 index 0000000..cb13f67 --- /dev/null +++ b/apps/web/src/pages/feed.xml.ts @@ -0,0 +1,29 @@ +import rss from '@astrojs/rss'; +import { getCollection } from 'astro:content'; +import type { APIContext } from 'astro'; + +export async function GET(context: APIContext) { + const statutes = await getCollection('statutes'); + + // Sort by generated_at descending to get most recently updated sections + const sorted = statutes + .filter(s => s.data.generated_at) + .sort((a, b) => { + const aDate = a.data.generated_at ?? ''; + const bDate = b.data.generated_at ?? ''; + return bDate.localeCompare(aDate); + }) + .slice(0, 50); + + return rss({ + title: 'US Code Tracker — Recent Updates', + description: 'Track amendments to the United States Code. Updated weekly from the Office of the Law Revision Counsel.', + site: context.site ?? 'https://civic-source.github.io/us-code-tracker/', + items: sorted.map(entry => ({ + title: `${entry.data.usc_title} U.S.C. § ${entry.data.usc_section} — ${entry.data.title.replace(/^Section \S+ - /, '')}`, + pubDate: new Date(entry.data.generated_at ?? Date.now()), + link: `/us-code-tracker/statute/${entry.id}/`, + description: `${entry.data.classification}. Current through ${entry.data.current_through}.`, + })), + }); +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 339730d..5ca99f5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,6 +47,9 @@ importers: apps/web: dependencies: + '@astrojs/rss': + specifier: ^4.0.18 + version: 4.0.18 '@astrojs/svelte': specifier: ^8.0.4 version: 8.0.4(@types/node@25.5.0)(astro@6.1.2(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.0)(typescript@5.9.3)(yaml@2.8.3))(jiti@2.6.1)(lightningcss@1.32.0)(svelte@5.55.0)(typescript@5.9.3)(yaml@2.8.3) @@ -256,6 +259,9 @@ packages: resolution: {integrity: sha512-nksZQVjlferuWzhPsBpQ1JE5XuKAf1id1/9Hj4a9KG4+ofrlzxUUwX4YGQF/SuDiuiGKEnzopGOt38F3AnVWsQ==} engines: {node: '>=22.12.0'} + '@astrojs/rss@4.0.18': + resolution: {integrity: sha512-wc5DwKlbTEdgVAWnHy8krFTeQ42t1v/DJqeq5HtulYK3FYHE4krtRGjoyhS3eXXgfdV6Raoz2RU3wrMTFAitRg==} + '@astrojs/svelte@8.0.4': resolution: {integrity: sha512-c5m3chjtgxBE3BzsE/bZbCFBkLPhq041rm2WJFaTIKGwt/3xNm/5efYCj23reuAcBsl4iYS8n2UwkAHQJzhkZA==} engines: {node: '>=22.12.0'} @@ -3158,6 +3164,12 @@ snapshots: dependencies: prismjs: 1.30.0 + '@astrojs/rss@4.0.18': + dependencies: + fast-xml-parser: 5.5.9 + piccolore: 0.1.3 + zod: 4.3.6 + '@astrojs/svelte@8.0.4(@types/node@25.5.0)(astro@6.1.2(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.0)(typescript@5.9.3)(yaml@2.8.3))(jiti@2.6.1)(lightningcss@1.32.0)(svelte@5.55.0)(typescript@5.9.3)(yaml@2.8.3)': dependencies: '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.55.0)(vite@7.3.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3))