Files
Reflect/PROJECT_OVERVIEW.md
Trey t 0442eab1f8 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>
2026-02-26 11:47:16 -06:00

198 lines
5.7 KiB
Markdown

# Reflect - iOS Mood Tracking App
## Overview
**Reflect** is a daily mood tracking iOS application that allows users to rate their emotional state each day on a 5-point scale (Horrible, Bad, Average, Good, Great) and visualize patterns over time through multiple view modes.
## Core Features
- **Daily Mood Tracking**: Rate your day on a 5-point scale
- **Multiple View Modes**: Day (chronological list), Month (calendar grid), Year (aggregate stats)
- **Customization**: Themes, color schemes, icon packs, notification personalities
- **Widgets**: iOS home screen widgets showing recent moods
- **Local Notifications**: Daily reminders with action buttons for quick mood entry
- **Data Export/Import**: CSV format for data portability
- **Subscription Model**: 30-day free trial, then monthly/yearly subscriptions
- **Localization**: English and Spanish
---
## Architecture
**Pattern**: MVVM (Model-View-ViewModel) with SwiftUI
### Project Structure
```
Reflect/
├── Shared/ # Core app code
│ ├── Models/ # Data models (Mood, Theme, MoodTintable, etc.)
│ ├── Views/ # SwiftUI views organized by feature
│ │ ├── DayView/ # Chronological list view
│ │ ├── MonthView/ # Calendar grid view
│ │ ├── YearView/ # Yearly statistics view
│ │ ├── CustomizeView/ # Settings and customization
│ │ └── Components/ # Reusable UI components
│ ├── Persisence/ # Core Data persistence layer
│ ├── Onboarding/ # First-run experience
│ └── Protocols/ # Protocol definitions
├── ReflectWidget/ # iOS Widget Extension (3 widget types)
├── en.lproj/ # English localization
├── es.lproj/ # Spanish localization
└── Tests iOS/ # Test targets
```
---
## Key Files
### App Entry
| File | Purpose |
|------|---------|
| `ReflectApp.swift` | Main app entry, Core Data setup, IAP manager, tab navigation |
### Data Layer
| File | Purpose |
|------|---------|
| `Reflect.xcdatamodeld` | Core Data model with `MoodEntry` entity |
| `Persistence.swift` | Core Data stack, App Group container |
| `PersistenceGET.swift` | Fetch operations |
| `PersistenceADD.swift` | Create/fill missing entries |
| `PersistenceUPDATE.swift` | Update operations |
| `PersistenceDELETE.swift` | Delete operations |
### Main Views
| File | Purpose |
|------|---------|
| `MainTabView.swift` | Root navigation (Day, Month, Year, Customize tabs) |
| `DayView.swift` | Chronological mood list with edit/delete |
| `MonthView.swift` | Calendar grid with color-coded moods |
| `YearView.swift` | Aggregate yearly statistics |
| `CustomizeView.swift` | Theme, colors, icons, shape settings |
### Services
| File | Purpose |
|------|---------|
| `IAPManager.swift` | StoreKit 2 subscriptions, 30-day trial |
| `LocalNotification.swift` | Daily reminders with quick actions |
| `BGTask.swift` | Background task for filling missing dates |
| `EventLogger.swift` | Analytics event tracking |
---
## Data Models
### MoodEntry (Core Data Entity)
```
- moodValue: Int16 (0-4 for mood ratings)
- forDate: Date (the day being rated)
- timestamp: Date (when entry was created)
- weekDay: Int16 (1-7)
- canEdit, canDelete: Boolean
- entryType: Int16 (header, list, filled-in-missing)
```
### Mood Enum
```swift
enum Mood: Int {
case horrible = 0
case bad = 1
case average = 2
case good = 3
case great = 4
case missing = 5
case placeholder = 6
}
```
---
## Customization System
### Themes (`Theme.swift`)
- System, iFeel (gradient), Dark, Light
- Protocol: `Themeable`
### Color Schemes (`MoodTintable.swift`)
- Default, Neon, Pastel, Custom (user-defined)
- Each mood has primary and secondary colors
### Icon Packs (`MoodImagable.swift`)
- FontAwesome, Emoji, Hand Emoji
- Protocol: `MoodImagable`
### Shapes
- Circle, Square, Diamond for calendar visualization
### Notification Personalities (`PersonalityPackable.swift`)
- "Nice": Friendly text
- "Rude": Sarcastic/aggressive text
---
## Widget System
Three widget types in `ReflectWidget/`:
1. **ReflectWidget**: Small/Medium/Large showing recent moods
2. **ReflectGraphicWidget**: Small widget with mood graphic
3. **ReflectIconWidget**: Custom icon widget
Data shared via App Groups: `group.com.88oakapps.reflect`
---
## Dependencies
### Apple Frameworks
- SwiftUI, CoreData, WidgetKit, StoreKit, UserNotifications, CloudKit, BackgroundTasks
### Third-Party
- CloudKitSyncMonitor
- Firebase (GoogleService-Info.plist)
---
## Configuration
### App Groups
- Production: `group.com.88oakapps.reflect`
- Debug: `group.com.88oakapps.reflect.debug`
### Background Tasks
- Identifier: `com.88oak.Reflect.dbUpdateMissing`
### StoreKit Products
- Monthly subscription
- Yearly subscription
- 30-day free trial
---
## Data Flow
```
User Input → Persistence (Core Data) → ViewModel Update → SwiftUI Re-render
Widget Update (WidgetCenter.shared.reloadAllTimelines())
```
---
## Localization
| Language | File |
|----------|------|
| English | `en.lproj/Localizable.strings` |
| Spanish | `es.lproj/Localizable.strings` |
Covers: Onboarding, mood names, UI labels, notifications, settings
---
## Notable Implementation Details
1. **Automatic Missing Date Fill**: Creates placeholder entries for days without ratings
2. **Entry Types**: `header`, `listView`, `filledInMissing` - tracks how entries were created
3. **Day Filtering**: Users can filter which weekdays appear in visualizations
4. **CSV Export**: Full data portability with all metadata preserved