> ## Documentation Index
> Fetch the complete documentation index at: https://docs.swiftaiboilerplate.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Feature Settings Module

> The **FeatureSettings** module provides settings management and beautiful paywall UI.

<Info>
  **Complete technical documentation:** See `docs/modules/Feature.Settings.md` in the project.
</Info>

## What's new in v2.2

* **`SettingsView.swift` is a ≤ 125-line composition root.** Every section lives in its own file under `Views/Settings/*.swift` (appearance, privacy, notifications, subscription, legal, AI, accessibility, about, and so on). Account sign in/out is handled in the view-model code (`ViewModels/SettingsViewModel+Account.swift`), not a standalone section view. The public entry point is unchanged; downstream customisations that used to edit one giant file now edit the matching section file.
* **Localized error surface.** Error call sites in this module use `AppError.localizedUserMessage` (en + es) from the Localization package, which FeatureSettings now links directly.
* **Paywall CTAs use the standard system styles**: `.buttonStyle(.borderedProminent)` for the primary CTA and `.bordered` for the secondary. If you were styling paywall buttons via `.background()`, switch to `.tint(YourColor)` on the standard styles so Liquid Glass handles the surface correctly on iOS 26.
* Profile, EmailSignUp, and related screens in the app target were split the same way. Check the `SwiftAIBoilerplatePro/AppShell/Profile/` and `SwiftAIBoilerplatePro/AppShell/Auth/` subfolders if a previous customisation disappears from the top-level file.

## Purpose

FeatureSettings module handles:

* **Settings UI** - User preferences management
* **Paywall** - Beautiful subscription screen
* **Theme Selection** - 5 built-in themes
* **Privacy Controls** - Diagnostics, notifications
* **Account Management** - Sign out, delete account

## Key Components

### SettingsViewModel

Manages app-wide settings:

```swift theme={null}
@MainActor
@Observable
public final class SettingsViewModel {
    public var theme: SettingsDTO.Theme
    public var shareDiagnostics: Bool
    public var notificationsEnabled: Bool
    public var hapticsEnabled: Bool
    public var reduceMotion: Bool
    public var isSubscribed: Bool

    public func setTheme(_ newTheme: SettingsDTO.Theme) async
    public func toggleDiagnostics(_ enabled: Bool) async
    public func signOut() async
}
```

### PaywallViewModel

Manages subscription purchases:

```swift theme={null}
@MainActor
@Observable
public final class PaywallViewModel {
    public var offerings: [PaymentsOffering]
    public var selectedOffering: PaymentsOffering?
    public var isLoading: Bool
    public var errorMessage: String?
    public var isSubscribed: Bool

    public func selectOffering(_ offering: PaymentsOffering)
    public func purchase() async
    public func restore() async
}
```

## Settings Categories

<AccordionGroup>
  <Accordion title="Appearance">
    **Theme Selection** (`SettingsDTO.Theme`):

    * System (follows iOS)
    * Light (always light)
    * Dark (always dark)
    * Aurora (premium light theme)
    * Obsidian (premium dark theme)

    Changes apply instantly. Aurora and Obsidian are flagged `isPremium`.
  </Accordion>

  <Accordion title="Privacy & Diagnostics">
    **User Controls:**

    * Share diagnostics (opt-in crash/usage reporting)

    Notification permissions live in their own Notifications section; account deletion is handled by the app-level Account flow.
  </Accordion>

  <Accordion title="Account & Subscription">
    **Management:**

    * Pro status / "Go Pro" and Restore Purchases (Subscription section)
    * Manage Subscription (App Store, from the paywall)
    * Sign in / Sign out (Auth)
    * Account deletion (app-level Account flow)
  </Accordion>

  <Accordion title="Legal">
    **Links:**

    * Privacy Policy
    * Terms of Service
    * Subscription Terms
    * App version display
  </Accordion>
</AccordionGroup>

## Paywall UI

Beautiful subscription screen with:

* ✅ Feature comparison
* ✅ Pricing display
* ✅ Monthly and annual options
* ✅ Clear CTAs
* ✅ Terms and privacy links
* ✅ Restore purchases button

## Customization Examples

### Add New Setting

```swift theme={null}
// 1. Add the field to the persisted SwiftData model (theme is stored as a String)
@Model
public final class Settings {
    public var theme: String
    public var shareDiagnostics: Bool
    public var autoSaveChats: Bool = true  // New setting
}

// 2. Add it to the SettingsDTO so the repository can load/save it
public struct SettingsDTO: Sendable, Equatable {
    public let autoSaveChats: Bool  // New setting
}

// 3. Add to ViewModel and persist via the repository's save(_:)
@Observable
public final class SettingsViewModel {
    public var autoSaveChats: Bool = true

    public func toggleAutoSave(_ enabled: Bool) async {
        autoSaveChats = enabled
        // load the current DTO, set the new value, then save the updated copy
    }
}

// 4. Add to UI
Toggle("Auto-save Chats", isOn: $viewModel.autoSaveChats)
    .onChange(of: viewModel.autoSaveChats) {
        Task { await viewModel.toggleAutoSave($0) }
    }
```

### Customize Paywall

```swift theme={null}
// In PaywallView, edit the feature list — each row is a FeatureRow
// (FeatureRow lives in PaywallView+Components.swift):
FeatureRow(icon: "sparkles", title: "Advanced AI", description: "Get smarter responses with enhanced models")
FeatureRow(icon: "bolt.fill", title: "Faster Processing", description: "Priority queue for quicker results")
FeatureRow(icon: "infinity", title: "Unlimited Usage", description: "No daily limits or restrictions")
FeatureRow(icon: "star.fill", title: "Your Feature", description: "Describe the benefit")  // Add your feature
```

### Add Custom Theme

```swift theme={null}
// 1. Add a color set in Packages/DesignSystem/Sources/DesignSystem/Resources/Assets.xcassets
// 2. Add a case to SettingsDTO.Theme (in the Storage package)
public enum Theme: String, Sendable, Equatable, CaseIterable {
    case system, light, dark, aurora, obsidian
    case custom  // New theme
}

// 3. Map the new case in DSColors / ThemePalette (DesignSystem) and in
//    SettingsDTO.Theme's displayName / symbolName / isPremium helpers
// 4. The Appearance picker is CaseIterable-driven, so it picks up the new case automatically
```

## Paywall Best Practices

<Steps>
  <Step title="Clear Value">
    Show exactly what users get:

    * List specific features
    * Highlight most popular plan
    * Show savings (annual vs monthly)
  </Step>

  <Step title="Easy Purchase">
    * Prominent CTAs
    * Clear pricing
    * Both monthly and annual
    * Restore purchases visible
  </Step>

  <Step title="Transparent Terms">
    * Link to subscription terms
    * Link to privacy policy
    * Cancellation policy clear
    * Auto-renewal explained
  </Step>

  <Step title="Handle Errors">
    * Purchase cancelled (don't error)
    * Network failures (retry)
    * Already subscribed (show status)
    * Restore failures (help user)
  </Step>
</Steps>

## Key Files

| Component   | Location                                                                    |
| ----------- | --------------------------------------------------------------------------- |
| ViewModels  | `Packages/FeatureSettings/Sources/FeatureSettings/ViewModels/`              |
| Settings UI | `Packages/FeatureSettings/Sources/FeatureSettings/Views/SettingsView.swift` |
| Paywall UI  | `Packages/FeatureSettings/Sources/FeatureSettings/Views/PaywallView.swift`  |

## Dependencies

* **Core** - Error handling, logging, theme manager
* **Storage** - `SettingsDTO` / `SettingsRepository` persistence
* **Auth** - Sign in / sign out
* **Payments** - Subscription management
* **DesignSystem** - UI components, `DSColors`
* **Localization** - `AppError.localizedUserMessage`, `L10n` strings

## Used By

* **Main App** - Settings tab
* **All features** - Theme observation
* **Profile** - Subscription status

## Best Practices

<AccordionGroup>
  <Accordion title="Settings Persistence">
    * Save immediately on change
    * Use repository pattern
    * Handle errors gracefully
    * Provide feedback
  </Accordion>

  <Accordion title="Paywall UX">
    * Make it beautiful
    * Highlight value
    * Easy to dismiss
    * Test purchase flow
  </Accordion>

  <Accordion title="Privacy">
    * Opt-in for tracking
    * Clear data policies
    * Easy account deletion
    * GDPR compliance
  </Accordion>
</AccordionGroup>

## Learn More

<CardGroup cols={2}>
  <Card title="Full Documentation" icon="book" href="https://github.com/SwiftAIBoilerplatePro/SwiftAIBoilerplatePro-Distribution/blob/main/docs/modules/Feature.Settings.md">
    Find complete FeatureSettings guide in your project
  </Card>

  <Card title="Payments Module" icon="dollar" href="/pages/modules/payments">
    Subscription management
  </Card>

  <Card title="Design System" icon="palette" href="/pages/modules/design-system">
    Theme system
  </Card>

  <Card title="Building Guide" icon="hammer" href="/pages/guides/building-your-app">
    Customize settings
  </Card>
</CardGroup>

## Build with AI (fast)

You can customize this module in minutes using our ready-to-paste LLM prompts.

### Example Prompt

Context: `Packages/FeatureSettings/**`
Prompt:
"Add a Privacy section to Settings that links to the policy page and includes a clear account-data explanation."

See all prompts → `docs/prompts/Feature.Settings.prompts.md`\
See in project: `docs/modules/Feature.Settings.md`

## Test Coverage

FeatureSettings has its own package test target, run as part of \~598 tests across 12 package test targets + the app test suites (one `Boilerplate.xctestplan` run).

Tests include:

* Settings persistence
* Theme switching
* Paywall display
* Purchase flows
* Error handling
