BUCKYVERSE

Buckyverse Library (DB-free) — One-page PRD + Engineering Spec (DigitalOcean Ubuntu)

Hosting target: existing BUCKYVERSE Ubuntu server on DigitalOcean
Principle: no database for core functionality. Catalog + routing come from a build-generated manifest.json and immutable, versioned artifacts.


1) One-page PRD

Summary

Replace Wiki.js with a purpose-built Library + Reader platform that publishes math-heavy books from LaTeX repos as reflowable HTML (and optionally EPUB/PDF). The platform should be fast, mobile-friendly, and simple to operate on a single Ubuntu server.

Problem

Wiki.js is poorly suited for book-scale, math-heavy content and for a LaTeX-repo publishing workflow. Rendering, navigation, and performance degrade as manuscripts grow.

Goals

Non-goals (MVP)

Key user flows

  1. Browse library → open a book → choose version (latest default) → read with TOC + font controls
  2. Share a section link
  3. Download PDF/EPUB as available

Success metrics


2) Engineering Spec (Single Ubuntu server)

Nginx

Phoenix

Why Nginx serves artifacts


2.2 Filesystem layout (atomic content deploys)

Use a release directory + symlink flip to update content atomically.

/srv/buckyverse/
  books/
    releases/
      2026-02-03_120000/
        manifest.json
        regular_polytopes/1.4.0/...
        order_in_space/0.9.1/...
      2026-02-10_090500/
        manifest.json
        ...
    current -> /srv/buckyverse/books/releases/2026-02-10_090500

Nginx points to /srv/buckyverse/books/current as the static root.
Publishing = upload new release dir → update current symlink → reload services.


2.3 URL & routing design

Public pages (Phoenix)

Artifacts (served by Nginx)

Important: Artifacts must be immutable by version. Never overwrite an existing version directory.


2.4 Manifest design

Location

Minimal schema (draft)

{
  "generated_at": "2026-02-03T12:00:00Z",
  "books": [
    {
      "id": "regular_polytopes",
      "title": "Regular Polytopes",
      "authors": ["H. S. M. Coxeter"],
      "description": "...",
      "tags": ["geometry", "polytopes"],
      "latest_version": "1.4.0",
      "versions": [
        {
          "version": "1.4.0",
          "html_root": "/static/books/regular_polytopes/1.4.0/",
          "html_entry": "index.html",
          "toc": [{"title":"Chapter 1","href":"ch01.html"}],
          "pdf_url": "/static/books/regular_polytopes/1.4.0/book.pdf",
          "epub_url": "/static/books/regular_polytopes/1.4.0/book.epub"
        }
      ]
    }
  ]
}

2.5 Phoenix module boundaries

Buckyverse.Library.Manifest

Responsibility: Load + parse + validate manifest, expose read-only queries.

Storage

Buckyverse.Library

Responsibility: Business queries derived from manifest.

Controllers

Plugs


2.6 Nginx configuration with caching headers

Assumptions:

server {
  server_name buckyverse.org www.buckyverse.org;

  # TLS handled here (LetsEncrypt recommended)
  # listen 443 ssl http2;
  # ssl_certificate ...
  # ssl_certificate_key ...

  # 1) Versioned artifacts: cache forever (immutable)
  location ^~ /static/books/ {
    alias /srv/buckyverse/books/current/;

    add_header Cache-Control "public, max-age=31536000, immutable" always;

    try_files $uri =404;
  }

  # 2) Manifest: short cache + revalidate
  location = /static/books/manifest.json {
    alias /srv/buckyverse/books/current/manifest.json;

    add_header Cache-Control "public, max-age=60, must-revalidate" always;
    try_files $uri =404;
  }

  # 3) Phoenix dynamic routes
  location / {
    proxy_pass http://127.0.0.1:4000;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    # Dynamic HTML: conservative caching (manifest-driven anyway)
    add_header Cache-Control "public, max-age=60" always;
  }
}

Caching rules summary


2.7 Deployment workflow (content-only, no DB)

Publish a new release

  1. CI builds artifacts + manifest.json into a folder like 2026-02-10_090500/
  2. Upload to:
    • /srv/buckyverse/books/releases/2026-02-10_090500/
  3. Atomic flip:
    • ln -sfn /srv/buckyverse/books/releases/2026-02-10_090500 /srv/buckyverse/books/current
  4. Reload:
    • nginx -s reload
    • If Phoenix reloads manifest only on boot: systemctl restart buckyverse
    • If Phoenix has mtime watcher: restart not needed

Rollback is the same: repoint current to prior release.


2.8 systemd unit example (Phoenix release)

[Unit]
Description=Buckyverse Phoenix App
After=network.target

[Service]
User=www-data
WorkingDirectory=/srv/buckyverse/app
Environment=PORT=4000
Environment=PHX_HOST=buckyverse.org
Environment=MANIFEST_PATH=/srv/buckyverse/books/current/manifest.json
ExecStart=/srv/buckyverse/app/bin/buckyverse start
Restart=on-failure
RestartSec=3

[Install]
WantedBy=multi-user.target

2.9 Reader UX notes (DB-free)


2.10 MVP decisions (defaults)