Commit Graph

42 Commits

Author SHA1 Message Date
alexandrev-tibco c6c33d8143 2.0: bump MARKETING_VERSION 1.2.1 → 2.0 (major feature release: ingredients + shopping list, photos, breakfast/snacks, CloudKit family sharing)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BkanrydYtrme8wipTzWssG
2026-07-12 17:37:21 +02:00
alexandrev-tibco 8ba8e4e933 1.2.1: bump MARKETING_VERSION 1.2.0 → 1.2.1 (1.2.0 shipped to App Store)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BkanrydYtrme8wipTzWssG
2026-07-11 10:59:43 +02:00
alexandrev-tibco 6ba71e6341 1.2.1: surface "Copy previous week" on the empty-week banner
The exact-copy-from-previous-week action already existed but was buried in the
magic-wand long-press context menu. Expose it as a visible secondary button on
the auto-assign banner (shown only when the previous week actually has a menu),
so users landing on a fresh week can one-tap copy last week's plan and then tweak
it. Confirms before overwriting a week that already has dishes.

- Extract requestCopyPreviousWeek() shared by the menu and the banner.
- Add week_copied_previous analytics (copied_slots + source: empty_banner|menu).
- Reuses the existing localized home_copy_previous_week string (all 6 languages).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BkanrydYtrme8wipTzWssG
2026-07-11 10:58:53 +02:00
alexandrev-tibco c5fd1088cd 1.2.0: bump build 55 → 56 after TestFlight upload (Crashlytics non-fatals)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BkanrydYtrme8wipTzWssG
2026-07-10 14:37:32 +02:00
alexandrev-tibco 56abe28a82 1.2.0: report non-fatal errors to Crashlytics across key error paths
CrashlyticsService was wired only for the is_premium custom key. Route the
swallowed errors in the main catch blocks through CrashlyticsService.record
with a context tag, so non-fatals show up in Firebase (StoreKit load/purchase/
restore, calendar access/create/update/delete, reset-all-data, onboarding save).
Debug prints kept.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BkanrydYtrme8wipTzWssG
2026-07-10 14:27:28 +02:00
alexandrev-tibco 313403ecd5 1.2.0: bump version 1.1.5 → 1.2.0, build 54 → 55 after TestFlight upload
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UtWT52pAE91D7mbDda1cAM
2026-07-03 10:19:43 +02:00
alexandrev-tibco cbe0ca1326 1.2.0: offer code redemption + share link alongside export image
- "Redeem promo code" button in PremiumView via offerCodeRedemption
  (hidden on Mac where the sheet is unavailable); entitlement re-checked
  on success — unblocks influencer/blog promo campaigns
- System share sheet now includes a localized text with the mealmood.app
  link next to the exported image (viral loop no longer QR-only)
- 2 new strings × 6 languages

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UtWT52pAE91D7mbDda1cAM
2026-07-03 10:14:58 +02:00
alexandrev-tibco f5cb67adc0 1.2.0: widget deep-link, Lock Screen widgets, in-app widget promo
- Tapping the widget now deep-links via mealmood://today back to the current
  week (URL scheme registered, onOpenURL handler in Home)
- New Lock Screen widget families: accessoryRectangular (weekday + both
  meals) and accessoryInline (next relevant meal)
- One-time dismissable widget promo card on Home from the 2nd session,
  with widget_promo_shown/dismissed analytics
- 2 new strings × 6 languages

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UtWT52pAE91D7mbDda1cAM
2026-07-03 10:11:40 +02:00
alexandrev-tibco 73c2039338 1.2.0: contextual notifications + in-onboarding auto-fill (aha moment)
- New "Week Ready" onboarding step: auto-fills the first week inline right
  after dish creation, then pitches the Sunday reminder with context before
  requesting OS notification permission (no more cold prompt on Home)
- Notifications section in Settings: weekly reminder toggle, deep-link to
  system settings when permission is denied
- NotificationService: remindersEnabled preference, requestPermission(),
  authorizationStatus(), cancelAllReminders()
- Post-onboarding premium prompt deferred to 2nd session (paywall was just
  shown as the final onboarding step — 2s-later alert was prompt fatigue)
- Back navigation blocked after onboarding commit to avoid duplicate dishes
- 10 new strings × 6 languages

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UtWT52pAE91D7mbDda1cAM
2026-07-03 10:08:04 +02:00
alexandrev-tibco 13ece5f2e7 1.1.5: bump build 53 → 54 after TestFlight upload
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UtWT52pAE91D7mbDda1cAM
2026-07-02 13:31:39 +02:00
alexandrev-tibco 9cadc1ad18 1.1.5: fix activation analytics blind spots + purchase environment tagging
- dish_added now carries a `source` param; onboarding-created dishes fire
  it with source="onboarding" (previously untracked, undercounting activation)
- onboarding_completed now reports dish_count
- premium_purchased tagged with StoreKit environment (production/sandbox/xcode)
  so test purchases can be excluded from conversion metrics
- add .gitignore to keep signing secrets (.p12/.cer/.mobileprovision) and
  build artifacts out of the repo
- document branch↔MARKETING_VERSION naming convention

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UtWT52pAE91D7mbDda1cAM
2026-07-02 13:26:45 +02:00
alexandrev-tibco caf25bc33f 1.1.5: auto-fill first week after onboarding
Land new users on a ready, auto-planned week (with confetti) instead of an
empty one, to improve activation. Only fires when the user added dishes;
otherwise keeps the current empty-week + auto-assign prompt behavior.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 08:02:15 +02:00
alexandrev-tibco 82d623aa05 1.1.5: bump build 51 → 52 after TestFlight upload
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 22:27:04 +02:00
alexandrev-tibco b45cb2a530 1.1.5: conversion funnel overhaul
Paywall:
- Redesigned PremiumView with yearly/monthly/lifetime side by side
- 7-day free trial badge with savings % vs monthly
- Social proof line, BEST VALUE highlight on yearly
- StoreManager: new yearlyProduct, lifetimeProduct, yearlySavingsPercent, hasTrialAvailable

Funnel:
- Paywall step added to onboarding (PaywallStepView)
- Contextual modal at dish limit (replaces silent block)
- Visible "X/15 dishes" counter in DishListView
- BottomPromoBanner rotates AdMob with internal "Remove ads" CTA (1 in 4)
- Free dish limit lowered 20 → 15
- Review prompt earlier: 2 weeks → 1 week

Analytics:
- paywall_viewed/dismissed with source + seconds_on_screen
- dish_limit_hit, week_limit_hit, free_trial_started events
- Every PremiumView call site now passes its source

StoreKit:
- MealMood.storekit: added yearly $19.99 + 7d trial, monthly trial, lifetime $39.99
- AppStoreConnect-1.1.5-setup.md with full manual setup instructions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 22:21:36 +02:00
alexandrev-tibco 72770801d3 1.1.5: add analytics for stats_viewed and week_rated events
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 13:49:33 +02:00
alexandrev-tibco f4e1aef8d5 1.1.4 (50): TestFlight upload — switch to ASC API key auth
Build 50 uploaded to TestFlight. Also migrates Fastfile from
Apple ID + app-specific-password to App Store Connect API key
(via pass) to avoid session expiry on future uploads.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 19:36:49 +02:00
alexandrev-tibco 304774991d 1.1.4 (49): bump version for TestFlight
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 19:26:13 +02:00
alexandrev-tibco 84b74f9ea4 Autocomplete feedback loop: implicit rejection + weekly rating
A) Implicit: HomeViewModel tracks auto-assigned slot IDs after each
   autocomplete run. When the user manually replaces one of those dishes,
   the rejected dish ID is recorded in FeedbackStore (UserDefaults).
   AutocompleteEngine applies a 25% penalty per rejection (floor 0.30).

B) Explicit: WeekPlan gains userRating (0/1/-1). Past weeks with dishes
   show a compact 👍/👎 row (Premium only). Liked weeks boost their
   dishes (+0.20 each, max +0.50); disliked weeks penalise them
   (-0.25 each, max -0.50). Signal is intentionally modest so the
   period cycle score remains dominant.

Also adds Stats + week-rating localization strings to all 6 languages
(were missing from the previous commit).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 18:09:15 +02:00
alexandrev-tibco e13771fa06 Autocomplete: period-based dish scoring
Replace flat recency penalty with cycle detection. For each dish with
≥2 appearances in history, compute the median interval between uses and
score by how well weeksSinceLast aligns with that period:
  ratio < 0.5  → 0.10 (too soon)
  ratio ~1.0   → 3.00 (right on schedule, boost)
  ratio > 2.5  → 1.00 (pattern may have changed, neutral)

Expand history window from 4 to 12 weeks so monthly cycles (period=4)
have enough data points to be detected reliably.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 16:30:22 +02:00
alexandrev-tibco 330f21a019 1.1.0: Smarter autocomplete + Statistics view
- AutocompleteEngine: MRV heuristic picks the most-constrained slot first
  at each step; historical scoring deprioritises dishes used in recent
  weeks (decay: 0.20 last week → 0.90 four+ weeks ago)
- HomeViewModel: passes last 4 weeks as recentPlans to autocomplete
- StatsView (Premium): streak, weeks planned, completion rate, top 8
  dishes with bar charts, top 6 tags with colour bars — 6 languages
- StoreManager: update product ID to approved bundle-ID convention
- Version bump to 1.1.3 / build 48

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 15:05:39 +02:00
alexandrev-tibco d09e8a7bee 1.1.2 (47): fix subscription purchase button fallback
Remove legacy CONSUMABLE fallback from monthlyProduct — when the
subscription fails to load, the UI now shows the retry state instead
of silently offering the legacy one-time product for purchase.
Legacy purchasers retain access via hasActiveSubscription() as before.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 19:58:57 +02:00
alexandrev-tibco 89b35dc4ae 1.1.1 (46): subscription IAP, export compliance, metadata
- Switch premium to AutoRenewable subscription (com.mealmood.premium.monthly.sub);
  legacy one-time purchasers retain lifetime access via StoreManager fallback
- Add ITSAppUsesNonExemptEncryption=false to Info.plist (no custom encryption)
- Update storekit config with both legacy NonConsumable and new subscription
- Bump version 1.1.1 build 46; update fastlane metadata and release notes (6 langs)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 11:28:14 +02:00
alexandrev-tibco 7da7995538 Fix SwiftData migration crash on schema upgrades
Add = false/true defaults to all non-optional Bool properties so
SwiftData's lightweight migration knows what value to assign existing
rows. Replace try! ModelContainer with crash-safe do-catch that resets
the store on migration failure instead of crashing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 11:24:56 +02:00
alexandrev-tibco 4ac81d6223 1.0.6: Fix widget version, bump to build 41, fix Fastfile signing
- MealMoodWidget CFBundleShortVersionString: 1.0.3 → 1.0.6 (fixes ITMS-90473)
- App + Widget build number: 40 → 41 (App Store release build)
- Fastfile: add manageAppVersionAndBuildNumber: false to EXPORT_OPTIONS
  to prevent xcodebuild from requiring App Store Connect during export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 08:36:31 +02:00
alexandrev-tibco a4dfb38feb 1.0.6: Priority dishes, day rules, auto-assign CTA, tap-to-replace, export incomplete weeks, Sunday notification
- Dish.isPriority: mark dishes as priority; auto-assign gives them 2.5x weight
- Tag.dayRestriction: restrict tags to weekdays or weekend only
- Auto-assign CTA banner shown when there are empty slots (was hidden in context menu)
- Tap on filled slot opens picker to replace dish directly (no need to remove first)
- Export callout visible as soon as ≥1 slot is filled (not only when week is complete)
- WeekPlanShareView shows localized "TBD" / "Eating out" for empty/eating-out slots
- Second Sunday 17:00 push notification to plan next week
- DishDrawer sorts: priority first, then by historical usage, then alphabetically
- Search in SlotDishPickerSheet already shipped in 1.0.5 (verified ✓)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 00:00:53 +02:00
alexandrev-tibco ac124342fa Fix CrashlyticsService API signature and unused tagMap warning
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 15:31:54 +02:00
alexandrev-tibco 87a0874f2a Fix Crashlytics dSYM run script: use inputPaths instead of inputFileListPaths
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 14:52:09 +02:00
alexandrev-tibco 110807d239 1.0.5: Eating out slots, rule violations panel, Crashlytics, search bar fix
- Eating out: tap any empty slot → "Mark as eating out"; shows teal indicator,
  skipped by auto-assign, counts as complete, tap again to unmark
- Rule violations panel: access via wand long-press context menu when conflicts exist;
  shows all isRuleOverridden slots with Fix (clear) or Ignore (acknowledge) actions
- Firebase Crashlytics integrated: CrashlyticsService + dSYM upload build phase,
  isPremium property tracked per session
- PremiumSyncService: extracted premium state machine, StoreKit Transaction.updates
  listener, isPremium no longer synced via iCloud to avoid stale state
- StoreManager: analytics on purchase/restore, bundle ID fallback for product ID lookup
- Search bar contrast bug fixed: TextField now has explicit foreground color for dark mode
- WelcomeStepView: redesigned onboarding welcome screen with week preview
- Version bump: 1.0.5 build 22

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 09:48:20 +02:00
alexandrev-tibco 6c7e12b41f 1.0.4: Smarter auto-assign, quick dish entry, calendar fix, frictionless onboarding
- AutocompleteEngine: no-repeat rule now applies to all dishes (not just tagless ones); fallback still allows repeats when no alternative exists
- CalendarService: update existing events instead of delete+create to prevent duplicates; fix weekStartDate using plan date instead of currentWeekStart
- DishFormView: form stays open after saving in create mode for quick multi-dish entry; Done button to close; saved feedback banner
- OnboardingViewModel/FirstDishesStepView: dishes are now optional during onboarding; Finish button always enabled
- AnalyticsService: new events — onboarding_step_viewed(step) and auto_assign_used(filled, unfilled)
- Localization: dish_done and first_dishes_optional_hint added in 6 languages; release notes updated in all 6 languages
- Version bump: 1.0.3 → 1.0.4 (build 19)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 11:35:50 +02:00
alexandrev-tibco c66132f494 1.0.2: Add multilingual support, redesign share view, and iCloud sync improvements
- Add localisations for German, French, Italian, and Brazilian Portuguese
- Redesign WeekPlanShareView with richer layout and sharing options
- Improve HomeView with various UI enhancements
- Update AppSettings and Tag models for new features
- Minor iCloud sync and Settings fixes
- Add archive & upload script for App Store submissions

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 19:02:33 +01:00
alexandrev-tibco a532afbee6 Stabilize planner UI, fix reset flow, and force Premium on TestFlight 2026-02-27 13:09:58 +01:00
alexandrev-tibco ae40ec6f09 Make onboarding added dishes list scrollable to keep Finish button stable 2026-02-26 11:08:30 +01:00
alexandrev-tibco 9f4cf7484d Fix dish deletion list flicker with stable identity/order and add regression test 2026-02-26 11:06:54 +01:00
alexandrev-tibco 37c2e01a09 Top-align onboarding content in all steps 2026-02-26 10:58:24 +01:00
alexandrev-tibco b0c7a41625 Adjust onboarding header to short step label and top-align step content 2026-02-26 10:56:25 +01:00
alexandrev-tibco 3d72d53889 Polish onboarding layout with fixed header, back nav, and consistent step framing 2026-02-26 10:53:46 +01:00
alexandrev-tibco 3937abeb6e Rework onboarding flow and move premium prompt post-setup 2026-02-26 10:50:09 +01:00
alexandrev-tibco 6db6659330 Fix Reset All Data crash by using safe cascade deletion 2026-02-26 10:42:35 +01:00
alexandrev-tibco c2dcaf07c7 1.0.1: remove trial wording from onboarding premium step 2026-02-26 10:39:41 +01:00
alexandrev-tibco 9bdbf80e67 1.0.1: add review funnel, trial onboarding, and app diagnostics 2026-02-26 10:33:45 +01:00
alexandrev-tibco c5c7e3d2e4 Release 1.0.0 baseline 2026-02-26 10:27:09 +01:00
alexandrev-tibco e593453abd Version casi lista 2026-02-17 13:34:02 +01:00