Files
bincio-wiki/CLAUDE.md
T

5.1 KiB

bincio_wiki — development notes

Project overview

A private wiki for the bincio group of friends. Built on Astro 6 using the brutsalvadi/astro-bloomz fork as a git submodule at site/. Content lives in pages/ and blog/ at the repo root; Astro loads them via glob loaders pointing to ../pages and ../blog (outside the submodule). No symlinks.

Directory layout

bincio_wiki/
  pages/          wiki content (*.md files the community edits)
    _docs/        software documentation (shown as separate section)
  blog/           blog/stories content (*.md files)
  assets/         user-uploaded images (gitignored; rsync'd to VPS separately)
  site/           Astro 6 app (git submodule → brutsalvadi/astro-bloomz)
  edit/           FastAPI edit server (Python, port 8001)
  pyproject.toml  Python dependencies (managed by uv)
  uv.lock         uv lockfile (committed)
  scripts/        dev.sh — starts both Astro and FastAPI together
  docs/           repo-level documentation (not served as wiki pages)

Running locally

bash scripts/dev.sh          # Astro only (port 4321)
bash scripts/dev.sh --edit   # Astro + FastAPI edit sidecar (port 8001)

Python dependencies are managed by uv. uv sync is called automatically by dev.sh --edit — no manual setup needed. To add a dependency: uv add <package> (updates pyproject.toml and uv.lock).

Content architecture

  • Wiki pages: pages/*.md (IDs in Astro content store are the bare filename without extension, e.g. digital-garden)
  • Docs section: pages/_docs/*.md (IDs start with _docs/)
  • Blog/stories: blog/*.md
  • Assets: assets/ — gitignored, not part of the Astro build. FastAPI serves them at /assets/{filename} in dev (Vite proxies /assets → port 8001). On the VPS, nginx serves /assets/ directly from the filesystem (rsync'd separately). Upload via POST /api/assets (multipart); returns {"url": "/assets/filename"}. The editor inserts ![name](/assets/filename) into the markdown on upload.
  • Bonsai index: stored in site/src/content/index/ — the i.bonsai.md file defines the semantic tree structure
  • The homepage (site/src/pages/index.astro) splits entries by _docs/ prefix into "Pagine recenti" and "Documentazione" sections

Astro 6 content layer notes

  • Collections use glob loaders in site/src/content.config.ts
  • entries collection base is ../pages (relative to site/), resolving to bincio_wiki/pages/. Vite is configured with server.fs.allow: ['..'] to permit serving files from outside the project root.
  • blog collection base is ../blog (same pattern)
  • index collection base is ./src/content/index (stays inside site/)
  • Custom generateId on entries and index — see content.config.ts for details. index preserves dots so i.bonsai is not mangled by githubSlug.
  • Use entry.id not entry.slug
  • Use import { render } from 'astro:content'; render(entry) not entry.render()

Language / i18n

Italian is the default language. All documentation in pages/_docs/ is in Italian. Technical terms (WikiRefs, Astro, plugin names, wikilink syntax, code) stay in English. See docs/lingua.md for the full rationale.

Authentication

Current approach (same as bincio_activity)

Not yet implemented in bincio_wiki — pending.

Planned pattern:

  • nginx serves the static Astro build publicly (no nginx-level auth)
  • Every Astro page layout calls GET /api/me on load
  • If the API returns 401/error, the page JS redirects to /login/
  • FastAPI (edit/server.py) handles sessions: SQLite users table, bcrypt passwords, HTTP-only session cookie
  • Login page at /login/ — a static Astro page that POSTs credentials to /api/auth/login

Security assessment

This is client-side enforcement only. The HTML is technically accessible to anyone who:

  • Uses curl or wget directly
  • Disables JavaScript in the browser
  • Views page source

For bincio_wiki this is an acceptable tradeoff. The content is community memories and shared activities (not financial/medical data), members are not adversarial, and the goal is keeping casual visitors and search engine crawlers out — not resisting determined attackers.

Future: making specific pages public

With this architecture, making a page public later is trivial: just use a layout variant that skips the /api/me check. No nginx changes needed since nginx already serves everything publicly at the static file level.

For stricter enforcement on genuinely sensitive pages, the alternative is Astro SSR with a server middleware that checks the session cookie before rendering any HTML. This would require migrating from static output to SSR mode — a bigger change, not warranted for now.

VPS deployment target

Debian 12 VPS. nginx serves the built site from /var/www/bincio/wiki/. FastAPI proxied from localhost:8001 via nginx location /api/ { proxy_pass }. See docs/vps.md for full nginx config and deployment steps.

Git conventions

  • No Co-Authored-By: Claude trailers in commits
  • Commit messages in English
  • Do not push without explicit user instruction