summaryrefslogtreecommitdiffstats
path: root/CLAUDE.md
diff options
context:
space:
mode:
authorivar <i@oiee.no>2026-04-07 22:10:20 +0200
committerivar <i@oiee.no>2026-04-07 22:10:20 +0200
commit8dc50f508c33aecac561b639155af808c8dd4e95 (patch)
tree839c2d07582e4adf30f8981351cbaeb54feb2950 /CLAUDE.md
parent12f1d175c3f14b1b3f002ef0020eeda4d9e97286 (diff)
downloadiblog-8dc50f508c33aecac561b639155af808c8dd4e95.tar.xz
iblog-8dc50f508c33aecac561b639155af808c8dd4e95.zip
Add claude and dockerfile
Diffstat (limited to 'CLAUDE.md')
-rw-r--r--CLAUDE.md72
1 files changed, 72 insertions, 0 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..c2aae8b
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,72 @@
+# CLAUDE.md
+
+This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
+
+## Commands
+
+```bash
+# Build and run
+go build ./cmd/iblog
+./iblog serve [--port 8080] [--root .]
+
+# Hot reload during development (uses air)
+air # serves on :8081 per .air.toml
+
+# Run all tests
+go test ./...
+
+# Run a single test
+go test ./internal/db/... -run TestPostSearch
+
+# User management
+./iblog user add <name>
+./iblog user list
+./iblog user passwd <name>
+./iblog user delete <name>
+
+# Build frontend JS (from assets/lib/ or assets/admin/lib/)
+cd assets/lib && bun run build
+cd assets/admin/lib && bun run build
+```
+
+## Architecture
+
+iblog is a Go blog engine with an admin UI. It uses a hybrid model: posts are authored via a browser-based editor, stored in SQLite, and then rendered to static HTML files in `public/` for serving.
+
+**Data flow:** Admin UI (EditorJS) → SQLite (`data/iblog.db`) → static HTML (`public/`) → served to readers
+
+**Key packages:**
+
+- `cmd/iblog/` — CLI entry point with `serve` and `user` subcommands
+- `internal/` (package `auth`) — htpasswd-compatible bcrypt password file; nginx can use the same file via `auth_basic_user_file`
+- `internal/db/` — SQLite wrapper; schema includes `posts`, `pages`, `redirects`, `settings`, and an FTS5 virtual table (`pages_fts`) for full-text search
+- `internal/server/` — Gin HTTP handlers: `adminserver.go` (admin CRUD, auth middleware, setup flow), `frontpage.go`, `posthandler.go`, `fileserver.go`
+- `internal/builder/` — Converts EditorJS block JSON to HTML (`editorjs.go`)
+- `internal/media/` — Image upload, processing (govips/libvips), and serving
+
+**Frontend assets** are embedded into the binary via `embed.go`:
+- `assets/lib/` — Shared site JS (thumbhash, built with bun → `dist/`)
+- `assets/admin/lib/` — Admin editor JS (EditorJS + plugins, built with bun → `dist/`)
+- `assets/components/` — Custom web components served to the public site
+- `assets/styles/` — CSS
+- `templates/` — Go `html/template` files; `templates/admin/` for admin UI
+
+**Directory layout at runtime** (controlled by `--root`):
+```
+data/iblog.db SQLite database
+data/.passwords htpasswd file (bcrypt, 0600)
+data/media/ uploaded media originals + processed images
+public/ generated static HTML output
+components/ optional user-supplied web components
+styles/ optional user-supplied CSS overrides
+```
+
+**Setup flow:** On first run (no password file), all requests redirect to `/setup` where the first admin user is created. After that, `/admin/` routes require HTTP Basic Auth.
+
+**Static generation:** Saving a post in the admin UI writes HTML to `public/<slug>/index.html` and updates the FTS5 index. The `public/` directory is served as a fallback for any route not matched by dynamic handlers.
+
+## Notes
+
+- `govips` wraps libvips; libvips must be installed on the host (`brew install vips` on macOS).
+- The JS bundles in `assets/*/lib/dist/` are committed — rebuild them with bun when changing JS dependencies.
+- Posts store content as raw EditorJS JSON (`blocks` column) and render to HTML on publish, not on read.