Commit Graph

21 Commits

Author SHA1 Message Date
466e4c7f7a test(02-07): add Compose Resources, theme seed, and failing LoginViewModel tests
- Add Phase 2 auth strings.xml with Polish scaffold copy from UI-SPEC
- Add RecipeTheme with #3B6939 / #A2D597 seed and isSystemInDarkTheme
- Add LoginViewModelTest covering cancelled/network/unknown error mapping
  and the clear-error-on-retry behavior; tests fail compile until Task 2
2026-04-28 17:35:11 +02:00
938f324bb8 feat(02-06): wire auth session into koin
- provide authModule singletons for store, OIDC, MeClient, AuthSession, and HttpClient
- include authModule from appModule bootstrap
2026-04-28 16:55:36 +02:00
0a24be9a95 feat(02-06): implement auth session runtime
- add AuthState and AuthSession restore/login/logout state machine
- add MeClient and token-redacting Ktor bearer HTTP client
2026-04-28 16:54:39 +02:00
06e5eaf94e test(02-06): add failing auth session state tests
- cover restore, login, refresh failure, logout, and cancellation
- assert Phase 2 authenticated householdId remains null
2026-04-28 16:53:46 +02:00
ac9fc61410 feat(02-05): implement iOS AppAuth client
- Add AppAuth login, refresh, logout actual
- Add iOS Keychain auth state store to unblock native compile
- Add iOS Podfile AppAuth integration
2026-04-28 16:14:04 +02:00
11a5eeb3ff fix(02-04): harden Android OIDC token result mapping
- Treat missing access tokens as auth failures
- Preserve AppAuth discovery errors for correct network/auth classification
2026-04-28 16:00:20 +02:00
6385453653 feat(02-04): register Android OIDC callback
- Add AppAuth redirect receiver for recipe://callback
- Preserve existing launcher activity manifest wiring
2026-04-28 15:58:12 +02:00
fa78ee31b4 feat(02-04): implement Android AppAuth OIDC client
- Add Android AppAuth login, fresh-token refresh, and end-session logout
- Add Android secure AuthState store actual required for Android compilation
2026-04-28 15:57:16 +02:00
0dbd374f46 feat(02-03): add Wasm auth stubs
- Keep Wasm OIDC behind explicit v2 NotImplementedError boundaries
- Add non-persistent Wasm AuthState store actual so the target compiles
2026-04-28 13:49:14 +02:00
edc2a1d4c8 feat(02-03): define common auth contracts
- Add OIDC result and expect client seam with pinned native AppAuth semantics
- Add secure AuthState JSON store contract and JVM dev actuals for test compilation
2026-04-28 13:48:25 +02:00
7ef222e71e test(02-03): add failing secure auth state store contract
- Covers write overwrite semantics
- Covers clear removing stored AuthState JSON
2026-04-28 13:36:48 +02:00
c1cc713bbb feat(02-01): wire Phase 2 dependency aliases without bumping Ktor
Task 02-01-02. Adds Phase 2 deps to the version catalog and routes
them into composeApp + server build files. Ktor stays pinned at
3.4.1 per the resolved Open Question — patch bump deferred unless a
concrete incompatibility appears.

Catalog (gradle/libs.versions.toml):
- Versions: appauth, appauth-ios, androidx-security-crypto, exposed,
  hikari, multiplatformSettings, testcontainers, plus the
  kotlinCocoapods plugin alias.
- Libraries: ktor server auth/auth-jwt/call-logging/status-pages,
  ktor client core/auth/content-negotiation/logging/okhttp/darwin/cio,
  ktor-serializationKotlinxJsonMpp (the multiplatform variant; the
  -jvm one stays for server), AppAuth, AndroidX Security Crypto,
  multiplatform-settings + coroutines, Exposed core/jdbc/java-time,
  HikariCP, Testcontainers postgresql + junit-jupiter.

composeApp/build.gradle.kts:
- Apply kotlinSerialization (alias) and kotlin.native.cocoapods (by
  id — the plugin is shipped inside the Kotlin Gradle plugin already
  on the classpath via recipe.kotlin.multiplatform; alias-applying
  it would request a fresh version and fail).
- Cocoapods block: ComposeApp baseName + isStatic, ../iosApp/Podfile,
  iOS deployment target 15.0, AppAuth pod pulled from
  libs.versions.appauth.ios.get() — no literal pin in the build
  file (verify-no-version-literals.sh stays green).
- Common deps: Ktor client family, MPP serialization, multiplatform
  settings; Android: AppAuth-Android + Security Crypto + OkHttp
  engine; iOS: Darwin engine; JVM: CIO engine.

server/build.gradle.kts: Adds Ktor server auth/JWT/CallLogging/
StatusPages, Exposed DSL trio, Hikari, kotlinx.serialization-json,
plus testImplementation testcontainers postgresql + junit-jupiter.

Deviations:
- Rule 3 (blocking): manifestPlaceholders["appAuthRedirectScheme"]
  = "recipe" added to Android defaultConfig because AppAuth-Android's
  bundled manifest declares a ${appAuthRedirectScheme} placeholder
  that breaks AGP merge before Plan 02-04 lands the full <intent-filter>.
- Rule 3 (blocking): top-level group/version on composeApp (required
  by the cocoapods podspec generator) pushes the Compose Resources
  Res-class package off recipe.composeapp.generated.resources, breaking
  Phase 1 App.kt imports. Lock the package via compose.resources {
  packageOfResClass = "recipe.composeapp.generated.resources" }.
- Rule 3 (housekeeping): *.podspec is generated by the cocoapods
  plugin on every build; ignored.

Verification:
- ./gradlew :composeApp:dependencies --configuration debugCompileClasspath
  :server:dependencies --configuration runtimeClasspath: PASS
  (the plan-stated androidMainCompileClasspath name doesn't exist
  under this AGP/Gradle combo; debugCompileClasspath is the
  functional equivalent and resolves all new deps).
- ./gradlew :composeApp:compileDebugKotlinAndroid :server:compileKotlin: PASS
- ./gradlew :composeApp:compileKotlinIosSimulatorArm64: PASS (cinterop
  pulls AppAuth pod cleanly).
- ./tools/verify-no-version-literals.sh: PASS
- ./tools/verify-shared-pure.sh: PASS
- All Task 2 grep acceptance criteria satisfied.
2026-04-28 10:52:40 +02:00
04b3d9b1d5 Remove unnecessary convention plugins 2026-04-26 22:22:28 +02:00
68655eae1a Phase 1 work 2026-04-24 20:21:03 +02:00
c79f9218aa merge(01-03): module refactor to recipe.* conventions + drop js 2026-04-24 18:41:51 +02:00
37f6191523 feat(01-04): wire JVM + Wasm main + Swift iOSApp to bootstrap Koin + Kermit
- Desktop main() calls configureLogging() → initKoin() before application { Window { App() } }
- Wasm main() calls configureLogging() → initKoin() before ComposeViewport { App() } (PITFALL #8 future-proof)
- iOSApp.swift imports ComposeApp and calls KoinIosKt.doInitKoin() in init() — single iOS call site (PITFALL #4)
- MainViewController.kt and App.kt unmodified (anti-pattern guards)
2026-04-24 18:22:47 +02:00
4e6192293f feat(01-04): add Android MainApplication + manifest registration
- Create MainApplication : Application() running configureLogging() then initKoin { androidContext(this@MainApplication) } in onCreate
- Register android:name=".MainApplication" on <application> element (MainActivity entry preserved)
- Establishes the canonical init order for Android process boot
2026-04-24 18:22:03 +02:00
7d750af710 feat(01-04): add Koin + Kermit bootstrap commonMain + iOS bridge
- Add initKoin(config) helper wrapping startKoin { modules(appModule) } (PITFALL #4 single entry)
- Add empty appModule placeholder (D-14) — Phase 2+ extends
- Add configureLogging() setting Kermit tag "recipe" (D-15)
- Add iosMain doInitKoin() bridge — Swift-accessible as KoinIosKt.doInitKoin()
- configureLogging() always runs before initKoin() so module loading can log
2026-04-24 18:21:36 +02:00
d76dcea18d refactor(01-03): apply recipe.* conventions to composeApp + shared, drop js
- composeApp/build.gradle.kts now applies 4 recipe.* IDs (kotlin.multiplatform, compose.multiplatform, android.application, quality); removes all structural target/android/nativeDistributions blocks (114 -> 28 lines)
- shared/build.gradle.kts applies recipe.kotlin.multiplatform + recipe.quality + androidLibrary; adds explicitApi() (D-12) and KotlinNativeTarget/Framework baseName = "Shared" override (D-07 / PITFALL #10); keeps android { } block per Open Question #1
- Adds libs.koin.android to androidMain dependencies (for Plan 04's MainApplication androidContext)
- Drops js target per D-01: removes js { browser() } from both modules and deletes shared/src/jsMain/Platform.js.kt
- iosX64 remains absent per D-02
- No version literals leak; tools/verify-no-version-literals.sh + verify-shared-pure.sh both pass
2026-04-24 18:21:35 +02:00
c50d747cf6 Fix hot reload for desktop target 2026-04-24 14:11:23 +02:00
bf8b46bff2 Initial commit 2026-04-23 22:50:48 +02:00