Spectrum Next Explorer

A Next.js application for exploring the Spectrum Next ecosystem. It ships with:

- Register Explorer: parsed from `data/nextreg.txt`, with real‑time search and deep links
- ZXDB Explorer: a deep, cross‑linked browser for entries, labels, genres, languages, and machine types backed by a MySQL ZXDB instance
- Bootstrap 5 theme with light/dark support

Quick start
- Prerequisites: Node.js 20+, pnpm (recommended), access to a MySQL server for ZXDB (optional for Registers)
- Install dependencies:
  - `pnpm install`
- Run in development (Turbopack, port 4000):
  - `pnpm dev` then open http://localhost:4000
- Build and start (production):
  - `pnpm build`
  - `pnpm start` (defaults to http://localhost:3000)
- Lint:
  - `pnpm lint`

Project scripts (package.json)
- `dev`: `PORT=4000 next dev --turbopack`
- `build`: `next build --turbopack`
- `start`: `next start`
- `deploy`: merge current branch into `deploy` and push to `explorer.specnext.dev`
- `deploy:branch`: same as `deploy`, but accepts a deploy branch argument
- `setup:zxdb-local`: configure local submodule excludes for ZXDB SQL files
- `deploy-test`: push to `test.explorer.specnext.dev`
- `deploy-prod`: push to `explorer.specnext.dev`

Routes
- `/` — Home
- `/registers` — Register Explorer
- `/zxdb` — ZXDB Explorer (hub)
- `/zxdb/entries` — Entries search + filters
- `/zxdb/entries/[id]` — Entry detail
- `/zxdb/releases` — Releases search + filters
- `/zxdb/labels` and `/zxdb/labels/[id]` — Labels search and detail
- `/zxdb/genres` and `/zxdb/genres/[id]` — Genres list and entries
- `/zxdb/languages` and `/zxdb/languages/[id]` — Languages list and entries
- `/zxdb/machinetypes` and `/zxdb/machinetypes/[id]` — Machine types list and entries
- `/zxdb/magazines` and `/zxdb/magazines/[id]` — Magazines list and issues
- `/zxdb/issues/[id]` — Issue detail (contents and references)

ZXDB setup (database, env, and helper tables)
The Registers section works without any database. The ZXDB Explorer requires a MySQL ZXDB database and one environment variable.

1) Prepare the database (outside this app)
- Import ZXDB data into MySQL. If you want only structure, use `ZXDB/ZXDB_mysql_STRUCTURE_ONLY.sql` in this repo. For data, import ZXDB via your normal process.
- Create the helper search tables (required for fast search):
  - Run `ZXDB/scripts/ZXDB_help_search.sql` against your ZXDB database.
- Create a read‑only role/user (recommended):
  - Example (see `bin/import_mysql.sh`):
    - Create role `zxdb_readonly`
    - Grant `SELECT, SHOW VIEW` on database `zxdb`

2) Configure environment
- Copy `.env` from `example.env`.
- Set `ZXDB_URL` to a MySQL URL, e.g. `mysql://zxdb_readonly:password@hostname:3306/zxdb`.
- On startup, `src/env.ts` validates env vars (t3.gg pattern with Zod) and will fail fast if invalid.

3) Run the app
- `pnpm dev` → open http://localhost:4000 and navigate to `/zxdb`.

4) Keep the ZXDB submodule clean (recommended)
- Run `pnpm setup:zxdb-local` once after cloning.
- This keeps `ZXDB/ZXDB_mysql.sql` and `ZXDB/ZXDB_mysql_STRUCTURE_ONLY.sql` available locally without appearing as untracked changes.

API (selected endpoints)
- `GET /api/zxdb/search?q=...&page=1&pageSize=20&genreId=...&languageId=...&machinetypeId=...&sort=title&facets=1`
- `GET /api/zxdb/entries/[id]`
- `GET /api/zxdb/releases/search?q=...&year=...&languageId=...&machinetypeId=...&sort=...`
- `GET /api/zxdb/labels/search?q=...`
- `GET /api/zxdb/labels/[id]?page=1&pageSize=20`
- `GET /api/zxdb/genres` and `/api/zxdb/genres/[id]?page=1`
- `GET /api/zxdb/languages` and `/api/zxdb/languages/[id]?page=1`
- `GET /api/zxdb/machinetypes` and `/api/zxdb/machinetypes/[id]?page=1`
- `GET /api/zxdb/{availabletypes,casetypes,currencies,filetypes,roletypes,schemetypes,sourcetypes}`

Implementation notes
- Next.js 15 dynamic params: pages and API routes that consume `params` must await it, e.g. `export default async function Page({ params }: { params: Promise<{ id: string }> }) { const { id } = await params; }`
- ZXDB integration uses Drizzle ORM over `mysql2` with a singleton pool at `src/server/db.ts`; API routes declare `export const runtime = "nodejs"`.
- Entry and detail pages server‑render initial content and use ISR (`revalidate = 3600`) for fast time‑to‑content; index pages avoid a blocking first client fetch.
- Database Schema: Repository queries include graceful fallback checks (via `information_schema.tables`) to remain functional even if optional tables (like `releases` or `downloads`) are missing from the connected MySQL instance.

Further reading
- ZXDB details and API usage: `docs/ZXDB.md`
- Agent/developer workflow and commit guidelines: `AGENTS.md`

License
- See `LICENSE.txt` for details.
