SPB Git

Repository Public

README.md 3.9 KB

# MacLustr Research Infrastructure — maclustr.spboucher.ai

Bilingual (English/French) research site documenting MacLustr, a personally owned Apple Silicon cluster. It is a technical showcase and research log, not a commercial service.

# Stack

Next.js 16 (App Router, static generation), React 19, TypeScript strict, Tailwind CSS 4, Zod 4, sharp, Vitest, Playwright + axe.

# Content model (all version-controlled, validated by Zod at build time)

File Content
data/nodes.json One record per machine (specs, role, lifecycle, placement, verifiedAt, source, publicVisibility)
data/photos.source.json → data/photos.json Captions and alt text → generated dimensions and blur placeholders
data/research.json Research log entries (completed / ongoing / proposed) with references
data/benchmarks.json Benchmark observations; empty until measured
data/timeline.json, data/planned.json, data/site.json History, planned hardware, contact and dates
src/lib/dict/{en,fr}.ts All interface and editorial text

Totals shown on the site are computed by src/lib/inventory.ts; planned, retired and hidden records never count. A total is withheld when one counted record lacks the value.

# Commands

bash
pnpm install
pnpm images      # assets/*.jpeg -> public/images (metadata stripped) + data/photos.json
pnpm dev
pnpm check       # validate data, lint, type-check, unit tests, build, privacy scan
pnpm test:e2e    # browser tests (starts `next start` on port 3210)

Put the original photographs in assets/ (git-ignored: they carry location metadata). Only pnpm images output is published.

# Updating the inventory

Edit data/nodes.json (or re-run scripts/import-discovery.py on fresh discovery output), set verifiedAt and source, update data/site.json dates, then pnpm check. Unknown values stay null and render as "Not yet documented".

# Environment variables

Variable Purpose
NEXT_PUBLIC_SITE_URL Extra allowed origin for the form endpoint (the canonical URL is in data/site.json)
SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS Optional. Enables server-side delivery of access requests
ACCESS_MAIL_TO, ACCESS_MAIL_FROM Recipient and sender for those requests

Without SMTP_HOST and ACCESS_MAIL_TO at build time, the access form prepares a message in the visitor's own mail application and says so; it never displays a "sent" state. No secret belongs in the repository.

# Deployment (owner's infrastructure)

The site runs as one Node process (next start) behind the public gateway's reverse proxy, which terminates HTTPS.

  1. DNS: A maclustr.spboucher.ai → public gateway.
  2. Manifest on the gateway node: ~/dispatch/apps/maclustr-research.json (port, health_path: /api/health, tunnel domain, build hook pnpm install --frozen-lockfile && next build).
  3. First deployment from the laptop: mld stage <this folder> maclustr-research && mld deploy maclustr-research.
  4. Afterwards the deployed folder is the reference clone: edit on the node, pnpm build && pm2 restart maclustr-research, commit and push from the node.
  • Health check: GET /api/health → {"status":"ok","records":N}.
  • Logs: pm2 logs maclustr-research on the node.
  • Backups: the site is stateless; the git repository is the backup.
  • Rollback: git checkout <previous commit> && pnpm build && pm2 restart maclustr-research; the orchestrator also rolls back a failed deploy.

# Security and privacy

  • Security headers and CSP in src/lib/security.ts; the browser never contacts a private node.
  • Form endpoint: same-origin JSON only, Zod validation, honeypot, rate limit, nothing persisted, contents never logged.
  • pnpm privacy fails if a private address, internal domain, credential pattern or image metadata is found in what ships.

# Documents

docs/INVENTORY-AUDIT.md (facts, unknowns, items for owner verification), docs/DESIGN.md, docs/screenshots/, CHANGELOG.md.

Files main
Menu

Theme