- 1A: Notificación mensual de resumen de portfolio (día 5 de cada mes)
- 1B: Badge de racha mensual en Dashboard (streak counter)
- 1C: Empty states mejorados en Goals y Journal con CTAs claros
- 2A: Quick Update sheet — actualiza todas las fuentes desde una pantalla
- 2B: Notificación batch update redirige al Quick Update sheet
- 2C: Widget deep link portfoliojournal://quickupdate abre Quick Update
- 3A: App Store version check banner en Settings
- 3C: What's New sheet en primer launch de versión nueva
- Localización completa en 7 idiomas para todas las nuevas strings
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Crashlytics: add FirebaseCrashlytics framework + dSYM upload build phase
- Onboarding: useSampleData off by default, Add First Investment as primary CTA
- AddSourceView: contextual placeholder and footer explaining what a source is
- Charts: CompactPaywallBanner visible to free users on every visit
- Notifications: re-engagement (7d) and monthly check-in local notifications
- Paywall: decorative chart preview replacing static crown icon
- Localization: all new strings in en + es-ES
iCloud sync:
- Force viewContext.refreshAllObjects() on remote change notifications so
data from other devices is picked up immediately without app restart
- Call refreshFromCloudKit() on foreground to merge any changes made while
the device was inactive
- Wait up to 10s for initial CloudKit sync on launch before showing onboarding
(shows "Checking iCloud..." during the wait)
- New OnboardingICloudCheckView: shown on fresh installs with iCloud available,
lets user restore from iCloud before starting onboarding from scratch
Localization:
- Added de, fr, it, ja, pt-BR lproj folders
- New iCloud onboarding strings in en + es-ES (+ button literals)
ASO metadata (fastlane):
- Updated en-US: new subtitle, keywords, description (fixed "no cloud sync"
claim), promotional text, release notes
- Added full metadata for es-ES, de-DE, fr-FR, it, ja, pt-BR (63 files total)
- All keyword fields validated ≤100 Unicode chars
Infrastructure:
- Gemfile + Gemfile.lock for fastlane
- Scripts/archive_and_upload_appstore.sh for CI/CD
Version: 1.2.1 (build 7)
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
The filter excluded snapshots with snapshot.date > completionDate for that month.
The bug: when a check-in for January is marked complete in February, the stored
completion date is backdated to Jan 31 (min(endOfMonth, now)), but batch update
snapshots were dated today (Feb 20). effectiveMonth maps Feb 20 → January, but
Feb 20 > Jan 31 triggered the exclusion, hiding all 2026 data from charts.
The check was redundant — monthDate <= lastCompleted already ensures only
completed months are included. Removing it also correctly handles the existing
snapshots already saved with a late date.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
BatchUpdateView now accepts a saveDate parameter. When saving from a past-month
check-in, the call site passes referenceDate.endOfMonth so snapshots are dated
within the correct month instead of today. For the current month, Date() is used.
Widget forward-fills missing month buckets (trend and category series) using the
most recent earlier month's value, preventing gaps when a check-in is done in the
following month.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Period now starts at startOfMonth of the first month in the interval,
not 30 days before the deadline. For monthly: Feb 1 → Feb 28.
For quarterly: Jan 1 → Mar 31. Formula: startOfMonth(nextDate - (interval-1) months).
Feb 20 with next check-in Feb 28: 19/27 days ≈ 70% instead of 0%.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previous logic measured elapsed days from lastCompletionDate to nextCheckInDate,
so completing a check-in today reset the bar to 0/8 days instead of showing
how far through the full monthly period we are.
New logic: the bar represents the full interval (e.g. 1 month) ending at
nextCheckInDate, starting from nextCheckInDate minus that interval.
Today (Feb 20) with next check-in Feb 28 now shows ~74% progress
(23 of 31 days elapsed since Jan 28) instead of 0%.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- OnboardingView: wrap page titles/descriptions with String(localized:)
using symbolic keys so SwiftUI can look them up correctly
- IAPService.paywallBenefits: change from static let to static var,
wrap all strings with String(localized:) using symbolic keys
- en.lproj: add symbolic keys for new onboarding pages and paywall benefits
- es-ES.lproj: add Spanish translations for all new keys (onboarding pages,
paywall benefits, batch update, contribution fields) plus pre-existing
gaps (Monthly Highlights, Best/Worst Performer, Best Contributor)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Covers paywall redesign (new copy), batch update view,
and contribution fields added in this version.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
AddSnapshotView: restore inputMode == .detailed guard for contribution section.
BatchUpdateView: show contribution field per row only when the source's
account is configured with inputMode == .detailed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
BUG FIX: parseDecimal ignored locale mismatch between currency and device.
CurrencyFormatter.locale(for: "EUR") could return any EUR locale (e.g.
en_IE with decimal='.'), causing "408857,62" to be parsed as 40,885,762.
New CurrencyFormatter.parseUserInput() uses digit-position detection:
a separator followed by ≤2 digits at the end is decimal, otherwise
it is a thousands separator. Fully locale-independent.
FEATURE: Contribution field now always visible in AddSnapshotView.
Previously gated behind inputMode == .detailed; now a toggle available
regardless of account mode.
FEATURE: BatchUpdateView pre-fills each text field with the source's
current value so the user only edits what changed. Adds an optional
contribution field per source row, persisted on save.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces hardcoded '1.1.0' with $(MARKETING_VERSION) so the version
is always in sync with the project.pbxproj setting.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Onboarding: replace feature-focused slides with outcome-focused copy
("Know exactly where you stand", "5 minutes a month is enough", etc.)
- Paywall: non-scrollable layout, reduce from 8 to 4 key benefits,
remove transactional language (Unlock/Upgrade/Premium),
new CTA "Get Full Access", floating close button
- Add IAPService.paywallBenefits for the condensed 4-item paywall list
- Update CompactPaywallBanner and PremiumLockOverlay copy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove unnecessary optional binding for non-optional source.id
- Break up AllocationEvolutionChart body to help Swift type-checker
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaces the simple progress bar with a custom milestone bar showing
individual circles for each achievement, filled when unlocked with a
checkmark indicator.
Fixes#27
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a "Show Forecast" toggle in Settings > Long-Term Focus section.
When disabled, hides the forecast from the total portfolio card and
removes the prediction chart type from the charts tab.
Fixes#26
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a stacked area chart under the Allocation tab that displays how the
portfolio allocation percentages have changed across months.
Fixes#25
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds multi-source selection to the evolution chart source filter.
Users can now tap multiple sources to compare their evolution side by side,
regardless of which category they belong to.
Fixes#24
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When toggling Face ID off, users must now verify their PIN first.
Adds a PinVerifyView component for PIN verification.
Fixes#23
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shows a highlights card with the best and worst performing sources by
percentage change, displayed between the summary and reflection cards.
Fixes#22
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a source has been updated this cycle, shows the value change from the
previous snapshot in green (increase) or red (decrease).
Fixes#21
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds chevron buttons to navigate between months, similar to Lose It Log view.
The next month button is disabled when already at the current month.
Fixes#20
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shows a warning-colored banner when sources need updating, with an X to dismiss.
The existing Pending Updates section lower in the dashboard remains unchanged.
Fixes#18
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaces confirmationDialog with a custom sheet for better title styling.
Increases share icon trailing padding in TotalValueCard.
Fixes#17
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>