SelfieCam/PRD.md

613 lines
19 KiB
Markdown

# Product Requirements Document (PRD)
## SelfieCam - Professional Selfie Camera App
**Version:** 1.0
**Platform:** iOS 18.0+
**Language:** Swift 6 with strict concurrency
**Framework:** SwiftUI
---
## Executive Summary
SelfieCam is a professional-grade selfie camera app featuring a customizable screen-based ring light overlay, premium camera controls, and beautiful branding. The app targets content creators, makeup artists, video call professionals, and anyone who needs flattering lighting for selfies.
---
## Target Audience
- Content creators and influencers
- Makeup artists and beauty professionals
- Video call and streaming professionals
- Casual users seeking better selfie lighting
- Portrait photographers needing on-the-go lighting
---
## Technical Requirements
### Platform & Tools
| Requirement | Specification |
|-------------|---------------|
| iOS Deployment Target | iOS 18.0+ |
| Swift Version | Swift 6 with strict concurrency checking |
| UI Framework | SwiftUI (primary) |
| Persistence | iCloud via CloudSyncManager |
| Subscriptions | RevenueCat SDK |
| Camera | MijickCamera framework |
| Design System | Bedrock (local package) |
### Architecture Principles
1. **Protocol-Oriented Programming (POP)** - All shared capabilities defined via protocols before concrete types
2. **MVVM-lite** - Views are "dumb" renderers; all logic lives in `@Observable` view models
3. **Bedrock Design System** - Centralized design tokens, no magic numbers
- Settings layout contract: `SettingsCard` owns horizontal insets, custom rows use `SettingsCardRow`, and in-card separators use `SettingsDivider`
4. **Full Accessibility** - Dynamic Type, VoiceOver labels/hints/traits/announcements
5. **Modern Swift & SwiftUI** - Swift 6 concurrency, `@MainActor`, modern APIs
6. **Testable & Reusable Design** - Protocols enable mocking and future package extraction
---
## Feature Requirements
### FR-100: Core Camera System
#### FR-101: Camera Preview
- **Priority:** P0 (Critical)
- **Description:** Full-screen camera preview with real-time display
- **Acceptance Criteria:**
- [ ] Smooth, low-latency camera preview
- [ ] Supports both front and back camera
- [ ] Camera switching via UI button
- [ ] Prevents screen dimming during camera use
- [ ] Uses MijickCamera framework for SwiftUI-native handling
#### FR-102: Photo Capture
- **Priority:** P0 (Critical)
- **Description:** High-quality photo capture with multiple trigger methods
- **Acceptance Criteria:**
- [ ] Capture button triggers photo capture
- [ ] Volume buttons trigger capture (hardware shutter)
- [ ] Camera Control button full press triggers capture (iPhone 16+)
- [ ] Post-capture preview with share functionality
- [ ] Auto-save option to Photo Library
#### FR-103: Zoom Control
- **Priority:** P1 (High)
- **Description:** Pinch-to-zoom gesture support
- **Acceptance Criteria:**
- [ ] Smooth pinch-to-zoom interpolation
- [ ] Zoom level persists during session
- [ ] Zoom resets on camera switch (optional behavior)
#### FR-104: Camera Control Button Support
- **Priority:** P2 (Medium)
- **Description:** iPhone 16+ Camera Control button integration
- **Acceptance Criteria:**
- [ ] Full press triggers photo capture
- [ ] Light press locks focus/exposure (if API available)
- [ ] Uses `AVCaptureEventInteraction` (iOS 17.2+)
- **Known Limitations:**
- Light press may be restricted to first-party apps
- Swipe-to-zoom is Apple-exclusive API
---
### FR-200: Ring Light System
#### FR-201: Ring Light Overlay
- **Priority:** P0 (Critical)
- **Description:** Screen-based ring light effect using colored border
- **Acceptance Criteria:**
- [ ] Configurable border thickness (10-120pt range)
- [ ] Border renders around camera preview
- [ ] Quick enable/disable toggle
- [ ] Smooth transition animations
#### FR-202: Ring Light Colors
- **Priority:** P0 (Critical)
- **Description:** Multiple color temperature presets
- **Free Colors:**
- Pure White
- Warm Cream
- **Premium Colors:**
- Ice Blue
- Soft Pink
- Warm Amber
- Cool Lavender
- **Acceptance Criteria:**
- [ ] Color picker UI with visual swatches
- [ ] Premium colors show lock indicator for free users
- [ ] Premium users can access custom color picker
#### FR-203: Ring Light Brightness
- **Priority:** P1 (High)
- **Description:** Adjustable ring light opacity/brightness
- **Acceptance Criteria:**
- [ ] Slider control for brightness (10%-100%)
- [ ] Real-time preview of brightness changes
- [ ] Debounced saving (300ms) to prevent excessive iCloud writes
---
### FR-300: Flash System
#### FR-301: Flash Modes
- **Priority:** P1 (High)
- **Description:** Multiple flash options for photo capture
- **Modes:**
- Off
- On
- Auto
- **Acceptance Criteria:**
- [ ] Mode selector in camera UI
- [ ] Flash fires during capture when enabled
- [ ] Auto mode uses ambient light detection
#### FR-302: Front Flash
- **Priority:** P1 (High)
- **Description:** Screen brightness-based flash for front camera
- **Acceptance Criteria:**
- [ ] Screen brightness increases to maximum during front camera capture
- [ ] Returns to original brightness after capture
#### FR-303: Flash Sync (Premium)
- **Priority:** P2 (Medium)
- **Description:** Match flash color with ring light color
- **Acceptance Criteria:**
- [ ] Premium feature with appropriate gating
- [ ] Screen color matches current ring light color during flash
- [ ] Toggle in settings to enable/disable
---
### FR-400: Self-Timer System
#### FR-401: Timer Options
- **Priority:** P1 (High)
- **Description:** Countdown timer before photo capture
- **Free Options:**
- Off
- 3 seconds
- **Premium Options:**
- 5 seconds
- 10 seconds
- **Acceptance Criteria:**
- [ ] Visual countdown indicator
- [ ] Audio feedback (optional)
- [ ] Cancel option during countdown
- [ ] VoiceOver announces countdown
---
### FR-500: Display & Enhancement Features
#### FR-501: Grid Overlay
- **Priority:** P2 (Medium)
- **Description:** Rule-of-thirds composition guide
- **Acceptance Criteria:**
- [ ] Toggle in settings to show/hide
- [ ] Semi-transparent grid lines
- [ ] Does not interfere with tap gestures
#### FR-502: True Mirror Mode (Premium)
- **Priority:** P2 (Medium)
- **Description:** Horizontally flipped preview like a real mirror
- **Acceptance Criteria:**
- [ ] Premium feature with appropriate gating
- [ ] Live preview is mirrored
- [ ] Captured photo reflects mirror setting
#### FR-503: Skin Smoothing (Premium)
- **Priority:** P2 (Medium)
- **Description:** Real-time subtle skin smoothing filter
- **Acceptance Criteria:**
- [ ] Premium feature with appropriate gating
- [ ] Toggle in settings
- [ ] Subtle, natural-looking effect
- [ ] Applied to both preview and captured photo
#### FR-504: Center Stage (Premium)
- **Priority:** P3 (Low)
- **Description:** Automatic subject tracking/centering
- **Acceptance Criteria:**
- [ ] Premium feature with appropriate gating
- [ ] Uses Apple's Center Stage API if available
- [ ] Graceful fallback on unsupported devices
---
### FR-600: Photo Quality Options
#### FR-601: HDR Mode (Premium)
- **Priority:** P2 (Medium)
- **Description:** High Dynamic Range photo capture
- **Modes:**
- Off
- On
- Auto
- **Acceptance Criteria:**
- [ ] Premium feature with appropriate gating
- [ ] HDR indicator in UI when enabled
- [ ] Uses system HDR capture capabilities
#### FR-602: Photo Quality Settings (Premium)
- **Priority:** P2 (Medium)
- **Description:** Resolution/quality selection
- **Options:**
- Medium (Free)
- High (Premium)
- **Acceptance Criteria:**
- [ ] Premium feature for High quality
- [ ] Clear indication of current quality setting
- [ ] Maximum resolution output for High setting
---
### FR-700: Settings & Synchronization
#### FR-701: iCloud Sync
- **Priority:** P1 (High)
- **Description:** Automatic settings synchronization across devices
- **Acceptance Criteria:**
- [ ] Available to all users (free and premium)
- [ ] Real-time sync status with last sync timestamp
- [ ] Manual "Sync Now" option
- [ ] Uses Bedrock's CloudSyncManager
#### FR-702: Settings Persistence
- **Priority:** P0 (Critical)
- **Description:** All user preferences stored in SyncedSettings model
- **Settings Include:**
- Ring light: size, color ID, custom color RGB, opacity, enabled
- Camera: position, flash mode, HDR mode, photo quality
- Display: mirror flip, skin smoothing, grid visible
- Capture: timer, capture mode, auto-save
- Premium features: flash sync, center stage
- **Acceptance Criteria:**
- [ ] Settings persist across app launches
- [ ] Debounced saves for slider values
- [ ] Settings sync via iCloud
---
### FR-800: Branding & Launch Experience
#### FR-801: Animated Launch Screen
- **Priority:** P2 (Medium)
- **Description:** Beautiful branded launch experience
- **Acceptance Criteria:**
- [ ] Animated launch with configurable duration
- [ ] Customizable colors, patterns, and layout
- [ ] Seamless transition to main app
- [ ] Uses Bedrock's LaunchScreenConfig
#### FR-802: App Icon
- **Priority:** P2 (Medium)
- **Description:** Consistent branded app icon
- **Acceptance Criteria:**
- [ ] Generated via Bedrock icon system
- [ ] Matches launch screen branding
- [ ] Icon generator available in DEBUG builds
---
### FR-900: Premium & Monetization
#### FR-901: Freemium Model
- **Priority:** P0 (Critical)
- **Description:** Free tier with optional Pro subscription
- **Free Features:**
- Basic ring light (2 colors)
- Photo capture
- 3-second timer
- Grid overlay
- Zoom
- iCloud sync
- **Premium Features:**
- Full color palette + custom colors
- HDR mode
- High quality photos
- Flash sync
- True mirror mode
- Skin smoothing
- Center stage
- Extended timers (5s, 10s)
#### FR-902: RevenueCat Integration
- **Priority:** P0 (Critical)
- **Description:** Subscription management via RevenueCat
- **Acceptance Criteria:**
- [ ] PremiumManager wraps RevenueCat SDK
- [ ] PremiumGate utility for consistent feature gating
- [ ] Entitlement named `pro`
- [ ] Settings automatically fall back to free defaults when not premium
#### FR-903: Paywall
- **Priority:** P1 (High)
- **Description:** Pro subscription purchase flow
- **Acceptance Criteria:**
- [ ] Clear presentation of premium features
- [ ] Monthly and yearly subscription options
- [ ] Restore purchases functionality
- [ ] Accessible and localized
#### FR-904: Debug Premium Mode
- **Priority:** P3 (Low)
- **Description:** Testing premium features without subscription
- **Acceptance Criteria:**
- [ ] Environment variable `ENABLE_DEBUG_PREMIUM=1`
- [ ] Only works in DEBUG builds
- [ ] Unlocks all premium features for testing
---
## Non-Functional Requirements
### NFR-100: Accessibility
#### NFR-101: VoiceOver Support
- **Priority:** P0 (Critical)
- **Acceptance Criteria:**
- [ ] All interactive elements have meaningful `.accessibilityLabel()`
- [ ] Dynamic state uses `.accessibilityValue()`
- [ ] Actions described with `.accessibilityHint()`
- [ ] Appropriate traits via `.accessibilityAddTraits()`
- [ ] Decorative elements hidden with `.accessibilityHidden(true)`
- [ ] Important events trigger accessibility announcements
#### NFR-102: Dynamic Type
- **Priority:** P0 (Critical)
- **Acceptance Criteria:**
- [ ] All text supports Dynamic Type
- [ ] Custom dimensions use `@ScaledMetric`
- [ ] UI remains usable at largest text sizes
---
### NFR-200: Performance
#### NFR-201: Camera Performance
- **Priority:** P0 (Critical)
- **Acceptance Criteria:**
- [ ] Smooth, real-time camera preview (30+ fps)
- [ ] Minimal latency on capture
- [ ] No UI blocking during photo processing
#### NFR-202: Battery Efficiency
- **Priority:** P1 (High)
- **Acceptance Criteria:**
- [ ] Efficient camera usage
- [ ] Debounced saves reduce iCloud writes
- [ ] Screen dimming prevention is intentional (user is actively using camera)
---
### NFR-300: Privacy & Security
#### NFR-301: Data Collection
- **Priority:** P0 (Critical)
- **Acceptance Criteria:**
- [ ] No data collection
- [ ] No analytics
- [ ] No tracking
- [ ] Privacy policy reflects minimal data usage
#### NFR-302: API Key Security
- **Priority:** P0 (Critical)
- **Acceptance Criteria:**
- [ ] API keys stored in `.xcconfig` files
- [ ] `Secrets.xcconfig` is gitignored
- [ ] Template file provided for setup
---
### NFR-400: Localization
#### NFR-401: String Catalogs
- **Priority:** P1 (High)
- **Acceptance Criteria:**
- [ ] Uses `.xcstrings` files for localization
- [ ] All user-facing strings in String Catalog
- [ ] Minimum supported languages: English (en), Spanish-Mexico (es-MX), French-Canada (fr-CA)
---
## Project Structure
```
SelfieCam/
├── App/ # App entry point with launch screen
├── Configuration/ # xcconfig files (API keys)
├── Features/
│ ├── Camera/ # Main camera UI
│ │ ├── ContentView.swift # Main screen coordinator
│ │ ├── Views/ # Camera UI components
│ │ │ ├── CustomCameraScreen.swift
│ │ │ ├── RingLightOverlay.swift
│ │ │ ├── CaptureButton.swift
│ │ │ ├── ExpandableControlsPanel.swift
│ │ │ ├── CaptureEventInteraction.swift
│ │ │ └── ...
│ │ ├── GridOverlay.swift
│ │ └── PostCapturePreviewView.swift
│ ├── Paywall/ # Pro subscription flow
│ │ └── ProPaywallView.swift
│ └── Settings/ # Configuration screens
│ ├── SettingsView.swift
│ ├── SettingsViewModel.swift
│ └── ...
├── Shared/
│ ├── BrandingConfig.swift # App icon & launch screen config
│ ├── DesignConstants.swift # Design tokens (uses Bedrock)
│ ├── Color+Extensions.swift # Ring light color presets
│ ├── Models/ # Data models
│ │ ├── CameraFlashMode.swift
│ │ ├── CameraHDRMode.swift
│ │ ├── PhotoQuality.swift
│ │ └── ...
│ ├── Protocols/ # Shared protocols
│ │ ├── RingLightConfigurable.swift
│ │ ├── CaptureControlling.swift
│ │ ├── CaptureEventHandling.swift
│ │ └── PremiumManaging.swift
│ ├── Premium/ # Subscription management
│ │ └── PremiumManager.swift
│ ├── Services/ # App services
│ │ └── PhotoLibraryService.swift
│ └── Storage/ # Persistence
│ └── SyncedSettings.swift
└── Resources/ # Assets, localization
├── Assets.xcassets/
│ ├── AppIcon.appiconset/
│ ├── LaunchBackground.colorset/
│ └── ...
└── Localizable.xcstrings
```
---
## Dependencies
| Dependency | Purpose | Integration |
|------------|---------|-------------|
| **Bedrock** | Design system, branding, cloud sync | Local Swift package |
| **MijickCamera** | Camera capture and preview | SPM dependency |
| **RevenueCat** | Subscription management | SPM dependency |
---
## Premium Feature Gating Pattern
All premium features use centralized `PremiumGate` utility:
```swift
// Getter pattern - returns free default if not premium
var isMirrorFlipped: Bool {
get { PremiumGate.get(cloudSync.data.isMirrorFlipped, default: false, isPremium: isPremiumUnlocked) }
set {
guard PremiumGate.canSet(isPremium: isPremiumUnlocked) else { return }
updateSettings { $0.isMirrorFlipped = newValue }
}
}
```
---
## Premium Feature Matrix
| Feature | Free Value | Premium Value |
|---------|-----------|---------------|
| Ring light colors | Pure White, Warm Cream | All presets + custom |
| Timer options | Off, 3s | Off, 3s, 5s, 10s |
| Photo quality | Medium | Medium, High |
| HDR mode | Off | Off, On, Auto |
| True mirror | Off | Configurable |
| Skin smoothing | Off | Configurable |
| Flash sync | Off | Configurable |
| Center stage | Off | Configurable |
---
## Known Limitations
### Camera Control Button Light Press
**Status:** Not Working - Needs Investigation
The Camera Control button (iPhone 16+) full press works for photo capture, but the light press (secondary action) does not work.
**What Works:**
- Camera Control full press → triggers photo capture
- Volume up/down → triggers capture
**What Doesn't Work:**
- Camera Control light press → no event received
- Camera Control swipe gestures (zoom) → Apple-exclusive API
**Possible Causes:**
1. Light press may be restricted to first-party apps
2. MijickCamera session may interfere with light press detection
3. Accessibility settings may need explicit enablement
**User Workaround:**
Check Settings > Accessibility > Camera Control:
- Ensure Camera Control is enabled
- Ensure Light-Press is turned ON
- Adjust Light-Press Force if needed
---
## Future Enhancements
Potential areas for expansion:
- [ ] Real-time filters (beauty, color grading)
- [ ] Gesture-based capture (smile detection)
- [ ] Widget for quick camera access
- [ ] Apple Watch remote trigger
- [ ] Export presets (aspect ratios, watermarks)
- [ ] Social sharing integrations
- [ ] Camera Control button swipe-to-zoom (if Apple makes API public)
---
## Required Permissions
| Permission | Reason |
|------------|--------|
| Camera | Photo preview and capture |
| Photo Library | Save captured photos |
| Microphone | May be requested by camera framework (not actively used) |
| iCloud | Settings synchronization (optional) |
---
## Development Setup
### 1. Clone and Configure
```bash
git clone https://github.com/yourusername/SelfieCam.git
cd SelfieCam
cp SelfieCam/Configuration/Secrets.xcconfig.template SelfieCam/Configuration/Secrets.xcconfig
```
### 2. Add API Key
Edit `Secrets.xcconfig`:
```
REVENUECAT_API_KEY = appl_your_actual_api_key_here
```
### 3. RevenueCat Setup
1. Create RevenueCat account and project
2. Connect to App Store Connect
3. Create products and entitlement named `pro`
4. Copy Public App-Specific API Key to `Secrets.xcconfig`
### 4. Test Premium Features
Set environment variable in scheme:
- **Name:** `ENABLE_DEBUG_PREMIUM`
- **Value:** `1`
---
## Code Quality Standards
- **No magic numbers**: All values from Design constants
- **Full accessibility**: Every interactive element has VoiceOver support
- **Protocol-first**: Shared behavior defined via protocols
- **Separation of concerns**: Views are dumb, ViewModels contain logic
- **Modern APIs**: Swift 6, async/await, @Observable
- **Documentation**: Code comments, README, PRD
---
*This PRD serves as the primary requirements document for SelfieCam development.*