# Overseer
A self-hosted family information system. One binary, one SQLite file,
one YAML config, one systemd unit. Server-rendered HTML with htmx for
the interactive bits — no SPA, no JS build step.
Overseer is structured as a set of independent modules. v1 ships a
single module:
- **Inventory** — track where things live at home. A tree of
*storages* (rooms, shelves, drawers…) holding *stuffs* (items). Each
stuff can have a photo, a description, and a rolling 10-entry move
history. Full-text search over names and descriptions. Inline name
editing and one-click move via htmx.
A *Doc* module is sketched in the design but not built yet.
## Features
- OIDC login (any provider with discovery — Keycloak, Authentik,
Dex, …). Tokens stay server-side; the browser holds an opaque
session cookie.
- Photo upload, scaled to 1024 px long-side and transcoded to AVIF.
Identical photos are stored once and shared by SHA-256.
- SQLite + FTS5 search, WAL journaling, foreign keys with
`ON DELETE RESTRICT`, versioned migrations with automatic pre-migration
backup.
- CSRF protection (double-submit token + same-origin check) on all
mutating routes.
- Structured logging via `spdlog`, with a journald sink when run
under systemd.
- Unix-socket or TCP bind. The socket mode is configurable so a
reverse proxy can connect without any group/user juggling.
## Build
Requires a C++23 compiler (GCC 14+ / Clang 18+), CMake ≥ 3.24, and:
- SQLite ≥ 3.38 (FTS5)
- libcurl
- ImageMagick (Magick++)
- libsystemd
- pkg-config
Other dependencies (`libmw`, `inja`, `nlohmann_json`, `spdlog`,
`yaml-cpp`, `cxxopts`, and optionally `googletest`) are fetched
through CMake's `FetchContent`.
```
cmake -B build -S . -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
```
For development / running tests:
```
cmake -B build -S . -DOVERSEER_BUILD_TEST=ON
cmake --build build -j
ctest --test-dir build
```
## Configuration
Copy `overseer.example.yaml` to `/etc/overseer.yaml` and edit it. The
config file must not be world-readable (the daemon refuses to start
otherwise) since it carries the OIDC client secret.
Minimum keys:
```yaml
bind_address: "unix:/run/overseer/overseer.sock" # or "127.0.0.1"
port: 8080 # only used for TCP binds
socket_permission: "0666" # only used for unix binds
log_level: "info"
db_path: "/var/lib/overseer/overseer.db"
oidc:
issuer_url: "https://keycloak.example.com/realms/family"
client_id: "overseer"
client_secret: "REPLACE_ME"
redirect_uri: "https://overseer.example.com/oidc/callback"
```
The redirect URI must be registered with the OIDC provider as an
allowed callback for the client.
## Running
```
overseer --config /etc/overseer.yaml
```
Other flags (run `overseer --help` for the full list):
- `--template-dir DIR` — override the template root (defaults to the
source tree in a dev build, `/usr/share/overseer/modules` in the
Arch package).
- `--static-dir DIR` — override the static-files root.
- `--dev` — verbose logging and template hot reload.
### Arch Linux
A `-git` PKGBUILD lives in `packages/arch/`:
```
cd packages/arch
makepkg -si
```
The package installs the binary to `/usr/bin/overseer`, templates to
`/usr/share/overseer/`, a sample config to `/etc/overseer.yaml`,
and registers a system user `overseer`, a tmpfiles entry for
`/var/lib/overseer/`, and an `overseer.service` unit. After editing
the config:
```
systemctl enable --now overseer.service
```
The unit binds to `/run/overseer/overseer.sock` by default. Point your
reverse proxy at that socket.
## Development
The source tree mirrors the module layout:
```
src/
inventory/ # liboverseer_inventory — pure repo/domain code
db/ # migrations + backup
overseer/ # the binary: web server, OIDC, render, session
modules/
inventory/ # routes, views, templates for the inventory module
static/ # CSS, JS (htmx)
tests/ # GoogleTest unit + HTTP integration tests
designs/ # design docs
packages/arch/ # PKGBUILD and systemd assets
```
The `inventory` library has no web dependency, so a future
agent-facing surface (MCP, REST) can reuse it directly.
For the full architectural rationale see
[designs/design-0-architecture.md](designs/design-0-architecture.md).