Prevent runtime crashes when `releases`, `downloads`, or related lookup tables
(`releasetypes`, `schemetypes`, `sourcetypes`, `casetypes`) are absent in the
connected ZXDB MySQL database.
- Repo: gate releases/downloads queries behind a schema capability check using
`information_schema.tables`; if missing, skip queries and return empty arrays.
- Keeps entry detail page functional on legacy/minimal DB exports while fully
utilizing rich data when available.
Refs: runtime error "Table 'zxdb.releasetypes' doesn't exist"
Signed-off-by: Junie@quinn
Expand and update documentation to reflect the current app (Registers + ZXDB Explorer), with clear setup and usage instructions.
Changes
- README: add project overview including ZXDB Explorer; routes tour; ZXDB setup (DB import, helper search tables, readonly role); environment configuration; selected API endpoints; implementation notes (Next 15 async params, Node runtime for mysql2, SSR/ISR usage); links to AGENTS.md and docs/ZXDB.md.
- docs/ZXDB.md (new): deep-dive guide covering database preparation, helper tables, environment, Explorer UI, API reference under /api/zxdb, performance approach (helper tables, parallel queries, ISR), troubleshooting, and roadmap.
- AGENTS.md: refresh Project Overview/Structure with ZXDB routes and server/client boundaries; document Next.js 15 dynamic params async pattern for pages and API routes; note Drizzle+mysql2, Node runtime, and lookup `text`→`name` mapping; keep commit workflow guidance.
- example.env: add reference to docs/ZXDB.md and clarify mysql:// format and setup pointers.
Notes
- Documentation focuses on the current state of the codebase (what the code does), not a log of agent actions.
- Helper SQL at ZXDB/scripts/ZXDB_help_search.sql is required for performant searches.
Signed-off-by: Junie@lucy.xalior.com
Why
- Reduce time-to-first-content on ZXDB index pages by eliminating the initial client-side fetch and enabling incremental static regeneration.
What
- Main Explorer (/zxdb):
- Server-renders first page of results and lookup lists (genres, languages, machinetypes) and passes them as initial props.
- Keeps client interactivity for subsequent searches/filters.
- Labels index (/zxdb/labels):
- Server-renders first page of empty search and passes as initial props to skip the first fetch.
- Category lists:
- Genres (/zxdb/genres), Languages (/zxdb/languages), Machine Types (/zxdb/machinetypes) now server-render their lists and export revalidate=3600.
- Refactored list components to accept server-provided items; removed on-mount fetching.
- Links & prefetch:
- Replaced remaining anchors with Next Link to enable prefetch where applicable.
Tech details
- Added revalidate=3600 to the index pages for ISR.
- Updated ZxdbExplorer to accept initial results and initial filter lists; skips first client fetch when initial props are present.
- Updated LabelsSearch to accept initial payload and skip first fetch in default state.
- Updated GenreList, LanguageList, MachineTypeList to be presentational components receiving items from server pages.
Notes
- Low-churn list APIs already emit Cache-Control for CDN; list pages now render instantly from server.
- Further polish (breadcrumbs, facet counts UI) can build on this foundation without reintroducing initial network waits.
Signed-off-by: Junie@lucy.xalior.com
Context
- Housekeeping commit to capture all current ZXDB Explorer work before index-page performance optimizations.
Includes
- Server-rendered entry detail page with ISR and parallelized DB queries.
- Node runtime for ZXDB API routes and params validation updates for Next 15.
- ZXDB repository extensions (facets, label queries, category queries).
- Cross-linking and Link-based prefetch across ZXDB UI.
- Cache headers on low-churn list APIs.
Notes
- Follow-up commit will focus specifically on speeding up index pages via SSR initial data and ISR.
Signed-off-by: Junie@lucy.xalior.com
End-to-end ZXDB integration with environment validation, Drizzle ORM MySQL
setup, typed repositories, Zod-validated API endpoints, and a deep, cross‑
linked Explorer UI under `/zxdb`. Also update dynamic route pages to the
Next.js 15 async `params` API and align ZXDB lookup table columns (`text` vs
`name`).
Summary
- Add t3.gg-style Zod environment validation and typed `env` access
- Wire Drizzle ORM to ZXDB (mysql2 pool, singleton) and minimal schemas
- Implement repositories for search, entry details, label browsing, and
category listings (genres, languages, machinetypes)
- Expose a set of Next.js API routes with strict Zod validation
- Build the ZXDB Explorer UI with search, filters, sorting, deep links, and
entity pages (entries, labels, genres, languages, machinetypes)
- Fix Next 15 “sync-dynamic-apis” warning by awaiting dynamic `params`
- Correct ZXDB lookup model columns to use `text` (aliased as `name`)
Details
Env & DB
- example.env: document `ZXDB_URL` with readonly role notes
- src/env.ts: Zod schema validates `ZXDB_URL` as `mysql://…`; fails fast on
invalid env
- src/server/db.ts: create mysql2 pool from `ZXDB_URL`; export Drizzle instance
- drizzle.config.ts: drizzle-kit configuration (schema path, mysql2 driver)
Schema (Drizzle)
- src/server/schema/zxdb.ts:
- entries: id, title, is_xrated, machinetype_id, language_id, genretype_id
- helper tables: search_by_titles, search_by_names, search_by_authors,
search_by_publishers
- relations: authors, publishers
- lookups: labels, languages, machinetypes, genretypes
- map lookup display columns from DB `text` to model property `name`
Repository
- src/server/repo/zxdb.ts:
- searchEntries: title search via helper table with filters (genre, language,
machine), sorting (title, id_desc), and pagination
- getEntryById: join lookups and aggregate authors/publishers
- Label flows: searchLabels (helper table), getLabelById, getLabelAuthoredEntries,
getLabelPublishedEntries
- Category lists: listGenres, listLanguages, listMachinetypes
- Category pages: entriesByGenre, entriesByLanguage, entriesByMachinetype
API (Node runtime, Zod validation)
- GET /api/zxdb/search: search entries with filters and sorting
- GET /api/zxdb/entries/[id]: fetch entry detail
- GET /api/zxdb/labels/search, GET /api/zxdb/labels/[id]: label search and detail
- GET /api/zxdb/genres, /api/zxdb/genres/[id]
- GET /api/zxdb/languages, /api/zxdb/languages/[id]
- GET /api/zxdb/machinetypes, /api/zxdb/machinetypes/[id]
UI (App Router)
- /zxdb: Explorer page with search box, filters (genre, language, machine), sort,
paginated results & links to entries; quick browse links to hubs
- /zxdb/entries/[id]: entry detail client component shows title, badges
(genre/lang/machine), authors and publishers with cross-links
- /zxdb/labels (+ /[id]): search & label detail with "Authored" and "Published"
tabs, paginated lists linking to entries
- /zxdb/genres, /zxdb/languages, /zxdb/machinetypes and their /[id] detail pages
listing paginated entries and deep links
- Navbar: add ZXDB link
Next 15 dynamic routes
- Convert Server Component dynamic pages to await `params` before accessing
properties:
- /zxdb/entries/[id]/page.tsx
- /zxdb/labels/[id]/page.tsx
- /zxdb/genres/[id]/page.tsx
- /zxdb/languages/[id]/page.tsx
- /registers/[hex]/page.tsx (Registers section)
- /api/zxdb/entries/[id]/route.ts: await `ctx.params` before validation
ZXDB schema column alignment
- languages, machinetypes, genretypes tables use `text` for display columns;
models now map to `name` to preserve API/UI contracts and avoid MySQL 1054
errors in joins (e.g., entry detail endpoint).
Notes
- Ensure ZXDB helper tables are created (ZXDB/scripts/ZXDB_help_search.sql)
— required for fast title/name searches and author/publisher lookups.
- Pagination defaults to 20 (max 100). No `select *` used in queries.
- API responses are `cache: no-store` for now; can be tuned later.
Deferred (future work)
- Facet counts in the Explorer sidebar
- Breadcrumbs and additional a11y polish
- Media assets and download links per release
Signed-off-by: Junie@lucy.xalior.com
Signed-off-by: Junie@lucy.xalior.com