diff --git a/.release-it.json b/.release-it.json index b3ca265..552aa28 100644 --- a/.release-it.json +++ b/.release-it.json @@ -11,6 +11,9 @@ "release": true, "releaseName": "v${version}" }, + "hooks": { + "before:git:release": "echo 'Check: README.md reflects current modules and env vars before tagging'" + }, "plugins": { "@release-it/conventional-changelog": { "preset": { diff --git a/README.md b/README.md index 9d12c58..c046265 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,158 @@ # famapp -Self-hosted family coordination: shared calendar, lists, notes. +Self-hosted family coordination web app. Shared calendar, lists, notes, and garden tracker — installable as a PWA, protected by OIDC single sign-on. -- **Plan & architecture:** [`CLAUDE.md`](CLAUDE.md) -- **Current progress:** [`STATUS.md`](STATUS.md) -- **Task briefs (for sub-sessions):** [`docs/tasks/`](docs/tasks/) -- **Architecture decisions:** [`docs/decisions/`](docs/decisions/) +[![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/`), 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=ghcr.io/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//` 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 — CI builds and pushes `ghcr.io/ginnoir/famapp:vX.Y.Z` automatically. diff --git a/docs/tasks/09-pre-deploy-checklist.md b/docs/tasks/09-pre-deploy-checklist.md index a788894..d4299b8 100644 --- a/docs/tasks/09-pre-deploy-checklist.md +++ b/docs/tasks/09-pre-deploy-checklist.md @@ -2,6 +2,10 @@ Run this before every production deploy (first deploy and each tagged release). Dev-login is intentionally retained behind a double gate; this checklist is what keeps that gate honest. +## README + +- [ ] `README.md` reflects the current module list and any env vars added since the last release. + ## Env hygiene - [ ] Server `.env` (next to `deploy/compose.yaml`) does **not** set: