initial commit
This commit is contained in:
214
tasks.org
Normal file
214
tasks.org
Normal file
@@ -0,0 +1,214 @@
|
||||
#+title: phone capture tasks
|
||||
#+startup: overview
|
||||
#+todo: TODO(t!) NEXT(n!) HOLD(h@!) | DONE(d!) CANX(c@!)
|
||||
|
||||
* goal
|
||||
build a tiny android-to-org capture system.
|
||||
|
||||
the app must be instant-feeling, capture-only, and boring. the phone stores notes locally, then posts them to a lan-only server. the server appends validated entries to a central org file.
|
||||
|
||||
* decisions
|
||||
- android-only native app.
|
||||
- kotlin + jetpack compose.
|
||||
- room sqlite for local queue/history.
|
||||
- okhttp or retrofit for http.
|
||||
- workmanager for opportunistic sync.
|
||||
- python fastapi listener in docker.
|
||||
- server owns all writes to the canonical org file.
|
||||
- phone never edits org files directly.
|
||||
- server dedupes by capture id.
|
||||
- no nextcloud/file-sync dependency.
|
||||
- no org parser on phone.
|
||||
- no public exposure.
|
||||
|
||||
* acceptance criteria
|
||||
- opening the app focuses the text field automatically.
|
||||
- saving a note works offline and returns the user to an empty entry state.
|
||||
- captures include local created timestamp with timezone.
|
||||
- user can mark capture as todo.
|
||||
- user can add optional tags.
|
||||
- manual sync posts all pending captures when server is reachable.
|
||||
- server appends valid captures to `phone.org`.
|
||||
- duplicate posts do not create duplicate org entries.
|
||||
- failed sync attempts remain visible and retryable.
|
||||
- app shows at least pending/synced/failed history.
|
||||
- service can run in docker on jeeves/unraid.
|
||||
- service has a `/health` endpoint.
|
||||
- service rejects missing/invalid auth token.
|
||||
- service rejects empty capture body.
|
||||
- service has tests for org formatting and duplicate handling.
|
||||
|
||||
* milestone 0: repo setup
|
||||
** TODO create monorepo skeleton
|
||||
*** acceptance
|
||||
- `android/`, `server/`, and `docs/` directories exist.
|
||||
- root `README.md`, `tasks.org`, `.env.example`, and `docker-compose.example.yml` exist.
|
||||
** TODO add root gitignore
|
||||
*** acceptance
|
||||
- ignores android build outputs.
|
||||
- ignores python virtualenv/cache.
|
||||
- ignores sqlite db files.
|
||||
- ignores local env files.
|
||||
- does not ignore docs or source files.
|
||||
** TODO document v1 scope in README
|
||||
*** acceptance
|
||||
- states capture-only scope.
|
||||
- states non-goals.
|
||||
- states architecture and build order.
|
||||
|
||||
* milestone 1: server mvp
|
||||
** TODO create fastapi app
|
||||
*** acceptance
|
||||
- `GET /health` returns 200 with simple json.
|
||||
- `POST /capture` accepts a valid capture payload.
|
||||
- auth token is required for `POST /capture`.
|
||||
** TODO define pydantic capture model
|
||||
*** acceptance
|
||||
- requires id, created_at, kind, body, tags, and device.
|
||||
- kind is constrained to note/todo.
|
||||
- body is trimmed and must not be empty.
|
||||
- tags are normalized before formatting.
|
||||
** TODO implement org formatter
|
||||
*** acceptance
|
||||
- todo captures produce `* TODO ...`.
|
||||
- note captures produce `* note ...`.
|
||||
- org property drawer includes created, source, and id.
|
||||
- tags are emitted as org heading tags.
|
||||
- multiline note body is preserved.
|
||||
- tests cover todo, note, tags, empty tags, and multiline body.
|
||||
** TODO implement sqlite idempotency store
|
||||
*** acceptance
|
||||
- accepted capture ids are stored.
|
||||
- repeated id returns accepted/already-seen without appending.
|
||||
- db path is configurable.
|
||||
** TODO implement append writer
|
||||
*** acceptance
|
||||
- appends to configured org path.
|
||||
- creates file if missing.
|
||||
- writes utf-8.
|
||||
- appends exactly one entry per new capture.
|
||||
- uses file lock or equivalent simple concurrency guard.
|
||||
** TODO add server tests
|
||||
*** acceptance
|
||||
- health endpoint test.
|
||||
- valid capture append test.
|
||||
- duplicate capture test.
|
||||
- invalid token test.
|
||||
- empty body rejection test.
|
||||
** TODO containerize server
|
||||
*** acceptance
|
||||
- dockerfile builds server image.
|
||||
- compose example maps `/data`.
|
||||
- env vars configure token, org file, and sqlite path.
|
||||
- container starts and exposes configured port.
|
||||
|
||||
* milestone 2: android local capture
|
||||
** TODO create android project
|
||||
*** acceptance
|
||||
- kotlin android app builds.
|
||||
- jetpack compose enabled.
|
||||
- min sdk is reasonable for current personal device.
|
||||
- app id is stable, e.g. `me.hgsky.phonecapture`.
|
||||
** TODO build capture screen
|
||||
*** acceptance
|
||||
- app opens to multiline text box.
|
||||
- keyboard opens automatically.
|
||||
- note/todo control exists.
|
||||
- tags field exists.
|
||||
- save button exists.
|
||||
- save and close affordance exists.
|
||||
** TODO implement local room database
|
||||
*** acceptance
|
||||
- capture entity has id, created_at, kind, body, tags, device, status, synced_at, and last_error.
|
||||
- saving creates pending row.
|
||||
- pending captures survive app restart.
|
||||
** TODO implement capture id generation
|
||||
*** acceptance
|
||||
- id format is stable and readable, e.g. `phone-yyyymmdd-hhmmss-rand`.
|
||||
- ids are generated client-side.
|
||||
- tests or simple assertions prevent blank/duplicate ids in normal flow.
|
||||
** TODO implement basic history screen
|
||||
*** acceptance
|
||||
- lists recent captures.
|
||||
- shows pending/synced/failed status.
|
||||
- failed row shows last error.
|
||||
- user can retry failed/pending sync.
|
||||
|
||||
* milestone 3: android sync
|
||||
** TODO implement api client
|
||||
*** acceptance
|
||||
- base url configurable in app settings or build config.
|
||||
- bearer token configurable in app settings or build config.
|
||||
- client can call `/health`.
|
||||
- client can post capture payload.
|
||||
** TODO implement manual sync
|
||||
*** acceptance
|
||||
- sync now posts all pending captures.
|
||||
- successful posts mark rows synced.
|
||||
- already-seen response marks row synced.
|
||||
- failures retain pending/failed status and last error.
|
||||
** TODO implement opportunistic workmanager sync
|
||||
*** acceptance
|
||||
- periodic sync is registered.
|
||||
- sync only runs when network is available.
|
||||
- worker first checks `/health`.
|
||||
- worker does not block capture speed.
|
||||
** TODO add simple server reachability settings
|
||||
*** acceptance
|
||||
- default url can be set to `http://jeeves.mother:8765`.
|
||||
- user can change server url.
|
||||
- user can change token.
|
||||
- invalid settings do not crash app.
|
||||
|
||||
* milestone 4: polish and hardening
|
||||
** TODO make launch path fast
|
||||
*** acceptance
|
||||
- app opens directly to capture field.
|
||||
- no network call blocks launch.
|
||||
- no history loading blocks text entry.
|
||||
** TODO normalize tags
|
||||
*** acceptance
|
||||
- whitespace-separated and comma-separated tags both work.
|
||||
- invalid org tag chars are stripped or replaced.
|
||||
- duplicate tags collapse.
|
||||
** TODO handle multiline notes well
|
||||
*** acceptance
|
||||
- first line can become note heading if body is multiline.
|
||||
- full body is preserved under heading.
|
||||
- todo body remains usable as a single todo heading, with extra lines under it if present.
|
||||
** TODO add basic logs
|
||||
*** acceptance
|
||||
- server logs accepted capture id.
|
||||
- server logs duplicate capture id.
|
||||
- server logs rejected payload without dumping secrets.
|
||||
** TODO create backup note
|
||||
*** acceptance
|
||||
- readme documents which paths need backup.
|
||||
- readme documents restore behavior.
|
||||
|
||||
* milestone 5: optional v1.5
|
||||
** TODO add android share target
|
||||
*** acceptance
|
||||
- sharing text to app opens prefilled capture.
|
||||
- user can save as note or todo.
|
||||
** TODO add home screen quick capture widget
|
||||
*** acceptance
|
||||
- widget opens capture screen quickly.
|
||||
- does not require sync to work.
|
||||
** TODO add recent tag chips
|
||||
*** acceptance
|
||||
- app shows recent tags.
|
||||
- tapping chip adds/removes tag.
|
||||
** TODO add edit-before-sync
|
||||
*** acceptance
|
||||
- pending/failed captures can be edited.
|
||||
- synced captures are read-only unless explicitly duplicated.
|
||||
|
||||
* implementation notes for coding agents
|
||||
- keep the server small and testable.
|
||||
- keep org formatting in one pure function.
|
||||
- do not add auth flows, accounts, or public hosting.
|
||||
- do not add org parsing.
|
||||
- do not write to org files from android.
|
||||
- prefer boring explicit settings over clever discovery.
|
||||
- if a design choice risks sync conflicts, do the simpler append-only thing.
|
||||
Reference in New Issue
Block a user