Files
sure/bitrig/App/Models.swift
T
0aa43de10a Add experimental Swift-native Sure Insights app (#3134)
* Add Swift-native Sure app

* Fix push subscriptions schema for CI

* Address native app review feedback

* Address remaining native app review feedback

* Use Flutter app logo for native icon

* Honor insight notification preferences and locale

---------

Co-authored-by: Juan Jose Mata <2v8shcb6pz@privaterelay.appleid.com>
Co-authored-by: sure-admin <sure-admin@splashblot.com>
2026-08-25 04:16:24 +02:00

185 lines
4.3 KiB
Swift

import Foundation
struct MoneyValue: Codable, Sendable {
var amount: String
var currency: String
var decimalAmount: Decimal {
Decimal(string: amount) ?? 0
}
var formatted: String {
decimalAmount.formatted(.currency(code: currency).precision(.fractionLength(0...2)))
}
}
struct BalanceSheet: Codable, Sendable {
var currency: String
var netWorth: MoneyValue
var assets: MoneyValue
var liabilities: MoneyValue
enum CodingKeys: String, CodingKey {
case currency
case netWorth = "net_worth"
case assets
case liabilities
}
}
struct SureAccount: Codable, Identifiable, Sendable {
var id: String
var name: String
var balance: String
var balanceCents: Int
var cashBalance: String
var cashBalanceCents: Int
var currency: String
var classification: String
var accountType: String?
var subtype: String?
var status: String
var institutionName: String?
enum CodingKeys: String, CodingKey {
case id, name, balance, currency, classification, subtype, status
case balanceCents = "balance_cents"
case cashBalance = "cash_balance"
case cashBalanceCents = "cash_balance_cents"
case accountType = "account_type"
case institutionName = "institution_name"
}
var isAsset: Bool { classification == "asset" }
}
struct AccountCollection: Codable, Sendable {
var accounts: [SureAccount]
var pagination: SurePagination?
}
struct SureBudget: Codable, Identifiable, Sendable {
var id: String
var name: String
var currency: String
var current: Bool
var budgetedSpending: String?
var allocatedSpending: String
var startDate: String
var endDate: String
enum CodingKeys: String, CodingKey {
case id, name, currency, current
case budgetedSpending = "budgeted_spending"
case allocatedSpending = "allocated_spending"
case startDate = "start_date"
case endDate = "end_date"
}
}
struct BudgetCollection: Codable, Sendable {
var budgets: [SureBudget]
var pagination: SurePagination?
}
struct SureInsight: Codable, Identifiable, Sendable, Equatable {
var id: String
var type: String
var title: String
var body: String
var priority: String
var status: String
var generatedAt: String?
enum CodingKeys: String, CodingKey {
case id, type, title, body, priority, status
case generatedAt = "generated_at"
}
var symbol: String {
switch type {
case "cash_flow_warning", "budget_at_risk": "exclamationmark.triangle.fill"
case "net_worth_milestone", "budget_on_track": "sparkles"
case "subscription_audit": "repeat"
case "idle_cash": "banknote.fill"
default: "chart.line.uptrend.xyaxis"
}
}
}
struct InsightCollection: Codable, Sendable {
var insights: [SureInsight]
}
struct SureChat: Codable, Identifiable, Sendable, Hashable {
var id: String
var title: String
var error: String?
var createdAt: String
var updatedAt: String
var lastMessageAt: String?
var messageCount: Int?
enum CodingKeys: String, CodingKey {
case id, title, error
case createdAt = "created_at"
case updatedAt = "updated_at"
case lastMessageAt = "last_message_at"
case messageCount = "message_count"
}
}
struct ChatCollection: Codable, Sendable {
var chats: [SureChat]
var pagination: SurePagination?
}
struct SurePagination: Codable, Sendable {
var page: Int
var perPage: Int
var totalCount: Int
var totalPages: Int
enum CodingKeys: String, CodingKey {
case page
case perPage = "per_page"
case totalCount = "total_count"
case totalPages = "total_pages"
}
}
struct SureMessage: Codable, Identifiable, Sendable, Equatable {
var id: String
var type: String
var role: String
var content: String
var createdAt: String
enum CodingKeys: String, CodingKey {
case id, type, role, content
case createdAt = "created_at"
}
var isUser: Bool { role == "user" || type == "user_message" }
}
struct ChatDetail: Codable, Sendable {
var id: String
var title: String
var error: String?
var createdAt: String
var updatedAt: String
var messages: [SureMessage]
var pagination: SurePagination?
enum CodingKeys: String, CodingKey {
case id, title, error, messages, pagination
case createdAt = "created_at"
case updatedAt = "updated_at"
}
var chat: SureChat {
SureChat(id: id, title: title, error: error, createdAt: createdAt, updatedAt: updatedAt)
}
}