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
4.8 KiB
ZXDB Guide
This document explains how the ZXDB Explorer works in this project, how to set up the database connection, and how to use the built‑in API and UI for software discovery.
What is ZXDB?
ZXDB ( https://github.com/zxdb/ZXDB )is a community‑maintained database of ZX Spectrum software, publications, and related entities. In this project, we connect to a MySQL ZXDB instance in read‑only mode and expose a fast, cross‑linked explorer UI under /zxdb.
Prerequisites
- MySQL server with ZXDB data (or at minimum the tables; data is needed to browse).
- Ability to run the helper SQL that builds search tables (required for efficient LIKE searches).
- A read‑only MySQL user for the app (recommended).
Database setup
-
Import ZXDB data into MySQL.
- For structure only (no data): use
ZXDB/ZXDB_mysql_STRUCTURE_ONLY.sqlin this repo. - For actual data, follow your usual ZXDB data import process.
- For structure only (no data): use
-
Create helper search tables (required).
- Run
ZXDB/scripts/ZXDB_help_search.sqlon your ZXDB database. - This creates
search_by_titles,search_by_names,search_by_authors, andsearch_by_publisherstables.
- Run
-
Create a read‑only role/user (recommended).
- Example (see
bin/import_mysql.sh):- Create role
zxdb_readonly. - Grant
SELECT, SHOW VIEWon yourzxdbdatabase to the user.
- Create role
- Example (see
Environment configuration
Set the connection string in .env:
ZXDB_URL=mysql://zxdb_readonly:password@hostname:3306/zxdb
Notes:
- The URL must start with
mysql://. Env is validated at boot bysrc/env.ts(Zod), failing fast if misconfigured. - The app uses a singleton
mysql2pool (src/server/db.ts) and Drizzle ORM for typed queries.
Running
pnpm install
pnpm dev
# open http://localhost:4000 and navigate to /zxdb
Explorer UI overview
/zxdb— Search entries by title and filter by genre, language, and machine type; sort and paginate results./zxdb/entries/[id]— Entry details with badges for genre/language/machine, and linked authors/publishers./zxdb/labelsand/zxdb/labels/[id]— Browse/search labels (people/companies) and view authored/published entries./zxdb/genres,/zxdb/languages,/zxdb/machinetypes— Category hubs with linked detail pages listing entries.
Cross‑linking: All entities are permalinks using stable IDs. Navigation uses Next Link so pages are prefetched.
Performance: Detail and index pages are server‑rendered with initial data and use ISR (revalidate = 3600) to reduce time‑to‑first‑content. Queries select only required columns and leverage helper tables for text search.
HTTP API reference (selected)
All endpoints are under /api/zxdb and validate inputs with Zod. Responses are JSON.
-
Search entries
GET /api/zxdb/search- Query params:
q— string (free‑text search; normalized via helper tables)page,pageSize— pagination (default pageSize=20, max=100)genreId,languageId,machinetypeId— optional filterssort—titleorid_descfacets— boolean; if truthy, includes facet counts for genres/languages/machines
-
Entry detail
GET /api/zxdb/entries/[id]- Returns: entry core fields, joined genre/language/machinetype names, authors and publishers.
-
Labels
GET /api/zxdb/labels/search?q=...GET /api/zxdb/labels/[id]?page=1&pageSize=20— includesauthoredandpublishedlists.
-
Categories
GET /api/zxdb/genresand/api/zxdb/genres/[id]?page=1GET /api/zxdb/languagesand/api/zxdb/languages/[id]?page=1GET /api/zxdb/machinetypesand/api/zxdb/machinetypes/[id]?page=1
Runtime: API routes declare export const runtime = "nodejs" to support mysql2.
Implementation notes
- Drizzle models map ZXDB lookup table column
textto propertynamefor ergonomics (e.g.,languages.text→name). - Next.js 15 dynamic params must be awaited in App Router pages and API routes. Example:
export default async function Page({ params }: { params: Promise<{ id: string }> }) { const { id } = await params; // ... } - Repository queries parallelize independent calls with
Promise.allfor lower latency.
Troubleshooting
- 400 from dynamic API routes: ensure you await
ctx.paramsbefore Zod validation. - Unknown column errors for lookup names: ZXDB tables use column
textfor names; Drizzle schema must selecttextasname. - Slow entry page: confirm server‑rendering is active and ISR is set; client components should not fetch on the first paint when initial props are provided.
- MySQL auth or network errors: verify
ZXDB_URLand that your user has read permissions.
Roadmap
- Facet counts displayed in the
/zxdbfilter UI. - Breadcrumbs and additional a11y polish.
- Media assets and download links per release (future).