# 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
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.*
