diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index f3bd313..f46857d 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -16,7 +16,8 @@ jobs: run: | apt-get update -qq && apt-get install -y -qq git unzip curl > /dev/null git init . - git fetch --depth 1 https://git.rehbock.xyz/${{ github.repository }}.git ${{ github.sha }} + # Token auth: the repo is private (until it's deliberately open-sourced). + git fetch --depth 1 https://gitea-actions:${{ secrets.GITHUB_TOKEN }}@git.rehbock.xyz/${{ github.repository }}.git ${{ github.sha }} git checkout FETCH_HEAD - name: Install Node.js diff --git a/server/CLAUDE.md b/server/CLAUDE.md new file mode 100644 index 0000000..ee00230 --- /dev/null +++ b/server/CLAUDE.md @@ -0,0 +1,38 @@ +# 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.