# 21. Real API Client Wiring (Replace StubAPIClient) meta: id: ios-production-21 feature: ios-production priority: P1 depends_on: [] tags: [backend, api, production] objective: - Replace the StubAPIClient with a real API client that connects to the production backend deliverables: - Real API client implementing AuthAPIClientProtocol - Backend OAuth endpoints for iOS - AuthService wired to real client in production - Environment-based client selection steps: 1. Create real API client: - Create iOS/Kordant/Services/RealAPIClient.swift - Implement AuthAPIClientProtocol methods: - login(email:password:) → POST /api/trpc/user.login - signup(name:email:password:) → POST /api/trpc/user.signup - resetPassword(email:) → POST /api/trpc/user.forgotPassword - Use existing APIClient for network layer - Handle tRPC response format (batch input, result wrapper) 2. Add OAuth support: - Apple Sign-In token exchange endpoint - Google Sign-In token exchange endpoint - Social account linking 3. Configure environment-based client: - Debug builds: use RealAPIClient pointing to staging - Release builds: use RealAPIClient pointing to production - Unit tests: continue using StubAPIClient or MockAPIClient 4. Update AuthService initialization: - Modify KordantApp.swift to inject RealAPIClient - Keep dependency injection pattern - Add build configuration for base URL 5. Add error handling: - Map API errors to user-friendly messages - Handle network errors gracefully - Retry on transient failures 6. Test integration: - Test login against staging backend - Test signup flow - Test token persistence - Test session restoration tests: - Unit: Test RealAPIClient with mock URLSession - Integration: Test against staging backend - E2E: Complete auth flow on physical device acceptance_criteria: - RealAPIClient implements all AuthAPIClientProtocol methods - Login works against production backend - Signup creates user in production database - Password reset sends email - Apple Sign-In and Google Sign-In tokens exchanged correctly - Auth token persisted in keychain - Session restored on app relaunch - Debug builds use staging, release builds use production - Unit tests still use mock clients - All auth errors mapped to user-friendly messages validation: - Build debug → login to staging → success - Build release → login to production → success - Run unit tests → all pass with mocks - Check keychain → token stored after login - Kill and relaunch app → still authenticated notes: - This is critical — currently StubAPIClient throws notImplemented for everything - Must be done before any backend integration tasks - Coordinate with backend team on OAuth endpoint contracts - Use APIConfig.swift for base URL configuration