Files
famapp/README.md
T
ginnoirandClaude Sonnet 4.6 4084c3af91
CI / checks (push) Successful in 1m46s
CI / build (push) Successful in 2m45s
Release Image / build-and-push (push) Failing after 49s
ci: publish famapp images to valhalla registry
Add Gitea Actions workflows (ci.yml, release.yml) that build and push
to registry.ginnoir.com. Disable GitHub release creation. Update all
doc/compose references from ghcr.io to registry.ginnoir.com.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 00:16:27 -05:00

159 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# famapp
Self-hosted family coordination web app. Shared calendar, lists, notes, and garden tracker — installable as a PWA, protected by OIDC single sign-on.
[![CI](https://github.com/ginnoir/famapp/actions/workflows/ci.yml/badge.svg)](https://github.com/ginnoir/famapp/actions/workflows/ci.yml)
[![Latest release](https://img.shields.io/github/v/release/ginnoir/famapp?sort=semver)](https://github.com/ginnoir/famapp/releases)
[![Docker image](https://img.shields.io/badge/image-ghcr.io%2Fginnoir%2Ffamapp-blue?logo=docker)](https://github.com/ginnoir/famapp/pkgs/container/famapp)
[![Node ≥ 22](https://img.shields.io/badge/node-%E2%89%A522-brightgreen?logo=node.js)](https://nodejs.org)
---
## Features
### Modules
| Module | What it does |
| ------------ | ------------------------------------------------------------------------------------------ |
| **Calendar** | Month / week / day views, drag-to-create, household and private calendars, event reminders |
| **Lists** | Shopping and task lists with real-time sync, reorder, keyboard-first item entry |
| **Notes** | Markdown notes with pinning, safe preview, and optional remind-at scheduling |
| **Garden** | Plant and container tracking, care schedules, care logs, species lookup via OpenPlantBook |
### Platform capabilities
| Capability | Detail |
| ---------------------- | ------------------------------------------------------------------------------------------- |
| **Dashboard** | Per-user named dashboards, drag-resize widget grid, configurable widget instances |
| **Quick-add** | `Cmd/Ctrl+K` command palette and `+` FAB — every module registers its own actions |
| **Share links** | Any entity produces a temporary public link (`/s/<token>`), scoped read or read-write |
| **Activity log** | Household-scoped feed of every create / update / delete across all modules |
| **Reminders** | Generic reminder engine ticked every 30 s; notes and calendar events both use it |
| **Push notifications** | VAPID web push + in-app inbox + optional ntfy fallback |
| **Themes** | Two palettes (`default` / `warm`) × light / dark / system, zero flash on load |
| **PWA / offline** | Installable on iOS and Android, offline shell, stale-while-revalidate caching |
| **Structured logging** | JSON logs via pino in production, pretty-printed in dev, `LOG_LEVEL` configurable |
| **Nightly backups** | `pg_dump` cron for both databases, 14-day daily / 8-week weekly / 6-month monthly retention |
---
## Requirements
- **Docker** with the Compose plugin (v2)
- **Caddy** (or any reverse proxy that handles HTTPS)
- **Authentik** — famapp delegates all authentication to an Authentik OIDC provider; see the [bootstrap guide](deploy/authentik/README.md)
- A domain with DNS pointing to your host
---
## Quick start
Full details are in [`deploy/README.md`](deploy/README.md). The short version:
```bash
# 1. Clone and enter the repo
git clone https://github.com/ginnoir/famapp.git /srv/famapp
cd /srv/famapp
# 2. Create your environment file
cp .env.production.example deploy/.env
# Edit deploy/.env — see Configuration below for required values
# 3. Configure your reverse proxy
# Add deploy/Caddyfile.snippet to your Caddyfile, then reload Caddy
# 4. Bootstrap Authentik and record the OIDC client id/secret in deploy/.env
# See deploy/authentik/README.md
# 5. Start the stack
docker compose -f deploy/compose.example.yaml up -d
```
The container runs database migrations automatically on start. The first user to sign in becomes the household owner; a second sign-in joins the same household as a member.
Pin `FAMAPP_IMAGE` in `deploy/.env` after the first deploy:
```
FAMAPP_IMAGE=registry.ginnoir.com/ginnoir/famapp:v0.4.7
```
---
## Development setup
Requires Node ≥ 22 and pnpm 10.
```bash
git clone https://github.com/ginnoir/famapp.git
cd famapp
pnpm install
# Copy the example env and fill in dev values (set ENABLE_DEV_LOGIN=true)
cp .env.example .env
# Start the local database, run migrations, seed, and launch the dev server
pnpm dev:local
```
Then open `http://localhost:3000/login` and click **Dev login**.
Additional dev commands:
| Command | Purpose |
| --------------------- | ---------------------------------------------- |
| `pnpm dev:reset` | Drop and reseed the local database |
| `pnpm db:studio` | Open Drizzle Studio against the local database |
| `pnpm db:generate` | Generate a new migration after schema changes |
| `pnpm typecheck` | Run `tsc --noEmit` |
| `pnpm lint` | ESLint |
| `pnpm test:e2e` | Playwright E2E suite |
| `pnpm vapid:generate` | Print VAPID key env vars to stdout |
| `pnpm gen:icons` | Regenerate PWA icons from `public/icon.svg` |
See [`docs/dev-login.md`](docs/dev-login.md) for push notification and E2E testing setup.
---
## Configuration
Copy `.env.production.example` to `deploy/.env` and fill in values. Key variables:
| Variable | Required | How to generate |
| -------------------------------- | -------- | -------------------------------------------------------------------- |
| `AUTH_URL` | Yes | Public HTTPS URL for the app (e.g. `https://fam.yourdomain.com`) |
| `AUTH_SECRET` | Yes | `openssl rand -base64 32` |
| `AUTH_OIDC_ISSUER` | Yes | From Authentik — `https://auth.yourdomain.com/application/o/famapp/` |
| `AUTH_OIDC_CLIENT_ID` | Yes | From Authentik application |
| `AUTH_OIDC_CLIENT_SECRET` | Yes | From Authentik application |
| `FAMAPP_DB_PASSWORD` | Yes | Strong random password |
| `AUTHENTIK_DB_PASSWORD` | Yes | Strong random password |
| `AUTHENTIK_SECRET_KEY` | Yes | `openssl rand -base64 60` |
| `VAPID_PUBLIC_KEY` | Push | `pnpm vapid:generate` |
| `VAPID_PRIVATE_KEY` | Push | `pnpm vapid:generate` |
| `VAPID_SUBJECT` | Push | `mailto:your-email@example.com` |
| `NTFY_URL` / `NTFY_TOPIC` | Optional | ntfy push fallback |
| `famapp_OPENPLANTBOOK_CLIENT_ID` | Optional | OpenPlantBook API — plant species lookup |
| `LOG_LEVEL` | Optional | `error` / `warn` / `info` / `debug` (default: `info`) |
---
## Architecture
famapp uses an extensibility-first module system: every feature lives under `src/modules/<name>/` and declares its tables, routes, dashboard widgets, quick-add actions, and share/reminder/search behaviors via a manifest. Core services (sharing, push, reminders, activity log, search) operate generically — adding a new module does not require touching core code.
See [`CLAUDE.md`](CLAUDE.md) for the full architecture brief and [`docs/decisions/`](docs/decisions/) for ADRs.
---
## Deployment
| Resource | Link |
| -------------------- | -------------------------------------------------------------------------------- |
| Full host setup | [`deploy/README.md`](deploy/README.md) |
| Authentik bootstrap | [`deploy/authentik/README.md`](deploy/authentik/README.md) |
| Backup / restore | [`deploy/backups/README.md`](deploy/backups/README.md) |
| Pre-deploy checklist | [`docs/tasks/09-pre-deploy-checklist.md`](docs/tasks/09-pre-deploy-checklist.md) |
| Changelog | [`CHANGELOG.md`](CHANGELOG.md) |
Cutting a release: tag `vX.Y.Z` on `main` and push — Gitea Actions builds and pushes `registry.ginnoir.com/ginnoir/famapp:vX.Y.Z` automatically.