diff --git a/ANDROID_PLAN.md b/ANDROID_PLAN.md index 8937aea..d7433b0 100644 --- a/ANDROID_PLAN.md +++ b/ANDROID_PLAN.md @@ -62,19 +62,20 @@ client-only (no server change). Kept current as parts land so a fresh session resumes without re-deriving. Verify against code. -> ### ▶ RESUME HERE — 2026-07-13 (documents track + release-prep) +> ### ▶ RESUME HERE — 2026-07-14 (keystore secrets set; payments landed; gate = RuStore account + merge/tag) > -> **Where we are.** The legal-documents track, the release-prep hygiene, **and the icon rebrand** are -> DONE. The RuStore release is now gated on **owner-side** items only (keystore, RuStore account) plus -> the merge/tag chain. Do not re-do or re-litigate the finished work; do not re-ask the locked decisions. +> **Where we are.** The legal-documents track, the release-prep hygiene, the icon rebrand **and the +> release keystore** are DONE (the keystore + its Gitea secrets set by the owner — see below). The +> RuStore MVP is now gated on **one owner-side item** — the **RuStore developer account** (owner going +> ИП; RuStore updated its requirements) — plus the agent's **promote/tag → signed-build** chain. Also +> landed on `development` since: the payments **E10 multi-shop split** (#266) + **E11 kill switch** +> (#267), both dormant / fail-open (no bearing on the Android build), and the signing-secret rename +> `ANDROID_*` → **`ANDROID_RUSTORE_*`** (#268). Do not re-do the finished work or re-ask the locked +> decisions. > -> **Branches / PRs (current working branch: `feature/android-release-prep`).** -> - `development` — has the **legal-documents track**, merged via **PR #253** (green, deployed to the -> test contour). `/privacy/`, `/eula/`, `/offer/` are live there, bilingual RU/EN. -> - `feature/android-release-prep` — the **release-prep hygiene**, **PR #254 OPEN, green, NOT merged** -> (the owner chose to hold the merge). It is branched off `development`, so it also contains the -> legal-documents track. Merge #254 into `development` when ready — needs **owner approval** (the -> agent cannot self-approve). +> **Branches / PRs.** All merged to `development` (contour-green): legal documents (#253); release-prep +> hygiene + the re-enabled `android-build` workflow (#254); the payments E10/E11 (#266/#267); the +> signing-secret rename (#268). No open Android branch. > > **Done this session.** > - **Legal documents** (satisfies the RuStore *hosted privacy-policy URL* prerequisite): authored @@ -113,12 +114,12 @@ Kept current as parts land so a fresh session resumes without re-deriving. Verif > 2. **Merge PR #254** → `development` (owner approval), then **promote `development` → `master`** and > **tag `vX.Y.Z`** for the release (the version stamps the APK `versionName`/`versionCode` and the > `X-Client-Version` header). -> 3. **Release keystore.** OWNER generates it (`keytool -genkeypair -v -keystore erudit-release.jks -> -alias erudit -keyalg RSA -keysize 4096 -validity 10000`), base64-encodes it, sets the four Gitea -> **secrets** `ANDROID_KEYSTORE_BASE64` / `ANDROID_KEYSTORE_PASSWORD` / `ANDROID_KEY_ALIAS` / -> `ANDROID_KEY_PASSWORD`, and backs the `.jks` up **off-host** (loss ⇒ the app can never be updated). -> The AGENT provides the exact commands on request. Without the secrets the workflow builds an -> UNSIGNED APK (a dry run still proves the pipeline). +> 3. **Release keystore — DONE (owner, 2026-07-14).** `erudit-release.jks` (RSA 4096, alias `erudit`, +> PKCS12) generated + backed up off-host; the four Gitea secrets are set under the RuStore-specific +> names `ANDROID_RUSTORE_KEYSTORE_BASE64` / `ANDROID_RUSTORE_KEYSTORE_PASSWORD` / +> `ANDROID_RUSTORE_KEY_ALIAS` / `ANDROID_RUSTORE_KEY_PASSWORD` (loss ⇒ the app can never be updated — +> the cert is pinned at the first RuStore upload). Google Play, later, would use its own +> `ANDROID_PLAY_*` upload key (Play App Signing) — a separate key. > 4. **RuStore developer account.** OWNER (verified legal entity or self-employed / самозанятый). Gates > publication, not the build. > 5. **Dispatch the signed build.** AGENT: on `master`, dispatch `android-build` (`confirm=build`) via @@ -132,6 +133,16 @@ Kept current as parts land so a fresh session resumes without re-deriving. Verif > 8. **Upload to RuStore.** OWNER. After publication, set the `ANDROID_RUSTORE_URL` Gitea variable to > the store deep-link so the update button works on future gated releases (empty until then — the > gate is dormant in the MVP). +> +> **Next tracks (design in a future session — interview the owner first).** +> - **Native notifications (push).** Promote FCM/push from "Out of scope" to a real track: a Capacitor +> push plugin, the Android send path (FCM — but **check RuStore's own push service vs FCM on RuStore +> devices**, since Google Play Services may be absent), token registration, and reusing the existing +> server notification dispatcher. Owner will bring specifics. +> - **A test APK for the emulator** (owner asked): the signed APK comes from `android-build` (needs the +> promote/tag chain, step 2). A quick **debug** APK is buildable without the release chain if the host +> has the Android SDK + JDK 21 (`pnpm build` → `cap sync` → `assembleDebug`). +> - Possibly other native polish (owner to flag). - **A. Capacitor scaffolding — ✅ DONE & verified (2026-07-12).** Capacitor 8 native project generated under `ui/android/` (tracked), `@capacitor/*` deps + `capacitor.config.ts`, hardware Back in