# Hướng Dẫn Kiến Trúc

> Tài liệu kiến trúc chi tiết cho ứng dụng iOS AppClientBaseSwift.

## Tổng Quan

AppClientBaseSwift là ứng dụng iOS native được xây dựng theo mẫu kiến trúc **MVVM (Model-View-ViewModel)** với **SwiftUI** cho UI declarative. Ứng dụng tuân theo các best practices phát triển hiện đại của Apple bao gồm:

- **Swift Concurrency** (async/await)
- **Combine** cho reactive data binding
- **Protocol-oriented programming** để tăng khả năng test
- **Keychain Services** cho lưu trữ bảo mật

## Sơ Đồ Kiến Trúc

```
┌─────────────────────────────────────────────────────────────────────────┐
│                          LỚP PRESENTATION                                │
│  ┌─────────────────────────────────────────────────────────────────────┐ │
│  │                         SwiftUI Views                                │ │
│  │  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐   │ │
│  │  │ SplashView  │ │  HomeView   │ │ ExploreView │ │ ProfileView │   │ │
│  │  └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘   │ │
│  │  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐                   │ │
│  │  │  LoginView  │ │RegisterView │ │ForgotPasswd │                   │ │
│  │  └─────────────┘ └─────────────┘ └─────────────┘                   │ │
│  └─────────────────────────────────────────────────────────────────────┘ │
│                        @StateObject / @EnvironmentObject                 │
│  ┌─────────────────────────────────────────────────────────────────────┐ │
│  │                        ViewModels (@MainActor)                       │ │
│  │  ┌────────────────┐ ┌────────────────┐ ┌────────────────┐           │ │
│  │  │ AuthViewModel  │ │ HomeViewModel  │ │ProfileViewModel│           │ │
│  │  └────────────────┘ └────────────────┘ └────────────────┘           │ │
│  └─────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
                    Dependency Injection (dựa trên Protocol)
┌─────────────────────────────────────────────────────────────────────────┐
│                            LỚP SERVICE                                   │
│  ┌─────────────────────────────┐  ┌─────────────────────────────┐       │
│  │        APIService           │  │       AuthManager            │       │
│  │  • request<T>()             │  │  • @Published authState      │       │
│  │  • get(), post()            │  │  • login(), register()       │       │
│  │  • URLSession               │  │  • Lưu trữ Keychain          │       │
│  └─────────────────────────────┘  └─────────────────────────────┘       │
└─────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│                             LỚP DATA                                     │
│  ┌─────────────────────────────┐  ┌─────────────────────────────┐       │
│  │          Models             │  │        Constants             │       │
│  │  • User (Codable)           │  │  • APIConfig                 │       │
│  │  • HomeItem                 │  │  • StorageKeys               │       │
│  │  • AuthState                │  │  • DesignSystem              │       │
│  └─────────────────────────────┘  └─────────────────────────────┘       │
└─────────────────────────────────────────────────────────────────────────┘
```

## Chi Tiết Component

### 1. Lớp Presentation

#### Views
| Component | Trách nhiệm |
|-----------|-------------|
| `SplashView` | Màn hình splash động, điều hướng trễ |
| `ContentView` | Container TabView gốc, routing theo auth state |
| `AuthContainerView` | Điều hướng luồng Auth (Login/Đăng ký/Quên MK) |
| `HomeView` | Tab Home với lời chào, promo, dịch vụ |
| `ExploreView` | Tính năng khám phá và tìm kiếm |
| `ProfileView` | Hồ sơ người dùng và cài đặt |

#### ViewModels
```swift
@MainActor
final class HomeViewModel: ObservableObject {
    @Published var isLoading: Bool = false
    @Published var items: [HomeItem] = []
    @Published var errorMessage: String?
    
    private let apiService: APIServiceProtocol
    
    func loadData() async { ... }
}
```

### 2. Lớp Service

#### APIService
HTTP client tuân theo nguyên tắc Single Responsibility:

```swift
protocol APIServiceProtocol {
    func request<T: Decodable>(
        endpoint: String,
        method: HTTPMethod,
        body: Encodable?,
        headers: [String: String]?
    ) async throws -> T
}
```

**Tính năng:**
- Xử lý request/response generic
- Tự động mã hóa/giải mã JSON (snake_case ↔ camelCase)
- Tự động thêm Bearer token
- Xử lý mã trạng thái HTTP

#### AuthManager
Singleton quản lý trạng thái xác thực:

```swift
final class AuthManager: ObservableObject {
    @MainActor static let shared = AuthManager()
    @Published var authState: AuthState = .unknown
}
```

**Enum AuthState:**
```swift
enum AuthState {
    case unknown        // Trạng thái khởi tạo
    case unauthenticated // Chưa đăng nhập
    case authenticated(User) // Đã đăng nhập
}
```

## Luồng Dữ Liệu

```mermaid
sequenceDiagram
    participant V as View
    participant VM as ViewModel
    participant S as Service
    participant API as Backend API

    V->>VM: Hành động User (tap button)
    VM->>VM: Đặt isLoading = true
    VM->>S: await service.request()
    S->>API: HTTP Request
    API-->>S: JSON Response
    S-->>VM: Model đã giải mã
    VM->>VM: Cập nhật @Published
    VM-->>V: SwiftUI render lại
```

## Luồng Xác Thực

```mermaid
stateDiagram-v2
    [*] --> Unknown: Khởi động App
    Unknown --> Authenticated: Token hợp lệ
    Unknown --> Unauthenticated: Không có Token
    
    Unauthenticated --> Login
    Login --> Authenticated: Thành công
    Login --> Register: Điều hướng
    Register --> Authenticated: Thành công
    
    Authenticated --> HomeScreen
    HomeScreen --> Unauthenticated: Đăng xuất
```

## Quyết Định Thiết Kế

### 1. Tại sao MVVM?

| Lợi ích | Mô tả |
|---------|-------|
| Khả năng test | ViewModel có thể test độc lập không cần UI |
| Phân tách trách nhiệm | View chỉ hiển thị, logic nằm ở ViewModel |
| Tương thích SwiftUI | `@ObservableObject` + `@Published` native |
| Cập nhật reactive | UI tự động làm mới dựa trên Combine |

### 2. Tại sao DI dựa trên Protocol?

```swift
// Protocol cho phép mock khi test
protocol APIServiceProtocol { ... }

// Production
final class APIService: APIServiceProtocol { ... }

// Test mock
final class MockAPIService: APIServiceProtocol { ... }
```

### 3. Tại sao Keychain thay vì UserDefaults?

| Keychain | UserDefaults |
|----------|--------------|
| ✅ Mã hóa khi lưu trữ | ❌ Text thuần |
| ✅ Secure enclave | ❌ Có thể truy cập |
| ✅ Riêng cho app | ❌ Shared prefs |

### 4. Tại sao @MainActor trên ViewModels?

- Đảm bảo tất cả cập nhật `@Published` xảy ra trên main thread
- Ngăn chặn vấn đề concurrency với SwiftUI
- Contract an toàn thread rõ ràng

## Kiến Trúc Bảo Mật

```
┌────────────────────────────────────────────────────────────┐
│                    CÁC LỚP BẢO MẬT                          │
├────────────────────────────────────────────────────────────┤
│  Lớp 1: Bảo mật Transport (HTTPS/TLS)                      │
│  • Tất cả API calls sử dụng HTTPS                          │
├────────────────────────────────────────────────────────────┤
│  Lớp 2: Bảo mật Token (Keychain)                           │
│  • Access token lưu trong Keychain                         │
│  • Refresh token lưu trong Keychain                        │
├────────────────────────────────────────────────────────────┤
│  Lớp 3: Bảo mật Session                                    │
│  • Kiểm tra hết hạn token                                  │
│  • Tự động refresh token                                   │
├────────────────────────────────────────────────────────────┤
│  Lớp 4: Validation Input                                   │
│  • Kiểm tra định dạng email                                │
│  • Kiểm tra độ mạnh mật khẩu                               │
└────────────────────────────────────────────────────────────┘
```

## Hướng Phát Triển

| Tính năng | Ưu tiên | Mô tả |
|-----------|---------|-------|
| Certificate Pinning | Cao | Xác thực chứng chỉ TLS |
| Xác thực sinh trắc | Cao | Đăng nhập Face ID / Touch ID |
| Chế độ Offline | Trung bình | Cache local với SwiftData |
| Push Notifications | Trung bình | Tích hợp APNs |

## Tài Liệu Liên Quan

- [README.md](./README.md) - Hướng dẫn bắt đầu nhanh
