228 lines
8.1 KiB
Markdown
228 lines
8.1 KiB
Markdown
|
|
<!-- go-doc:generated:begin source=go-bananas signature=14ab62420e5091c8fd2da3a6c2a07232 generated=2026-10-07 09:29 UTC -->
|
||
|
|
# 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
|
||
|
|
<!-- go-doc:generated:end -->
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Related Documentation
|
||
|
|
|
||
|
|
- [go-doc](go-doc.md) — The documentation platform itself
|
||
|
|
- [go-loose](go-loose.md) — Auth middleware (referenced in integration docs)
|