# CLAUDE.md - Monolith stack Profile
# Extends: Universal CLAUDE.md rules
---
## Stack
- Backend: Go (single binary)
- Frontend: Datastar (SSE + signals, no JS build step)
- DB: SQLite with WAL
- Process manager: systemd
- Runtime: LXC container, Debian latest
---
## Go
- Stdlib first. No framework unless justified.
- One binary. Embed templates and static assets via embed.FS.
- Build target: GOOS=linux GOARCH=amd64
- Structure:
  ```
  cmd/app/       main.go
  internal/      business logic
  templates/     HTML + Datastar
  static/        CSS, datastar.js
  ```
 
## Datastar
- Handlers stream HTML fragments via SSE (Server-Sent Events), never JSON.
- Use `data-signals` for client state, `data-on-*` for events, `data-bind` for two-way binding.
- SSE responses must set `Content-Type: text/event-stream` and flush after each event.
- Use the official SSE helper format:
  ```
  event: datastar-merge-fragments
  data: fragments <div id="target">...</div>
  ```
- No client-side routing. Use `data-on-click="@get('/route')"` for navigation.
- Keep templates dumb. Logic stays in Go.
- Load Datastar from CDN or embed `datastar.js` in static/:
  ```html
  <script type="module" src="/static/datastar.js"></script>
  ```
 
## SQLite
- Single sql.DB instance, shared across the app.
- Open with WAL pragmas at startup:
  ```
  PRAGMA journal_mode=WAL;
  PRAGMA synchronous=NORMAL;
  ```
- No ORM. Raw SQL only.
- Migrations are plain .sql files, applied at startup, versioned manually.
- Enable foreign keys if the schema uses them: `PRAGMA foreign_keys=ON;`
## systemd
- Binary lives in `/opt/app/bin/app`
- Data and DB in `/opt/app/data/`
- Unit file minimum:
  ```
  [Unit]
  After=network.target
 
  [Service]
  Type=simple
  User=app
  WorkingDirectory=/opt/app
  ExecStart=/opt/app/bin/app
  Restart=on-failure
 
  [Install]
  WantedBy=multi-user.target
  ```
- Logs go to journald. Use `log/slog` in Go for structured output.
- After any binary change: `systemctl daemon-reload && systemctl restart app`
## LXC / Debian
- No Docker. The LXC container is the isolation boundary.
- Keep apt packages minimal. Binary only needs glibc + ca-certificates.
- Backups: `rsync /opt/app/data/` is sufficient.
## Deploy
```bash
GOOS=linux GOARCH=amd64 go build -o bin/app ./cmd/app
rsync -av bin/app user@host:/opt/app/bin/app
ssh user@host systemctl restart app
```
 
## Override Rule
User instructions always override this file.