mp3-com-meta-browser/AGENTS.md

152 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Agent Guide
This document orients automation agents and contributors to the mp3-com-meta-browser project. The app is a static, single-page experience for browsing a large mp3.com metadata dataset entirely in the browser.
## Mission
- Deliver a fast, predictable search and browse experience over the bundled metadata database.
- Keep the implementation lightweight: no server-side code, no build system, minimal dependencies.
- Preserve accessibility, keyboard navigation, and responsive layout from mobile through desktop.
## Non-Goals
- Hosting or streaming audio files.
- Mutating the SQLite database (it's read-only at runtime).
- Introducing new frameworks, bundlers, or complex build steps.
## Runtime & Architecture
- `index.html` is the only HTML page and contains `<template>` definitions for base views (`tpl-*`) and overlay dialogs.
- `script.js` bootstraps the app, loads the WASM SQLite runtime, manages view transitions via `UX.replace(...)`, and handles overlays with `UX.openOverlay(...)` / `UX.closeTop()`.
- Bulma (`bulma.min.css`) supplies the UI vocabulary; project-specific tweaks live in `site.css`.
- The SQLite database (`assets/mp3com-meta.sqlite`) is fetched lazily using the HTTP virtual file system so only required pages are read.
- `sql.js` (bundled `sql-wasm.js` / `sql-wasm.wasm`) provides SQLite + FTS5 inside the browser.
## Key Assets
- `index.html` SPA shell, templates, base structure.
- `script.js` Application state, data layer, helpers, and view constructors.
- `site.css` Minimal overrides, transitions, and utility classes.
- `assets/mp3com-meta.sqlite` Read-only metadata database.
- `bulma.min.css` Upstream Bulma build; keep pristine.
## Data Access Notes
- Expect to run entirely client-side; the database is opened with read-only mode via `sql.js`.
- Always page results with `LIMIT ? OFFSET ?`; avoid `SELECT *` unless fetching a single record by ID.
- Prefer prepared statements or cached query strings when querying repeatedly.
- HTTP servers used in development or deployment must send `Accept-Ranges: bytes` so the VFS can issue range requests.
## Database Schema
Use the current schema when writing queries or documentation:
```sql
PRAGMA foreign_keys=ON;
CREATE TABLE artists(
id INTEGER PRIMARY KEY,
name TEXT NOT NULL COLLATE NOCASE UNIQUE
);
CREATE TABLE albums(
id INTEGER PRIMARY KEY,
artist_id INTEGER NOT NULL REFERENCES artists(id),
title TEXT COLLATE NOCASE,
year INTEGER,
UNIQUE(artist_id, title, year)
);
CREATE TABLE tracks(
id INTEGER PRIMARY KEY,
artist_id INTEGER NOT NULL REFERENCES artists(id),
album_id INTEGER REFERENCES albums(id),
title TEXT NOT NULL COLLATE NOCASE,
track_no INTEGER,
year INTEGER,
genre TEXT,
duration_sec INTEGER,
bitrate_kbps INTEGER,
samplerate_hz INTEGER,
channels INTEGER,
filesize_bytes INTEGER,
sha1 TEXT,
relpath TEXT NOT NULL
);
CREATE TABLE site_stats (
name TEXT PRIMARY KEY,
value TEXT NOT NULL
);
CREATE VIRTUAL TABLE fts_tracks USING fts5(
title,
artist,
album,
genre,
content='tracks',
content_rowid='id',
tokenize='unicode61 remove_diacritics 2',
prefix='2 3 4'
);
CREATE TABLE 'fts_tracks_data'(id INTEGER PRIMARY KEY, block BLOB);
CREATE TABLE 'fts_tracks_idx'(segid, term, pgno, PRIMARY KEY(segid, term)) WITHOUT ROWID;
CREATE TABLE 'fts_tracks_docsize'(id INTEGER PRIMARY KEY, sz BLOB);
CREATE TABLE 'fts_tracks_config'(k PRIMARY KEY, v) WITHOUT ROWID;
CREATE INDEX idx_tracks_artist_id ON tracks(artist_id);
CREATE INDEX idx_tracks_album_id ON tracks(album_id);
CREATE INDEX idx_tracks_year ON tracks(year);
CREATE INDEX idx_tracks_genre ON tracks(genre);
CREATE INDEX idx_artists_name ON artists(name COLLATE NOCASE);
CREATE INDEX idx_artists_name_nocase ON artists(name COLLATE NOCASE);
```
`site_stats` stores pre-computed metrics that power the stats dashboard. The FTS data tables are SQLite internals; do not query them directly.
## UI/UX Conventions
- Stick to semantic HTML with Bulma classes; avoid inline styles.
- Maintain clear focus states and keyboard navigation. `/` focuses search, `Esc` closes the active overlay, and list views support arrow + Enter activation.
- Use polite `aria-live` regions for async loading states (see `createAsyncListState`).
- Keep DOM renders incremental—do not preload entire datasets or render long tables without pagination.
## Shared Utilities (already implemented in `script.js`)
- `createTableRenderer` Safely renders tabular data with built-in HTML escaping.
- `createPagination` Standard pagination controls with page size selector.
- `Keyboard` helper Normalizes Enter/Esc handling for list rows and overlays.
- `createAsyncListState` Manages loading, error, and empty states for async lists.
- `prepareForView` Wraps `db.prepare` to attach view/label metadata for logging.
- `normalizePaginationState` / `clampPaginationToTotal` Normalizes and clamps pagination inputs while emitting DEBUG telemetry.
## Debugging & Logging
- Runtime diagnostics are gated behind a localStorage flag. Enable with `localStorage.setItem('mp3com.debug', 'true')` (or `'false'`/`removeItem` to disable) before reloading the app.
- When DEBUG is on, every SQLite statement logs `Query begin`/`Query end` entries (with view, SQL, params, row count, and duration) and captures detailed error payloads before rethrowing.
- Pagination helpers emit `[Pagination]` logs whenever raw inputs are normalized or clamped (including `clampedToTotal` flags when high page numbers are corrected after a count query).
- Use `prepareForView(db, VIEW_NAMES.someView, sql, label)` so statement metadata matches the originating view; this keeps console traces actionable.
## View Status
- [x] Navigation hub (`tpl-nav`, `createNavView`).
- [x] Search (`tpl-search`).
- [x] Browse Artists (`tpl-browse-artists`).
- [x] Browse Albums (`tpl-browse-albums`).
- [x] Browse Years (`tpl-browse-years`).
- [x] Browse Genres (`tpl-browse-genres`).
- [x] Stats (`tpl-stats`).
- [x] Artist overlay (`tpl-artist`).
- [x] Album overlay (`tpl-album`).
- [x] Track overlay (`tpl-track`).
- [ ] Filters overlay (`tpl-filters`).
- [ ] Keyboard shortcuts overlay (`tpl-keyboard-shortcuts`).
- [ ] About / help overlay (`tpl-about`).
- [ ] Error overlay (`tpl-error`).
## Implementation Guardrails
- Keep JavaScript modular inside `script.js`; annotate non-obvious sections with short explanatory comments when necessary.
- Reuse existing helpers before adding new ones.
- Store new assets under `assets/` and prefer lazy loading.
- Do not modify `bulma.min.css`; override in `site.css` if required.
- Maintain ASCII-only sources unless a file already contains UTF-8 text that requires preservation.
## QA Checklist Before Delivery
- Serve the site via a local static server and load `http://localhost:8000/`.
- Confirm the console is clean (no errors or unhandled promise rejections).
- Verify keyboard navigation (Tab, arrow keys, Enter, Esc) across base views and overlays.
- Exercise search and pagination to ensure queries remain performant (< ~300 ms after warm-up).
- Validate layout on both narrow and wide viewports.
Stay within these constraints to keep the project fast, accessible, and easy to host.