Repository navigation
Development
For contributors working on the Albm codebase.
npm ci
cp .env.example .env # set SESSION_SECRET
npm run dev # http://localhost:3200On first run with no ADMIN_PASSWORD_HASH, a temporary admin password is printed to the console — use it at /admin/login.
See also CONTRIBUTING.md.
npm run typecheck
npm run lint
npm run buildCI runs typecheck, lint, build, and Playwright e2e on PRs.
npm run test:e2e:install # once
npm run test:e2e # Playwright; throwaway data dir-
SQLite via Drizzle ORM. Schema lives in
src/db/schema.ts. -
Migrations in this repo are hand-written, not generated (
drizzle-kit generatedoesn't produce a usable migration here). After changing the schema:-
Write the raw
.sqlfile directly underdrizzle/(next sequential number). -
Append a matching entry to
drizzle/meta/_journal.json. -
Test the full migration chain against a scratch copy of a dev database before committing:
cp data/gallery.db /tmp/scratch.db node -e " const Database = require('better-sqlite3'); const { drizzle } = require('drizzle-orm/better-sqlite3'); const { migrate } = require('drizzle-orm/better-sqlite3/migrator'); migrate(drizzle(new Database('/tmp/scratch.db')), { migrationsFolder: './drizzle' }); console.log('OK'); "
Commit both the new
.sqlfile and the updated journal. Migrations apply automatically at boot; an existing database is backed up toDATA_DIR/backups/first. A failed migration aborts startup rather than serving a half-migrated DB. -
- TypeScript, App Router, server components by default;
'use client'only where needed. - Keep the security bar: server-side length caps + rate limiting on public writes, existence-404 (not 403) for unpublished galleries, never render user input as HTML, no new outbound network calls.
- Self-contained only — no external CDN/font/script requests from pages.
-
docs/openapi.yaml(mirrored topublic/openapi.yaml) is hand-maintained, like the changelog. If a route's request/response shape changes, update its spec entry in the same commit.
Next.js 15 (App Router, standalone) · SQLite + Drizzle + better-sqlite3 · sharp · Tailwind · iron-session · @simplewebauthn · Playwright.
Optional: tesseract.js, @vladmandic/face-api + WASM TensorFlow.
Required native modules: sharp, better-sqlite3.
Albm is a focused single-admin app. Please open an issue to discuss larger features (multi-tenant, plugins, etc.) before building them.