Skip to content

chore(scripts): read the models catalog from Neon instead of Supabase - #157

Merged
charlesrhoward merged 1 commit into
mainfrom
chore/gen-models-from-neon
Oct 20, 2026
Merged

charlesrhoward merged 1 commit into
mainfrom
chore/gen-models-from-neon

Conversation

@charlesrhoward

@charlesrhoward charlesrhoward commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Why

The Mogplex Supabase project (enxvgkxsrpbtqlaeotjz) is being deleted. Production has served from Neon since Aug 3. pnpm gen:models still read ai_models from Supabase over PostgREST, so it was producing a catalog frozen at the cutover and will stop working once the project is gone.

What changes

  • scripts/gen-models-table.ts queries public.ai_models in Neon over DATABASE_URL, using pg. It keeps the same filters (is_hidden = false, is_available = true), ordering and output shape. Numeric columns are cast to float8 so the JSON keeps number types.
  • pg and @types/pg are added as dev dependencies.
  • .env.local needs DATABASE_URL (read access to Mogplex Neon) instead of the two NEXT_PUBLIC_SUPABASE_* keys.

The snapshot itself (src/data/ai-models.json, last refreshed Jul 2) is not refreshed in this PR. A test run against Neon wrote 177 models with the right types. That run was reverted to keep this PR to the data-source change.

Verification

  • pnpm types:check: pass
  • pnpm lint: pass
  • pnpm test: 18 pass
  • pnpm exec tsx scripts/gen-models-table.ts against Neon prod (read-only): wrote 177 models; output reverted

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

The Supabase project is being deleted. gen:models now queries
public.ai_models in Neon over DATABASE_URL with pg (numeric columns cast
to float8 so the snapshot keeps JSON numbers).
@vercel

vercel Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
mogplex-docs Ready Ready Preview Oct 20, 2026 6:05pm UTC

Request Review

@mogplex mogplex Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Mogplex PR Review

Status: Attention needed

Approve-ready change: the swap from Supabase PostgREST to a direct Neon read in scripts/gen-models-table.ts is faithful — same filters, ordering, column set and JSON shape — and pg@8.23.1 carries no known advisories. Fold in three things before merge: the published docs and AGENTS.md still say the snapshot comes from Supabase, the DATABASE_URL contract (shape, sslmode, least-privilege role) is undocumented, and the new SQL has no coverage in tests/.

4 findings were added inline.

Warnings

  • Published docs still say the snapshot comes from Supabase (content/docs/web/models.mdx)
    • content/docs/web/models.mdx tells readers: "The snapshot is regenerated from the Supabase ai_models table by pnpm gen:models." After this change the source is Neon, and the Supabase project is being deleted, so that statement is wrong on a page that ships to users.
    • Update the sentence (and any other Supabase wording on the page) in this PR or a follow-up.
    • AGENTS.md carries the same stale wording in two places: "Refresh src/data/ai-models.json from Supabase" and "src/data/ai-models.json is a snapshot of the Supabase ai_models table" — the repo's own agent guidance will keep sending contributors at the dead project.
    • Nothing else in package.json or src/ references the old Supabase keys, so the doc strings are the only remaining Supabase trace.

View check run

const DATABASE_URL = requireEnv('DATABASE_URL');

const OUTPUT = resolve(process.cwd(), 'src/data/ai-models.json');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Warning: Document the required DATABASE_URL shape (sslmode) and prefer a read-only role

  • new Client({ connectionString: DATABASE_URL }) carries no TLS configuration of its own.
  • node-postgres defaults to ssl: false unless the connection string carries sslmode=… (or PGSSLMODE is set), and Neon "rejects connections that do not use SSL/TLS" — so a DATABASE_URL copied without the query parameter fails with a confusing server-side error instead of the script's own "Missing DATABASE_URL" message.
  • Document the expected value, e.g. postgresql://<user>:<pass>@<neon-host>/<db>?sslmode=require, in the script header comment and/or the PR description.
  • The requireEnv failure message only says "Add it to .env.local first"; make it say where to get the URL and that sslmode is required.
  • The script only needs select on public.ai_models; prefer a dedicated role with GRANT SELECT on that table over handing every contributor a full production credential, since the connection string now carries a real password instead of the old public anon key.
  • No credential exposure found: .env*.local is gitignored so DATABASE_URL stays out of the repo, and pnpm-lock.yaml is updated so pnpm install --frozen-lockfile in CI still resolves.

capabilities,
pricing_input::float8 as pricing_input,
pricing_output::float8 as pricing_output,
pricing_cache_read::float8 as pricing_cache_read,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: Note the row-count jump before the snapshot is refreshed

  • The committed src/data/ai-models.json is a ~20 KB file, which can hold at most ~80 model entries at the current formatting, while the Neon query returns 177 rows.
  • The catalog cardinality therefore differs substantially between the two sources, consistent with the old PostgREST path being filtered by anon-role RLS.
  • The snapshot is intentionally not refreshed in this PR, so the next pnpm gen:models will grow the rendered table on content/docs/web/models.mdx several times over.
  • Worth a follow-up PR that refreshes the snapshot, eyeballs the page, and confirms the extra rows are genuinely visible to users rather than rows RLS was intentionally hiding.

rows = (await client.query<Row>(QUERY, [PAGE_SIZE])).rows;
} finally {
await client.end();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: Consider an explicit ssl option instead of relying on the URL

  • Passing ssl in the config object and sslmode in the connection string interact: per the node-postgres SSL docs, the ssl object is replaced when the URL contains sslcert/sslkey/sslrootcert/sslmode.
  • If you ever add an explicit ssl: { rejectUnauthorized: true } (or Neon's ca.pem for verify-full), decide deliberately which source of truth wins.
  • Note the choice in a comment so a future reader does not assume the in-code option is authoritative.

// the snapshot shape the PostgREST export produced.
const QUERY = `
select
id,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: Consider testing the query independently of the live database

  • The SQL is now embedded in the script, so nothing in tests/ covers the filters (is_hidden = false and is_available = true), the ordering, or the column set.
  • A typo in a column name only surfaces when someone runs the script against production.
  • The repo already runs node --test tests/*.test.mjs; a small test asserting the query string contains the expected filters and ordering would help.
  • Alternatively, a dry-run mode that prints the planned output without writing the file keeps the same benefit without a test.

@charlesrhoward
charlesrhoward merged commit feaefe5 into main Oct 20, 2026
7 checks passed
@charlesrhoward
charlesrhoward deleted the chore/gen-models-from-neon branch October 20, 2026 18:14

This branch was successfully deployed

1 active deployment
Preview — 458cb804 Deployed Oct 20, 2026 by vercel[bot]
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