docs: update planning documents and todos
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -47,20 +47,13 @@ Inside "Pro Access" group, click "+" → Add Subscription:
|
||||
|
||||
Edit Scheme → Run → Options → StoreKit Configuration → Select `SportsTime.storekit`
|
||||
|
||||
**Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add SportsTime/SportsTime.storekit SportsTime.xcodeproj
|
||||
git commit -m "feat(iap): add StoreKit configuration file with Pro subscriptions"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 2: Create ProFeature Enum
|
||||
|
||||
**Files:**
|
||||
- Create: `SportsTime/SportsTime/Core/Store/ProFeature.swift`
|
||||
- Test: `SportsTime/SportsTimeTests/Store/ProFeatureTests.swift`
|
||||
- Create: `SportsTime/SportsTimeTests/Store/ProFeatureTests.swift`
|
||||
|
||||
**Step 1: Write the test**
|
||||
|
||||
@@ -104,13 +97,7 @@ struct ProFeatureTests {
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' -only-testing:SportsTimeTests/ProFeatureTests test`
|
||||
|
||||
Expected: FAIL with "cannot find 'ProFeature' in scope"
|
||||
|
||||
**Step 3: Write minimal implementation**
|
||||
**Step 2: Write implementation**
|
||||
|
||||
Create `SportsTime/SportsTime/Core/Store/ProFeature.swift`:
|
||||
|
||||
@@ -160,26 +147,13 @@ enum ProFeature: String, CaseIterable, Identifiable {
|
||||
}
|
||||
```
|
||||
|
||||
**Step 4: Run test to verify it passes**
|
||||
|
||||
Run: `xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' -only-testing:SportsTimeTests/ProFeatureTests test`
|
||||
|
||||
Expected: PASS
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add SportsTime/SportsTime/Core/Store/ProFeature.swift SportsTime/SportsTimeTests/Store/ProFeatureTests.swift
|
||||
git commit -m "feat(iap): add ProFeature enum defining gated features"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 3: Create StoreError Enum
|
||||
|
||||
**Files:**
|
||||
- Create: `SportsTime/SportsTime/Core/Store/StoreError.swift`
|
||||
- Test: `SportsTime/SportsTimeTests/Store/StoreErrorTests.swift`
|
||||
- Create: `SportsTime/SportsTimeTests/Store/StoreErrorTests.swift`
|
||||
|
||||
**Step 1: Write the test**
|
||||
|
||||
@@ -203,13 +177,7 @@ struct StoreErrorTests {
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' -only-testing:SportsTimeTests/StoreErrorTests test`
|
||||
|
||||
Expected: FAIL
|
||||
|
||||
**Step 3: Write minimal implementation**
|
||||
**Step 2: Write implementation**
|
||||
|
||||
Create `SportsTime/SportsTime/Core/Store/StoreError.swift`:
|
||||
|
||||
@@ -242,26 +210,13 @@ enum StoreError: LocalizedError {
|
||||
}
|
||||
```
|
||||
|
||||
**Step 4: Run test to verify it passes**
|
||||
|
||||
Run: `xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' -only-testing:SportsTimeTests/StoreErrorTests test`
|
||||
|
||||
Expected: PASS
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add SportsTime/SportsTime/Core/Store/StoreError.swift SportsTime/SportsTimeTests/Store/StoreErrorTests.swift
|
||||
git commit -m "feat(iap): add StoreError enum for purchase error handling"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 4: Create StoreManager Core
|
||||
|
||||
**Files:**
|
||||
- Create: `SportsTime/SportsTime/Core/Store/StoreManager.swift`
|
||||
- Test: `SportsTime/SportsTimeTests/Store/StoreManagerTests.swift`
|
||||
- Create: `SportsTime/SportsTimeTests/Store/StoreManagerTests.swift`
|
||||
|
||||
**Step 1: Write the test**
|
||||
|
||||
@@ -303,13 +258,7 @@ struct StoreManagerTests {
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' -only-testing:SportsTimeTests/StoreManagerTests test`
|
||||
|
||||
Expected: FAIL
|
||||
|
||||
**Step 3: Write minimal implementation**
|
||||
**Step 2: Write implementation**
|
||||
|
||||
Create `SportsTime/SportsTime/Core/Store/StoreManager.swift`:
|
||||
|
||||
@@ -458,19 +407,6 @@ final class StoreManager {
|
||||
}
|
||||
```
|
||||
|
||||
**Step 4: Run test to verify it passes**
|
||||
|
||||
Run: `xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' -only-testing:SportsTimeTests/StoreManagerTests test`
|
||||
|
||||
Expected: PASS
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add SportsTime/SportsTime/Core/Store/StoreManager.swift SportsTime/SportsTimeTests/Store/StoreManagerTests.swift
|
||||
git commit -m "feat(iap): add StoreManager with StoreKit 2 entitlement checking"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 5: Create ProBadge View
|
||||
@@ -531,13 +467,6 @@ extension View {
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add SportsTime/SportsTime/Features/Paywall/Views/ProBadge.swift
|
||||
git commit -m "feat(iap): add ProBadge view for locked feature indicators"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 6: Create PaywallView
|
||||
@@ -863,20 +792,13 @@ struct PricingOptionCard: View {
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add SportsTime/SportsTime/Features/Paywall/Views/PaywallView.swift
|
||||
git commit -m "feat(iap): add PaywallView with pricing options and purchase flow"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 7: Create ProGate View Modifier
|
||||
|
||||
**Files:**
|
||||
- Create: `SportsTime/SportsTime/Features/Paywall/ViewModifiers/ProGate.swift`
|
||||
- Test: `SportsTime/SportsTimeTests/Store/ProGateTests.swift`
|
||||
- Create: `SportsTime/SportsTimeTests/Store/ProGateTests.swift`
|
||||
|
||||
**Step 1: Write the test**
|
||||
|
||||
@@ -901,13 +823,7 @@ struct ProGateTests {
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' -only-testing:SportsTimeTests/ProGateTests test`
|
||||
|
||||
Expected: FAIL
|
||||
|
||||
**Step 3: Write minimal implementation**
|
||||
**Step 2: Write implementation**
|
||||
|
||||
Create `SportsTime/SportsTime/Features/Paywall/ViewModifiers/ProGate.swift`:
|
||||
|
||||
@@ -985,19 +901,6 @@ extension View {
|
||||
}
|
||||
```
|
||||
|
||||
**Step 4: Run test to verify it passes**
|
||||
|
||||
Run: `xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' -only-testing:SportsTimeTests/ProGateTests test`
|
||||
|
||||
Expected: PASS
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add SportsTime/SportsTime/Features/Paywall/ViewModifiers/ProGate.swift SportsTime/SportsTimeTests/Store/ProGateTests.swift
|
||||
git commit -m "feat(iap): add ProGate view modifier for feature gating"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 8: Create OnboardingPaywallView
|
||||
@@ -1318,23 +1221,16 @@ struct OnboardingPricingRow: View {
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add SportsTime/SportsTime/Features/Paywall/Views/OnboardingPaywallView.swift
|
||||
git commit -m "feat(iap): add OnboardingPaywallView with feature pages and pricing"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 9: Integrate StoreManager in App Lifecycle
|
||||
|
||||
**Files:**
|
||||
- Modify: `SportsTime/SportsTime/SportsTimeApp.swift:46-53` (add transaction listener)
|
||||
- Modify: `SportsTime/SportsTime/SportsTimeApp.swift`
|
||||
|
||||
**Step 1: Add transaction listener property and initialization**
|
||||
|
||||
In `SportsTimeApp.swift`, add after line 45 (after `sharedModelContainer`):
|
||||
In `SportsTimeApp.swift`, add after `sharedModelContainer` (around line 45):
|
||||
|
||||
```swift
|
||||
/// Task that listens for StoreKit transaction updates
|
||||
@@ -1393,25 +1289,12 @@ Update the `body` to show onboarding paywall:
|
||||
}
|
||||
```
|
||||
|
||||
**Step 5: Run full test suite**
|
||||
|
||||
Run: `xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' test`
|
||||
|
||||
Expected: All tests PASS
|
||||
|
||||
**Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add SportsTime/SportsTime/SportsTimeApp.swift
|
||||
git commit -m "feat(iap): integrate StoreManager in app lifecycle with onboarding paywall"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 10: Gate Trip Saving
|
||||
|
||||
**Files:**
|
||||
- Modify: `SportsTime/SportsTime/Features/Trip/Views/TripDetailView.swift:525-540`
|
||||
- Modify: `SportsTime/SportsTime/Features/Trip/Views/TripDetailView.swift`
|
||||
|
||||
**Step 1: Add saved trip count query**
|
||||
|
||||
@@ -1468,25 +1351,12 @@ Add sheet modifier to the view body (after existing sheets around line 93):
|
||||
}
|
||||
```
|
||||
|
||||
**Step 5: Run tests**
|
||||
|
||||
Run: `xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' test`
|
||||
|
||||
Expected: PASS
|
||||
|
||||
**Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add SportsTime/SportsTime/Features/Trip/Views/TripDetailView.swift
|
||||
git commit -m "feat(iap): gate trip saving to 1 trip for free users"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 11: Gate PDF Export
|
||||
|
||||
**Files:**
|
||||
- Modify: `SportsTime/SportsTime/Features/Trip/Views/TripDetailView.swift:72-78`
|
||||
- Modify: `SportsTime/SportsTime/Features/Trip/Views/TripDetailView.swift`
|
||||
|
||||
**Step 1: Modify export button in toolbar**
|
||||
|
||||
@@ -1512,25 +1382,12 @@ Replace the PDF export button (around line 72) with gated version:
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Run tests**
|
||||
|
||||
Run: `xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' test`
|
||||
|
||||
Expected: PASS
|
||||
|
||||
**Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add SportsTime/SportsTime/Features/Trip/Views/TripDetailView.swift
|
||||
git commit -m "feat(iap): gate PDF export behind Pro subscription"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 12: Gate Progress Tracking Tab
|
||||
|
||||
**Files:**
|
||||
- Modify: `SportsTime/SportsTime/Features/Home/Views/HomeView.swift:86-95`
|
||||
- Modify: `SportsTime/SportsTime/Features/Home/Views/HomeView.swift`
|
||||
|
||||
**Step 1: Add paywall state to HomeView**
|
||||
|
||||
@@ -1634,19 +1491,6 @@ Add after the existing sheet modifiers (around line 123):
|
||||
}
|
||||
```
|
||||
|
||||
**Step 5: Run tests**
|
||||
|
||||
Run: `xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' test`
|
||||
|
||||
Expected: PASS
|
||||
|
||||
**Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add SportsTime/SportsTime/Features/Home/Views/HomeView.swift
|
||||
git commit -m "feat(iap): gate Progress tab behind Pro subscription"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 13: Add Subscription Management to Settings
|
||||
@@ -1663,15 +1507,21 @@ Add new section after `aboutSection` (around line 173):
|
||||
subscriptionSection
|
||||
```
|
||||
|
||||
**Step 2: Implement subscription section**
|
||||
**Step 2: Add showPaywall state**
|
||||
|
||||
Add at top of SettingsView with other @State properties:
|
||||
|
||||
```swift
|
||||
@State private var showPaywall = false
|
||||
```
|
||||
|
||||
**Step 3: Implement subscription section**
|
||||
|
||||
Add the section implementation:
|
||||
|
||||
```swift
|
||||
// MARK: - Subscription Section
|
||||
|
||||
@State private var showPaywall = false
|
||||
|
||||
private var subscriptionSection: some View {
|
||||
Section {
|
||||
if StoreManager.shared.isPro {
|
||||
@@ -1748,32 +1598,27 @@ Add the section implementation:
|
||||
}
|
||||
```
|
||||
|
||||
**Step 3: Run tests**
|
||||
|
||||
Run: `xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' test`
|
||||
|
||||
Expected: PASS
|
||||
|
||||
**Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add SportsTime/SportsTime/Features/Settings/Views/SettingsView.swift
|
||||
git commit -m "feat(iap): add subscription management to Settings"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 14: Run Full Test Suite and Manual Verification
|
||||
## Task 14: Build, Test, and Fix Issues
|
||||
|
||||
**Step 1: Run all tests**
|
||||
**Step 1: Build the project**
|
||||
|
||||
```bash
|
||||
xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' build
|
||||
```
|
||||
|
||||
Fix any compilation errors that arise.
|
||||
|
||||
**Step 2: Run all tests**
|
||||
|
||||
```bash
|
||||
xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' test
|
||||
```
|
||||
|
||||
Expected: All tests PASS
|
||||
Fix any test failures.
|
||||
|
||||
**Step 2: Manual testing checklist**
|
||||
**Step 3: Manual testing checklist**
|
||||
|
||||
Test in Simulator with StoreKit configuration:
|
||||
|
||||
@@ -1794,7 +1639,7 @@ Test in Simulator with StoreKit configuration:
|
||||
- [ ] Settings shows "Manage Subscription" for Pro users
|
||||
- [ ] Restore Purchases works
|
||||
|
||||
**Step 3: Commit final state**
|
||||
**Step 4: Commit all changes**
|
||||
|
||||
```bash
|
||||
git add -A
|
||||
|
||||
Reference in New Issue
Block a user