# Architecture

Go huma API, SQLite/sqlc/goose, Astro 6/Svelte 5 frontend, go-yoto client, and the design system.

Four frameworks enforce correctness at compile time. Understanding them before making changes is essential — they interact, and bypassing one usually breaks another.

## The four frameworks

| Layer | Tool | Source of truth | Generated output |
|---|---|---|---|
| API | huma v2 | Go I/O structs in `internal/api/` | OpenAPI spec |
| Database | sqlc | SQL in `internal/db/queries/*.sql` | Go in `internal/db/gen/` |
| Migrations | goose | SQL in `internal/db/migrations/` | Schema with rollback |
| Config | koanf | `internal/config/config.go` | Validated config struct |
| Frontend types | openapi-typescript | huma's generated OpenAPI spec | `frontend/src/lib/api/types.ts` |
| Frontend client | openapi-fetch | Generated types | `frontend/src/lib/api/client.ts` |

## Repository layout

| Directory | Purpose |
|---|---|
| `cmd/yotoshelf/` | CLI entrypoints: `serve`, `create-admin`, `seed`, `migrate` |
| `internal/api/` | huma API operations (HTTP layer). One file per domain. |
| `internal/db/` | SQLite, goose migrations, sqlc queries, and generated code |
| `internal/config/` | koanf configuration struct and loader |
| `internal/` | Domain packages: `auth`, `card`, `icons`, `jobs`, `labels`, and others |
| `frontend/` | Astro 6 + Svelte 5 frontend; embedded into the binary via `go:embed` |
| `frontend/design` | Git submodule — this site's design tokens, components, and brand assets |
| `e2e/` | Playwright end-to-end tests |
| `scripts/` | CI helper scripts (file size check, i18n check) |
| `docs/hardware.md` | Canonical Yoto hardware specs |

## Tech stack

| Layer | Technologies |
|---|---|
| Backend runtime | Go 1.25, CGO-free (`modernc.org/sqlite`) |
| HTTP | huma v2 + chi v5 |
| Database | SQLite with sqlc (type-safe queries) and goose (migrations) |
| Auth | argon2id password hashing, gorilla/sessions, OIDC (PKCE S256) |
| Frontend build | Astro 6, Svelte 5 (runes — not stores), Tailwind v4 |
| UI components | shadcn-svelte |
| Icons | Phosphor duotone only |
| i18n | Paraglide JS — all user-facing strings in `frontend/messages/en.json` |
| Image generation | Ideogram (recommended AI provider) |

## go-yoto sibling module

The Yoto API client lives in a separate module at [gitlab.com/yotoshelf/go-yoto](https://gitlab.com/yotoshelf/go-yoto). It is a standalone library — not a subdirectory of this repository. Changes to Yoto API integration belong there; changes to how YotoShelf calls it belong in `internal/`.

## Design submodule

`frontend/design` is a git submodule pointing at [yotoshelf/yotoshelf.dev](https://gitlab.com/yotoshelf/yotoshelf.dev) — this documentation site, which is also the canonical home of the design system. It provides design tokens, shared Svelte components, fonts, and brand assets. The submodule must be initialised before building the frontend:

```sh
git submodule update --init
```

## New feature workflow

Every new feature follows this sequence:

1. Write the SQL query in `internal/db/queries/{domain}.sql`
2. Run `just generate` — sqlc emits type-safe Go into `internal/db/gen/`
3. Write the huma operation in `internal/api/{domain}.go`
4. Run the server — the OpenAPI spec updates automatically
5. Run `just generate` again — openapi-typescript updates `frontend/src/lib/api/types.ts`
6. Use the shared typed client in Svelte: `import { api } from '$lib/api/client'`
7. Build the UI component in Svelte 5 with typed props
