Skip to content

About

Homepad API — the Go backend for Homepad (the self-hosted multi-tenant home dashboard). https://gethomepad.dev

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Go 1.25 Postgres Local + PocketID OIDC 26 Go tests passing MIT License

homepad-api

Backend (Go) for homepad — the self-hosted homelab launcher with live uptime badges. Serves the shared service catalog, per-user favorites & ordering, admin catalog CRUD, and both auth paths; polls Gatus server-side so the browser never sees the Gatus URL.

Web frontend (React + Vite) lives at homepad — see its README for the banner, screenshots, and rendered architecture / auth diagrams.

Spec: homepad/specs/v1-launcher.md Test plan: homepad/specs/test-plan-v1.md

Status

✅ Alpha-complete. Every acceptance criterion this repo owns (A1, A4, A5, A6, A9, A10, A11-backend) is implemented and green against real Postgres — no 501 stubs remain. go test ./... runs 26 tests green; go vet ./... clean.

What it does

  • Auth — local register / login / logout (bcrypt, in-memory sessions) and PocketID OIDC (Authorization Code + PKCE, ID-token verified on stdlib crypto, account-link by email, admin role from the OIDC group). OIDC is fully additive and only active when OIDC_ENABLED=true.
  • Catalog — shared service list; order-aware GET /api/services merges each user's saved layout. Admin-only create / edit / delete (non-admin → 403).
  • Per-user state — favorites and personal sort order, persisted in Postgres.
  • Status poller — polls Gatus on an interval (≤30s, status as_of exposed) and serves status per service; Gatus unreachable → all UNKNOWN, never a 5xx.
  • A11 — the Gatus URL is never present in any API response.

Endpoints

POST   /api/register            GET  /api/me
POST   /api/login               POST /api/logout
GET    /api/auth/config         GET  /api/auth/oidc/login        (when OIDC on)
                                GET  /api/auth/oidc/callback      (when OIDC on)
GET    /api/services            POST   /api/services             (admin)
PUT    /api/layout              PATCH  /api/services/{id}         (admin)
                                DELETE /api/services/{id}         (admin)
GET    /api/status              POST   /api/status/refresh        (re-poll Gatus now)

GET /api/services carries responseTimeMs per service — the latest Gatus check's response time — only when there is one; the key is omitted (never 0) for unmonitored services or when Gatus reported no duration. A service whose latest check succeeded but took longer than GATUS_DEGRADED_MS (default 1000; 0 disables) reads DEGRADED — "Slow" on the tile. Gatus has no degraded state of its own; homepad derives it from the reported duration. Admins can change the threshold at runtime from the System panel: it is statusDegradedMs on GET /api/system/config (the effective value) and PATCH /api/admin/settings (migration 0014); a saved value wins over the env var and applies to the next poll with no restart. POST /api/status/refresh re-polls Gatus synchronously: 200 {as_of} when it answered, 503 {error, as_of} when it could not be reached (the last good snapshot and its as_of stand).

GET /api/me / PATCH /api/me carry densityPref (large|compact|list, default compact) alongside themePref. PATCH takes either or both fields; only the fields present are validated and written.

categories.gridWidth is a 12-column span — 3 (quarter), 4 (third), 6 (half) or 12 (full); default 6. PATCH /api/categories/{id} {gridWidth} rejects anything else with 400. Migration 0013 remapped the old 1–8 tile counts (1→3, 2→4, 3→6, 4→6, 5→12, 6–8→12) and kept the old value in grid_width_legacy.

Layout

cmd/homepad-api/        entry point (opens Store, migrates, starts Poller)
internal/api/           HTTP router + handlers (+ integration tests)
internal/oidc/          PocketID OIDC: discovery, PKCE, ID-token verify, JWKS
internal/gatus/         Gatus client + status poller
internal/session/       in-memory session manager (v1)
internal/storage/       Postgres access + migrations
internal/testsupport/   test harness (httptest server, Gatus + IdP stubs)
migrations/             SQL migrations

Run locally

cp .env.example .env
make db-up         # docker compose Postgres on :5432
make run           # boots on :8080

Test

make test          # full suite (Postgres tests skipped if DATABASE_URL unset)
make test-unit     # fast subset
make test-integration  # spins Postgres + runs everything

Deploy

K8s manifests are owned by Joe (homie / SRE bot), not in this repo. This repo ships:

  • Dockerfile (multi-stage, distroless final image, nonroot)
  • .env.example (the full env contract, incl. the OIDC_* values)
  • specs/v1-launcher.md § Deployment contract (canonical: image, ports, env, secrets, probes)

About

Homepad API — the Go backend for Homepad (the self-hosted multi-tenant home dashboard). https://gethomepad.dev

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages