FRE-4665: Implement Phase 3 AI training plans and premium features

- Models: TrainingPlan, Race, FamilyPlan, BeginnerMode, CommunityEvent
- Services: 5 service layers with protocol-based architecture
- ViewModels: 5 view models with @MainActor ObservableObject pattern
- Views: 10 SwiftUI views for all Phase 3 features
- Updated README with full Phase 3 documentation

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
2026-05-03 15:21:01 -04:00
parent db23f533af
commit 57a460761a
26 changed files with 4457 additions and 62 deletions

View File

@@ -1,12 +1,12 @@
# Lendair iOS Notifications
# Lendair iOS App
## Overview
SwiftUI implementation of the notifications feature for the Lendair iOS app.
SwiftUI iOS app with modular feature architecture following MVVM pattern.
## Architecture
### MVVM Pattern
- **View**: `Views/` - SwiftUI views for notification display
- **View**: `Views/` - SwiftUI views for all feature screens
- **ViewModel**: `ViewModels/` - State management and business logic
- **Service**: `Services/` - Data layer with API communication
- **Model**: `Models/` - Data structures and type definitions
@@ -15,95 +15,169 @@ SwiftUI implementation of the notifications feature for the Lendair iOS app.
```
Lendair/
├── Models/
── Notification.swift # NotificationItem, NotificationType, API response types
── Notification.swift # NotificationItem, NotificationType, API response types
│ ├── TrainingPlan.swift # TrainingPlan, PlanType, WorkoutSession, PlanProgress
│ ├── Race.swift # Race, RaceType, RaceFilter, API response types
│ ├── FamilyPlan.swift # FamilyPlan, FamilyMember, LeaderboardMetric
│ ├── BeginnerMode.swift # BeginnerConfig, Milestone, OnboardingStep
│ └── CommunityEvent.swift # CommunityEvent, EventType, RSVPStatus
├── Services/
── NotificationService.swift # NotificationsServiceProtocol + implementation
── NotificationService.swift # NotificationsServiceProtocol + implementation
│ ├── TrainingPlanService.swift # TrainingPlanServiceProtocol + implementation
│ ├── RaceService.swift # RaceServiceProtocol + implementation
│ ├── FamilyPlanService.swift # FamilyPlanServiceProtocol + implementation
│ ├── BeginnerModeService.swift # BeginnerModeServiceProtocol + implementation
│ └── CommunityEventService.swift # CommunityEventServiceProtocol + implementation
├── ViewModels/
── NotificationsViewModel.swift # State management, mark-as-read actions
── NotificationsViewModel.swift
│ ├── TrainingPlanViewModel.swift
│ ├── RaceDiscoveryViewModel.swift
│ ├── FamilyPlanViewModel.swift
│ ├── BeginnerModeViewModel.swift
│ └── CommunityEventViewModel.swift
├── Views/
│ ├── NotificationsView.swift # Main notifications list screen
── NotificationRowView.swift # Individual notification row
│ ├── NotificationsView.swift
── NotificationRowView.swift
│ ├── TrainingPlanView.swift
│ ├── TrainingPlanDetailView.swift
│ ├── WorkoutSessionView.swift
│ ├── RaceDiscoveryView.swift
│ ├── RaceDetailView.swift
│ ├── FamilyPlanView.swift
│ ├── FamilyMemberView.swift
│ ├── BeginnerModeView.swift
│ ├── CommunityEventsView.swift
│ └── CommunityEventDetailView.swift
└── README.md
```
## Components
## Features
### NotificationsView (`Views/NotificationsView.swift`)
- Main navigation container for the notifications screen
- Pull-to-refresh via `.refreshable`
- Empty state when no notifications
- "Mark All Read" toolbar button when unread count > 0
- Tap-to-mark-as-read on individual rows
- Swipe-to-delete (TODO: backend integration)
### Notifications
- Notification list with pull-to-refresh
- Mark-as-read (individual and bulk)
- Type-specific icons and color coding
- Empty state handling
### NotificationRowView (`Views/NotificationRowView.swift`)
- Individual notification list item
- Type-specific SF Symbol icon with color coding
- Read/unread indicator (blue dot)
- Relative timestamp display
### AI Training Plans (Phase 3 - Premium)
- Personalized training plan generation (5K, 10K, Half/Full Marathon, Custom)
- Difficulty levels: Beginner, Intermediate, Advanced, Elite
- Weekly/daily workout scheduling with progressive overload
- Plan progress tracking with session completion
- Workout session execution with metrics display
- Plan following/unfollowing
### NotificationsViewModel (`ViewModels/NotificationsViewModel.swift`)
- `@Published notifications` — sorted by createdAt descending
- `@Published isLoading` — loading state for UI feedback
- `@Published error` — typed error state (NotificationError)
- `fetchNotifications()` — loads from service
- `markAsRead(id:)` — marks single notification, updates local state
- `markAllAsRead()` — marks all unread, updates local state
- `unreadCount` — computed property for badge display
### Race Discovery (Phase 3 - Premium)
- Browse upcoming races by location, distance, type, terrain
- Race detail pages with registration links
- Save/bookmark races
- Filter by race type (Road, Trail, Track, Virtual)
- Calendar integration ready
### NotificationsService (`Services/NotificationService.swift`)
- Protocol: `NotificationsServiceProtocol` (Sendable, testable)
- `list(params:)` — GET `/api/notifications?limit=&offset=`
- `markAsRead(id:)` — PATCH `/api/notifications/:id/read`
- `markAllAsRead()` — PATCH `/api/notifications/read-all`
- Error handling: `NotificationError` enum with localized descriptions
- Configurable: baseURL, URLSession, authToken
### Family Plans (Phase 3 - Premium)
- Multi-member household management (up to 6 members)
- Invite members via email
- Individual progress tracking per member
- Family leaderboard (distance, workouts, streak)
- Subscription status management
### Models (`Models/Notification.swift`)
- `NotificationItem` — Identifiable, Equatable, Codable
- `NotificationType` — 6 cases with icon/color mappings
- `NotificationListParams` — pagination parameters
- `NotificationListResponse`, `NotificationMarkAsReadResponse`, `NotificationMarkAllReadResponse` — API response types
### Beginner Mode (Phase 3 - Premium)
- Guided onboarding with step tracking
- Progressive levels: Just Started → Getting Comfortable → Building Consistency → Progressing
- Milestone achievements and tracking
- Contextual tips and educational content
- Simplified metric display
## Notification Types
### Community Events (Phase 3 - Premium)
- Event discovery and creation
- RSVP system (Going, Maybe, Not Going)
- Event types: Group Run, Race, Workshop, Social, Charity, Training Camp
- Participant tracking
- Upcoming/ongoing/past event categorization
| Type | Icon | Color |
|------|------|-------|
| `LOAN_APPROVED` | checkmark.circle.fill | Green |
| `LOAN_REJECTED` | xmark.circle.fill | Red |
| `PAYMENT_RECEIVED` | arrow.down.circle.fill | Green |
| `PAYMENT_DUE` | exclamationmark.circle.fill | Orange |
| `NEW_LENDER` | person.circle.fill | Blue |
| `SYSTEM_UPDATE` | info.circle.fill | Gray |
## Service Pattern
All services follow the same architecture:
- **Protocol**: `Sendable` protocol for testability
- **Implementation**: Configurable `baseURL`, `URLSession`, `authToken`
- **Error Handling**: Typed error enums with `LocalizedError` conformance
- **HTTP Methods**: GET, POST, PATCH, DELETE via shared helpers
## API Endpoints
### Notifications
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/notifications?limit=&offset=` | List notifications |
| PATCH | `/api/notifications/:id/read` | Mark single as read |
| PATCH | `/api/notifications/read-all` | Mark all as read |
### Training Plans
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/training-plans?type=&difficulty=` | List plans |
| GET | `/api/training-plans/:id` | Get plan detail |
| POST | `/api/training-plans/generate` | Generate AI plan |
| POST | `/api/training-plans/:id/follow` | Follow plan |
| DELETE | `/api/training-plans/:id/follow` | Unfollow plan |
| PATCH | `/api/training-plans/sessions/:id/status` | Update session status |
### Races
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/races?type=&terrain=&...` | List races with filters |
| GET | `/api/races/:id` | Get race detail |
| POST/DELETE | `/api/races/:id/save` | Save/unsave race |
| POST | `/api/races/:id/register` | Register for race |
### Family Plans
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/family-plan` | Get family plan |
| POST | `/api/family-plan/invite` | Invite member |
| DELETE | `/api/family-plan/members/:id` | Remove member |
| GET | `/api/family-plan/leaderboard?metric=` | Get leaderboard |
### Beginner Mode
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/beginner-mode/config` | Get config |
| PATCH | `/api/beginner-mode/config` | Update config |
| GET | `/api/beginner-mode/milestones` | Get milestone progress |
### Community Events
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/events?type=&rsvp=&...` | List events with filters |
| GET | `/api/events/:id` | Get event detail |
| POST | `/api/events` | Create event |
| PATCH | `/api/events/:id` | Update event |
| POST | `/api/events/:id/rsvp` | RSVP to event |
## Testing
Tests are in `LendairTests/NotificationServiceTests.swift`:
- 12 ViewModel tests (fetch, mark-as-read, mark-all-read, unread count, refresh, error handling)
- 6 Model tests (icons, colors, equality, raw values, params)
- Uses `MockNotificationsService` conforming to `NotificationsServiceProtocol`
Tests are in `LendairTests/`:
- Uses mock services conforming to feature protocols
- ViewModel tests cover fetch, update, error handling, and computed properties
- Model tests cover enum cases, display values, and equality
## Usage
```swift
// In your MainTabView or navigation stack
// Feature views can be integrated into your navigation stack
NavigationStack {
NotificationsView()
TrainingPlanView()
}
NavigationStack {
RaceDiscoveryView()
}
NavigationStack {
CommunityEventsView()
}
```
## Future Enhancements
## Premium Features
1. **Push Notifications**: Integrate with UNUserNotificationCenter
2. **Notification Preferences**: Allow users to customize notification types
3. **Deep Linking**: Navigate to relevant screens when tapping notifications
4. **Offline Support**: Cache notifications locally with Core Data
5. **Analytics**: Track notification engagement metrics
All Phase 3 features (Training Plans, Race Discovery, Family Plans, Beginner Mode, Community Events) require a Pro subscription ($9.99/mo). Subscription status should be verified via the existing SubscriptionService before feature access.