Rebrand entire project from Feels to Reflect

Complete rename across all bundle IDs, App Groups, CloudKit containers,
StoreKit product IDs, data store filenames, URL schemes, logger subsystems,
Swift identifiers, user-facing strings (7 languages), file names, directory
names, Xcode project, schemes, assets, and documentation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-02-26 11:47:16 -06:00
parent b1a54d2844
commit 0442eab1f8
380 changed files with 858 additions and 1077 deletions

View File

@@ -1,4 +1,4 @@
# Feels
# Reflect
iOS mood tracking app. Users rate their day on a 5-point scale (Horrible to Great) and view patterns via Day, Month, Year, and Insights views. Includes watchOS companion, widgets, Live Activities, and AI-powered insights.
@@ -6,16 +6,16 @@ iOS mood tracking app. Users rate their day on a 5-point scale (Horrible to Grea
```bash
# Build
xcodebuild -project Feels.xcodeproj -scheme "Feels (iOS)" -destination 'platform=iOS Simulator,name=iPhone 16 Pro' build
xcodebuild -project Reflect.xcodeproj -scheme "Reflect (iOS)" -destination 'platform=iOS Simulator,name=iPhone 17 Pro' build
# Run all tests
xcodebuild -project Feels.xcodeproj -scheme "Feels (iOS)" -destination 'platform=iOS Simulator,name=iPhone 16 Pro' test
xcodebuild -project Reflect.xcodeproj -scheme "Reflect (iOS)" -destination 'platform=iOS Simulator,name=iPhone 17 Pro' test
# Run a single test suite
xcodebuild -project Feels.xcodeproj -scheme "Feels (iOS)" -destination 'platform=iOS Simulator,name=iPhone 16 Pro' -only-testing:"Tests iOS/Tests_iOS" test
xcodebuild -project Reflect.xcodeproj -scheme "Reflect (iOS)" -destination 'platform=iOS Simulator,name=iPhone 17 Pro' -only-testing:"Tests iOS/Tests_iOS" test
# Run a single test
xcodebuild -project Feels.xcodeproj -scheme "Feels (iOS)" -destination 'platform=iOS Simulator,name=iPhone 16 Pro' -only-testing:"Tests iOS/Tests_iOS/testDatesBetween" test
xcodebuild -project Reflect.xcodeproj -scheme "Reflect (iOS)" -destination 'platform=iOS Simulator,name=iPhone 17 Pro' -only-testing:"Tests iOS/Tests_iOS/testDatesBetween" test
```
## Architecture Overview
@@ -236,7 +236,7 @@ DataController.shared.add(mood: .good, forDate: date, entryType: .listView)
### Startup Flow
1. `FeelsApp.init()` — Configure `AnalyticsManager`, register `BGTaskScheduler`, reset `FeelsTipsManager`, initialize `LiveActivityScheduler`, initialize `WatchConnectivityManager`
1. `ReflectApp.init()` — Configure `AnalyticsManager`, register `BGTaskScheduler`, reset `ReflectTipsManager`, initialize `LiveActivityScheduler`, initialize `WatchConnectivityManager`
2. `MainTabView` receives `DataController.shared.container` as `modelContainer`
3. `IAPManager`, `BiometricAuthManager`, `HealthKitManager` injected as `@EnvironmentObject`
4. On `scenePhase` change to `.active``DataController.shared.refreshFromDisk()` picks up widget/watch changes
@@ -247,7 +247,9 @@ DataController.shared.add(mood: .good, forDate: date, entryType: .listView)
### Framework & Location
- **Framework**: XCTest
- **Test directory**: `Tests iOS/` (iOS), `Tests macOS/` (macOS — template only)
- **UI test directory**: `Tests iOS/` (XCUITest suites)
- **Unit test directory**: `ReflectTests/` (XCTest unit tests)
- **macOS tests**: `Tests macOS/` (template only)
- **File naming**: `{SuiteName}Tests.swift`
### UI Test Architecture (XCUITest)
@@ -277,10 +279,10 @@ Mandatory UI test rules:
```bash
# Run one suite
xcodebuild -project Feels.xcodeproj -scheme "Feels (iOS)" -destination 'platform=iOS Simulator,name=iPhone 16 Pro' -only-testing:"Tests iOS/<SuiteName>" test
xcodebuild -project Reflect.xcodeproj -scheme "Reflect (iOS)" -destination 'platform=iOS Simulator,name=iPhone 17 Pro' -only-testing:"Tests iOS/<SuiteName>" test
# Run all iOS UI tests
xcodebuild -project Feels.xcodeproj -scheme "Feels (iOS)" -destination 'platform=iOS Simulator,name=iPhone 16 Pro' -only-testing:"Tests iOS" test
xcodebuild -project Reflect.xcodeproj -scheme "Reflect (iOS)" -destination 'platform=iOS Simulator,name=iPhone 17 Pro' -only-testing:"Tests iOS" test
```
### Unit Test Guidance
@@ -343,7 +345,7 @@ When fixing a bug:
| Background Tasks | `BGTask` | System scheduler | System may not run task, task killed by system, insufficient time |
| Apple Foundation Models | `FoundationModelsInsightService` | On-device AI | Model not available on device, generation failure, unexpected output |
| PostHog | `AnalyticsManager` | Network | analytics.88oakapps.com unreachable, event queue overflow |
| Deep Links | `FeelsApp.onOpenURL` | URL scheme `feels://` | Malformed URL, unknown host/path |
| Deep Links | `ReflectApp.onOpenURL` | URL scheme `reflect://` | Malformed URL, unknown host/path |
| App Shortcuts / Siri | `AppShortcuts.swift` | SiriKit | Intent not recognized, missing parameter |
## Analytics
@@ -373,13 +375,16 @@ AnalyticsManager.shared.trackScreen(.day)
## Environment Configuration
- **Debug**: Uses `iCloud.com.88oakapps.feels.debug` CloudKit container, `group.com.88oakapps.feels.debug` App Group, `Feels-Debug.store` filename
- **Production**: Uses `iCloud.com.88oakapps.feels` CloudKit container, `group.com.88oakapps.feels` App Group, `Feels.store` filename
- **Debug**: Uses `iCloud.com.88oakapps.reflect.debug` CloudKit container, `group.com.88oakapps.reflect.debug` App Group, `Reflect-Debug.store` filename
- **Production**: Uses `iCloud.com.88oakapps.reflect` CloudKit container, `group.com.88oakapps.reflect` App Group, `Reflect.store` filename
- **Toggle**: `#if DEBUG` preprocessor directive in `SharedModelContainer` and throughout codebase
- **StoreKit Testing**: `IAPManager.bypassSubscription` flag (DEBUG only) — set to `true` to bypass paywall during development
- **Subscription Group ID**: `21914363`
- **Product IDs**: `com.88oakapps.feels.IAP.subscriptions.monthly`, `com.88oakapps.feels.IAP.subscriptions.yearly`
- **Product IDs**: `com.88oakapps.reflect.IAP.subscriptions.monthly`, `com.88oakapps.reflect.IAP.subscriptions.yearly`
- **Trial**: 30-day free trial tracked via `firstLaunchDate` in `GroupUserDefaults`
- **URL Scheme**: `reflect://` (deep links: `reflect://subscribe`)
- **BGTask ID**: `com.88oakapps.reflect.dbUpdateMissing`
- **Logger Subsystem**: `com.88oakapps.reflect`
## Directory Conventions
@@ -389,9 +394,10 @@ When adding new files:
- New models: `Shared/Models/`
- New services/managers: `Shared/Services/`
- New persistence operations: `Shared/Persisence/DataController{OPERATION}.swift` (note directory typo)
- New widget code: `FeelsWidget2/`
- New watch code: `Feels Watch App/`
- New tests: `Tests iOS/`
- New widget code: `ReflectWidget/`
- New watch code: `Reflect Watch App/`
- New UI tests: `Tests iOS/`
- New unit tests: `ReflectTests/`
### Naming Conventions
@@ -404,9 +410,10 @@ When adding new files:
## Localization
- English: `en.lproj/Localizable.strings`
- Spanish: `es.lproj/Localizable.strings`
- **Format**: String Catalogs (`Reflect/Localizable.xcstrings`)
- **Languages**: English (en), German (de), Spanish (es), French (fr), Japanese (ja), Korean (ko), Portuguese-Brazil (pt-BR)
- Use `String(localized:)` for all user-facing strings
- "Reflect" is a brand name — keep it untranslated in all languages
## Dependencies