# go-bananas **Runtime design-token service.** Author design-token themes in a web interface, serve them to any application as CSS custom properties at run time. Consumers install nothing and have no build step. | | | | --- | --- | | Module | github.com/urpi/go-bananas · go 1.27.1 · 49 Go files | | Endpoints | 30 endpoints | | Components | 0 component directories | | Tests | 128 in 14 files | | Go lines | 16314 lines | > Everything between the generated markers is rewritten by every sync. Notes written outside the markers are kept. ## For Users ### What this application does **Runtime design-token service.** Author design-token themes in a web interface, serve them to any application as CSS custom properties at run time. Consumers install nothing and have no build step. The project ships its own README at `README.md`, which is the long form of this page. The three audience tabs split the same facts three ways so you only read the part that concerns you. ### Reading this in go-doc Open the page and pick the tab that matches you: - **User** — you use the finished application. This section is all you need. - **Operator** — you run it. Configuration, ports and deployment notes are under that tab. - **Developer** — you integrate with it or change it. The API and layout tables are under that tab. The feedback panel stores a note per audience, tagged with your badge, so operators and developers can see which audience raised it. ### Where the original documentation lives This project already carries 15 Markdown documents. They stay in the project repository: this page points at them instead of copying them, so there is always exactly one copy of the truth. | Document | Size | | --- | --- | | `README.md` | 18070 bytes | | `docs/adr/0001-embedded-sqlite.md` | 8480 bytes | | `docs/adr/0002-runtime-delivery.md` | 6721 bytes | | `docs/adr/0003-stateful-sessions.md` | 4438 bytes | | `docs/adr/0004-typescript-version.md` | 2624 bytes | | `docs/adr/0005-shared-token-contract.md` | 5659 bytes | | `docs/api.md` | 12685 bytes | | `docs/architecture.md` | 16634 bytes | | `docs/deployment.md` | 20188 bytes | | `docs/development.md` | 8483 bytes | | `docs/integration.md` | 17511 bytes | | `docs/operations.md` | 10048 bytes | | `docs/security.md` | 12400 bytes | | `docs/standards.md` | 26476 bytes | | `docs/styling-contract.md` | 8545 bytes | --- ## For Operators ### Running it locally This project has no root Makefile, so the binary or container is run directly. ### Local containers The compose file defines these services: | Service | Image | Published ports | | --- | --- | --- | | go-bananas | `${IMAGE:-go-bananas:dev}` | internal only | | keycloak | `quay.io/keycloak/keycloak:26.3` | internal only | | postgres | `postgres:18-alpine` | internal only | ### Image `Dockerfile` builds from `node:${NODE_VERSION}-alpine`, `golang:${GO_VERSION}-alpine`, `alpine:${ALPINE_VERSION}`, `runtime` in stages: assets, build, runtime, final and exposes 8080. ### Configuration Every environment variable found in the source or in a `.env` file: | Variable | Example | Found in | | --- | --- | --- | | `BANANAS_AUTH_MODE` | `dev` | .env file | | `BANANAS_DATABASE_PATH` | `./data/go-bananas.db` | .env file | | `BANANAS_DB_BUSY_TIMEOUT` | `5s` | .env file | | `BANANAS_DB_MAX_CONNS` | `8` | .env file | | `BANANAS_DEV_FALLBACK_ROLE` | `admin` | .env file | | `BANANAS_ENABLE_METRICS` | `true` | .env file | | `BANANAS_ENABLE_PROFILER` | `false` | .env file | | `BANANAS_ENVIRONMENT` | `development` | .env file | | `BANANAS_HTTP_ADDR` | `:8080` | .env file | | `BANANAS_HTTP_IDLE_TIMEOUT` | `120s` | .env file | | `BANANAS_HTTP_READ_TIMEOUT` | `15s` | .env file | | `BANANAS_HTTP_WRITE_TIMEOUT` | `30s` | .env file | | `BANANAS_LOG_FORMAT` | `text` | .env file | | `BANANAS_LOG_LEVEL` | `info` | .env file | | `BANANAS_OIDC_CLIENT_ID` | `go-bananas` | .env file | | `BANANAS_OIDC_ISSUER` | `https://auth-dev.urpi.be/realms/urpi` | .env file | | `BANANAS_PUBLIC_BASE_URL` | `http://localhost:8080` | .env file | | `BANANAS_RATE_LIMIT_PER_MINUTE` | `600` | .env file | | `BANANAS_RUNTIME_CACHE_CONTROL` | `public, max-age=60, stale-while-revalidate=86400` | .env file | | `BANANAS_SEED_ON_START` | `true` | .env file | | `BANANAS_SESSION_COOKIE_NAME` | `go-bananas-session` | .env file | | `BANANAS_SESSION_SAMESITE` | `Lax` | .env file | | `BANANAS_SESSION_SECURE` | `false` | .env file | | `BANANAS_SESSION_TTL` | `8h` | .env file | | `BANANAS_SHUTDOWN_TIMEOUT` | `25s` | .env file | | `DATABASE_PATH` | — | source | Command-line flags override the environment where both exist: | Flag | Default | Purpose | | --- | --- | --- | | `-backup=flag.ContinueOnError` | `flag.ContinueOnError` | — | ### Network surface Ports referenced across the project: `8080`. ### Deployment artefacts Helm 1 chart found: - `deploy/helm/go-bananas` ### Operations documentation that already exists Read these in place rather than duplicating them here: - `docs/deployment.md` — Deployment - `docs/operations.md` — Operations --- ## For Developers ### Module layout - go.mod — module github.com/urpi/go-bananas, go 1.27.1, 3 direct and 11 indirect dependencies - hack/go.mod — module hack/tools, go 1.27.1, 0 direct and 254 indirect dependencies ### HTTP API Every route registration found in the source: | Method | Path | Handler | | --- | --- | --- | | `GET` | `/*` | `ServeHTTP` | | `HEAD` | `/*` | `ServeHTTP` | | `GET` | `/auth/callback` | `Callback` | | `GET` | `/auth/login` | `Login` | | `GET` | `/auth/logout` | `Logout` | | `POST` | `/auth/logout` | `Logout` | | `GET` | `/contract.css` | `ContractCSS` | | `GET` | `/contract.json` | `ContractJSON` | | `GET` | `/contrast` | `contrast` | | `GET` | `/embed` | `EmbedSnippet` | | `GET` | `/embed-page` | `EmbedPage` | | `GET` | `/healthz` | `Live` | | `GET` | `/livez` | `Live` | | `GET` | `/manifest.json` | `Manifest` | | `GET` | `/meta` | `Meta` | | `GET` | `/metrics` | — | | `GET` | `/palette` | `generatePalette` | | `DELETE` | `/preferences` | `Reset` | | `GET` | `/preferences` | `Get` | | `PUT` | `/preferences` | `Update` | | `GET` | `/readyz` | `Ready` | | `GET` | `/schema` | `tokenSchema` | | `GET` | `/stats` | `stats` | | `GET` | `/theme.css` | `ThemeCSS` | | `GET` | `/theme.json` | `ThemeJSON` | | `GET` | `/themes/{slug}/embed` | `EmbedSnippet` | | `GET` | `/themes/{slug}/embed-page` | `EmbedPage` | | `GET` | `/themes/{slug}/theme.css` | `ThemeCSS` | | `GET` | `/themes/{slug}/theme.json` | `ThemeJSON` | | `POST` | `/validate` | `validateTokens` | ### Direct dependencies - `github.com/coreos/go-oidc/v3` v3.21.0 - `golang.org/x/oauth2` v0.37.0 - `modernc.org/sqlite` v1.60.1 ### Directory map | Directory | Files | Lines | Likely purpose | | --- | --- | --- | --- | | `internal/` | 51 | 16405 | unimportable application internals | | `web/` | 43 | 7897 | frontend assets | | `deploy/` | 21 | 274 | deployment manifests | | `docs/` | 14 | 0 | project documentation | | `sdk/` | 14 | 3261 | unknown — inspect directly | | `hack/` | 10 | 2248 | operational tooling | | `cmd/` | 1 | 95 | binary entry points | | `data/` | 1 | 186 | flat-file data | ### Languages - **Go** — 49 files, 16314 lines - **JSON** — 11 files, 8329 lines - **TypeScript** — 33 files, 7763 lines - **YAML** — 21 files, 5290 lines - **Markdown** — 15 files, 4560 lines - **JavaScript** — 15 files, 3820 lines - **Shell** — 4 files, 529 lines - **Templates** — 1 file, 255 lines - **CSS** — 1 file, 211 lines - **SQL** — 3 files, 186 lines ### Developer documentation that already exists - `docs/adr/0005-shared-token-contract.md` — ADR 0005: One token contract for every application, with a legacy alias layer - `docs/api.md` — HTTP API - `docs/architecture.md` — Architecture - `docs/development.md` — Development - `docs/integration.md` — Integrating a go-bananas theme - `docs/styling-contract.md` — The shared styling contract --- ## Related Documentation - [go-doc](go-doc.md) — The documentation platform itself - [go-loose](go-loose.md) — Auth middleware (referenced in integration docs)