Impulse AI Docs
Intern dokumentasjon
skipLink.label

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.

MiljoAPI URLBruksomrade
Developmenthttp://127.0.0.1:3001Lokal utvikling i simulator
Staginghttps://api-stg.impulseai.appTesting pa device, TestFlight
Productionhttps://api.impulseai.appApp Store-distribusjon

Hver miljo har egne Supabase-instanser og API-nokler. All konfigurasjon ligger i KMP shared-modulen (Environment.kt).


Automatisk miljovelg

heading.anchorLabel

Appen bestemmer miljo automatisk uten manuell konfigurasjon:

ScenarioMiljoDeteksjon
Simulator (Debug)Development#if DEBUG + targetEnvironment(simulator)
USB-device fra XcodeStaging#if DEBUG + fysisk device
TestFlightStagingRelease-build + sandboxReceipt
App StoreProductionRelease-build + ikke sandbox

Hvordan det fungerer

heading.anchorLabel

Logikken 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
}
#endif

Nøkkelkonsepter:

  • #if DEBUG er en kompilator-flagg — satt til true i Debug-konfigurasjon, false i Release
  • targetEnvironment(simulator) skiller mellom simulator og fysisk device i Debug-builds
  • sandboxReceipt er Apples markør for TestFlight-installerte apper — App Store-versjoner har receipt i stedet

Manuell override

heading.anchorLabel

For spesielle tilfeller kan du overstyre miljoet manuelt. Overrides har høyere prioritet enn de automatiske reglene.

Via Xcode scheme

heading.anchorLabel
  1. Product → Scheme → Edit Scheme (eller ⌘<)
  2. Velg RunArgumentsEnvironment Variables
  3. Legg til eller aktiver APP_ENVIRONMENT med verdi STAGING, PRODUCTION eller DEVELOPMENT

Verdier som stettes

heading.anchorLabel
VerdiMiljo
STAGING eller STGStaging
PRODUCTION eller PRDProduction
DEVELOPMENT eller DEVDevelopment (fjerner override)

Nar 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=DEVELOPMENT eller slette appen

Konfigurasjon per miljo

heading.anchorLabel

API og backend

heading.anchorLabel
DevelopmentStagingProduction
APIhttp://127.0.0.1:3001https://api-stg.impulseai.apphttps://api.impulseai.app
Supabasehttp://127.0.0.1:54331conxpuqktkeiphnnpfiv.supabase.cojksqfeutntcvukrisrno.supabase.co
Webim-landing-seven.vercel.appim-landing-seven.vercel.appimpulseai.app

Appen bruker to typer nokler, begge hardkodet i Environment.kt:

NokkelRolleSikkerhetsniva
X-API-KeyAnti-bot-beskyttelse, per miljoLav — ikke en hemmelighet
Supabase publishable keyKlient-autentiseringLav — designet for klienten

Ingen hemmeligheter lagres i appen. Bruker-autentisering skjer via OAuth → JWT-tokens som lagres i iOS Keychain.


Arkitektur: Environment.kt

heading.anchorLabel

All miljokonfigurasjon er sentralisert i KMP shared-modulen:

shared/src/commonMain/kotlin/com/im/shared/config/Environment.kt
enum 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 requests

Fordi 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.anchorLabel

Debug-builds (fra Xcode)

heading.anchorLabel
Terminal window
# Simulator → DEVELOPMENT automatisk
# Device → STAGING automatisk
# Bare trykk Run (⌘R) i Xcode

TestFlight (via Fastlane)

heading.anchorLabel
Terminal window
cd apps/mobile-kmp/iosApp
bundle exec fastlane ios beta
  • Bygger Release-konfigurasjon
  • Laster opp til App Store Connect
  • Appen detekterer sandboxReceipt → bruker Staging

App Store (produksjon)

heading.anchorLabel
Terminal window
bundle exec fastlane ios promote
  • Promoterer siste TestFlight-build til App Store Review
  • Appen detekterer fravær av sandboxReceipt → bruker Production

Appen bruker feil miljo

heading.anchorLabel
  1. Sjekk om det ligger en manuell override i UserDefaults:

    • Slett appen fra device/simulator og installer pa nytt
    • Eller sett APP_ENVIRONMENT=DEVELOPMENT i Xcode scheme
  2. Verifiser hvilket miljo appen bruker:

    • Sjekk Xcode-konsollen ved oppstart — Sentry og analytics logger miljoinformasjon

TestFlight-build bruker localhost

heading.anchorLabel

Dette skal ikke skje med den automatiske konfigurasjonen. Hvis det skjer:

  1. Verifiser at builden er Release-konfigurasjon (Fastlane setter dette automatisk)
  2. Sjekk at det ikke er en UserDefaults-override som sitter igjen

Device fra Xcode bruker localhost i stedet for staging

heading.anchorLabel

Sjekk 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.anchorLabel

Appen 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.anchorLabel
App 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 oppstart

Miljovariabel-kontroll (Doppler)

heading.anchorLabel
VariabelBeskrivelseDefault
MIN_APP_VERSION_IOSMinimum iOS-versjon (hard block)0.0.0 (ingen)
MIN_APP_VERSION_ANDROIDMinimum Android-versjon (hard block)0.0.0 (ingen)
LATEST_APP_VERSION_IOSNyeste iOS-versjon (soft nudge)0.0.0 (ingen)
LATEST_APP_VERSION_ANDROIDNyeste 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-Version og X-App-Platform headere pa alle API-kall

API-nokkelrotasjon

heading.anchorLabel

API-klientnokkelen (X-API-Key) stotter komma-separerte verdier for trygg rotasjon uten nedetid.

Multi-key mekanisme

heading.anchorLabel
Terminal window
# En nokkel (normalt)
API_CLIENT_KEY=abc123
# To nokler (under rotasjon)
API_CLIENT_KEY=abc123,def456

Serveren aksepterer enhver nokkel i listen. Klienten sender alltid bare en.

Rotasjonsworkflow

heading.anchorLabel
1. Generer ny nokkel: openssl rand -hex 32
2. 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-oppdatering
6. 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 = 0

Dekommisjoneringsovervaking

heading.anchorLabel

Middleware-en logger keyPrefix (forste 8 tegn) ved akseptert nokkel:

{"keyPrefix":"315dc797"} API key accepted

Filtrer pa keyPrefix i Railway logs for a se nar gammel nokkel ikke lenger brukes.


FilInnhold
shared/.../config/Environment.ktMiljo-enum, URL-er, API-nokler, AppConfig
iosApp/ImpulseApp.swiftAutomatisk miljodeteksjon ved oppstart
iosApp/iosApp.xcodeproj/xcshareddata/xcschemes/iosApp.xcschemeManuell APP_ENVIRONMENT override
shared/.../api/ApiClient.ktHTTP-klient som bruker AppConfig.apiUrl
shared/.../util/BuildConfig.ios.ktiOS-spesifikk debug-deteksjon og localhost-adresse