From 50690edb9ed6d9aa3c87d11183cd99114d564f5d Mon Sep 17 00:00:00 2001 From: claude Date: Thu, 23 Jul 2026 12:00:49 +0200 Subject: [PATCH] =?UTF-8?q?Seeda=20wiki:=20arkitektur,=20designbeslut,=20s?= =?UTF-8?q?ignering,=20CI=20p=C3=A5=20arm64?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01Kf4MAbZ3c3B4Xy5XfuGsCP --- Home.md | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 Home.md diff --git a/Home.md b/Home.md new file mode 100644 index 0000000..84e195c --- /dev/null +++ b/Home.md @@ -0,0 +1,60 @@ +# FitnessDroid + +Android-klient (Android 12+) för gym-API:t — samma backend som gym-delen i +[brasse-pc.eu-v2](https://gitea.brasse-pc.eu/brasse/brasse-pc.eu-v2). +README:n täcker "få det att bygga"; här ligger arkitektur och designbeslut. + +## Arkitektur + +``` +MainActivity (Compose, edge-to-edge) +└── FitnessDroidApp — växlar på AuthState (Restoring/LoggedOut/LoggedIn) + ├── LoginScreen — användarnamn/lösenord + API-url under "Avancerat" + └── HomeScreen — profil + kommande flikar (pass, logg, statistik, PB) + +AppContainer (manuell DI i Application) +├── TokenStore — DataStore; username/sessionId/jwt/refreshToken/expiration/apiUrl +├── GraphQlClient — OkHttp POST {query,variables} + Bearer-header +├── AuthRepository — login/restore/refresh/logout, exponerar StateFlow +└── GymApi — autentiserade queries (myProfile, växer per milstolpe) +``` + +## Designbeslut + +- **Handskrivna GraphQL-strängar** (samma som webbens `gymTrackerApi.js`) + i stället för Apollo-codegen — API-ytan ägs av samma person, och parity + med webben är enklast att verifiera strängvis. Kan omprövas när fler + queries tillkommit. +- **Auth speglar webben:** JWT (2 h) + roterande refresh-token (7 d) + + sessions-id; förnyas automatiskt 2 min före utgång bakom en mutex + (`AuthRepository.bearerToken()`). Vid nätfel vid appstart släpps + användaren in om JWT:n ännu är giltig. +- **Manuell DI** — appen är för liten för Hilt; `AppContainer` i + `FitnessDroidApplication`. +- **Material You** — dynamiska färger kan användas villkorslöst eftersom + minSdk är 31. +- **versionCode = GITHUB_RUN_NUMBER** i CI så att varje release-APK räknas + som uppdatering på telefonen. + +## Signering + +Nyckeln är inte incheckad (publikt repo). Lokalt: `signing/` (gitignorerad). +CI: secrets `KEYSTORE_B64` + `KEYSTORE_PASSWORD` skrivs till samma filer i +jobbet. Utan nyckel faller release-bygget tillbaka på debug-signering — +bygger, men kan inte uppdatera en installation från släppsidan. + +## CI på arm64 (Pi5-runnern) + +Googles aapt2 distribueras bara för linux x86_64. Bygget använder därför en +statiskt byggd arm64-aapt2 från +[lzhiyong/android-sdk-tools](https://github.com/lzhiyong/android-sdk-tools) +via `-Pandroid.aapt2FromMavenOverride=…`. Allt annat i Android-bygget +(kotlinc, d8, apksigner) är JVM-baserat och kör nativt på arm64. +cmdline-tools + `platforms;android-35` installeras i jobbet; gradle-cache +via `actions/cache`. + +## Milstolpar + +Se [doc/plan.md](https://gitea.brasse-pc.eu/brasse/FitnessDroid/src/branch/main/doc/plan.md) +— 1: grund+login (klar), 2: aktivt pass, 3: passhistorik, 4: lyftlogg+PB, +5: statistik, 6: mallar, 7: grunddata+profil.