- Add updatedTask field to TaskCompletionResponse model from API
- Modify CompleteTaskView callback to pass back the updated task
- Add updateTaskInKanban() function to AllTasksView and ResidenceDetailView
- Move completed tasks to correct kanban column without additional API call
- Remove debug print statements from ResidenceDetailView
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
iOS:
- Add AuthenticatedImage.swift component with auth header support
- Update PhotoViewerSheet, ImageViewerSheet, DocumentDetailView, DocumentFormView
- Use TokenStorage for auth and ApiClient.getMediaBaseUrl() for URLs
- In-memory image caching for performance
Android/KMM:
- Add AuthenticatedImage.kt Compose component using Coil3 httpHeaders
- Add mediaUrl field to TaskCompletionImage and DocumentImage models
- Update PhotoViewerDialog, DocumentDetailScreen, DocumentFormScreen
- Use authenticated media URLs instead of public image URLs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add fixedSize to stat label to allow text wrapping
- Expand stat box to full width for better text flow
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Reduce icon and glow sizes for more content space
- Use smaller font sizes for title, subtitle, and description
- Add fixedSize modifier to prevent description truncation
- Use minLength spacers instead of flexible spacers
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update stats to include cost values for urgency
- Ensure each stat relates directly to its feature's value proposition
- Replace HVAC-specific stat with broader home repair data
- Update documentation with reorganized sources and additional reference stats
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace fabricated stats with real data from industry surveys
- 60% delay maintenance (FinanceBuzz 2024)
- 65% repairs preventable (Hippo Insurance 2023)
- 75% claim denials from coverage misunderstanding (This Old House)
- 37% more tasks with digital tools (Journal of Family Psychology 2023)
- Add docs/ONBOARDING_STATISTICS_SOURCES.md with full citations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add complete onboarding flow with 7 screens: Welcome, Name Residence,
Value Props, Create Account, Verify Email, First Task, Subscription
- Auto-create residence after email verification for "Start Fresh" users
- Add predefined task templates (HVAC, Smoke Detectors, Lawn Care, Leaks)
that create real tasks with today as due date
- Add returning user login button on welcome screen
- Update RootView to prioritize onboarding flow for first-time users
- Use app icon asset instead of house.fill SF Symbol
- Smooth slide transitions with fade-out for back navigation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Expand localization support across all platforms with professional translations:
- KMM: Added strings.xml for zh, ja, ko, it, nl (473 strings each)
- iOS: Updated Localizable.xcstrings with ~1,500 new translation entries
App now supports 10 languages: en, es, fr, de, pt, zh, ja, ko, it, nl
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
KMM (Android/Shared):
- Add strings.xml with 200+ localized strings
- Add translation files for es, fr, de, pt languages
- Update all screens to use stringResource() for i18n
- Add Accept-Language header to API client for all platforms
iOS:
- Add L10n.swift helper with type-safe string accessors
- Add Localizable.xcstrings with translations for all 5 languages
- Update all SwiftUI views to use L10n.* for localized strings
- Localize Auth, Residence, Task, Contractor, Document, and Profile views
Supported languages: English, Spanish, French, German, Portuguese
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add centralized formatWidgetDate() helper that handles both yyyy-MM-dd and ISO8601 formats
- Update widget date display to show "Today", "in X days", or "X days ago"
- Fix isTaskOverdue() to parse ISO8601 dates from Go API
- Remove duplicate date formatting functions from widget views
- Switch API environment back to DEV
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add DateUtils.kt for shared Kotlin date formatting with formatDate,
formatDateMedium, formatDateTime, formatRelativeDate, and isOverdue
- Add DateUtils.swift for iOS with matching date formatting functions
- Enhance ContractorDetailScreen (Android) with quick action buttons
(call, email, website, directions), clickable contact rows, residence
association, statistics section, and metadata
- Enhance ContractorDetailView (iOS) with same features, refactored into
smaller @ViewBuilder functions to fix Swift compiler type-check timeout
- Fix empty string handling in iOS - check !isEmpty in addition to != nil
for optional fields like phone, email, website, address
- Update various task and document views to use centralized DateUtils
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Kotlin/KMM:
- Update Contractor model with optional residenceId and specialties array
- Rename averageRating to rating, update address field names
- Add ContractorMinimal model for task references
- Add residence picker and multi-select specialty chips to AddContractorDialog
- Fix ContractorsScreen and ContractorDetailScreen field references
iOS:
- Rewrite ContractorFormSheet with residence and specialty pickers
- Update ContractorDetailView with FlowLayout for specialties
- Add FlowLayout component for wrapping badge layouts
- Fix ContractorCard and CompleteTaskView field references
- Update ContractorFormState with residence/specialty selection
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add NotificationPreferencesScreen (Android) and NotificationPreferencesView (iOS)
- Add NotificationPreferencesViewModel for shared business logic
- Wire up notification preferences from ProfileScreen on both platforms
- Add subscription verification on app launch for iOS (StoreKit) and Android (Google Play Billing)
- Update SubscriptionApi to match Go backend endpoints (/subscription/purchase/)
- Update StoreKit Configuration with correct product IDs and pricing ($2.99/month, $27.99/year)
- Update Android placeholder prices to match App Store pricing
- Fix NotificationPreference model to match Go backend schema
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Kotlin Shared Layer:
- Add AppleSignInRequest and AppleSignInResponse models
- Add appleSignIn method to AuthApi and APILayer
- Add appleSignInState and appleSignIn() to AuthViewModel
iOS App:
- Create AppleSignInManager for AuthenticationServices integration
- Create AppleSignInViewModel to coordinate Apple auth flow
- Update LoginView with "Sign in with Apple" button
- Add Sign in with Apple entitlement
- Add accessibility identifier for UI testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add dismissKeyboard() helper that types newline to dismiss keyboard
- Call dismissKeyboard() before every tap() in RegistrationTests to prevent
keyboard from covering buttons
- Update fillRegistrationForm to dismiss keyboard after form completion
- Fixes testSuccessfulRegistrationAndVerification test failure
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Change TEST_TARGET_NAME from iosApp to Casera to fix
"UITargetAppPath should be provided" error after rebranding.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update google-services.json package name to com.example.casera
- Fix Xcode project paths from MyCrib/ to Casera/
- Update app display name and usage descriptions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Rename Kotlin package from com.example.mycrib to com.example.casera
- Update Android app name, namespace, and application ID
- Update iOS bundle identifiers and project settings
- Rename iOS directories (MyCribTests -> CaseraTests, etc.)
- Update deep link schemes from mycrib:// to casera://
- Update app group identifiers
- Update subscription product IDs
- Update all UI strings and branding
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Change residence to residence_id with @SerialName annotation
- Change contractor to contractor_id with @SerialName annotation
- Update DocumentApi.kt to use correct field names in form data and JSON requests
- Fixes iOS document creation failing with "missing residence_id" error
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add CompletionHistorySheet for viewing task completion history (Android & iOS)
- Update TaskCard and DynamicTaskCard with completion history access
- Add getTaskCompletions API endpoint to TaskApi and APILayer
- Update models (CustomTask, Document, TaskCompletion, User) for Go API alignment
- Improve TaskKanbanView with completion history integration
- Update iOS TaskViewModel with completion history loading
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update all Kotlin API models to match Go API response structures
- Fix Swift type aliases (TaskDetail→TaskResponse, Residence→ResidenceResponse, etc.)
- Update TaskCompletionCreateRequest to simplified Go API format (taskId, notes, actualCost, photoUrl)
- Fix optional handling for frequency, priority, category, status in task models
- Replace isPrimaryOwner with ownerId comparison against current user
- Update ResidenceUsersResponse to use owner.id instead of ownerId
- Fix non-optional String fields to use isEmpty checks instead of optional binding
- Add type aliases for backwards compatibility in Kotlin models
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Create WidgetDataManager to write task data as JSON to App Group shared container
- Update widget CacheManager to read from App Group file instead of UserDefaults
- Add LargeWidgetView for .systemLarge widget family showing 5-6 tasks
- Add widget data save in AllTasksView after tasks load successfully
- Clear widget cache on logout in AuthenticationManager
- Add residenceName and isOverdue fields to widget task model
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix RegisterView to call AuthenticationManager.login() after email verification
so user is properly transitioned to home screen instead of returning to login
- Fix ResidencesListView to load data when authentication state becomes true,
ensuring residences load after registration/login
- Add accessibility identifier to verification code field for UI testing
- Add NSAppTransportSecurity exceptions for localhost/127.0.0.1 for local dev
- Add comprehensive XCUITest suite for registration flow including:
- Form validation tests (empty fields, invalid email, mismatched passwords)
- Full registration and verification flow test
- Logout from verification screen test
- Helper scripts for test user cleanup
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Enable system-level password generation and iCloud Keychain integration:
RegisterView:
- Add .textContentType(.username) to username field
- Add .textContentType(.emailAddress) to email field
- Add .textContentType(.newPassword) to password fields for Strong Password
- iOS will suggest secure passwords and offer to save to Keychain
LoginView:
- Add .textContentType(.username) to email/username field
- Add .textContentType(.password) to password fields
- Enables AutoFill from saved Keychain credentials
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Load subscription status and upgrade triggers during Android app
initialization in LookupsRepository.initialize(). Previously, only
iOS was loading this data via APILayer.initializeLookups().
Without subscription data, SubscriptionHelper couldn't enforce limits
because SubscriptionCache.currentSubscription was always null.
Changes:
- Add SubscriptionApi calls to load subscription status and upgrade
triggers in parallel with other lookup data
- Clear SubscriptionCache on logout in clear() method
- Add debug logging for subscription loading
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update UpgradeFeatureView to display complete paywall experience
(promo content, subscription products, purchase flow) instead of
simple teaser
- Disable add button in Documents view when upgrade screen is showing
- Disable add button in Contractors view when upgrade screen is showing
- Gray out disabled add buttons to indicate non-interactive state
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Core Infrastructure:
- Add StateFlowObserver for reusable Kotlin StateFlow observation
- Add ValidationRules for centralized form validation
- Add ActionState enum for tracking async operations
- Add KotlinTypeExtensions with .asKotlin helpers
- Add Dependencies factory for dependency injection
- Add ViewState, FormField, and FormState for view layer
- Add LoadingOverlay and AsyncContentView components
- Add form state containers (Task, Residence, Contractor, Document)
ViewModel Updates (9 files):
- Refactor all ViewModels to use StateFlowObserver pattern
- Add optional DI support via initializer parameters
- Reduce boilerplate by ~330 lines across ViewModels
View Updates (4 files):
- Update ResidencesListView to use ListAsyncContentView
- Update ContractorsListView to use ListAsyncContentView
- Update WarrantiesTabContent to use ListAsyncContentView
- Update DocumentsTabContent to use ListAsyncContentView
Net reduction: -332 lines (1007 removed, 675 added)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changes:
- Make currentTier a computed property from StoreKit instead of stored value
- Initialize StoreKit at app launch and refresh on foreground for ready subscription status
- Fix empty state logic: show empty state when limit > 0, upgrade prompt when limit = 0
- Add subscription status display in Profile screen (iOS/Android)
- Add upgrade prompts to Residences and Tasks screens for free tier users
- Improve SubscriptionHelper with better tier checking logic
iOS:
- SubscriptionCache: currentTier now computed from StoreKit.purchasedProductIDs
- StoreKitManager: add refreshSubscriptionStatus() method
- AppDelegate: initialize StoreKit at launch and refresh on app active
- ContractorsListView: use shouldShowUpgradePrompt(currentCount:limitKey:)
- WarrantiesTabContent/DocumentsTabContent: same empty state fix
- ProfileTabView: display current tier and limitations status
- ResidencesListView/ResidenceDetailView: add upgrade prompts for free users
- AllTasksView: add upgrade prompt for free users
Android:
- ContractorsScreen/DocumentsScreen: fix empty state logic
- ProfileScreen: display subscription status and limits
- ResidencesScreen/ResidenceDetailScreen: add upgrade prompts
- UpgradeFeatureScreen: improve UI layout
Shared:
- APILayer: add getSubscriptionStatus() method
- SubscriptionHelper: add hasAccessToFeature() utility
- Remove duplicate subscription checking logic
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed all compilation errors:
1. Changed from switch/case to if-let pattern for Kotlin ApiResult types
- ApiResult doesn't have .success/.failure/.loading/.idle cases in Swift
- Used "as? ApiResultSuccess" and "as? ApiResultError" pattern instead
2. Fixed SubscriptionStatus name conflict
- Fully qualified as ComposeApp.SubscriptionStatus
- Avoids conflict with StoreKit's Product.SubscriptionInfo.Status
3. Fixed VerificationResponse handling
- VerificationResponse only has success, tier, error fields
- After verification, fetch full subscription status via getSubscriptionStatus
- Properly unwrap optional response.data
4. Added try-catch for Kotlin suspend functions
- Kotlin suspend functions throw in Swift
- Wrapped await calls in do-try-catch blocks
5. Removed unused getReceiptData function
- Inlined the logic directly in verifyTransactionWithBackend
iOS build now succeeds with no errors.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed Swift compilation error by explicitly passing httpClient parameter
to SubscriptionApi constructor. Kotlin default parameters are not
available when calling from Swift.
Changed from:
SubscriptionApi()
To:
SubscriptionApi(client: ApiClient.shared.httpClient)
iOS build now succeeds.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed unresolved references by matching the standard API client pattern:
- Changed from apiCall helper to try-catch pattern
- Use ApiClient.httpClient instead of direct httpClient reference
- Use ApiClient.getBaseUrl() instead of ApiConfig.baseUrl
- Added proper HttpClient parameter with default value
- Added proper error handling with response status checks
- Fixed verifyIOSReceipt to include transactionId parameter
- Fixed Android verification request format (use map instead of data class)
Now matches the pattern used by other API classes (ResidenceApi, TaskApi, etc.)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Created Configuration.storekit with two subscription products:
- MyCrib Pro Monthly ($4.99/month)
* Product ID: com.example.mycrib.pro.monthly
* 1 week free trial
* Recurring monthly subscription
- MyCrib Pro Annual ($49.99/year)
* Product ID: com.example.mycrib.pro.annual
* 1 month free trial
* Recurring annual subscription (17% savings)
This allows testing StoreKit 2 purchase flows in the iOS Simulator
without needing TestFlight or App Store Connect configuration.
Setup instructions:
1. Open iosApp.xcodeproj in Xcode
2. Add Configuration.storekit to project (drag into Project Navigator)
3. Edit scheme (Product > Scheme > Edit Scheme)
4. Go to Run > Options tab
5. Set StoreKit Configuration to "Configuration.storekit"
6. Run app in simulator to test purchases locally
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implemented Android subscription UI components:
- UpgradeFeatureScreen: Full-screen view for restricted features (contractors, documents)
* Shows feature icon, name, and description
* Displays "This feature is available with Pro" badge
* Opens UpgradePromptDialog on button click
- UpgradePromptDialog: Modal dialog with upgrade options
* Trigger-specific title and message from backend
* Feature preview list with Material icons
* "Upgrade to Pro" button with loading state
* "Compare Free vs Pro" button
* "Maybe Later" cancel option
- FeatureComparisonDialog: Full-screen comparison table
* Free vs Pro feature comparison
* Displays data from SubscriptionCache.featureBenefits
* Default features if no data loaded
* Upgrade button
- BillingManager: Google Play Billing Library placeholder
* Singleton manager for in-app purchases
* Product query placeholder
* Purchase flow placeholder
* Backend receipt verification placeholder
* Restore purchases placeholder
All components follow Material3 design system with theme-aware colors and spacing constants.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Client-Side Changes:
- Add WarrantyStatus data class to Document model for backend-calculated status
- Update WarrantyCard to display backend status (statusText, statusColor) with client fallback
- Fix document list refresh: call loadDocuments() after create/update operations
Testing:
- Add ComprehensiveDocumentWarrantyTests with 25+ XCUITest cases
- Test document creation, update, delete, image upload
- Test warranty-specific fields and property selection
- Test both general documents and warranties
- Includes helper methods for form interaction and cleanup
Other:
- Update ApiConfig and PushNotificationManager
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit adds persistent theme storage and comprehensive documentation for Android development.
Theme Persistence:
- Created ThemeStorage with platform-specific implementations (SharedPreferences/UserDefaults)
- Updated ThemeManager.initialize() to load saved theme on app start
- Integrated ThemeStorage initialization in MainActivity and MainViewController
- Theme selection now persists across app restarts
Documentation (CLAUDE.md):
- Added comprehensive Android Design System section
- Documented all 11 themes and theme management
- Provided color system guidelines (use MaterialTheme.colorScheme)
- Documented spacing system (AppSpacing/AppRadius constants)
- Added standard component usage examples (StandardCard, FormTextField, etc.)
- Included screen patterns (Scaffold, pull-to-refresh, lists)
- Provided button and dialog patterns
- Listed key design principles for Android development
Build Status:
- ✅ Android builds successfully
- ✅ iOS builds successfully
- ✅ Theme persistence works on both platforms
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit adds a comprehensive theming system to Android matching iOS, and fixes package declarations throughout the codebase to match directory structure.
Theme System Additions:
- Added 11 themes matching iOS: Default, Teal, Ocean, Forest, Sunset, Monochrome, Lavender, Crimson, Midnight, Desert, Mint
- Created ThemeColors.kt with exact iOS color values for light/dark modes
- Added ThemeManager.kt for dynamic theme switching
- Created Spacing.kt with standardized spacing constants (xs/sm/md/lg/xl)
- Added ThemePickerDialog.kt for theme selection UI
- Integrated theme switching in ProfileScreen.kt
- Updated App.kt to observe ThemeManager for reactive theming
Component Library:
- Added StandardCard.kt and CompactCard.kt for consistent card styling
- Added FormTextField.kt with error/helper text support
- Added FormSection.kt for grouping related form fields
- Added StandardEmptyState.kt for empty state UI
Package Migration:
- Fixed all package declarations to match directory structure (com.example.mycrib.*)
- Updated package declarations in commonMain, androidMain, and iosMain
- Fixed all import statements across entire codebase
- Ensures compilation on both Android and iOS platforms
iOS Theme Rename:
- Renamed "Default" theme to "Teal" in iOS
- Renamed "Bright" theme to "Default" in iOS to make vibrant colors the default
Build Status:
- ✅ Android builds successfully
- ✅ iOS builds successfully
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove pagination from all Django REST Framework endpoints
- Update Kotlin API clients to return direct lists instead of paginated responses
- Update iOS ViewModels to handle direct list responses
- Remove ContractorListResponse, DocumentListResponse, and PaginatedResponse models
- Fix contractor form specialty selector loading with improved DataCache access
- Fix contractor sheet presentation to use full screen (.presentationDetents([.large]))
- Improve UI test scrolling to handle lists of any size with smart end detection
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Expanded the theming system from 5 to 10 total themes with comprehensive light/dark mode support. Each new theme includes unique color palettes optimized for visibility and WCAG contrast compliance.
New Themes:
- Lavender: Soft purple with pink accents
- Crimson: Bold red with warm highlights
- Midnight: Deep navy with sky blue tones
- Desert: Warm terracotta and sand palette
- Mint: Fresh green with turquoise accents
Technical Details:
- Created 45 new colorset files (9 colorsets × 5 themes)
- Each theme includes Primary, Secondary, Accent, 2 Backgrounds, and 4 Text colors
- Dark mode colors use 60-90% lightness for high visibility on dark backgrounds
- Consistent text colors across all themes for accessibility
- Updated ThemeManager.swift to include all 10 themes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Document the 5-color semantic design system, including color palette reference,
usage guidelines, and complete patterns for creating new views, cards, buttons,
and UI components. Add critical styling rules for Form/List views with proper
background colors and row styling requirements.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>