Conversation
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughAdds a podcast collections feature: static collection definitions, keyword-based scoring utilities, transcript analysis tooling, computed collection augmentation, collection pages and index, navigation link, and related styling and build ignore updates. Changes
Sequence Diagram(s)sequenceDiagram
participant Caller as Build / Page
participant Lib as getComputedCollections()
participant Episodes as getAllEpisodes()
participant FS as Transcript Files (src/content/transcripts)
participant Scorer as scoreTopicRelevance / scoreLLMRelevance
participant Result as Augmented Collections
Caller->>Lib: request computed collections
Lib->>Episodes: fetch episode metadata
Episodes-->>Lib: episode list (slugs, numbers, titles)
Lib->>FS: read transcript files (*.md)
FS-->>Lib: transcript text per episode
Lib->>Scorer: compute relevance per collection/topic
Scorer-->>Lib: relevance scores
Lib->>Lib: apply thresholds & augment static collections
Lib-->>Result: return augmented collections array
Result-->>Caller: consumed by pages / index
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In `@scripts/analyze-transcripts.ts`:
- Around line 155-166: The regex built from raw keywords is not escaped and
treats characters like '.' as regex meta-characters (in the loop over
topicKeywords, using lowerText.match(regex)), causing incorrect matches; add a
small helper (e.g., escapeRegExp) that escapes regex metacharacters and use it
when building the regex for each keyword (replace new
RegExp(keyword.toLowerCase(), 'gi') with new
RegExp(escapeRegExp(keyword.toLowerCase()), 'gi')); optionally wrap the escaped
keyword with word-boundaries if you want whole-word matches; update references
in the for-loop where regex is constructed (topicKeywords, lowerText,
wordCounts) to use the escaped form.
In `@src/lib/collections.ts`:
- Around line 1-3: The code currently calls readdirSync(join(...)) which will
throw if the transcripts directory is missing; update the collections loading
logic (the code that uses readdirSync, readFileSync and exports/merges with
staticCollections) to guard against a missing directory by either wrapping
readdirSync in a try/catch or checking fs.existsSync before reading and
returning an empty array when the directory is absent, and likewise avoid
readFileSync on non-existent files (apply the same guard to the block around
lines that use readFileSync). Ensure you reference the same symbols
(readdirSync, readFileSync, join, staticCollections) when making the change so
the collections export gracefully falls back to staticCollections + [] instead
of throwing.
In `@src/lib/topic-keywords.ts`:
- Around line 71-79: In scoreTopicRelevance, keyword strings are used raw in new
RegExp which treats characters like "." as regex metacharacters and lets short
tokens match inside words; fix by escaping regex metacharacters in each keyword
(the variable used to build regex in the loop) before constructing the RegExp,
and for short alpha-numeric tokens additionally wrap the escaped keyword in word
boundaries (\\b) to avoid partial-word matches; update the regex creation logic
where regex is declared so matches correctly reflect literal keyword
occurrences.
In `@src/pages/collections/index.astro`:
- Around line 16-37: collectionsWithEpisodes currently deduplicates artwork
globally using usedImageUrls and seenInGroup which can leave unique empty for a
collection even though eps exist; update the logic after the for-loop that
builds unique (using getImg, seenInGroup, usedImageUrls) to detect when
unique.length === 0 and then populate unique with a sensible fallback: take the
first up to 4 episodes from eps (or map to a show-level image via getImg) so the
collection isn’t rendered as “No episodes”; keep references to the same symbols
(collectionsWithEpisodes, getImg, unique, eps, seenInGroup, usedImageUrls) so
the fallback runs only when no unique images were found and still preserves
global de-duplication behavior for subsequent collections.
🧹 Nitpick comments (2)
src/lib/collections.ts (1)
30-81: Memoize computed collections to reduce repeated transcript scans.
getComputedCollections()is invoked from multiple pages; caching avoids repeated filesystem reads and scoring during build/SSR. If you need live updates in dev, you can gate the cache or add invalidation.♻️ Optional memoization to reduce repeated work
+let computedCollectionsCache: typeof staticCollections | null = null; + export async function getComputedCollections() { + if (computedCollectionsCache) return computedCollectionsCache; const allEpisodes = await getAllEpisodes(); @@ - return staticCollections.map((col) => ({ + const computed = staticCollections.map((col) => ({ ...col, episodeSlugs: Array.from(membership.get(col.slug)!).sort() - })); + })); + computedCollectionsCache = computed; + return computed; }src/pages/collections/[slug].astro (1)
10-30: Avoid recomputing collections per page by passing prev/next in props.
getComputedCollections()runs ingetStaticPaths()and again to compute pagination. You can compute prev/next once and pass them through props to avoid extra work.♻️ Example refactor to compute prev/next in getStaticPaths
export async function getStaticPaths() { const collections = await getComputedCollections(); - return collections.map((collection) => ({ + return collections.map((collection, index) => ({ params: { slug: collection.slug }, - props: { collection } + props: { + collection, + prevCollection: index > 0 ? collections[index - 1] : null, + nextCollection: index < collections.length - 1 ? collections[index + 1] : null + } })); } -const { collection } = Astro.props; +const { collection, prevCollection, nextCollection } = Astro.props; @@ -// Find current collection index for pagination -const computedCollections = await getComputedCollections(); -const currentIndex = computedCollections.findIndex((c) => c.slug === collection.slug); -const prevCollection = currentIndex > 0 ? computedCollections[currentIndex - 1] : null; -const nextCollection = currentIndex < computedCollections.length - 1 ? computedCollections[currentIndex + 1] : null; +// prevCollection / nextCollection provided by getStaticPaths
Summary by CodeRabbit
New Features
Accessibility / Navigation
Style
✏️ Tip: You can customize this high-level summary in your review settings.