Files
gtd/README.md
marcuspaico dab6cb3347
Some checks failed
Build & Release APK / check (push) Has been cancelled
Build & Release APK / build (push) Has been cancelled
feat(nav): three tabs and a Lists board; drop Review
Next up, Today and Lists replace the six-button launcher. Lists is a 2x2
board (Next up / Waiting / Someday / Projects): full scrolling panes on a
desktop window, preview cards on a phone, each header opening its list and
each project opening its tasks. The Needs-attention card collapses to one
row of status pills under the title. Review and its screen are gone; Done
and Trash move under the Settings gear. v1.24.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SW5iVXkZ2JBHgyweMCRymY
2026-09-08 17:38:51 +10:00

45 lines
3.2 KiB
Markdown

# GTD
Minimal Getting Things Done app. One Expo/React Native codebase for iPhone, Android, and web; data lives in Postgres on the VPS.
- **Web**: https://gtd.rehbock.xyz (Expo web export, static)
- **API**: https://gtd.rehbock.xyz/api → `gtd-api` container (Bun, `server/`)
- **DB**: `gtd` database in the `personal-db` Postgres container (`server/schema.sql`)
- **Auth**: single bearer token (`API_TOKEN` in `server/.env` on the VPS); enter it once in the app's Settings
## Layout
- `app/` — Expo app (expo-router, TypeScript). Home shows the top 3 next actions plus a launcher menu: Today / Next / Waiting / Someday / Projects / Review.
- **Personal / Work**: the toggle in the home header is a global lens — every list, Today, Projects and Review show only the active area, and new tasks/projects are born into it. Tasks and projects carry an `area` column (`personal` default); the task form's Area chip re-files a task across areas. The choice persists locally (`area_v1`). There is no inbox — every task is born fully scoped (title, priority, due date). Tap a task to clarify (list, project, context, waiting-for, due/defer dates, repeat).
- **Quick add**: the title field parses tokens live — `Pay rent tmr p1 @home #Sydney ~30m monthly` — and mirrors them into the form.
- **Repeat**: daily / weekdays / weekly / monthly / yearly; completing spawns the next occurrence (lapsed tasks catch up to today).
- **Defer**: deferred tasks are hidden from action lists until their date; a footer link reveals them.
- `server/` — Bun API + Dockerfile + compose. Deployed at `~/personal/gtd` on rehbock.xyz, joined to `personal-db_default` + `caddy_net`.
## Develop
```sh
cd app && npx expo start # scan QR with Expo Go (iPhone or Pixel)
```
- **Node 22 only** (`app/.nvmrc`): CI's npm 10 rejects lockfiles written by newer npm. Never run bare `npm install` to change deps — use `npm run lock` (regenerates the lock via a `node:22` container), or run npm from node 22.
- **Hook**: `git config core.hooksPath .githooks` enables a pre-push check that validates the lockfile against CI's npm before it can break a build.
- **Local Android builds** need JDK 21 (AGP chokes on newer): pinned via `org.gradle.java.home` in `~/.gradle/gradle.properties` → `~/.local/share/java/jdk-21.0.12+8`.
- **`expo prebuild` is safe to re-run**: `app/plugins/withAndroidRelease.js` re-injects the release signing, env-driven versionCode/Name, and gradle.properties tuning into the committed `android/`.
## Release (Android APK → Obtainium)
Every push to `main` runs `.gitea/workflows/release.yml` on the desktop runner: fast check job (lockfile/types/lint), then a signed `assembleRelease`, published as Gitea release `v1.<run>` with the APK attached. Phones track it with Obtainium → source `https://git.rehbock.xyz/marcus/gtd` (Forgejo/Gitea source type). CI failures push to ntfy topic `gtd-ci` when the `NTFY_TOKEN` repo secret is set.
## Deploy
```sh
# API
rsync -a server/ --exclude .env.token.local rehbock.xyz:personal/gtd/
ssh rehbock.xyz 'cd ~/personal/gtd; and docker compose up -d --build'
# Web
cd app && npx expo export --platform web
rsync -a --delete dist/ rehbock.xyz:personal/gtd/web/
```