Growth y monetización: fixes críticos, paywall multi-plan, teasers y App Intents

CRÍTICO — enlaces del App Store rotos (adquisición viral = 0):
- GoalShareService.appStoreURL apuntaba a id6744983373 (404): el QR de TODAS las
  imágenes compartidas llevaba a una página muerta. Corregido a id6757678318.
- SettingsView enlazaba id6741412965 (una novela romántica). Ahora usa la constante.

Monetización:
- IAPService multi-producto: sub anual (com.portfoliojournal.premium.annual, con
  intro offer/trial) + lifetime como ancla. isPremium acepta cualquiera de los dos.
  Paywall con selector de plan (anual por defecto si existe; degrada a solo lifetime
  mientras el producto no esté creado en App Store Connect).
- paywallBenefits: añadidos Multiple Accounts y Family Sharing (diferenciadores).
- Teaser de historia bloqueada en Charts: "N meses más con Premium" en vez de
  truncar en silencio (FreemiumValidator.hiddenHistoryMonths + banner).
- Trigger de paywall de backups ahora instrumentado (logPaywallShown "backups").

Retención / adquisición:
- Rating velocity: prompt tras 2 check-ins y 30 días (antes 3 + 90 — en una app
  mensual eso era >3 meses sin poder pedir la primera review con ~0 ratings).
- Sample data ON por defecto en onboarding (skip ya no aterriza en dashboard vacío).
- Notificación de protección de streak el día 25 si el check-in del mes está pendiente.
- App Intents + AppShortcutsProvider: "Update my portfolio" / "Check my portfolio"
  vía Siri/Shortcuts/Spotlight.
- Instrumentación: onboarding_step/onboarding_skipped y content_shared (viral loop).
- ScreenshotMode (--screenshots) para capturas de marketing automatizadas.

ASO:
- 6 locales nuevos en metadata (en-GB, en-CA, en-AU, es-MX, fr-CA, pt-PT) reusando
  traducciones — 6 campos de keywords extra; pt-PT adaptado (reforma).
- Categoría secundaria: PRODUCTIVITY.
- 17 strings nuevas localizadas en los 7 idiomas.

Pendiente manual: crear la sub anual en App Store Connect (grupo de suscripción +
intro offer 7 días) con el id exacto com.portfoliojournal.premium.annual.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015qUZrBusG82T37R7PeokqJ
This commit is contained in:
alexandrev-tibco
2026-07-02 22:12:32 +02:00
parent 19e80c912b
commit 197bddcd7e
81 changed files with 944 additions and 14 deletions
@@ -414,3 +414,22 @@
"insight_forecast_title" = "Auf dem Weg zu";
"notification_milestone_title" = "Portfolio-Meilenstein! 🎉";
"notification_milestone_body" = "Dein Portfolio hat gerade %@ überschritten. Herzlichen Glückwunsch!";
"streak_protection_notification_title" = "Brich deine Serie nicht 🔥";
"streak_protection_notification_body" = "Dein monatlicher Check-in steht noch aus. 2 Minuten genügen, um deine Serie zu halten.";
"paywall_benefit_accounts_title" = "Mehrere Konten";
"paywall_benefit_accounts_subtitle" = "Getrennte Portfolios für Familie oder Business";
"paywall_benefit_family_title" = "Familienfreigabe";
"paywall_benefit_family_subtitle" = "Ein Kauf, bis zu 5 Familienmitglieder";
"paywall_plan_annual" = "Jährlich";
"paywall_plan_annual_per_year" = "%@ / Jahr";
"paywall_plan_lifetime" = "Lebenslang";
"paywall_plan_lifetime_badge" = "BESTER WERT";
"paywall_trial_days" = "Tage";
"paywall_trial_weeks" = "Wochen";
"paywall_trial_months" = "Monate";
"paywall_trial_years" = "Jahre";
"paywall_trial_format" = "%d %@ gratis";
"chart_history_locked" = "%d weitere Monate Verlauf — mit Premium freischalten";
@@ -422,3 +422,22 @@
"insight_forecast_title" = "On track for";
"notification_milestone_title" = "Portfolio Milestone! 🎉";
"notification_milestone_body" = "Your portfolio just passed %@. Congrats!";
"streak_protection_notification_title" = "Don't break your streak 🔥";
"streak_protection_notification_body" = "Your monthly check-in is still pending. It takes 2 minutes to keep your streak alive.";
"paywall_benefit_accounts_title" = "Multiple Accounts";
"paywall_benefit_accounts_subtitle" = "Separate portfolios for family or business";
"paywall_benefit_family_title" = "Family Sharing";
"paywall_benefit_family_subtitle" = "One purchase, up to 5 family members";
"paywall_plan_annual" = "Annual";
"paywall_plan_annual_per_year" = "%@ / year";
"paywall_plan_lifetime" = "Lifetime";
"paywall_plan_lifetime_badge" = "BEST VALUE";
"paywall_trial_days" = "days";
"paywall_trial_weeks" = "weeks";
"paywall_trial_months" = "months";
"paywall_trial_years" = "years";
"paywall_trial_format" = "%d %@ free";
"chart_history_locked" = "%d more months of history — unlock with Premium";
@@ -366,3 +366,22 @@
"insight_forecast_title" = "En camino hacia";
"notification_milestone_title" = "¡Hito de cartera! 🎉";
"notification_milestone_body" = "Tu cartera acaba de superar %@. ¡Enhorabuena!";
"streak_protection_notification_title" = "No rompas tu racha 🔥";
"streak_protection_notification_body" = "Aún tienes pendiente el check-in de este mes. Son 2 minutos y tu racha sigue viva.";
"paywall_benefit_accounts_title" = "Varias cuentas";
"paywall_benefit_accounts_subtitle" = "Carteras separadas para familia o negocio";
"paywall_benefit_family_title" = "En familia";
"paywall_benefit_family_subtitle" = "Una compra, hasta 5 miembros de la familia";
"paywall_plan_annual" = "Anual";
"paywall_plan_annual_per_year" = "%@ / año";
"paywall_plan_lifetime" = "Para siempre";
"paywall_plan_lifetime_badge" = "MEJOR VALOR";
"paywall_trial_days" = "días";
"paywall_trial_weeks" = "semanas";
"paywall_trial_months" = "meses";
"paywall_trial_years" = "años";
"paywall_trial_format" = "%d %@ gratis";
"chart_history_locked" = "%d meses más de historial — desbloquéalos con Premium";
@@ -414,3 +414,22 @@
"insight_forecast_title" = "En bonne voie pour";
"notification_milestone_title" = "Jalon de portefeuille ! 🎉";
"notification_milestone_body" = "Votre portefeuille vient de dépasser %@. Félicitations !";
"streak_protection_notification_title" = "Ne brisez pas votre série 🔥";
"streak_protection_notification_body" = "Votre bilan mensuel est encore en attente. 2 minutes suffisent pour garder votre série.";
"paywall_benefit_accounts_title" = "Comptes multiples";
"paywall_benefit_accounts_subtitle" = "Des portefeuilles séparés pour la famille ou le travail";
"paywall_benefit_family_title" = "Partage familial";
"paywall_benefit_family_subtitle" = "Un achat, jusqu'à 5 membres de la famille";
"paywall_plan_annual" = "Annuel";
"paywall_plan_annual_per_year" = "%@ / an";
"paywall_plan_lifetime" = "À vie";
"paywall_plan_lifetime_badge" = "MEILLEURE OFFRE";
"paywall_trial_days" = "jours";
"paywall_trial_weeks" = "semaines";
"paywall_trial_months" = "mois";
"paywall_trial_years" = "ans";
"paywall_trial_format" = "%d %@ gratuits";
"chart_history_locked" = "%d mois d'historique en plus — débloquez avec Premium";
@@ -414,3 +414,22 @@
"insight_forecast_title" = "In direzione di";
"notification_milestone_title" = "Traguardo raggiunto! 🎉";
"notification_milestone_body" = "Il tuo portafoglio ha appena superato %@. Complimenti!";
"streak_protection_notification_title" = "Non interrompere la tua serie 🔥";
"streak_protection_notification_body" = "Il check-in di questo mese è ancora in sospeso. Bastano 2 minuti per mantenere viva la serie.";
"paywall_benefit_accounts_title" = "Più account";
"paywall_benefit_accounts_subtitle" = "Portafogli separati per famiglia o lavoro";
"paywall_benefit_family_title" = "In famiglia";
"paywall_benefit_family_subtitle" = "Un acquisto, fino a 5 membri della famiglia";
"paywall_plan_annual" = "Annuale";
"paywall_plan_annual_per_year" = "%@ / anno";
"paywall_plan_lifetime" = "Per sempre";
"paywall_plan_lifetime_badge" = "MIGLIOR VALORE";
"paywall_trial_days" = "giorni";
"paywall_trial_weeks" = "settimane";
"paywall_trial_months" = "mesi";
"paywall_trial_years" = "anni";
"paywall_trial_format" = "%d %@ gratis";
"chart_history_locked" = "%d mesi di storico in più — sblocca con Premium";
@@ -414,3 +414,22 @@
"insight_forecast_title" = "目標に向けて順調";
"notification_milestone_title" = "ポートフォリオ達成!🎉";
"notification_milestone_body" = "ポートフォリオが%@を突破しました。おめでとうございます!";
"streak_protection_notification_title" = "連続記録を守ろう 🔥";
"streak_protection_notification_body" = "今月のチェックインがまだ完了していません。2分で連続記録を守れます。";
"paywall_benefit_accounts_title" = "複数アカウント";
"paywall_benefit_accounts_subtitle" = "家族用・事業用にポートフォリオを分けて管理";
"paywall_benefit_family_title" = "ファミリー共有";
"paywall_benefit_family_subtitle" = "1回の購入で家族5人まで利用可能";
"paywall_plan_annual" = "年額";
"paywall_plan_annual_per_year" = "%@ / 年";
"paywall_plan_lifetime" = "買い切り";
"paywall_plan_lifetime_badge" = "ベストバリュー";
"paywall_trial_days" = "日間";
"paywall_trial_weeks" = "週間";
"paywall_trial_months" = "か月";
"paywall_trial_years" = "年間";
"paywall_trial_format" = "%d%@無料";
"chart_history_locked" = "さらに%dか月分の履歴 — プレミアムで解除";
@@ -414,3 +414,22 @@
"insight_forecast_title" = "Caminhando para";
"notification_milestone_title" = "Meta de portfólio! 🎉";
"notification_milestone_body" = "Seu portfólio acabou de ultrapassar %@. Parabéns!";
"streak_protection_notification_title" = "Não quebre sua sequência 🔥";
"streak_protection_notification_body" = "O check-in deste mês ainda está pendente. Leva 2 minutos para manter sua sequência viva.";
"paywall_benefit_accounts_title" = "Várias contas";
"paywall_benefit_accounts_subtitle" = "Carteiras separadas para família ou negócios";
"paywall_benefit_family_title" = "Compartilhamento Familiar";
"paywall_benefit_family_subtitle" = "Uma compra, até 5 membros da família";
"paywall_plan_annual" = "Anual";
"paywall_plan_annual_per_year" = "%@ / ano";
"paywall_plan_lifetime" = "Vitalício";
"paywall_plan_lifetime_badge" = "MELHOR VALOR";
"paywall_trial_days" = "dias";
"paywall_trial_weeks" = "semanas";
"paywall_trial_months" = "meses";
"paywall_trial_years" = "anos";
"paywall_trial_format" = "%d %@ grátis";
"chart_history_locked" = "%d meses a mais de histórico — desbloqueie com o Premium";