milestone 4: org header, logging, backup docs, mark all m4 tasks done

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-18 14:46:37 -04:00
parent 0799595b26
commit fd28a45cd7
3 changed files with 77 additions and 6 deletions

View File

@@ -303,30 +303,74 @@ SettingsScreen + SettingsViewModel from milestone 2. DataStore-backed. Default s
- datetime: [2026-05-18 Sun 18:00]
* milestone 4: polish and hardening
** TODO make launch path fast
** DONE 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
*** notes
LaunchedEffect(Unit) { focusRequester.requestFocus() } fires immediately on composition. No network calls in MainActivity or CaptureScreen init path. History loads via Room Flow on a background coroutine — never blocks text entry.
*** evidence
- commit: 19b05a8
- tests: manual — cold launch, keyboard appears without any loading state
- datetime: [2026-05-18 Sun 19:00]
** DONE 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
*** notes
Two-layer normalization: parseTags() in CaptureViewModel splits on [,\s]+ before storing to Room. normalize_tags() in server/app/org_writer.py lowercases, strips #, replaces spaces with _, removes non-[a-z0-9_] chars, deduplicates. 7 unit tests cover all cases.
*** evidence
- commit: e873a00 (server), 19b05a8 (android)
- tests: pytest tests/test_org_writer.py::TestNormalizeTags — 7 passed
- datetime: [2026-05-18 Sun 19:00]
** DONE fix org formatting
*** acceptance
- add `#+startup: overview` to synq.org
*** notes
Append writer in main.py checks if org file exists before first write. If missing, creates it with #+title and #+startup: overview header. Existing files are never modified.
*** evidence
- commit: (this commit)
- tests: manual — delete synq.org, post a capture, verify header present
- datetime: [2026-05-18 Sun 19:00]
** DONE 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
*** notes
format_capture() in org_writer.py: multiline note uses first line as heading suffix ("* note: <first line>"), full body preserved below drawer. Single-line note uses "* note" heading, body below. Covered by test_note_multiline.
*** evidence
- commit: e873a00
- tests: pytest tests/test_org_writer.py::TestFormatCapture::test_note_multiline — passed
- datetime: [2026-05-17 Sat 17:00]
** DONE 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
*** notes
logger.info for accepted and duplicate (id only, no body). logger.warning for invalid token (client IP only, no token value logged). logger.warning for validation errors (field names only, no body content).
*** evidence
- commit: (this commit)
- tests: manual — send bad token, send empty body, check uvicorn stdout
- datetime: [2026-05-18 Sun 19:00]
** DONE create backup note
*** acceptance
- readme documents which paths need backup.
- readme documents restore behavior.
*** notes
Added "backup" section to README.md covering synq.org, capture.sqlite3, token.txt. Restore section documents behavior when each file is lost individually.
*** evidence
- commit: (this commit)
- tests: n/a
- datetime: [2026-05-18 Sun 19:00]
* milestone 5: optional v1.5
** TODO add android share target