Closer/iphone/Closer/Models/DomainModels.swift

222 lines
5.1 KiB
Swift

import Foundation
import SwiftUI
// MARK: - Question
struct Question: Codable, Identifiable, Hashable, Sendable {
let id: String
var text: String
var type: String // "text" | "multiple_choice" | "scale"
var options: [String]?
var scaleMin: Int?
var scaleMax: Int?
var categoryId: String?
var packId: String?
}
struct QuestionCategory: Codable, Identifiable, Hashable, Sendable {
let id: String
var name: String
var description: String?
var icon: String?
var color: String?
var packId: String?
var order: Int?
}
struct QuestionPack: Codable, Identifiable, Hashable, Sendable {
let id: String
var name: String
var description: String?
var categories: [String]?
var isPremium: Bool
}
// MARK: - Question Threads
struct QuestionThread: Codable, Identifiable, Sendable {
let id: String
var questionId: String
var senderId: String
var status: String // "pending" | "answered" | "revealed"
var createdAt: Date
}
struct QuestionMessage: Codable, Identifiable, Sendable {
let id: String
var threadId: String
var userId: String
var text: String
var createdAt: Date
}
struct QuestionReaction: Codable, Identifiable, Sendable {
let id: String
var threadId: String
var userId: String
var emoji: String
var createdAt: Date
}
struct QuestionSession: Codable, Identifiable, Sendable {
let id: String
var gameType: String
var status: String
var startedAt: Date
var completedAt: Date?
var createdBy: String
}
// MARK: - Date Ideas
struct DateIdea: Codable, Identifiable, Hashable, Sendable {
let id: String
var title: String
var description: String?
var category: String?
var cost: String? // "free" | "low" | "medium" | "high"
var duration: String? // "short" | "medium" | "long"
var location: String? // "indoor" | "outdoor" | "both"
var imageUrl: String?
}
struct DateSwipe: Codable, Identifiable, Sendable {
let id: String
var dateIdeaId: String
var userId: String
var action: String // "love" | "pass"
var swipedAt: Date
}
struct DateMatch: Codable, Identifiable, Sendable {
let id: String
var coupleId: String
var dateIdeaId: String
var matchedAt: Date
}
struct DatePlan: Codable, Identifiable, Sendable {
let id: String
var coupleId: String
var title: String
var description: String?
var date: Date?
var location: String?
var notes: String?
var createdBy: String
var createdAt: Date
}
struct BucketListItem: Codable, Identifiable, Sendable {
let id: String
var title: String
var description: String?
var createdBy: String
var completed: Bool
var completedAt: Date?
var createdAt: Date
}
// MARK: - Challenges & Capsules
struct ConnectionChallenge: Codable, Identifiable, Sendable {
let id: String
var title: String
var description: String
var durationDays: Int
var tasks: [ChallengeTask]
var isPremium: Bool
}
struct ChallengeTask: Codable, Sendable {
var day: Int
var title: String
var description: String
}
struct ChallengeState: Codable, Sendable {
var challengeId: String
var currentDay: Int
var completedDays: [Int]
var startedAt: Date
var status: String // "active" | "completed" | "abandoned"
}
struct MemoryCapsule: Codable, Identifiable, Sendable {
let id: String
var title: String
var content: String?
var imageUrls: [String]?
var status: String // "sealed" | "unlocked"
var unlockAt: Date
var createdBy: String
var createdAt: Date
}
struct TimeCapsule: Codable, Identifiable, Sendable {
let id: String
var title: String
var message: String
var status: String
var unlockAt: Date
var createdBy: String
var createdAt: Date
}
// MARK: - Streaks
enum StreakType: Sendable {
case couple(count: Int, lastActiveDate: Date?, includesToday: Bool)
case personal(count: Int, lastActiveDate: Date?, includesToday: Bool)
case weeklyRhythm(count: Int, lastActiveDate: Date?, includesToday: Bool)
}
struct StreakResult: Sendable {
let coupleStreak: StreakType
let personalStreak: StreakType
let weeklyRhythm: StreakType
let milestoneCopy: String?
let canRepair: Bool
let repairDueDate: Date?
}
// MARK: - Game Types
enum GameType: String, Sendable {
case wheel = "wheel"
case thisOrThat = "this_or_that"
case howWell = "how_well"
case desireSync = "desire_sync"
case connectionChallenges = "connection_challenges"
}
// MARK: - Local Answer Caching
struct LocalAnswer: Codable, Sendable {
let questionId: String
let answer: String
let answeredAt: Date
var isRevealed: Bool
}
// MARK: - Weekly Recap
struct WeeklyRecap: Codable, Sendable {
var weekStart: Date
var streakCount: Int
var answersShared: Int
var gamesPlayed: Int
var badgesEarned: [String]
}
// MARK: - Answer Model
struct Answer: Codable, Identifiable, Sendable {
let id: String
var coupleId: String
var questionId: String
var userId: String
var answerText: String
var createdAt: Date
var isRevealed: Bool
}