feat: полноценное Pulse приложение с TabBar

- Auth: переключено на Pulse API (api.digital-home.site) вместо health
- TabBar: Главная, Задачи, Привычки, Здоровье, Финансы
- Models: TaskModels, HabitModels, FinanceModels, обновлённые AuthModels
- Services: APIService (Pulse API), HealthAPIService (health отдельно)
- Dashboard: обзор дня с задачами, привычками, readiness, балансом
- Tasks: список, фильтр, создание, выполнение, удаление
- Habits: список с прогресс-баром, отметка выполнения, стрики
- Health: бывший DashboardView, HealthKit sync через health API key
- Finance: баланс, список транзакций, добавление расхода/дохода
- Health данные через x-api-key вместо JWT токена health сервиса
This commit is contained in:
Cosmo
2026-03-25 11:49:52 +00:00
parent cf0e535639
commit c015824b36
23 changed files with 1090 additions and 202 deletions

View File

@@ -1,5 +1,29 @@
import Foundation
struct LoginRequest: Codable { let email: String; let password: String }
struct LoginResponse: Codable { let token: String; let user: UserInfo }
struct UserInfo: Codable { let id: Int; let email: String; let name: String }
struct ProfileResponse: Codable { let user: UserInfo; let apiKey: String? }
struct LoginRequest: Codable {
let email: String
let password: String
}
struct RegisterRequest: Codable {
let email: String
let password: String
let name: String
}
struct AuthResponse: Codable {
let token: String
let user: UserInfo
}
struct UserInfo: Codable {
let id: Int
let email: String
let name: String?
let createdAt: String?
enum CodingKeys: String, CodingKey {
case id, email, name
case createdAt = "created_at"
}
}

View File

@@ -0,0 +1,51 @@
import Foundation
struct FinanceTransaction: Codable, Identifiable {
let id: Int
var amount: Double
var categoryId: Int?
var description: String?
var type: String // "income" or "expense"
var date: String?
var createdAt: String?
enum CodingKeys: String, CodingKey {
case id, amount, description, type, date
case categoryId = "category_id"
case createdAt = "created_at"
}
}
struct FinanceCategory: Codable, Identifiable {
let id: Int
var name: String
var icon: String?
var color: String?
var type: String
}
struct FinanceSummary: Codable {
var totalIncome: Double?
var totalExpenses: Double?
var balance: Double?
var month: String?
enum CodingKeys: String, CodingKey {
case totalIncome = "total_income"
case totalExpenses = "total_expenses"
case balance, month
}
}
struct CreateTransactionRequest: Codable {
var amount: Double
var categoryId: Int?
var description: String?
var type: String
var date: String?
enum CodingKeys: String, CodingKey {
case amount, description, type, date
case categoryId = "category_id"
}
}

View File

@@ -0,0 +1,46 @@
import Foundation
enum HabitFrequency: String, Codable {
case daily, weekly, monthly
var displayName: String {
switch self {
case .daily: return "Ежедневно"
case .weekly: return "Еженедельно"
case .monthly: return "Ежемесячно"
}
}
}
struct Habit: Codable, Identifiable {
let id: Int
var name: String
var description: String?
var icon: String?
var color: String?
var frequency: HabitFrequency
var reminderTime: String?
var targetDays: Int?
var currentStreak: Int?
var longestStreak: Int?
var completedToday: Bool?
var totalCompleted: Int?
enum CodingKeys: String, CodingKey {
case id, name, description, icon, color, frequency
case reminderTime = "reminder_time"
case targetDays = "target_days"
case currentStreak = "current_streak"
case longestStreak = "longest_streak"
case completedToday = "completed_today"
case totalCompleted = "total_completed"
}
}
struct HabitLogRequest: Codable {
var completedAt: String?
var note: String?
enum CodingKeys: String, CodingKey {
case completedAt = "completed_at"
case note
}
}

View File

@@ -0,0 +1,51 @@
import Foundation
enum TaskPriority: String, Codable, CaseIterable {
case low, medium, high, urgent
var displayName: String {
switch self {
case .low: return "Низкий"
case .medium: return "Средний"
case .high: return "Высокий"
case .urgent: return "Срочный"
}
}
var color: String {
switch self {
case .low: return "8888aa"
case .medium: return "ffa502"
case .high: return "ff4757"
case .urgent: return "ff0000"
}
}
}
struct PulseTask: Codable, Identifiable {
let id: Int
var title: String
var description: String?
var done: Bool
var priority: TaskPriority?
var dueDate: String?
var reminderTime: String?
var createdAt: String?
enum CodingKeys: String, CodingKey {
case id, title, description, done, priority
case dueDate = "due_date"
case reminderTime = "reminder_time"
case createdAt = "created_at"
}
}
struct CreateTaskRequest: Codable {
var title: String
var description: String?
var priority: TaskPriority?
var dueDate: String?
enum CodingKeys: String, CodingKey {
case title, description, priority
case dueDate = "due_date"
}
}