Skip to content

Migrate guides from Sanity to Course Builder#1592

Open
Creeland wants to merge 3 commits intomainfrom
creeland/egg-424-migrate-guides-from-sanity-to-course-builder
Open

Migrate guides from Sanity to Course Builder#1592
Creeland wants to merge 3 commits intomainfrom
creeland/egg-424-migrate-guides-from-sanity-to-course-builder

Conversation

@Creeland
Copy link
Copy Markdown
Contributor

@Creeland Creeland commented Apr 1, 2026

Summary

  • Data layer: Add guides-from-course-builder.ts with full hierarchy queries (guide → sections → resources) reading from Course Builder's ContentResource/ContentResourceResource tables
  • Route rewrite: Update /guides and /guides/[slug] pages to use Course Builder via a server-side wrapper (load-guide-wrapper.ts), with zero changes to GuideTemplate
  • Search: Add Inngest event + TypeSense upsert function so guides appear in search with type: 'guide' facet
  • Sanity cleanup: Remove guide schema, desk structure entry, and GROQ fetching code from Sanity studio
  • Schema: Extract guide Zod types to src/schemas/guide.ts; add ListTypeSchema (tutorial | nextUp | guide) in src/schemas/list.ts

Test plan

  • Verify /guides index page renders published guides from Course Builder
  • Verify /guides/coding-your-way-to-the-job renders with correct sections and resources
  • Verify guide appears in TypeSense search with correct type facet
  • Verify Sanity studio loads without errors (guide removed from schema/desk)
  • Run npx tsc --noEmit — passes cleanly

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Integrated guides with Course Builder as the primary data source
    • Added event-driven publishing that automatically indexes published guides in search
  • Refactor

    • Migrated guide data loading to server-safe wrappers and updated guide type imports across pages/components
  • Chores

    • Removed Sanity CMS guide document schema and related admin/studio configurations

Creeland and others added 2 commits April 1, 2026 12:50
Rewrite guide pages to read from Course Builder database instead of
Sanity CMS. Guides are stored as ContentResource with type='list' and
fields.type='guide', with sections and resource links via the
ContentResourceResource join table.

- Add guides-from-course-builder.ts with CB query functions
- Add load-guide-wrapper.ts for client-safe server-side imports
- Update guide index and slug pages to use new data source
- Add guide/published Inngest event and TypeSense upsert function
- Register upsertGuideToTypesense in Inngest config

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Guides now fully read from Course Builder. Move guide Zod schemas
to src/schemas/guide.ts, delete Sanity fetching code (src/lib/guides.ts),
remove guide from Sanity studio schema/structure/desk, and add
ListTypeSchema for list-type resource discrimination.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@linear
Copy link
Copy Markdown

linear bot commented Apr 1, 2026

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 1, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
egghead-io-nextjs Ready Ready Preview, Comment Apr 1, 2026 6:20pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 1, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 19f6ed4d-bd7a-4d1a-98f8-0f621009bfa7

📥 Commits

Reviewing files that changed from the base of the PR and between 1e984c6 and f8305d3.

📒 Files selected for processing (1)
  • studio/schemas/documents/resource.tsx
💤 Files with no reviewable changes (1)
  • studio/schemas/documents/resource.tsx

📝 Walkthrough

Walkthrough

Migrates guide content from Sanity to a Course Builder MySQL backend, adds Inngest event and Typesense upsert workflow for published guides, implements server-side DB loaders with client-safe wrappers, updates Next.js guide pages to use the new loaders, and removes Sanity guide schemas/Studio structures.

Changes

Cohort / File(s) Summary
Type Imports & Schemas
src/components/guides/guide-template.tsx, src/schemas/guide.ts, src/schemas/list.ts
Switched component type imports to @/schemas/guide; removed Sanity fetch functions from src/schemas/guide.ts; added ListTypeSchema (`'tutorial'
Inngest Events & Types
src/inngest/events/guide-published.ts, src/inngest/inngest.server.ts, src/inngest/inngest.config.ts
Added GUIDE_PUBLISHED_EVENT, Zod event schema and inferred types; registered event in Inngest server event map and added the function to config.
Typesense Upsert Function
src/inngest/functions/typesense/upsert-guide-to-typesense.ts
New Inngest function upsertGuideToTypesense: initializes Typesense client from env, validates guide payload, transforms data, and upserts into configured Typesense collection.
Course Builder DB Loaders
src/lib/guides-from-course-builder.ts, src/lib/load-guide-wrapper.ts
New MySQL-backed getGuidesFromCourseBuilder and getGuideFromCourseBuilder with pooling and mapping to Guide/GuideResource shapes; added server-only wrappers loadGuides/loadGuide that no-op on client.
Next.js Page Changes
src/pages/guides/[slug].tsx, src/pages/guides/index.tsx
Pages now call loadGuides/loadGuide from wrapper and Guide types from schemas; [slug] uses fallback: 'blocking', returns notFound: true when missing, and filters static paths to published guides.
Sanity Studio Removal
studio/deskStructure.ts, studio/schemas/documents/guide.tsx, studio/schemas/schema.js, studio/src/structure/guides.js, studio/schemas/documents/resource.tsx
Removed the guide document schema and Studio guides structure; removed guide reference target from resource references; updated desk/schema exports to omit guide.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant App as Next.js App
    participant CourseDB as Course Builder DB
    participant Inngest as Inngest
    participant Typesense as Typesense

    User->>App: Publish or update guide
    App->>Inngest: Emit GUIDE_PUBLISHED_EVENT
    Inngest->>Inngest: Validate event (Zod)
    Inngest->>Typesense: upsert-guide step with payload
    Typesense->>Typesense: Transform payload -> document
    Typesense-->>Inngest: Upsert result

    App->>CourseDB: loadGuide(slug) / loadGuides()
    CourseDB-->>App: Return guide(s) rows
    App->>App: Map DB rows -> Guide types
    App-->>User: Render guide pages
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Suggested reviewers

  • joelhooks
  • zacjones93

Poem

🐰 I hopped from Sanity's meadow wide,
To Builder's burrow, tucked inside.
Inngest hums and Typesense gleams,
Guides now bound for faster streams.
Thump-thump—now off to index dreams!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.56% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Migrate guides from Sanity to Course Builder' accurately and directly describes the primary objective of the changeset: moving guide content management from Sanity to Course Builder.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch creeland/egg-424-migrate-guides-from-sanity-to-course-builder

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

The resource document schema still referenced the deleted guide type,
causing a Sanity studio error.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (3)
src/inngest/functions/typesense/upsert-guide-to-typesense.ts (1)

40-49: Avoid schema drift by reusing GuidePublishedEventSchema directly.

guideSchema duplicates the event schema fields. Reuse the imported schema so producer/consumer contracts stay locked.

Proposed simplification
-export const guideSchema = z.object({
-  guideId: z.string(),
-  title: z.string(),
-  description: z.string().optional(),
-  slug: z.string(),
-  path: z.string(),
-  image: z.string().optional(),
-  createdAt: z.string().optional(),
-  updatedAt: z.string(),
-})
+export const guideSchema = GuidePublishedEventSchema
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/inngest/functions/typesense/upsert-guide-to-typesense.ts` around lines 40
- 49, The current guideSchema duplicates fields from GuidePublishedEventSchema;
replace the z.object literal by reusing the imported GuidePublishedEventSchema
to prevent schema drift. Locate guideSchema and change its definition to
reference GuidePublishedEventSchema directly (or use
GuidePublishedEventSchema.pick(...) / .omit(...) if only a subset is needed) so
the consumer/producer contract is shared via the single source of truth.
src/pages/guides/index.tsx (1)

19-20: Minor: Redundant filter condition.

The && guide is unnecessary since guide is always truthy when iterating over an array.

Suggested simplification
         resources: guides.filter(
-          (guide) => guide.state === 'published' && guide,
+          (guide) => guide.state === 'published',
         ),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/guides/index.tsx` around lines 19 - 20, The filter predicate in the
expression using guides.filter currently has a redundant "&& guide" check;
update the predicate (the arrow function for guides.filter) to only check
guide.state === 'published' (remove the "&& guide") so the filter only tests the
published state; locate the arrow function passed to guides.filter in the
component/page and simplify it accordingly.
src/lib/guides-from-course-builder.ts (1)

140-207: N+1 query pattern for section resources.

Each section triggers a separate database query for its child resources. For guides with many sections, this results in N+1 queries. While acceptable for SSG (build-time only), consider a single JOIN query if performance becomes a concern with larger guides.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/guides-from-course-builder.ts` around lines 140 - 207, The current
code issues an N+1 query inside the sectionRows.map async loop by calling
activeConn.execute for each sectionId; instead, run one query up-front that
selects all resource rows WHERE crr.resourceOfId IN (all section ids) (using the
same SELECT fields and JOIN from the existing activeConn.execute),
parse/JSON-decode each row's metadata and compute resource fields exactly as
done in the per-section mapper, then group the returned rows by resourceOfId
and, in the existing sectionRows.map, lookup the grouped resources for that
sectionId to build GuideResource objects (use the same identifiers resourceRow,
resourceFields, metadata, mapResourceType, etc.) so you replace the per-section
execute call with a single batch fetch and grouping step.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/inngest/functions/typesense/upsert-guide-to-typesense.ts`:
- Around line 82-90: The upsert path started in the async
step.run('upsert-guide', ...) around syncWithSearchProvider (using guideSchema,
syncToTypeSense, transformGuideData) lacks structured start/success/error logs
and respect for the repo-wide log toggle; add an explicit info log before
starting the upsert (e.g., "starting upsert-guide" with event id/context), a
success info log after syncWithSearchProvider resolves, and an error log that
catches and logs handled errors and unexpected exceptions (including the error
object) within the step.run block; ensure these logs use the shared logger used
elsewhere (e.g., processLogger or repo logger) and honor the LOG_LEVEL/--no-log
toggle so that when logging is disabled no log file is created and no output is
emitted.
- Around line 79-82: The repository registers upsertGuideToTypesense to handle
GUIDE_PUBLISHED_EVENT but never emits that event; add an event producer by
calling inngest.send({ name: GUIDE_PUBLISHED_EVENT, data: { ...guide payload...
} }) at the point where guides are published (the code path that performs the
publish/save action), ensuring the payload includes the guide id, title,
content/summary and any metadata the upsertGuideToTypesense handler expects so
indexing will be triggered.

In `@src/inngest/inngest.server.ts`:
- Line 63: The import for GUIDE_PUBLISHED_EVENT and GuidePublished should use
the repository's src alias; update the import statement that currently imports
GUIDE_PUBLISHED_EVENT and GuidePublished from './events/guide-published' to use
'@/inngest/events/guide-published' so it follows the "src/**/*.{ts,tsx}" `@/` path
alias convention.

In `@src/lib/guides-from-course-builder.ts`:
- Around line 5-7: The module-level const access = { uri:
process.env.COURSE_BUILDER_DATABASE_URL } reads the env var at import time and
can be undefined; move the environment access into the runtime scope (e.g.,
inside the functions that use ConnectionOptions or inside any function that
constructs the connection) or use the shared pool from db.ts instead of the
module-scoped access; specifically replace module-scope use of
access/ConnectionOptions with code that reads
process.env.COURSE_BUILDER_DATABASE_URL at call time (or calls the db.ts pool
factory) and pass that constructed ConnectionOptions into the functions that
establish connections.
- Around line 9-21: The file defines a duplicate singleton getConnectionPool()
and connectionPool which should be removed and replaced with the shared
getPool() from db.ts; delete the local connectionPool variable and
getConnectionPool() function, import or use the existing getPool() function
instead, and replace all calls to getConnectionPool() in this module with
getPool() to avoid duplicate pools and ensure a single shared connection pool is
used.

---

Nitpick comments:
In `@src/inngest/functions/typesense/upsert-guide-to-typesense.ts`:
- Around line 40-49: The current guideSchema duplicates fields from
GuidePublishedEventSchema; replace the z.object literal by reusing the imported
GuidePublishedEventSchema to prevent schema drift. Locate guideSchema and change
its definition to reference GuidePublishedEventSchema directly (or use
GuidePublishedEventSchema.pick(...) / .omit(...) if only a subset is needed) so
the consumer/producer contract is shared via the single source of truth.

In `@src/lib/guides-from-course-builder.ts`:
- Around line 140-207: The current code issues an N+1 query inside the
sectionRows.map async loop by calling activeConn.execute for each sectionId;
instead, run one query up-front that selects all resource rows WHERE
crr.resourceOfId IN (all section ids) (using the same SELECT fields and JOIN
from the existing activeConn.execute), parse/JSON-decode each row's metadata and
compute resource fields exactly as done in the per-section mapper, then group
the returned rows by resourceOfId and, in the existing sectionRows.map, lookup
the grouped resources for that sectionId to build GuideResource objects (use the
same identifiers resourceRow, resourceFields, metadata, mapResourceType, etc.)
so you replace the per-section execute call with a single batch fetch and
grouping step.

In `@src/pages/guides/index.tsx`:
- Around line 19-20: The filter predicate in the expression using guides.filter
currently has a redundant "&& guide" check; update the predicate (the arrow
function for guides.filter) to only check guide.state === 'published' (remove
the "&& guide") so the filter only tests the published state; locate the arrow
function passed to guides.filter in the component/page and simplify it
accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9ce3cea9-d8eb-485e-be76-64118f86ce7c

📥 Commits

Reviewing files that changed from the base of the PR and between e92b91f and 1e984c6.

📒 Files selected for processing (15)
  • src/components/guides/guide-template.tsx
  • src/inngest/events/guide-published.ts
  • src/inngest/functions/typesense/upsert-guide-to-typesense.ts
  • src/inngest/inngest.config.ts
  • src/inngest/inngest.server.ts
  • src/lib/guides-from-course-builder.ts
  • src/lib/load-guide-wrapper.ts
  • src/pages/guides/[slug].tsx
  • src/pages/guides/index.tsx
  • src/schemas/guide.ts
  • src/schemas/list.ts
  • studio/deskStructure.ts
  • studio/schemas/documents/guide.tsx
  • studio/schemas/schema.js
  • studio/src/structure/guides.js
💤 Files with no reviewable changes (3)
  • src/schemas/guide.ts
  • studio/schemas/documents/guide.tsx
  • studio/src/structure/guides.js

Comment on lines +79 to +82
export const upsertGuideToTypesense = inngest.createFunction(
{id: 'upsert-guide-to-typesense', name: 'Upsert Guide to Typesense'},
{event: GUIDE_PUBLISHED_EVENT},
async ({event, step}) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify producer coverage for GUIDE_PUBLISHED_EVENT

# 1) Find all references to the event constant/string
rg -nP --type=ts -C2 '\bGUIDE_PUBLISHED_EVENT\b|guide/published'

# 2) Find Inngest send callsites
rg -nP --type=ts -C3 '\binngest\.send\s*\('

# Expected:
# - At least one send call that emits GUIDE_PUBLISHED_EVENT (or name: "guide/published")

Repository: skillrecordings/egghead-next

Length of output: 8163


Add producer for GUIDE_PUBLISHED_EVENT to enable guide indexing.

The upsertGuideToTypesense function is registered to listen for guide/published events, but no code path in the repository calls inngest.send() to emit this event. Without an event producer, guide search indexing will never execute. Add an inngest.send({name: GUIDE_PUBLISHED_EVENT, data: {...}}) call at the point where guides are published.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/inngest/functions/typesense/upsert-guide-to-typesense.ts` around lines 79
- 82, The repository registers upsertGuideToTypesense to handle
GUIDE_PUBLISHED_EVENT but never emits that event; add an event producer by
calling inngest.send({ name: GUIDE_PUBLISHED_EVENT, data: { ...guide payload...
} }) at the point where guides are published (the code path that performs the
publish/save action), ensuring the payload includes the guide id, title,
content/summary and any metadata the upsertGuideToTypesense handler expects so
indexing will be triggered.

Comment on lines +82 to +90
async ({event, step}) => {
await step.run('upsert-guide', async () => {
return syncWithSearchProvider(
guideSchema,
event.data,
syncToTypeSense,
transformGuideData,
)
})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add structured logs around the upsert operation.

This new background indexing path lacks explicit start/success/error logs, which makes troubleshooting hard and misses the repo’s logging requirements.

As per coding guidelines, "Record start/end of major operations, successful paths, handled errors, and unexpected failures" and "Provide a toggle to disable file logging: LOG_LEVEL=off or --no-log; when disabled, do not create the log file and suppress log output".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/inngest/functions/typesense/upsert-guide-to-typesense.ts` around lines 82
- 90, The upsert path started in the async step.run('upsert-guide', ...) around
syncWithSearchProvider (using guideSchema, syncToTypeSense, transformGuideData)
lacks structured start/success/error logs and respect for the repo-wide log
toggle; add an explicit info log before starting the upsert (e.g., "starting
upsert-guide" with event id/context), a success info log after
syncWithSearchProvider resolves, and an error log that catches and logs handled
errors and unexpected exceptions (including the error object) within the
step.run block; ensure these logs use the shared logger used elsewhere (e.g.,
processLogger or repo logger) and honor the LOG_LEVEL/--no-log toggle so that
when logging is disabled no log file is created and no output is emitted.

WORKSHOP_QUOTE_REQUEST_EVENT,
WorkshopQuoteRequest,
} from './events/workshop-quote-request'
import {GUIDE_PUBLISHED_EVENT, GuidePublished} from './events/guide-published'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use the @/ alias for this new src import.

Please switch this new import to @/inngest/events/guide-published to match repo import conventions.

As per coding guidelines, "src/**/*.{ts,tsx}: Use the @/ path alias for imports from the src directory".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/inngest/inngest.server.ts` at line 63, The import for
GUIDE_PUBLISHED_EVENT and GuidePublished should use the repository's src alias;
update the import statement that currently imports GUIDE_PUBLISHED_EVENT and
GuidePublished from './events/guide-published' to use
'@/inngest/events/guide-published' so it follows the "src/**/*.{ts,tsx}" `@/` path
alias convention.

Comment on lines +5 to +7
const access: ConnectionOptions = {
uri: process.env.COURSE_BUILDER_DATABASE_URL,
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Module-scope environment access may fail if env var is loaded later.

The access object reads process.env.COURSE_BUILDER_DATABASE_URL at module load time. If this wrapper is imported before environment variables are fully loaded (e.g., during module resolution), access.uri will be undefined even when the functions later check for the env var.

Consider moving the env var access inside the function scope, or rely on the shared pool from db.ts which handles this.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/guides-from-course-builder.ts` around lines 5 - 7, The module-level
const access = { uri: process.env.COURSE_BUILDER_DATABASE_URL } reads the env
var at import time and can be undefined; move the environment access into the
runtime scope (e.g., inside the functions that use ConnectionOptions or inside
any function that constructs the connection) or use the shared pool from db.ts
instead of the module-scoped access; specifically replace module-scope use of
access/ConnectionOptions with code that reads
process.env.COURSE_BUILDER_DATABASE_URL at call time (or calls the db.ts pool
factory) and pass that constructed ConnectionOptions into the functions that
establish connections.

Comment on lines +9 to +21
let connectionPool: Pool | null = null

function getConnectionPool(): Pool {
if (!connectionPool) {
connectionPool = mysql.createPool({
...access,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0,
})
}
return connectionPool
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify there's a shared pool implementation in db.ts that can be reused
ast-grep --pattern 'export function getPool() {
  $$$
}'

Repository: skillrecordings/egghead-next

Length of output: 54


🏁 Script executed:

# Search for db.ts file and its content
find . -name "db.ts" -o -name "db.js" | head -20

Repository: skillrecordings/egghead-next

Length of output: 87


🏁 Script executed:

# Search for getConnectionPool or getPool functions in the codebase
rg "getConnectionPool|getPool" --type ts --type js | head -30

Repository: skillrecordings/egghead-next

Length of output: 1397


🏁 Script executed:

# Check the actual guides-from-course-builder.ts file
cat src/lib/guides-from-course-builder.ts

Repository: skillrecordings/egghead-next

Length of output: 8525


🏁 Script executed:

# Read the db.ts file to verify getPool() implementation
cat src/lib/db.ts

Repository: skillrecordings/egghead-next

Length of output: 544


Remove duplicate connection pool; use the shared getPool() from db.ts.

This file creates its own getConnectionPool() singleton, but src/lib/db.ts already provides getPool() configured for the same database. Both implement identical connection pool configs (connectionLimit: 10), creating unnecessary duplication and risking connection exhaustion during builds or concurrent operations.

Per coding guidelines: "Always use the existing getConnectionPool() when accessing the Course Builder database."

Suggested fix: reuse existing pool
-import * as mysql from 'mysql2/promise'
-import {ConnectionOptions, RowDataPacket, Pool} from 'mysql2/promise'
+import {RowDataPacket} from 'mysql2/promise'
+import {getPool} from '@/lib/db'
 import type {Guide, GuideSection, GuideResource} from '@/schemas/guide'
 
-const access: ConnectionOptions = {
-  uri: process.env.COURSE_BUILDER_DATABASE_URL,
-}
-
-let connectionPool: Pool | null = null
-
-function getConnectionPool(): Pool {
-  if (!connectionPool) {
-    connectionPool = mysql.createPool({
-      ...access,
-      waitForConnections: true,
-      connectionLimit: 10,
-      queueLimit: 0,
-    })
-  }
-  return connectionPool
-}

Then replace all getConnectionPool() calls with getPool().

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/guides-from-course-builder.ts` around lines 9 - 21, The file defines
a duplicate singleton getConnectionPool() and connectionPool which should be
removed and replaced with the shared getPool() from db.ts; delete the local
connectionPool variable and getConnectionPool() function, import or use the
existing getPool() function instead, and replace all calls to
getConnectionPool() in this module with getPool() to avoid duplicate pools and
ensure a single shared connection pool is used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant