26922af9970039879d87e68b5ef0d1428349e53f
The desktop runner is gone. Jobs now target label "macbook": a gitea-runner in host mode on the MacBook Air using Homebrew JDK 21, the local Android SDK and node 22, so no container or SDK download. eas.json bumped to 1.22 to match the locally built release. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wmf3K9nCoEsXvvwkmMnuiM
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-apicontainer (Bun,server/) - DB:
gtddatabase in thepersonal-dbPostgres container (server/schema.sql) - Auth: single bearer token (
API_TOKENinserver/.envon 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. 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.
- Weekly review: overdue, stalled (14d), aging waiting-fors (7d), someday sweep, deferred preview, stuck projects — with one-tap triage per row. Done and Trash (restorable) live at the bottom of Review.
- Quick add: the title field parses tokens live —
server/— Bun API + Dockerfile + compose. Deployed at~/personal/gtdon rehbock.xyz, joined topersonal-db_default+caddy_net.
Develop
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 barenpm installto change deps — usenpm run lock(regenerates the lock via anode:22container), or run npm from node 22. - Hook:
git config core.hooksPath .githooksenables 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.homein~/.gradle/gradle.properties→~/.local/share/java/jdk-21.0.12+8. expo prebuildis safe to re-run:app/plugins/withAndroidRelease.jsre-injects the release signing, env-driven versionCode/Name, and gradle.properties tuning into the committedandroid/.
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
# 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/
Description
v1.24
Latest
Languages
TypeScript
89.4%
JavaScript
4%
Shell
2.5%
Kotlin
2.2%
HTML
1.1%
Other
0.6%