Files
Reflect/Shared/Models/AIReport.swift
Trey t 5bd8f8076a Add guided reflection flow with mood-adaptive CBT/ACT questions
Walks users through 3-4 guided questions based on mood category:
positive (great/good) gets gratitude-oriented questions, neutral
(average) gets exploratory questions, and negative (bad/horrible)
gets empathetic questions. Stored as JSON in MoodEntryModel,
integrated into PDF reports, AI summaries, and CSV export.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 15:52:56 -05:00

149 lines
4.6 KiB
Swift

//
// AIReport.swift
// Reflect
//
// Data models for AI-generated mood reports with PDF export.
//
import Foundation
import FoundationModels
// MARK: - Report Type
enum ReportType: String, CaseIterable {
case quickSummary = "Quick Summary"
case detailed = "Detailed Report"
var icon: String {
switch self {
case .quickSummary: return "doc.text"
case .detailed: return "doc.text.magnifyingglass"
}
}
var description: String {
switch self {
case .quickSummary: return "AI overview of your mood patterns"
case .detailed: return "Week-by-week analysis with full data"
}
}
}
// MARK: - Report Entry (decoupled from SwiftData)
struct ReportEntry {
let date: Date
let mood: Mood
let notes: String?
let weather: WeatherData?
let reflection: GuidedReflection?
init(from model: MoodEntryModel) {
self.date = model.forDate
self.mood = model.mood
self.notes = model.notes
self.weather = model.weatherJSON.flatMap { WeatherData.decode(from: $0) }
self.reflection = model.reflectionJSON.flatMap { GuidedReflection.decode(from: $0) }
}
}
// MARK: - Report Overview Stats
struct ReportOverviewStats {
let totalEntries: Int
let averageMood: Double
let moodDistribution: [Mood: Int]
let trend: String
let dateRange: String
}
// MARK: - Report Week
struct ReportWeek: Identifiable {
let id = UUID()
let weekNumber: Int
let startDate: Date
let endDate: Date
let entries: [ReportEntry]
var aiSummary: String?
}
// MARK: - Report Month Summary
struct ReportMonthSummary: Identifiable {
let id = UUID()
let month: Int
let year: Int
let entryCount: Int
let averageMood: Double
var aiSummary: String?
var title: String {
let formatter = DateFormatter()
formatter.dateFormat = "MMMM yyyy"
var components = DateComponents()
components.month = month
components.year = year
let date = Calendar.current.date(from: components) ?? Date()
return formatter.string(from: date)
}
}
// MARK: - Report Year Summary
struct ReportYearSummary: Identifiable {
let id = UUID()
let year: Int
let entryCount: Int
let averageMood: Double
var aiSummary: String?
}
// MARK: - Assembled Report
struct MoodReport {
let reportType: ReportType
let generatedAt: Date
let overview: ReportOverviewStats
let weeks: [ReportWeek]
let monthlySummaries: [ReportMonthSummary]
let yearlySummaries: [ReportYearSummary]
var quickSummary: String?
}
// MARK: - @Generable AI Response Structs
@available(iOS 26, *)
@Generable
struct AIWeeklySummary: Equatable {
@Guide(description: "A clinical, factual summary of the user's mood patterns for this week. Use third-person perspective (e.g., 'The individual'). 2-3 sentences covering mood trends, notable patterns, and any significant changes. Neutral, professional tone suitable for a therapist to read.")
var summary: String
}
@available(iOS 26, *)
@Generable
struct AIMonthSummary: Equatable {
@Guide(description: "A clinical, factual summary of the user's mood patterns for this month. Use third-person perspective. 3-4 sentences covering overall mood trend, week-over-week changes, and notable patterns. Professional tone suitable for clinical review.")
var summary: String
}
@available(iOS 26, *)
@Generable
struct AIYearSummary: Equatable {
@Guide(description: "A clinical, factual summary of the user's mood patterns for this year. Use third-person perspective. 3-5 sentences covering seasonal patterns, long-term trends, and significant periods. Professional tone suitable for clinical review.")
var summary: String
}
@available(iOS 26, *)
@Generable
struct AIQuickSummaryResponse: Equatable {
@Guide(description: "A comprehensive clinical summary of the user's mood data for the selected period. Use third-person perspective (e.g., 'The individual'). 4-6 sentences covering: overall mood patterns, notable trends, day-of-week patterns, and any areas of concern or improvement. Factual, neutral, professional tone suitable for sharing with a therapist.")
var summary: String
@Guide(description: "2-3 key clinical observations as brief bullet points. Each should be a single factual sentence about a pattern or trend observed in the data.")
var keyObservations: [String]
@Guide(description: "1-2 brief, neutral recommendations based on observed patterns. Frame as observations rather than prescriptions (e.g., 'Mood data suggests weekday routines may benefit from...').")
var recommendations: [String]
}