# Kin server (the `crm` container) Personal relationships CRM — serves the Kin mobile app and the web UI at https://crm.rehbock.xyz. **Source of truth is the git repo** `git.rehbock.xyz/marcus/kin` (`server/` directory); the copy at `~/personal/crm` on the VPS is a deploy target. Don't edit it in place — edit in the repo (`~/kin` on the desktop), then: rsync -a --delete --exclude .env --exclude .env.token.local --exclude node_modules \ server/ rehbock.xyz:personal/crm/ ssh rehbock.xyz 'cd ~/personal/crm; and docker compose up -d --build' Restart is NOT enough — the Dockerfile bakes source in. ## Stack - Bun + Hono, `postgres` (porsager) client, DB `personal` in the shared `personal-db` container. `DATABASE_URL`, `PORT`, `API_TOKEN` in `./.env` (VPS-only, never in git). - Migrations: `migrations/*.sql` applied at boot, recorded in `schema_migrations`. Add numbered files; never edit applied ones. ## Auth - Browser → Caddy basic_auth (`~/personal/proxy/Caddyfile`, user `admin`). - Kin app → `Authorization: Bearer $API_TOKEN`; Caddy passes Bearer requests through, `src/index.ts` middleware validates. - Docker-network access is unauthenticated by design; never publish port 3000. ## API (src/routes/) - `people.ts`: stats, tags, people CRUD, interactions add/delete, relationships add/delete. - `due.ts`: `GET /api/due` (urgency = days_since / cadence_days, sections computed client-side), `POST /api/people/:id/snooze`. ## Schema notes - `people.cadence_days` null = no reminders; `archived` hides from everything; `snoozed_until` hides from due list; logging an interaction clears snooze. - `last_contacted`/`interaction_count` computed from `interactions` at query time, not stored.