Miljoer og bygg-konfigurasjon
Impulse AI kjorer mot tre miljoer: Development (localhost), Staging (Railway staging) og Production (Railway production). Hvilket miljo appen bruker bestemmes automatisk ved bygg-tid basert pa hvordan appen er bygget og distribuert.
Miljoer
heading.anchorLabel| Miljo | API URL | Bruksomrade |
|---|---|---|
| Development | http://127.0.0.1:3001 | Lokal utvikling i simulator |
| Staging | https://api-stg.impulseai.app | Testing pa device, TestFlight |
| Production | https://api.impulseai.app | App Store-distribusjon |
Hver miljo har egne Supabase-instanser og API-nokler. All konfigurasjon ligger i KMP shared-modulen (Environment.kt).
Automatisk miljovelg
heading.anchorLabelAppen bestemmer miljo automatisk uten manuell konfigurasjon:
| Scenario | Miljo | Deteksjon |
|---|---|---|
| Simulator (Debug) | Development | #if DEBUG + targetEnvironment(simulator) |
| USB-device fra Xcode | Staging | #if DEBUG + fysisk device |
| TestFlight | Staging | Release-build + sandboxReceipt |
| App Store | Production | Release-build + ikke sandbox |
Hvordan det fungerer
heading.anchorLabelLogikken kjorer i ImpulseApp.swift ved oppstart:
#if DEBUG #if targetEnvironment(simulator) // Simulator → localhost (DEVELOPMENT) #else // Fysisk device via USB → STAGING #endif#else // Release-build let isTestFlight = Bundle.main.appStoreReceiptURL? .lastPathComponent == "sandboxReceipt" if isTestFlight { // TestFlight → STAGING } else { // App Store → PRODUCTION }#endifNøkkelkonsepter:
#if DEBUGer en kompilator-flagg — satt tiltruei Debug-konfigurasjon,falsei ReleasetargetEnvironment(simulator)skiller mellom simulator og fysisk device i Debug-buildssandboxReceipter Apples markør for TestFlight-installerte apper — App Store-versjoner harreceipti stedet
Manuell override
heading.anchorLabelFor spesielle tilfeller kan du overstyre miljoet manuelt. Overrides har høyere prioritet enn de automatiske reglene.
Via Xcode scheme
heading.anchorLabel- Product → Scheme → Edit Scheme (eller
⌘<) - Velg Run → Arguments → Environment Variables
- Legg til eller aktiver
APP_ENVIRONMENTmed verdiSTAGING,PRODUCTIONellerDEVELOPMENT
Verdier som stettes
heading.anchorLabel| Verdi | Miljo |
|---|---|
STAGING eller STG | Staging |
PRODUCTION eller PRD | Production |
DEVELOPMENT eller DEV | Development (fjerner override) |
Persistering
heading.anchorLabelNar du setter APP_ENVIRONMENT via Xcode, lagres verdien i UserDefaults. Det betyr:
- Appen beholder miljovalget etter at du kobler fra Xcode
- Virker ogsa etter restart av appen
- Nullstill ved a sette
APP_ENVIRONMENT=DEVELOPMENTeller slette appen
Konfigurasjon per miljo
heading.anchorLabelAPI og backend
heading.anchorLabel| Development | Staging | Production | |
|---|---|---|---|
| API | http://127.0.0.1:3001 | https://api-stg.impulseai.app | https://api.impulseai.app |
| Supabase | http://127.0.0.1:54331 | conxpuqktkeiphnnpfiv.supabase.co | jksqfeutntcvukrisrno.supabase.co |
| Web | im-landing-seven.vercel.app | im-landing-seven.vercel.app | impulseai.app |
API-nokler
heading.anchorLabelAppen bruker to typer nokler, begge hardkodet i Environment.kt:
| Nokkel | Rolle | Sikkerhetsniva |
|---|---|---|
| X-API-Key | Anti-bot-beskyttelse, per miljo | Lav — ikke en hemmelighet |
| Supabase publishable key | Klient-autentisering | Lav — designet for klienten |
Ingen hemmeligheter lagres i appen. Bruker-autentisering skjer via OAuth → JWT-tokens som lagres i iOS Keychain.
Arkitektur: Environment.kt
heading.anchorLabelAll miljokonfigurasjon er sentralisert i KMP shared-modulen:
shared/src/commonMain/kotlin/com/im/shared/config/Environment.ktenum class Environment { DEVELOPMENT, // localhost STAGING, // Railway staging PRODUCTION // Railway production}
object AppConfig { var environment: Environment = Environment.DEVELOPMENT
val apiUrl: String get() = environment.apiBaseUrl + "/api/v1" val isDevelopment: Boolean get() = environment == Environment.DEVELOPMENT val isProduction: Boolean get() = environment == Environment.PRODUCTION}Flyten:
ImpulseApp.swift init() → Bestem miljo (automatisk eller override) → AppConfig.shared.setEnvironment(env:) → ApiClient bruker AppConfig.apiUrl for alle requestsFordi Environment.kt er i KMP shared-modulen, deler iOS og Android samme URL-er og konfigurasjon. Bare deteksjonslogikken (ImpulseApp.swift vs Android Application) er plattformspesifikk.
Bygg og distribusjon
heading.anchorLabelDebug-builds (fra Xcode)
heading.anchorLabel# Simulator → DEVELOPMENT automatisk# Device → STAGING automatisk# Bare trykk Run (⌘R) i XcodeTestFlight (via Fastlane)
heading.anchorLabelcd apps/mobile-kmp/iosAppbundle exec fastlane ios beta- Bygger Release-konfigurasjon
- Laster opp til App Store Connect
- Appen detekterer
sandboxReceipt→ bruker Staging
App Store (produksjon)
heading.anchorLabelbundle exec fastlane ios promote- Promoterer siste TestFlight-build til App Store Review
- Appen detekterer fravær av
sandboxReceipt→ bruker Production
Feilsoking
heading.anchorLabelAppen bruker feil miljo
heading.anchorLabel-
Sjekk om det ligger en manuell override i UserDefaults:
- Slett appen fra device/simulator og installer pa nytt
- Eller sett
APP_ENVIRONMENT=DEVELOPMENTi Xcode scheme
-
Verifiser hvilket miljo appen bruker:
- Sjekk Xcode-konsollen ved oppstart — Sentry og analytics logger miljoinformasjon
TestFlight-build bruker localhost
heading.anchorLabelDette skal ikke skje med den automatiske konfigurasjonen. Hvis det skjer:
- Verifiser at builden er Release-konfigurasjon (Fastlane setter dette automatisk)
- Sjekk at det ikke er en UserDefaults-override som sitter igjen
Device fra Xcode bruker localhost i stedet for staging
heading.anchorLabelSjekk at du kjorer pa fysisk device, ikke simulator. I Xcode: se at target-velgeren viser device-navnet ditt, ikke en simulator.
Versjonssjekk og tvungen oppdatering
heading.anchorLabelAppen sjekker ved hver oppstart om versjonen er stottet via GET /api/v1/config. Endepunktet krever kun X-API-Key (ingen JWT), slik at sjekken fungerer for oppstart.
Hvordan det fungerer
heading.anchorLabelApp starter → GET /api/v1/config → Server returnerer min_version ↓ App sammenligner sin versjon ↓ ├─ Under min_version → BLOKKERT (fullskjerm, kun "Oppdater") ├─ Under latest_version → Soft nudge (dismissbar) └─ OK → Normal oppstartMiljovariabel-kontroll (Doppler)
heading.anchorLabel| Variabel | Beskrivelse | Default |
|---|---|---|
MIN_APP_VERSION_IOS | Minimum iOS-versjon (hard block) | 0.0.0 (ingen) |
MIN_APP_VERSION_ANDROID | Minimum Android-versjon (hard block) | 0.0.0 (ingen) |
LATEST_APP_VERSION_IOS | Nyeste iOS-versjon (soft nudge) | 0.0.0 (ingen) |
LATEST_APP_VERSION_ANDROID | Nyeste Android-versjon (soft nudge) | 0.0.0 (ingen) |
Viktige regler
heading.anchorLabel- Nettverksfeil = normal oppstart — aldri blokker brukeren pga. feilet config-kall
- Sjekken skjer under splash — brukeren ser aldri innhold for force-update vises
- Versjon sendes i
X-App-VersionogX-App-Platformheadere pa alle API-kall
API-nokkelrotasjon
heading.anchorLabelAPI-klientnokkelen (X-API-Key) stotter komma-separerte verdier for trygg rotasjon uten nedetid.
Multi-key mekanisme
heading.anchorLabel# En nokkel (normalt)API_CLIENT_KEY=abc123
# To nokler (under rotasjon)API_CLIENT_KEY=abc123,def456Serveren aksepterer enhver nokkel i listen. Klienten sender alltid bare en.
Rotasjonsworkflow
heading.anchorLabel1. Generer ny nokkel: openssl rand -hex 322. Doppler: API_CLIENT_KEY = "gammel_key,ny_key"3. Deploy API (begge nokler fungerer na)4. Oppdater Environment.kt (ny nokkel i STAGING/PRODUCTION)5. Ship app-oppdatering6. Sett MIN_APP_VERSION (tvinger brukere til a oppdatere)7. Monitorer logger (se keyPrefix for a spore gammel vs ny)8. Fjern gammel nokkel nar trafikk pa gammel prefix = 0Dekommisjoneringsovervaking
heading.anchorLabelMiddleware-en logger keyPrefix (forste 8 tegn) ved akseptert nokkel:
{"keyPrefix":"315dc797"} API key acceptedFiltrer pa keyPrefix i Railway logs for a se nar gammel nokkel ikke lenger brukes.
Nøkkelfiler
heading.anchorLabel| Fil | Innhold |
|---|---|
shared/.../config/Environment.kt | Miljo-enum, URL-er, API-nokler, AppConfig |
iosApp/ImpulseApp.swift | Automatisk miljodeteksjon ved oppstart |
iosApp/iosApp.xcodeproj/xcshareddata/xcschemes/iosApp.xcscheme | Manuell APP_ENVIRONMENT override |
shared/.../api/ApiClient.kt | HTTP-klient som bruker AppConfig.apiUrl |
shared/.../util/BuildConfig.ios.kt | iOS-spesifikk debug-deteksjon og localhost-adresse |