# KA Android — la super-app Groupe-KA Portage Android natif complet de l'app iOS « KA » : tout l'écosystème Groupe-KA (12 univers ·Ka) dans une seule app **Kotlin + Jetpack Compose**, compilée en ligne de commande (aucun Android Studio requis). **v2.0.0** = refonte majeure alignée sur le build 6 iOS (AUDIT-REFONTE.md §5) : carte Mapbox 2D/3D, galeries, recherches sauvegardées + alertes honnêtes, historique, collections éditoriales, playground API·Ka. ## Build ```bash export JAVA_HOME=$(brew --prefix openjdk@21) # local.properties doit pointer vers le SDK : # sdk.dir=/opt/homebrew/share/android-commandlinetools ./gradlew test # 22 tests JVM (adaptateurs + clustering + stores) ./gradlew assembleDebug # → app/build/outputs/apk/debug/app-debug.apk ./gradlew assembleRelease # → app/build/outputs/apk/release/app-release.apk (SIGNÉ) ``` Trio de versions éprouvé : **Gradle 8.13 + AGP 8.9.2 + Kotlin 2.1.20** (plugin Compose intégré), Compose BOM 2024.09.03, **MapLibre GL 10.3.1**, minSdk 26, target/compileSdk 34. Portrait-first (téléphones). ### Signature release (APK téléchargeable publiquement) Le keystore est à la racine : `ka-release.keystore` - alias : `ka` - **storepass / keypass : `ka-groupe-2026`** - certificat : CN=Groupe KA, RSA 2048, validité 10 000 jours. `assembleRelease` signe automatiquement (signingConfig `release` dans `app/build.gradle.kts`). ⚠️ Conserver ce keystore : toute mise à jour de l'app doit être signée avec la même clé. ## La carte (pièce maîtresse, onglet « Carte ») `ui/MapScreen.kt` — **MapLibre GL Android** (libre) rendant le style officiel **Mapbox streets-v12** (`Mapbox.getInstance(ctx, token, WellKnownTileServer.Mapbox)` + `mapbox://styles/mapbox/streets-v12` ; token public déjà exposé sur lou-ka.com) : - **Bascule 2D/3D** : pitch 0° ↔ 60° animé + couche `fill-extrusion` des bâtiments (source composite, `source-layer building`, hauteur interpolée au zoom) — même recette que Ka Maps web. - **Marqueurs-pilules avec PRIX** teintés par univers (bitmaps dessinés au Canvas, cache), badge circulaire pour les groupes. - **Clustering par grille** : `core/ClusterEngine.kt` (pur, testé, miroir exact d'iOS) — ~9×9 cellules sur la région, plafond 150 rendus, dégroupage par zoom au tap. - **« Rechercher dans cette zone »** : bbox RÉEL côté API (`/api/listings.geojson?bbox=w,s,e,n` lou-ka/immo-ka, `/api/jobs.geojson` job-ka — vérifiés) ; resto-ka/sorti-ka : liste + filtre client sur la région. - **Fiche compacte** au tap → fiche complète (l'état de la carte — caméra, items, chips — est conservé via `MapStateHolder`), **bascule liste/carte** synchronisée, chips par univers aux couleurs officielles. ## Refonte v2 (parité iOS build 6) - **Fiches** : galerie multi-photos (`images[]` → `KAItem.imageURLs`, pager + compteur + **plein écran zoomable** pincement/double-tap), **itinéraire** (intent `geo:`), **semblables** (même univers/ville), provenance datée (`Source : `), enregistrement dans l'historique. - **Recherche** : tri (pertinence / prix ↑ / prix ↓), **sauvegarde + alerte** (🔔), partage de la recherche. - **Alertes honnêtes** : `core/RecentsStore.kt` recompte le champ `total` réel de l'API à l'ouverture (`UniverseService.total`) et affiche le delta « +N » — jamais de faux chiffre. « Marquer comme vues » replie le delta. - **Historique consulté** : 30 derniers, dédupliqués, persistés. - **Accueil** : bande « Reprendre » (recherches sauvegardées avec badge +N, derniers consultés), **collections éditoriales** ×4 (les mêmes requêtes réelles qu'iOS : sorties gratuites, soldes d'épicerie, autos < 15 000 $ ≥ 2015, 4½ récents). - **Profil** : hub « Mes contenus » (Favoris / Historique / Recherches & alertes avec badge). - **Navigation** : Accueil · Recherche · Explorer · **Carte** · Profil (Favoris accessibles depuis le Profil, comme sur iOS). ## Fix Trouve-Ka `/api/search` **exige `q`** (422 sinon). `UniverseService.fetch` garde le cas (retour vide sans appel réseau) et l'explorateur Trouve-Ka est « recherche d'abord » : aucun fetch initial, état vide dédié « Cherchez le web québécois ». Items sous la clé `results`. ## Playground API·Ka `ui/ApiKaPlaygroundScreen.kt` — l'univers API·Ka est un playground natif : charge `https://www.api-ka.com/openapi.json` **en direct**, liste les endpoints **GET** (chemin, résumé, paramètres), génère le formulaire (paramètres query et path, requis marqués \*), **Envoyer** → statut HTTP + latence ms + **réponse JSON colorisée** (clés lime, chaînes vertes, nombres orange) **pliable**, et **« Copier en curl »**. ## Architecture — miroir de l'app iOS (`~/Desktop/KA`) | iOS (SwiftUI) | Android (Compose) | |-----------------------------|-----------------------------------------------------| | `Core/Ecosystem.swift` | `core/Ecosystem.kt` — 12 univers config-driven, galeries `imageURLs` | | `Core/Services.swift` | `core/Services.kt` — cache disque hors ligne, fetch, `total()`, `mapItems()` bbox geojson, liveTotal, AgentService SSE | | `Core/KAFilters.swift` | `core/Filters.kt` | | `Core/FavoritesStore.swift` | `core/FavoritesStore.kt` | | `Core/RecentsStore.swift` | `core/RecentsStore.kt` + `Editorial` | | `Features/MapView.swift` | `ui/MapScreen.kt` + `core/ClusterEngine.kt` | | `Core/KAID.swift` | `auth/KaId.kt` — SSO Custom Tabs, client `ka-android` | | `Design/Theme.swift` | `ui/theme/Theme.kt` — éditorial sharp, clair par défaut | | `Features/*` | `ui/*Screen.kt` | Icône : « liquid glass » (KA verre lime sur fond blanc, perles des univers) — mipmaps générés depuis `docs/icon-glass-1024.png` d'iOS. ## Ajouter un univers Une entrée dans `Ecosystem.all` (`core/Ecosystem.kt`) : identité, config d'API, lambda de mapping. La grille, la recherche, l'accueil, les compteurs, la fiche — et la carte si l'API expose lat/lng — suivent automatiquement. ## Écarts vs iOS (v2) - Localisation « ma position » non incluse (aucune permission de localisation demandée) — la carte démarre sur Québec. - Widgets iOS sans équivalent. - SF Symbols → Material Icons ; haptique simplifiée. - MapLibre 10.3.1 (packages `com.mapbox.mapboxsdk.*`) : dernière lignée qui résout nativement les URL `mapbox://` du style officiel via `WellKnownTileServer.Mapbox` — MapLibre 11 les a retirées. ## Tests (22, tous verts) - `AdapterTests` (12) : mappings d'univers (mêmes échantillons que `KATests.swift`), URLs de liste, favoris/collections + persistance. - `RefonteTests` (10) : clustering (regroupement/centroïde, plafond 150, items sans coordonnées), historique (déduplication, plafond 30, persistance), alertes (markSeen replie le delta, somme des alertes actives seulement), galerie ≤ 10 images http, garde Trouve-Ka sans réseau, collections éditoriales pointant vers de vrais univers.