/admin/prompts shows you which prompts your app has registered, what the
latest version of each is, and when it was last updated. It’s intentionally
read-only — publishing a new version is a deliberate act that should go
through code review or a server action, not a freeform admin panel. This page
is the audit trail; the editing happens elsewhere.
Prerequisites
- Your user record has
role = 'admin'. The/admin/*layout callsrequireAdmin()and 403s otherwise. - Prompts registered in the database — usually seeded by your app at startup via the prompt registry pattern (see /docs/ai/prompts).
- The
promptandprompt_versiontables exist (created bypnpm db:pushfromsrc/db/ai.schema.ts).
Step-by-step
-
Sign in as an admin at
/login, then visit/admin/prompts. -
Scan the table:
Column What it shows slug Stable identifier the app uses to fetch the prompt name + desc Human label and one-liner about what it does latest version vNfrom a join toprompt_versionupdated prompt.updatedAt, formatted via date-fns -
Sort & filter — currently neither is implemented. Rows come back
sorted by
updatedAt descwith a hardlimit(100). Either rebuild the page with sortable columns or paginate (see pitfall 1). -
To publish a new version, write SQL or a server action that inserts
into
prompt_versionand updatesprompt.latestVersionId. The full registry pattern is documented at /docs/ai/prompts.
How the join works
The page does one query for prompts, then resolves eachlatestVersionId in
a follow-up loop:
Verify it works
- Register a new prompt via your registry’s
register()call (or insert directly into theprompttable for testing). - Refresh
/admin/prompts— the new row should appear at the top (sorted byupdatedAt desc). - Insert a
prompt_versionrow pointing back to the prompt and updateprompt.latestVersionId— refresh, the version column should now showv1. - Delete the test rows when done; there’s no UI delete (yet).
Common pitfalls
- Pagination missing. The hard
limit(100)silently truncates large registries. Add a query-string?page=Nor switch to keyset pagination before you cross 100 prompts. - N+1 query under load. Acceptable at admin volume, painful past a few
hundred prompts. Rewrite as a
LEFT JOIN promptVersion ON promptVersion.id = prompt.latestVersionIdin one query. - Latest version shows
—. Meansprompt.latestVersionIdis null — the prompt has no published version yet. Insert aprompt_versionrow and setlatestVersionIdon the parent. - Edits don’t show up. Updates to
prompt_version.textdon’t bumpprompt.updatedAt. Either touch the parent row in the same transaction or sort by the version’screatedAtinstead. - No edit UI. This is the design — read-only on purpose. Don’t add a freeform editor unless you also add audit logging and a review workflow.
Official docs
- Prompt registry pattern: /docs/ai/prompts
- Drizzle ORM: orm.drizzle.team
- next-safe-action (for write actions if you add edit UI): next-safe-action.dev
- date-fns (used to format the
updatedcolumn): date-fns.org