Commit Graph

211 Commits

Author SHA1 Message Date
Trey t
7d858abf9d Unify sharing codec and wire iOS KMP actuals 2026-02-18 21:37:38 -06:00
Trey t
5e3596db77 Complete re-validation remediation: KMP architecture, iOS platform, XCUITest rewrite
Phases 1-6 of fixes.md — closes all 13 issues from codex_issues_2.md re-validation:

KMP Architecture:
- Fix subscription purchase/restore response contract (VerificationResponse aligned)
- Add feature benefits auth token + APILayer init flow
- Remove ResidenceFormScreen direct API bypass (use APILayer)
- Wire paywall purchase/restore to real SubscriptionApi calls

iOS Platform:
- Add iOS Keychain token storage via Swift KeychainHelper
- Implement Google Sign-In via ASWebAuthenticationSession (GoogleSignInManager)
- DocumentViewModelWrapper observes DataManager for auto-updates
- Add missing accessibility identifiers (document, task columns, Google Sign-In)

XCUITest Rewrite:
- Rewrite test infrastructure: zero sleep() calls, accessibility ID lookups
- Create AuthCriticalPathTests and NavigationCriticalPathTests
- Delete 14 legacy brittle test files (Suite0-10, templates)
- Fix CaseraTests module import (@testable import Casera)

All platforms build clean. TEST BUILD SUCCEEDED.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 18:50:13 -06:00
Trey t
7444f73b46 Close all 25 codex audit findings across KMP, iOS, and Android
Remediate all P0-S priority findings from cross-platform architecture audit:
- Harden token storage with EncryptedSharedPreferences (Android) and Keychain (iOS)
- Add SSL pinning and certificate validation to API clients
- Fix subscription cache race conditions and add thread-safe access
- Add input validation for document uploads and file type restrictions
- Refactor DocumentApi to use proper multipart upload flow
- Add rate limiting awareness and retry logic to API layer
- Harden subscription tier enforcement in SubscriptionHelper
- Add biometric prompt for sensitive actions (Login, Onboarding)
- Fix notification permission handling and device registration
- Add UI test infrastructure (page objects, fixtures, smoke tests)
- Add CI workflow for mobile builds

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 13:15:34 -06:00
Trey t
ffe5716167 wip 2026-02-18 10:54:25 -06:00
Trey t
2fc4a48fc9 Replace PostHog integration with AnalyticsManager architecture
Remove old PostHogAnalytics singleton and replace with guide-based
two-file architecture: AnalyticsManager (singleton wrapper with super
properties, session replay, opt-out, subscription funnel) and
AnalyticsEvent (type-safe enum with associated values).

Key changes:
- New API key, self-hosted analytics endpoint
- All 19 events ported to type-safe AnalyticsEvent enum
- Screen tracking via AnalyticsManager.Screen enum + SwiftUI modifier
- Remove all identify() calls — fully anonymous analytics
- Add lifecycle hooks: flush on background, update super properties on foreground
- Add privacy opt-out toggle in Settings
- Subscription funnel methods ready for IAP integration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 09:48:49 -06:00
Trey t
09be5fa444 Add cancel task confirmation dialog
- Add L10n strings for cancel confirmation
- Add confirmation dialog to ResidenceDetailView
- Fix AllTasksView cancel dialog (was using archive strings)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 10:46:13 -06:00
Trey t
49f4cf168f Simplify task completion animations to 4 celebration types
Keep only implode, firework, starburst, and ripple animations.
Remove slide, fade, scale, flip, bounce, spring, rotation, morph,
confetti, and cascade animations for a more focused experience.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 21:35:42 -06:00
Trey t
3274924937 Add task completion animations and fix 7-day task count
Animation Testing:
- Add AnimationTesting module with 14 animation types for task completion
- Include 4 celebration animations: Implode, Firework, Starburst, Ripple
- Card shrinks, shows checkmark with effect, then moves to next column
- Extended timing (2.2s) for celebration animations

Task Count Fix:
- Fix "7 Days" and "30 Days" counts on residence cards and dashboard
- Previously used API column membership (30-day "due soon" column)
- Now calculates actual days until due from task's effectiveDueDate
- Correctly counts tasks due within 7 days vs 8-30 days

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 21:21:48 -06:00
Trey t
556b187508 Add background task for overnight widget data refresh
- Create BackgroundTaskManager that schedules refresh at random time
  between 12:00 AM - 4:00 AM local time
- Fetches tasks from API, writes to DataManager and shared App Group
- Reloads widget timelines after refresh
- Register task in AppDelegate, schedule when app goes to background
- Add BGTaskSchedulerPermittedIdentifiers and fetch/processing modes to Info.plist

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 20:36:17 -06:00
Trey t
4daaa1f7d8 Consolidate task metrics to single source of truth
- Add API column name constants to WidgetDataManager (overdueColumn,
  dueWithin7DaysColumn, due8To30DaysColumn, etc.)
- Update DataManagerObservable to use WidgetDataManager column constants
- Remove duplicate ResidenceTaskStats struct, use TaskMetrics everywhere
- Delete TaskStatsCalculator.swift (consolidated into WidgetDataManager)
- Rename confusing flags: isUpcoming → isDueWithin7Days, isLater → isDue8To30Days
- Add comprehensive unit tests for TaskMetrics and WidgetTask

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 20:26:52 -06:00
Trey t
cacdf86938 Add ExportOptions.plist for TestFlight automation
Configures automatic App Store Connect upload with:
- app-store-connect distribution method
- Automatic signing
- Symbol upload enabled
- Auto-managed version/build numbers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 18:03:04 -06:00
Trey t
20e79b704f Fix widget overdue count to use kanban categorization
The widget was calculating overdue count from due dates, which didn't
account for in-progress tasks. Now uses the isOverdue flag from kanban
categorization, ensuring the count matches the displayed tasks.

Before: 3 overdue (date-based calc included in-progress tasks)
After: 2 overdue (matches kanban which excludes in-progress)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 17:51:06 -06:00
Trey t
4d9d8d8e45 Fix date parsing to handle ISO datetime format
The toDate() extension was only parsing "yyyy-MM-dd" format, causing
ISO datetime strings like "2025-01-02T00:00:00Z" to fail parsing and
display as raw strings. Now extracts the date part before the "T"
before parsing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 21:15:12 -06:00
Trey t
59cbc60668 android ui 2025-12-18 12:18:33 -06:00
Trey t
b39d37a6e8 Fix residence auto-update, widget theming, and document patterns
- Fix residence detail not updating after edit:
  - DataManager.updateResidence() now updates both _residences and _myResidences
  - ResidenceViewModel auto-updates selectedResidence when data changes
  - No pull-to-refresh needed after editing

- Add widget theme support:
  - Widgets now use user's selected theme via App Group UserDefaults
  - ThemeManager has simplified version for widget extension context
  - Added WIDGET_EXTENSION compiler flag to CaseraExtension target

- Redesign widget views with organic aesthetic:
  - Updated FreeWidgetView, SmallWidgetView, MediumWidgetView, LargeWidgetView
  - Created OrganicTaskRowView, OrganicStatsView, OrganicStatPillWidget

- Document patterns in CLAUDE.md:
  - Added Mutation & Auto-Update Pattern section
  - Added iOS Shared Components documentation
  - Documented reusable buttons, forms, empty states, cards, modifiers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 22:58:55 -06:00
Trey t
7d76393e40 Fix residence detail caching to check both data sources
- APILayer.getResidence() now checks both residences and myResidences caches
- Home screen loads myResidences, but getResidence() only checked residences,
  causing unnecessary network calls on every residence detail visit
- Remove flawed iOS-side cache check in TaskViewModel that had race condition
  with Kotlin StateFlow - let Kotlin handle all caching logic

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 14:00:28 -06:00
Trey t
7d2ac309ab Fix password visibility toggle position in LoginView
Add SecureIconTextField component that includes the eye toggle button
inside the text field (matching RegisterView's OrganicSecureField).

Update LoginView to use SecureIconTextField instead of IconTextField
with an external button, ensuring consistent UI across auth screens.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 13:35:21 -06:00
Trey t
338c9a6d09 Update localization strings for shared utilities refactoring
- Update cost format string to use pre-formatted currency
- Add new localization entries for refactored components
- Remove unused "Pros" string (renamed to "Contractors")

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 13:22:59 -06:00
Trey t
42eda6a8c8 Add shared utilities and refactor iOS codebase for DRY compliance
Create centralized shared utilities in iosApp/Shared/:
- Extensions: ViewExtensions, DateExtensions, StringExtensions, DoubleExtensions
- Components: FormComponents, SharedEmptyStateView, ButtonStyles
- Modifiers: CardModifiers
- Utilities: ValidationHelpers, ErrorMessages

Migrate existing views to use shared utilities:
- LoginView: Use IconTextField, FieldLabel, FieldError, OrganicPrimaryButton
- TaskFormView: Use .loadingOverlay() modifier
- TaskCard/DynamicTaskCard: Use .toFormattedDate() extension
- CompletionCardView: Use .toCurrency() (with KotlinDouble support)
- ResidenceDetailView: Use OrganicEmptyState, StandardLoadingView
- Profile views: Use .standardFormStyle(), .sectionBackground()
- Form views: Use consistent form styling modifiers

Benefits:
- Eliminates ~180 lines of duplicate code
- Consistent styling across all forms and components
- KotlinDouble extensions for seamless KMM interop
- Single source of truth for UI patterns

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 13:19:59 -06:00
Trey t
44c7b23cc2 Unify task stats calculation and update UI labels
- Create shared TaskStatsCalculator for consistent date bucket logic
- Fix widget stats to use exclusive buckets (overdue | 7 days | 30 days)
- Update labels: "This Week" → "Next 7 Days" / "7 Days"
- Large widget now shows Overdue, 7 Days, 30 Days (removed Total)
- Rename "Pros" tab to "Contractors"
- Remove red pulsing ring from residence card icons

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 12:07:35 -06:00
Trey t
bcd8b36a9b Fix TokenStorage stale cache bug and add user-friendly error messages
- Fix TokenStorage.getToken() returning stale cached token after login/logout
- Add comprehensive ErrorMessageParser with 80+ error code mappings
- Add Suite9 and Suite10 UI test files for E2E integration testing
- Fix accessibility identifiers in RegisterView and ResidenceFormView
- Fix UITestHelpers logout to target alert button specifically
- Update various UI components with proper accessibility identifiers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 11:48:35 -06:00
Trey t
b05e52521f Apply Warm Organic design system to all iOS views
- Full-screen views: Added WarmGradientBackground() to CompleteTaskView,
  ContractorDetailView, DocumentDetailView, DocumentFormView,
  FeatureComparisonView, TaskTemplatesBrowserView, ManageUsersView,
  ContractorPickerView

- Onboarding: Redesigned all 8 screens with organic styling including
  animated hero sections, gradient buttons, decorative blobs

- Components: Updated ErrorView, EmptyStateView, EmptyResidencesView,
  EmptyTasksView, TaskSuggestionsView, StatView, SummaryStatView,
  CompletionCardView, DynamicTaskColumnView with organic styling

- Applied consistent patterns: OrganicSpacing, naturalShadow modifier,
  RoundedRectangle with .continuous style, rounded font designs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 09:05:47 -06:00
Trey t
c3a9494b0f Fix task stats consistency and improve residence card UI
- Compute task stats locally from kanban data for both summary card and residence cards
- Filter out completed_tasks and cancelled_tasks columns from counts
- Use startOfDay for accurate date comparisons (overdue, due this week, next 30 days)
- Add parseDate helper to DateUtils
- Make address tappable to open in Apple Maps
- Remove navigation title from residences list
- Update CLAUDE.md with Go backend references and DataManager architecture

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 23:57:01 -06:00
Trey t
7f3ed69574 Add localized strings for Warm Organic design
New strings for redesigned views:
- "Welcome to Your Space" - empty residences view
- "Your Home Dashboard" - main home view title
- "Primary" - residence badge label
- "Overdue" - task status label
- Updated task templates count format

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 20:16:40 -06:00
Trey t
3598a8d57f Add Warm Organic design system to iOS app
- Add OrganicDesign.swift with reusable components:
  - WarmGradientBackground, OrganicBlobShape, GrainTexture
  - OrganicDivider, OrganicCardBackground, NaturalShadow modifier
  - OrganicSpacing constants (cozy, comfortable, spacious, airy)

- Update high-priority screens with organic styling:
  - LoginView: hero glow, organic card background, rounded fonts
  - ResidenceDetailView, ResidencesListView: warm backgrounds
  - ResidenceCard, SummaryCard, PropertyHeaderCard: organic cards
  - TaskCard: metadata pills, secondary buttons, card background
  - TaskFormView: organic loading overlay, templates button
  - CompletionHistorySheet: organic loading/error/empty states
  - ProfileView, NotificationPreferencesView, ThemeSelectionView

- Update task badges with icons and capsule styling:
  - PriorityBadge: priority-specific icons
  - StatusBadge: status-specific icons

- Fix TaskCard isOverdue error using DateUtils.isOverdue()

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 20:15:32 -06:00
Trey t
67f8dcc80f Fix wheel picker crash caused by UIKit/SwiftUI race condition
The crash occurred when UIKit's didSelectRow callback fired during
SwiftUI view teardown, causing an array index out of bounds error.

Fixes:
- Use Identifiable struct for stable ForEach identity
- Hide picker before dismissing to prevent race condition
- Add .id() modifier for stable picker identity
- Disable interactive dismiss to prevent mid-scroll dismissal
- Add small delay before dismiss callbacks

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 18:02:23 -06:00
Trey t
59a827f692 Fix iOS build errors and notification time picker crash
- Remove invalid 'summary' parameter from TaskColumnsResponse calls
- Remove invalid 'totalDueSoon' parameter from TotalSummary call
- Fix TimePickerSheet crash when scrolling by properly initializing @State
  with State(initialValue:) and pre-computing hours array

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 17:40:03 -06:00
Trey t
fbe45da9ff Remove summary from list responses, calculate client-side
- Remove summary field from MyResidencesResponse and TaskColumnsResponse
- Update HomeScreen and ResidencesScreen to observe DataManager.totalSummary
- Load tasks when residence views appear to ensure accurate summary
- Add pull-to-refresh for tasks on ResidencesScreen
- Update iOS views to use client-side calculated summary

Summary is now calculated via refreshSummaryFromKanban() from cached
kanban data. This ensures summary is always up-to-date after CRUD
operations and when residence views are shown.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 17:06:48 -06:00
Trey t
6dfc4ee57c Fix home screen summary showing zeros
The setAllTasks() function was not calling refreshSummaryFromKanban()
after loading kanban data, so the summary statistics (totalTasks,
totalOverdue, etc.) were never calculated - they stayed at zero.

Also switch API environment back to DEV.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 16:06:01 -06:00
Trey t
96ea1f4686 Improve error handling for Echo backend error format
- Update ErrorResponse model to make detail and statusCode optional since
  backend now returns simple {"error": "message"} format
- Update AuthApi to parse actual backend error messages instead of generic
  "Registration failed"/"Login failed" strings
- Update ErrorParser to prioritize the "error" field and add fallback for
  simple error map responses
- Update iOS ViewModels (Login, Register, AppleSignIn) to properly handle
  400 and 409 status codes by displaying backend error messages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 14:01:33 -06:00
Trey t
2517435551 Add swipe hint for empty first column in task kanban
Shows a subtle "Swipe to see your tasks" hint centered on the first
column (Overdue) when it's empty but other columns have tasks. The
hint uses the theme primary color and scrolls with the column.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 22:04:31 -06:00
Trey t
e7c09f687a Add keyboard dismiss toolbar for iOS numeric and multi-line fields
Creates a reusable KeyboardDismissToolbar view modifier that adds a
"Done" button to dismiss keyboards that don't have a return key.
Applied to all numeric keyboards (numberPad, decimalPad, phonePad)
and multi-line text inputs (TextEditor, TextField with axis: .vertical).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 21:20:33 -06:00
Trey t
e44bcdd988 Add full-screen iOS parity screens and navigation
- Add CompleteTaskScreen for full-screen task completion (matches iOS CompleteTaskView)
- Add ManageUsersScreen for full-screen user management (matches iOS ManageUsersView)
- Add PhotoViewerScreen with swipeable gallery and pinch-to-zoom
- Add UpgradeScreen for full-screen subscription flow (matches iOS UpgradeFeatureView)
- Add navigation routes for new screens (CompleteTaskRoute, ManageUsersRoute, PhotoViewerRoute, UpgradeRoute)
- Wire navigation callbacks into AllTasksScreen, ResidenceDetailScreen, ProfileScreen
- Add overdue count with red color to Summary Card
- Add pulsing animation to residence cards when overdue
- Add property type, isPrimary star, and street address to Residence Card
- Add Edit Profile, Privacy Policy, and App Version to ProfileScreen
- Add string resources for new UI elements and localization

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 17:02:08 -06:00
Trey t
b150c20e4b Reorganize share UI with Easy Share on top
Move Easy Share (.casera file) section above Share Code section in the
invite users dialog. Both platforms now have consistent UI with both
buttons using the same filled button style.

iOS changes:
- Move share functionality into ManageUsersView
- Remove share button from ResidenceDetailView toolbar
- Redesign ShareCodeCard with Easy Share on top

Android changes:
- Update ManageUsersDialog with matching layout
- Connect share package callback to existing share function

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 13:17:19 -06:00
Trey t
e2d264da7e Add client-side summary calculation and lookup resolution from cache
- Add calculateSummaryFromKanban() to compute summary stats from cached kanban data
- Add refreshSummaryFromKanban() called after task CRUD operations
- Fix column name matching to use API format (e.g., "overdue_tasks" not "overdue")
- Fix tasksDueNextMonth to only include due_soon tasks (not upcoming)
- Update TaskResponse computed properties to resolve from DataManager cache
- Update iOS task cards to use computed properties for priority/frequency/category
- This enables API to skip preloading lookups for better performance

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 01:04:52 -06:00
Trey t
4592c4493c Cache contractors at startup and filter by residence from cache
- Load contractors during initializeLookups() when authenticated
- Update getContractorsByResidence() to filter from cache instead of making network call
- Only fetch from API if cache is empty or stale

This eliminates the /contractors/by-residence/{id}/ call when visiting residences.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 23:38:43 -06:00
Trey t
33ee445aea Add custom interval days support for task frequency
- Add customIntervalDays field to Kotlin models (TaskResponse, TaskCreateRequest, TaskUpdateRequest)
- Update Android AddTaskDialog to show interval field only for "Custom" frequency
- Update Android EditTaskScreen for custom frequency support
- Update iOS TaskFormView for custom frequency support
- Fix preview data in TaskCard and TasksSection to include new field
- Add customIntervalDays to OnboardingFirstTaskView

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 19:05:59 -06:00
Trey t
3140c75815 Fix CaseraIconView to use theme color instead of hardcoded orange
- Add backgroundColor parameter to CaseraIconView and PulsingIconView
- Update ResidenceCard to pass Color.appPrimary for themed icon background
- Icon now matches the app's current theme like PropertyHeaderCard

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 01:11:56 -06:00
Trey t
311a30ed2d Add haptic feedback, rich task completion, and Google Sign-In preparation
- Add platform haptic feedback abstraction (HapticFeedback.kt) with
  implementations for Android, iOS, JVM, JS, and WASM
- Enhance CompleteTaskDialog with interactive 5-star rating, image
  thumbnails, and haptic feedback
- Add ImageBitmap platform abstraction for displaying selected images
- Localize TaskTemplatesBrowserSheet with string resources
- Add Android widgets infrastructure (small, medium, large sizes)
- Add Google Sign-In button components and auth flow preparation
- Update strings.xml with new localization keys for completions,
  templates, and document features
- Integrate haptic feedback into ThemePickerDialog

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 01:06:02 -06:00
Trey t
a3e1c338d2 Add X-Timezone header to all API requests
Send the device's IANA timezone identifier (e.g., "America/Los_Angeles")
with every API request to enable timezone-aware overdue task detection.

Platform implementations:
- Android/JVM: TimeZone.getDefault().id
- iOS: NSTimeZone.localTimeZone.name
- JS/WASM: Intl.DateTimeFormat().resolvedOptions().timeZone

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 00:04:44 -06:00
Trey t
258ccf7354 Improve error message handling with user-friendly messages
- Add ErrorMessageParser in Kotlin and Swift to detect network errors
  and technical messages, replacing them with human-readable text
- Update all ViewModels to use ErrorMessageParser.parse() for error display
- Remove redundant error popup from LoginView (error shows inline only)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 20:46:43 -06:00
Trey t
1839bd0e11 Add nextDueDate field to TaskResponse for recurring task support
- Add nextDueDate field to TaskResponse model (from API's next_due_date)
- Add effectiveDueDate computed property (nextDueDate ?? dueDate)
- Update DynamicTaskCard, TaskCard to display effectiveDueDate
- Update WidgetDataManager to save effectiveDueDate to widget cache
- Update TaskFormView to use effectiveDueDate when editing
- Fix preview mock data to include nextDueDate parameter

This ensures recurring tasks show the correct next due date after completion
instead of the original due date.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 11:10:56 -06:00
Trey t
cbe073aa21 Add push notification deep linking and sharing subscription checks
- Add deep link navigation from push notifications to specific task column on kanban board
- Fix subscription check in push notification handler to allow navigation when limitations disabled
- Add pendingNavigationTaskId to handle notifications when app isn't ready
- Add ScrollViewReader to AllTasksView for programmatic scrolling to task column
- Add canShareResidence() and canShareContractor() subscription checks (iOS & Android)
- Add test APNS file for simulator push notification testing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 23:17:28 -06:00
Trey t
ed14a1c69e Update myResidences when residence is deleted
DataManager.removeResidence() now also updates _myResidences so the
residence list view updates immediately without requiring a manual refresh.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 23:24:22 -06:00
Trey t
4a04aff1e6 Replace status_id with in_progress boolean across mobile apps
- Remove TaskStatus model and status_id foreign key references
- Add in_progress boolean field to task models and forms
- Update TaskApi to use dedicated POST endpoints for task actions:
  - POST /tasks/:id/cancel/ instead of PATCH with is_cancelled
  - POST /tasks/:id/uncancel/
  - POST /tasks/:id/archive/
  - POST /tasks/:id/unarchive/
- Fix iOS TaskViewModel to use error-first pattern for Kotlin-Swift
  generic type bridging issues
- Update iOS callback signatures to pass full TaskResponse instead
  of just taskId to avoid stale closure lookups
- Add in_progress localization strings
- Update widget preview data to use inProgress boolean

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 20:47:59 -06:00
Trey t
a067228597 remove icon from overview summary 2025-12-08 12:03:54 -06:00
Trey t
efdb760438 Add interactive iOS widget with subscription-based views
- Add direct API completion from widget via quick-complete endpoint
- Share auth token and API URL with widget via App Group UserDefaults
- Add dirty flag mechanism to refresh tasks when app returns from background
- Widget checkbox colors indicate priority (red=urgent, orange=high, yellow=medium, green=low)
- Show simple "X tasks waiting" view for free tier users when limitations enabled
- Show interactive task completion widget for premium users or when limitations disabled
- Sync subscription status with widget extension for view selection

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 12:02:16 -06:00
Trey t
c5b08befea Update API layer to use TotalSummary from CRUD responses
Frontend changes:
- Add generic WithSummaryResponse<T> model for CRUD responses
- Update TaskApi, TaskCompletionApi, ResidenceApi return types
- Update APILayer to extract summary from responses and call DataManager.setTotalSummary()
- Replace refreshTasks() calls with DataManager.updateTask() for local cache updates
- Remove redundant refreshMyResidences() calls
- Remove unused helper methods (refreshTasks, refreshMyResidences, refreshSummary)
- Add summary field to JoinResidenceResponse model

This pairs with the backend changes to eliminate redundant network calls
after CRUD operations - dashboard stats now update from the mutation response.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 10:39:53 -06:00
Trey t
c334ce0bd0 Add PostHog analytics integration for Android and iOS
Implement comprehensive analytics tracking across both platforms:

Android (Kotlin):
- Add PostHog SDK dependency and initialization in MainActivity
- Create expect/actual pattern for cross-platform analytics (commonMain/androidMain/iosMain/jvmMain/jsMain/wasmJsMain)
- Track screen views: registration, login, residences, tasks, contractors, documents, notifications, profile
- Track key events: user_registered, user_signed_in, residence_created, task_created, contractor_created, document_created
- Track paywall events: contractor_paywall_shown, documents_paywall_shown
- Track sharing events: residence_shared, contractor_shared
- Track theme_changed event

iOS (Swift):
- Add PostHog iOS SDK via SPM
- Create PostHogAnalytics wrapper and AnalyticsEvents constants
- Initialize SDK in iOSApp with session replay support
- Track same screen views and events as Android
- Track user identification after login/registration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 23:53:00 -06:00
Trey t
6cbcff116f Add Daily Digest notification preferences with custom time support
- Add dailyDigest and dailyDigestHour fields to Kotlin NotificationPreference model
- Update NotificationPreferencesViewModel to support new fields
- Add Daily Summary toggle with time picker to Android NotificationPreferencesScreen
- Add Daily Summary toggle with time picker to iOS NotificationPreferencesView
- Add localized strings for Daily Summary in all 10 languages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 22:51:50 -06:00