Project skeleton: Gradle 9.4.1 wrapper, AGP 9.2.1, Compose, manifest with reminder permission set
Milestone 1 of the build brief. Version catalog pins verified against Maven Central / Google Maven on 2026-06-10; Kotlin held at 2.3.10 to match AGP 9.2's bundled KGP (built-in Kotlin) because KSP has no Kotlin 2.4 release yet. compileSdk 37 (forced by core-ktx 1.19), targetSdk 35 per brief. allowBackup=false + full dataExtractionRules opt-out; own encrypted backup comes in milestone 5. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
commit
7256c49112
21 changed files with 845 additions and 0 deletions
66
CLAUDE.md
Normal file
66
CLAUDE.md
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# «Med det samme» — Claude Code project memory
|
||||
|
||||
Local-first Android medication reminder. My personal MyTherapy replacement: no ads,
|
||||
no account, no analytics, no cloud service of yours. Single user, single device.
|
||||
Reminders are the entire point — reliability beats polish wherever they trade off.
|
||||
The name says the brief: nag me to take the dose *now*.
|
||||
|
||||
- Package / applicationId: `no.naiv.meddetsamme`
|
||||
- Display name: `Med det samme` (in `strings.xml`, referenced from the manifest)
|
||||
- minSdk 26, targetSdk 35, JVM 17, Kotlin + Compose (Material3)
|
||||
- Stack: Room (+KSP), WorkManager, OkHttp, security-crypto, kotlinx-serialization.
|
||||
Gradle Kotlin DSL + version catalog. No AWS SDK, no DI framework.
|
||||
|
||||
<!-- Personal prefs (24h, concise, explain-why, Linux-assumed) may already be in my
|
||||
global ~/.claude/CLAUDE.md. If so, trim the Working agreement here to avoid drift. -->
|
||||
|
||||
## Working agreement
|
||||
- Senior dev, Linux host. Be concise; explain *why* for non-obvious choices in a line
|
||||
or two (XAI, not essays). 24h clocks everywhere.
|
||||
- Never claim it builds without running the build. Verify; don't assert.
|
||||
- Verify current stable library versions yourself before bumping — don't trust memory.
|
||||
- Smallest change that works. No speculative abstraction.
|
||||
- Ask before anything irreversible (schema migrations, data deletion).
|
||||
- This is a medication app: wrong schedule/dose math is a real harm. Keep schedule
|
||||
logic pure and unit-tested before anything depends on it.
|
||||
|
||||
## Decisions — don't relitigate (flag and wait if you think one's wrong)
|
||||
1. Native, not PWA — PWA notification reliability is unacceptable for meds.
|
||||
2. Exact alarms (`USE_EXACT_ALARM`), always gated on `canScheduleExactAlarms()` with an
|
||||
inexact fallback; `setExactAndAllowWhileIdle` so Doze doesn't eat doses.
|
||||
3. Re-arm every alarm on `BOOT_COMPLETED` + `MY_PACKAGE_REPLACED` (state is wiped then).
|
||||
4. Surface a one-time battery-optimisation exemption prompt — biggest cause of dropped
|
||||
reminders on aggressive OEMs.
|
||||
5. No Google Auto Backup (`allowBackup="false"`, excluded from cloud-backup + transfer).
|
||||
6. Own backup: versioned JSON → encrypted → S3-compatible PUT to self-hosted **Garage**,
|
||||
path-style, hand-rolled SigV4. One serializer for export, import, and auto-backup.
|
||||
7. Crypto target is **age** (passphrase/scrypt) so backups are `age -d`-decryptable and
|
||||
never lock me into this app. JCE AES-GCM is the baseline behind an interface; verify
|
||||
age against the age test vectors before trusting it.
|
||||
8. **FEST, not Felleskatalogen**, and **not** as a live API: its open Rekvirent extract
|
||||
is a SOAP/WCF M30 XML dump. The phone reads a slim pre-flattened JSON synced from my
|
||||
server (that job lives outside this repo) and does autocomplete offline.
|
||||
9. Refill is **derived** from inventory + consumption. Prescription renewal
|
||||
(`rxExpiryEpochDay`, `refillsRemaining`) is tracked **separately** from stock.
|
||||
|
||||
## Load-bearing — change with care
|
||||
- The reminder subsystem is the reliability core. After any change, re-verify: alarms
|
||||
re-arm on boot/update, escalation cancels on Taken, the next occurrence is always
|
||||
armed, Taken decrements inventory.
|
||||
- Escalation contract: due dose → PENDING log + notify, re-nag every 10 min (cap ~6 /
|
||||
~1 h) until Taken or Snooze; Snooze pushes the next nag 15 min and stays PENDING.
|
||||
- The S3 SigV4 signer: if a PUT fails it's almost always clock skew or a non-path-style
|
||||
endpoint, not the maths. Don't "fix" the signer first.
|
||||
- The schedule engine is pure — add tests here before touching the math.
|
||||
|
||||
## Out of scope — don't add without asking
|
||||
Caregiver/"Team" alerts, multi-profile, Health Connect, streaks/gamification,
|
||||
injection-site tracking, symptom/mood diary. (Modelling "trackable" generically is fine
|
||||
if cheap; build no diary UI.)
|
||||
|
||||
## Commands
|
||||
- Build debug: `./gradlew assembleDebug`
|
||||
- Unit tests: `./gradlew test`
|
||||
- Lint: `./gradlew lint`
|
||||
|
||||
<!-- Once a README exists, add: See @README.md for architecture detail. -->
|
||||
Loading…
Add table
Add a link
Reference in a new issue