d10517b356
La 2.0 salio a la App Store el 2026-07-28 con los dos ultimos pasos del onboarding sin mostrarse. 2.0.1 lleva ese fix. El Info.plist del widget lleva la version hardcodeada y fastlane no la toca, asi que se alinea a mano (2.0.1 / 65) antes de construir. Documentado en CLAUDE.md para no volver a tropezar. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Ks8uUcMA9mjypVK7F2Pkt
78 lines
3.7 KiB
Markdown
78 lines
3.7 KiB
Markdown
# MealMood — Project Context for Claude Code
|
|
|
|
## App
|
|
- **Name**: MealMood: Family Meal Planner
|
|
- **Bundle ID**: com.alexandrevazquez.mealmood
|
|
- **Platform**: iOS/iPadOS (also runs as iOS app on Mac)
|
|
- **Current version**: 2.0.1 (dev, beta-bound; 2.0 shipped to the App Store 2026-07-28)
|
|
- **Main branch**: `1.0.1` (production), feature branches named after versions
|
|
|
|
### Branch ↔ version convention (IMPORTANT)
|
|
The active dev branch is named after the **current** `MARKETING_VERSION`, not the one it was created with. Whenever the iOS app version changes, **rename the branch to match**:
|
|
```bash
|
|
# after bumping MARKETING_VERSION in the Xcode project to e.g. 1.1.6
|
|
git branch -m <old-version> 1.1.6 # e.g. git branch -m 1.1.5 1.1.6
|
|
```
|
|
Right now: `MARKETING_VERSION = 2.0.1` → active branch is `2.0.1`. Keep them in sync. (The build number bump within the same version does NOT rename the branch — only a version change does.)
|
|
|
|
**The widget version is not automated.** `MealMoodWidget/Info.plist` hardcodes `CFBundleShortVersionString` and `CFBundleVersion`; `fastlane`'s `increment_build_number` only touches the app target. Update the widget by hand to match the app **before** running `fastlane beta`, or App Store Connect rejects the upload for a version mismatch:
|
|
```bash
|
|
plutil -replace CFBundleShortVersionString -string "<version>" MealMoodWidget/Info.plist
|
|
plutil -replace CFBundleVersion -string "<build>" MealMoodWidget/Info.plist
|
|
```
|
|
|
|
## Credentials — all managed via `pass` (GPG-encrypted, syncs to Gitea)
|
|
|
|
Never hardcode credentials. Always read from `pass`:
|
|
|
|
```bash
|
|
# Apple
|
|
pass show apple/mealmood/apple-id # alexandre.vazquez@gmail.com
|
|
pass show apple/mealmood/developer-team-id # 2825Q76T7H
|
|
pass show apple/mealmood/appstore-connect-team-id # 128443966
|
|
pass show apple/mealmood/app-store-app-id # 6759255553
|
|
pass show apple/mealmood/app-specific-password-fastlane # for fastlane uploads
|
|
|
|
# Firebase
|
|
pass show firebase/mealmood/api-key
|
|
pass show firebase/mealmood/project-id
|
|
pass show firebase/mealmood/google-app-id
|
|
|
|
# AdMob
|
|
pass show admob/mealmood/app-id
|
|
pass show admob/mealmood/banner-home-unit-id
|
|
```
|
|
|
|
### TestFlight upload
|
|
```bash
|
|
export FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD=$(pass show apple/mealmood/app-specific-password-fastlane)
|
|
fastlane beta
|
|
```
|
|
|
|
## Stack
|
|
- SwiftUI + SwiftData (iOS 17+)
|
|
- Firebase Analytics (`AnalyticsService.swift`)
|
|
- Google AdMob (banner, free tier only, hidden on Mac)
|
|
- StoreKit 2 (subscription `com.mealmood.premium.monthly`)
|
|
- iCloud KV sync (`ICloudSyncService.swift`) — does NOT sync `isPremium`
|
|
- Widget extension (`MealMoodWidget/`) — requires App Group `group.com.alexandrevazquez.mealmood`
|
|
- Fastlane for CI/CD
|
|
|
|
## Premium logic
|
|
- `PremiumSyncService` is the source of truth for premium state transitions
|
|
- `isPremium` is determined **only** by StoreKit — never by iCloud sync
|
|
- `Transaction.updates` listener in `ContentView` catches purchases in real-time
|
|
- Tests: `MealMoodTests/PremiumSyncServiceTests.swift`
|
|
|
|
## Key files
|
|
| File | Purpose |
|
|
|------|---------|
|
|
| `MealMood/ContentView.swift` | App root, premium sync, Transaction.updates listener |
|
|
| `MealMood/Services/PremiumSyncService.swift` | Premium state machine (testable) |
|
|
| `MealMood/Services/StoreManager.swift` | StoreKit 2 purchase/restore |
|
|
| `MealMood/Services/ICloudSyncService.swift` | Cross-device sync (dishes, tags, plans — NOT isPremium) |
|
|
| `MealMood/Views/Home/WeekPlanShareView.swift` | Export styles (default, school, vertical A4) |
|
|
| `MealMoodWidget/MealMoodWidget.swift` | Home screen widget |
|
|
| `fastlane/Fastfile` | `beta` and `release` lanes |
|
|
| `fastlane/metadata/` | App Store metadata in 6 languages |
|