# CLAUDE.md — Cloudzilla > ⚠️ **Alpha**: APIs, project structure, and conventions may change. Self-hosted git forge. Go (chi, sqlx, go-git, cobra) + PostgreSQL; UI is server-rendered [Templ](https://templ.guide/) with HTMX, Alpine.js, and Tailwind. Git transport (HTTP smart protocol + SSH) is pure Go — no `git` binary. ## Layering Stores → Services → Handlers, strictly: - `internal/store/` holds raw SQL; `internal/service/` holds business logic; `internal/handler/` calls services only. - `context.Context` is the first arg of every store and service method. - Handlers render with `h.render(w, r, component)` — a page from `internal/view/pages/` or a fragment from `internal/view/fragments/`. HTMX requests are detected with `r.Header.Get("HX-Request") == "true"`. JSON APIs use `writeJSON(w, status, v)`. - View-model structs live in `internal/view/viewmodels_*.go`; pages embed `BasePage` from `basePage(r, h.Services)`. ## Commands Targets live in the `Makefile` (`dev`, `build`, `migrate`, `seed`, `lint`, `test`, `test-integration`). Integration tests need `TEST_DATABASE_DSN`; `make test-integration` starts the test DB and sets it. ## Templ - Edit `.templ` files, then run `make generate-templ`. `_templ.go` files are generated output — regenerate them, keep hands off. - Keep `{{if}}` inside `class`/`style` attributes on one line: VS Code's HTML formatter splits the string literal and breaks the comparison. - Use `templ.Raw(...)` only for trusted HTML such as rendered Markdown. ## CSS Tailwind v4 utilities only. `tailwind/input.css` is the whole config: `@theme` maps the tokens to utilities, and `@source` scans only `internal/view/**/*.templ`, so a class that appears only in Go code isn't generated. Templates outside `internal/view/` need their own `@source`. `space-y-*` and `divide-y` style every child but the last: keep a rendered element last (hidden inputs, `