Add Phase 2 community features: clubs and challenges (FRE-4664)

Implement full MVVM stack for two new community features:

Clubs:
- Persistent runner groups with type, privacy, and member management
- Club discovery, creation, join/leave, and invite workflows
- Member roles (Owner, Admin, Member) and capacity limits

Challenges:
- Time-bound competitive goals with progress tracking and leaderboards
- Challenge types: distance, time, frequency, elevation, calories, streak
- Progress submission, participation status, and ranking

Files:
- Models: Club.swift, Challenge.swift
- Services: ClubService.swift, ChallengeService.swift
- ViewModels: ClubViewModel.swift, ChallengeViewModel.swift
- Views: ClubsView.swift, ClubDetailView.swift, ChallengesView.swift, ChallengeDetailView.swift
- Tests: ClubServiceTests.swift, ChallengeServiceTests.swift
- Updated README.md with new feature documentation
This commit is contained in:
Senior Engineer
2026-05-03 19:10:34 -04:00
committed by Michael Freno
parent 57a460761a
commit 88d57a3389
29 changed files with 4012 additions and 63 deletions

View File

@@ -20,21 +20,27 @@ Lendair/
│ ├── Race.swift # Race, RaceType, RaceFilter, API response types
│ ├── FamilyPlan.swift # FamilyPlan, FamilyMember, LeaderboardMetric
│ ├── BeginnerMode.swift # BeginnerConfig, Milestone, OnboardingStep
── CommunityEvent.swift # CommunityEvent, EventType, RSVPStatus
── CommunityEvent.swift # CommunityEvent, EventType, RSVPStatus
│ ├── Club.swift # Club, ClubType, ClubPrivacy, MembershipStatus, ClubMember
│ └── Challenge.swift # Challenge, ChallengeType, ChallengeStatus, LeaderboardEntry
├── Services/
│ ├── NotificationService.swift # NotificationsServiceProtocol + implementation
│ ├── TrainingPlanService.swift # TrainingPlanServiceProtocol + implementation
│ ├── RaceService.swift # RaceServiceProtocol + implementation
│ ├── FamilyPlanService.swift # FamilyPlanServiceProtocol + implementation
│ ├── BeginnerModeService.swift # BeginnerModeServiceProtocol + implementation
── CommunityEventService.swift # CommunityEventServiceProtocol + implementation
── CommunityEventService.swift # CommunityEventServiceProtocol + implementation
│ ├── ClubService.swift # ClubServiceProtocol + implementation
│ └── ChallengeService.swift # ChallengeServiceProtocol + implementation
├── ViewModels/
│ ├── NotificationsViewModel.swift
│ ├── TrainingPlanViewModel.swift
│ ├── RaceDiscoveryViewModel.swift
│ ├── FamilyPlanViewModel.swift
│ ├── BeginnerModeViewModel.swift
── CommunityEventViewModel.swift
── CommunityEventViewModel.swift
│ ├── ClubViewModel.swift
│ └── ChallengeViewModel.swift
├── Views/
│ ├── NotificationsView.swift
│ ├── NotificationRowView.swift
@@ -47,7 +53,11 @@ Lendair/
│ ├── FamilyMemberView.swift
│ ├── BeginnerModeView.swift
│ ├── CommunityEventsView.swift
── CommunityEventDetailView.swift
── CommunityEventDetailView.swift
│ ├── ClubsView.swift
│ ├── ClubDetailView.swift
│ ├── ChallengesView.swift
│ └── ChallengeDetailView.swift
└── README.md
```
@@ -95,6 +105,24 @@ Lendair/
- Participant tracking
- Upcoming/ongoing/past event categorization
### Clubs (Phase 2 - Community)
- Persistent community groups for runners and fitness enthusiasts
- Club types: Running, Walking, Cycling, Triathlon, CrossFit, General Fitness
- Privacy levels: Public, Private, Invitation Only
- Member management with roles (Owner, Admin, Member)
- Invite members via email
- Club rules and capacity limits
- Discover clubs by type, location, and privacy
### Challenges (Phase 2 - Community)
- Time-bound competitive goals with progress tracking
- Challenge types: Distance, Time, Frequency, Elevation, Calories, Streak
- Real-time leaderboard with rankings
- Progress submission and percentage tracking
- Join/leave challenges
- Create custom challenges with rules and targets
- Active/upcoming/completed challenge categorization
## Service Pattern
All services follow the same architecture:
@@ -154,23 +182,48 @@ All services follow the same architecture:
| PATCH | `/api/events/:id` | Update event |
| POST | `/api/events/:id/rsvp` | RSVP to event |
### Clubs
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/clubs?type=&privacy=&...` | List clubs with filters |
| GET | `/api/clubs/:id` | Get club detail with members |
| POST | `/api/clubs` | Create club |
| PATCH | `/api/clubs/:id` | Update club |
| POST | `/api/clubs/:id/join` | Join club |
| POST | `/api/clubs/:id/leave` | Leave club |
| POST | `/api/clubs/:id/invite` | Invite member by email |
| DELETE | `/api/clubs/:id/members/:memberId` | Remove member |
### Challenges
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/challenges?type=&status=&...` | List challenges with filters |
| GET | `/api/challenges/:id` | Get challenge detail with participants |
| POST | `/api/challenges` | Create challenge |
| PATCH | `/api/challenges/:id` | Update challenge |
| POST | `/api/challenges/:id/join` | Join challenge |
| POST | `/api/challenges/:id/leave` | Leave challenge |
| GET | `/api/challenges/:id/leaderboard` | Get challenge leaderboard |
| POST | `/api/challenges/:id/progress` | Submit progress |
## Testing
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
- Model tests cover enum cases, display values, equality, and computed properties
- Available test files: `NotificationServiceTests.swift`, `ClubServiceTests.swift`, `ChallengeServiceTests.swift`
## Usage
```swift
// Feature views can be integrated into your navigation stack
NavigationStack {
TrainingPlanView()
ClubsView()
}
NavigationStack {
RaceDiscoveryView()
ChallengesView()
}
NavigationStack {