diff --git a/Mark-In/Sources/Data/DTOs/FolderDTO.swift b/Mark-In/Sources/Data/DTOs/FolderDTO.swift new file mode 100644 index 0000000..3d3f309 --- /dev/null +++ b/Mark-In/Sources/Data/DTOs/FolderDTO.swift @@ -0,0 +1,28 @@ +// +// FolderDTO.swift +// Mark-In +// +// Created by 이정동 on 4/21/25. +// + +import Foundation + +struct FolderDTO: Codable { + var id: String + var name: String + var createdBy: Date + + init(_ folder: Folder) { + self.id = folder.id + self.name = folder.name + self.createdBy = folder.createdBy + } + + func toEntity() -> Folder { + return Folder( + id: self.id, + name: self.name, + createdBy: self.createdBy + ) + } +} diff --git a/Mark-In/Sources/Data/Repositories/FolderRepositoryImpl.swift b/Mark-In/Sources/Data/Repositories/FolderRepositoryImpl.swift new file mode 100644 index 0000000..affb2e0 --- /dev/null +++ b/Mark-In/Sources/Data/Repositories/FolderRepositoryImpl.swift @@ -0,0 +1,86 @@ +// +// FolderRepositoryImpl.swift +// Mark-In +// +// Created by 이정동 on 4/21/25. +// + +import Foundation + +import FirebaseFirestore + +struct FolderRepositoryImpl: FolderRepository { + + typealias VoidCheckedContinuation = CheckedContinuation + + private let db = Firestore.firestore() + + func createFolder(_ folder: Folder) async throws -> Folder { + /// 1. Folder 문서 참조 생성 + // TODO: 후에 testUser를 실제 로그인 된 유저로 변경 예정 + let folderDocRef = db.collection("users/testUser/folders").document() + + /// 2. Entity를 DTO로 변환 및 새로 생성된 문서 ID를 프로퍼티에 저장 + var folderDTO = FolderDTO(folder) + folderDTO.id = folderDocRef.documentID + + /// 3. Firestore에 추가 + try await withCheckedThrowingContinuation { (continuation: VoidCheckedContinuation) in + do { + try folderDocRef.setData(from: folderDTO) { error in + if let error { continuation.resume(throwing: error) } + else { continuation.resume(returning: ()) } + } + } catch { + continuation.resume(throwing: error) + } + } + + /// 4. DocumentID가 업데이트 된 Folder Entity로 리턴 + return folderDTO.toEntity() + } + + func fetchAllFolders() async throws -> [Folder] { + /// 1. Folders 컬렉션 참조 생성 + // TODO: 후에 testUser를 실제 로그인 된 유저로 변경 예정 + let folderColRef = db.collection("users/testUser/folders") + + /// 2. 컬렉션의 모든 문서 가져오기 + let snapshot = try await folderColRef.getDocuments() + + /// 3. 문서를 DTO로 변환 후 다시 Entity로 변환 + return snapshot.documents.compactMap { + try? $0.data(as: FolderDTO.self).toEntity() + } + } + + func updateFolder(_ folder: Folder) async throws { + /// 1. Folder 문서 참조 생성 + // TODO: 후에 testUser를 실제 로그인 된 유저로 변경 예정 + let folderDocRef = db.document("users/testUser/folders/\(folder.id)") + + /// 2. Entity를 DTO로 변환 + let folderDTO = FolderDTO(folder) + + /// 3. 업데이트 + try await withCheckedThrowingContinuation { (continuation: VoidCheckedContinuation) in + do { + try folderDocRef.setData(from: folderDTO) { error in + if let error { continuation.resume(throwing: error) } + else { continuation.resume(returning: ()) } + } + } catch { + continuation.resume(throwing: error) + } + } + } + + func deleteFolder(_ folder: Folder) async throws { + /// 1. Folder 문서 참조 생성 + // TODO: 후에 testUser를 실제 로그인 된 유저로 변경 예정 + let folderDocRef = db.document("users/testUser/folders/\(folder.id)") + + /// 2. Folder 삭제 + try await folderDocRef.delete() + } +} diff --git a/Mark-In/Sources/Domain/Entities/Folder.swift b/Mark-In/Sources/Domain/Entities/Folder.swift new file mode 100644 index 0000000..152fb6c --- /dev/null +++ b/Mark-In/Sources/Domain/Entities/Folder.swift @@ -0,0 +1,14 @@ +// +// Folder.swift +// Mark-In +// +// Created by 이정동 on 4/21/25. +// + +import Foundation + +struct Folder { + var id: String = "" + var name: String + var createdBy: Date = .now +} diff --git a/Mark-In/Sources/Domain/Interfaces/FolderRepository.swift b/Mark-In/Sources/Domain/Interfaces/FolderRepository.swift new file mode 100644 index 0000000..f5e777c --- /dev/null +++ b/Mark-In/Sources/Domain/Interfaces/FolderRepository.swift @@ -0,0 +1,15 @@ +// +// FolderRepository.swift +// Mark-In +// +// Created by 이정동 on 4/21/25. +// + +import Foundation + +protocol FolderRepository { + func createFolder(_ folder: Folder) async throws -> Folder + func fetchAllFolders() async throws -> [Folder] + func updateFolder(_ folder: Folder) async throws + func deleteFolder(_ folder: Folder) async throws +}