Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions dogether/Data/DataSources/ChallengeGroupsDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ final class ChallengeGroupsDataSource {
}

func getMemberTodos(groupId: String, memberId: String) async throws -> GetMemberTodosResponse {
try await NetworkManager.shared.request(ChallengeGroupsRouter.getMemberTodos(groupId: groupId, memberId: memberId))
try await NetworkManager.shared.request(
ChallengeGroupsRouter.getMemberTodos(groupId: groupId, memberId: memberId)
)
}

func createTodos(groupId: String, createTodosRequest: CreateTodosRequest) async throws {
try await NetworkManager.shared.request(ChallengeGroupsRouter.createTodos(groupId: groupId, createTodosRequest: createTodosRequest))
try await NetworkManager.shared.request(
ChallengeGroupsRouter.createTodos(groupId: groupId, createTodosRequest: createTodosRequest)
)
}

func certifyTodo(todoId: String, certifyTodoRequest: CertifyTodoRequest) async throws {
try await NetworkManager.shared.request(ChallengeGroupsRouter.certifyTodo(todoId: todoId, certifyTodoRequest: certifyTodoRequest))
}

func readTodo(todoId: String) async throws {
try await NetworkManager.shared.request(ChallengeGroupsRouter.readTodo(todoId: todoId))
func readTodo(todoHistoryId: String) async throws {
try await NetworkManager.shared.request(ChallengeGroupsRouter.readTodo(todoHistoryId: todoHistoryId))
}
}
26 changes: 26 additions & 0 deletions dogether/Data/DataSources/TodosDataSource.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// TodosDataSource.swift
// dogether
//
// Created by seungyooooong on 1/3/26.
//

import Foundation

final class TodosDataSource {
static let shared = TodosDataSource()

private init() { }

func certifyTodo(todoId: String, certifyTodoRequest: CertifyTodoRequest) async throws {
try await NetworkManager.shared.request(
TodosRouter.certifyTodo(todoId: todoId, certifyTodoRequest: certifyTodoRequest)
)
}

func remindTodo(todoId: String, remindTodoRequest: RemindTodoRequest) async throws {
try await NetworkManager.shared.request(
TodosRouter.remindTodo(todoId: todoId, remindTodoRequest: remindTodoRequest)
)
}
}
5 changes: 5 additions & 0 deletions dogether/Data/DataSources/UserDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ final class UserDataSource {
try await NetworkManager.shared.request(UserRouter.getMyCertificationStats(groupId: groupId))
}


func getMyActivityFromTodo(todoId: Int, sort: String) async throws -> GetMyActivityFromTodoResponse {
try await NetworkManager.shared.request(UserRouter.getMyActivityFromTodo(todoId: todoId, sort: sort))
}

func getMyProfile() async throws -> GetMyProfileResponse {
try await NetworkManager.shared.request(UserRouter.getMyProfile)
}
Expand Down
12 changes: 12 additions & 0 deletions dogether/Data/Network/Request/RemindTodoRequest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// RemindTodoRequest.swift
// dogether
//
// Created by seungyooooong on 1/3/26.
//

import Foundation

struct RemindTodoRequest: Encodable {
let reminderType: String
}
20 changes: 15 additions & 5 deletions dogether/Data/Network/Response/GetMemberTodosResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,41 @@
import Foundation

struct GetMemberTodosResponse: Decodable {
let isMine: Bool
let currentTodoHistoryToReadIndex: Int
let todos: [MemberTodo]
let todos: [TodoEntityInGetMemberTodos]
}

struct MemberTodo: Decodable {
let id: Int
struct TodoEntityInGetMemberTodos: Decodable {
let historyId: Int
let todoId: Int
let content: String
let status: String
let canRequestCertification: Bool
let canRequestCertificationReview: Bool
let certificationContent: String?
let certificationMediaUrl: String?
let isRead: Bool
let reviewFeedback: String?

init(
id: Int,
historyId: Int,
todoId: Int,
content: String,
status: String,
canRequestCertification: Bool,
canRequestCertificationReview: Bool,
certificationContent: String? = nil,
certificationMediaUrl: String? = nil,
isRead: Bool,
reviewFeedback: String? = nil
) {
self.id = id
self.historyId = historyId
self.todoId = todoId
self.content = content
self.status = status
self.canRequestCertification = canRequestCertification
self.canRequestCertificationReview = canRequestCertificationReview
self.certificationContent = certificationContent
self.certificationMediaUrl = certificationMediaUrl
self.isRead = isRead
Expand Down
23 changes: 23 additions & 0 deletions dogether/Data/Network/Response/GetMyActivityFromTodoResponse.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// GetMyActivityFromTodoResponse.swift
// dogether
//
// Created by seungyooooong on 1/20/26.
//

import Foundation

struct GetMyActivityFromTodoResponse: Decodable {
let certifications: [CertificationEntityInGetMyActivityFromTodoResponse]
}


struct CertificationEntityInGetMyActivityFromTodoResponse: Decodable {
let id: Int
let content: String
var status: String
var canRequestCertificationReview: Bool
var certificationContent: String
var certificationMediaUrl: String
var reviewFeedback: String?
}
1 change: 1 addition & 0 deletions dogether/Data/Network/Response/GetMyTodosResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ struct TodoEntityInGetMyTodos: Decodable {
let id: Int
let content: String
var status: String
var canRequestCertificationReview: Bool
var certificationContent: String?
var certificationMediaUrl: String?
var reviewFeedback: String?
Expand Down
17 changes: 6 additions & 11 deletions dogether/Data/Network/Router/ChallengeGroupsRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,31 @@ import Foundation

enum ChallengeGroupsRouter: NetworkEndpoint {
case createTodos(groupId: String, createTodosRequest: CreateTodosRequest)
case certifyTodo(todoId: String, certifyTodoRequest: CertifyTodoRequest)
case getMyTodos(groupId: String, date: String)
case getMyYesterdayTodos
case getMemberTodos(groupId: String, memberId: String)
case readTodo(todoId: String)
case readTodo(todoHistoryId: String)

var path: String {
switch self {
case .createTodos(let groupId, _):
return Path.api + Path.v1 + Path.challengeGroups + "/\(groupId)/todos"
case .certifyTodo(let todoId, _): // FIXME: 추후 TodosRouter 분리
return Path.api + Path.v1 + Path.todos + "/\(todoId)/certify"
case .getMyTodos(let groupId, _):
return Path.api + Path.v1 + Path.challengeGroups + "/\(groupId)/my-todos"
return Path.api + Path.v2 + Path.challengeGroups + "/\(groupId)/my-todos"
case .getMyYesterdayTodos:
return Path.api + Path.v1 + Path.challengeGroups + "/my/yesterday"
case .getMemberTodos(let groupId, let memberId):
return Path.api + Path.v1 + Path.challengeGroups + "/\(groupId)/challenge-group-members/\(memberId)/today-todo-history"
case .readTodo(let todoId): // FIXME: 추후 TodoHistoryRouter 분리
return Path.api + Path.v1 + Path.todoHistory + "/\(todoId)"
return Path.api + Path.v2 + Path.challengeGroups + "/\(groupId)/challenge-group-members/\(memberId)/today-todo-history"
case .readTodo(let todoHistoryId): // FIXME: 추후 TodoHistoryRouter 분리
return Path.api + Path.v1 + Path.todoHistory + "/\(todoHistoryId)"
}
}

var method: NetworkMethod {
switch self {
case .getMyTodos, .getMyYesterdayTodos, .getMemberTodos:
return .get
case .createTodos, .certifyTodo, .readTodo:
case .createTodos, .readTodo:
return .post
}
}
Expand Down Expand Up @@ -64,8 +61,6 @@ enum ChallengeGroupsRouter: NetworkEndpoint {
switch self {
case .createTodos(_, let createTodosRequest):
return createTodosRequest
case .certifyTodo(_, let certifyTodoRequest):
return certifyTodoRequest
default:
return nil
}
Expand Down
55 changes: 55 additions & 0 deletions dogether/Data/Network/Router/TodosRouter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// TodosRouter.swift
// dogether
//
// Created by seungyooooong on 1/2/26.
//

import Foundation

enum TodosRouter: NetworkEndpoint {
case certifyTodo(todoId: String, certifyTodoRequest: CertifyTodoRequest)
case remindTodo(todoId: String, remindTodoRequest: RemindTodoRequest)

var path: String {
switch self {
case .certifyTodo(let todoId, _):
return Path.api + Path.v1 + Path.todos + "/\(todoId)/certify"
case .remindTodo(let todoId, _):
return Path.api + Path.v1 + Path.todos + "/\(todoId)/reminders"
}
}

var method: NetworkMethod {
switch self {
case .certifyTodo, .remindTodo:
return .post
}
}

var parameters: [URLQueryItem]? {
switch self {
default:
return nil
}
}

var header: [String : String]? {
switch self {
default:
return [
Header.Key.contentType: Header.Value.applicationJson,
Header.Key.authorization: Header.Value.bearer + (UserDefaultsManager.shared.accessToken ?? "")
]
}
}

var body: (any Encodable)? {
switch self {
case .certifyTodo(_, let certifyTodoRequest):
return certifyTodoRequest
case .remindTodo(_, let remindTodoRequest):
return remindTodoRequest
}
}
}
9 changes: 8 additions & 1 deletion dogether/Data/Network/Router/UserRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ enum UserRouter: NetworkEndpoint {
case getMyGroupActivity(groupId: Int)
case getMyActivity(sort: String, page: String)
case getMyCertificationStats(groupId: Int?)
case getMyActivityFromTodo(todoId: Int, sort: String)
case getMyProfile

var path: String {
Expand All @@ -21,14 +22,16 @@ enum UserRouter: NetworkEndpoint {
return Path.api + Path.v2 + Path.my + "/certifications"
case .getMyCertificationStats:
return Path.api + Path.v2 + Path.my + "/certification-stats"
case .getMyActivityFromTodo(let todoId, _):
return Path.api + Path.v1 + Path.my + "/activity" + "/todos/\(todoId)" + "/group-certifications"
case .getMyProfile:
return Path.api + Path.v1 + Path.my + "/profile"
}
}

var method: NetworkMethod {
switch self {
case .getMyGroupActivity, .getMyActivity, .getMyCertificationStats, .getMyProfile:
case .getMyGroupActivity, .getMyActivity, .getMyCertificationStats, .getMyActivityFromTodo, .getMyProfile:
return .get
}
}
Expand All @@ -45,6 +48,10 @@ enum UserRouter: NetworkEndpoint {
return [
.init(name: "groupId", value: String(groupId))
]
case let.getMyActivityFromTodo(_, sort):
return [
.init(name: "sortBy", value: sort)
]
default:
return nil
}
Expand Down
21 changes: 12 additions & 9 deletions dogether/Data/Repository/ChallengeGroupsRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,38 +25,41 @@ final class ChallengeGroupsRepository: ChallengeGroupsProtocol {
id: $0.id,
content: $0.content,
status: TodoStatus(rawValue: $0.status) ?? .waitCertification,
canRemindReview: $0.canRequestCertificationReview,
certificationContent: $0.certificationContent,
certificationMediaUrl: $0.certificationMediaUrl,
reviewFeedback: $0.reviewFeedback
)
}
}

func getMemberTodos(groupId: Int, memberId: Int) async throws -> (index: Int, todos: [TodoEntity]) {
func getMemberTodos(groupId: Int, memberId: Int) async throws -> (index: Int, isMine: Bool, todos: [TodoEntity]) {
let response = try await challengeGroupsDataSource.getMemberTodos(
groupId: String(groupId), memberId: String(memberId)
)

if response.todos.isEmpty { throw NetworkError.noData }

let currentIndex = response.currentTodoHistoryToReadIndex
let isMine = response.isMine
let memberTodos = response.todos.map {
TodoEntity(
id: $0.id,
historyId: $0.historyId,
id: $0.todoId,
content: $0.content,
status: TodoStatus(rawValue: $0.status) ?? .waitCertification,
thumbnailStatus: $0.isRead ? .done : .yet,
canRemindCertification: $0.canRequestCertification,
canRemindReview: $0.canRequestCertificationReview,
certificationContent: $0.certificationContent,
certificationMediaUrl: $0.certificationMediaUrl,
reviewFeedback: $0.reviewFeedback
)
}
return (currentIndex, memberTodos)
}

func readTodo(todoId: String) async throws {
try await challengeGroupsDataSource.readTodo(todoId: todoId)
return (currentIndex, isMine, memberTodos)
}

func certifyTodo(todoId: String, certifyTodoRequest: CertifyTodoRequest) async throws {
try await challengeGroupsDataSource.certifyTodo(todoId: todoId, certifyTodoRequest: certifyTodoRequest)
func readTodo(todoHistoryId: String) async throws {
try await challengeGroupsDataSource.readTodo(todoHistoryId: todoHistoryId)
}
}
24 changes: 24 additions & 0 deletions dogether/Data/Repository/TodosRepository.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// TodosRepository.swift
// dogether
//
// Created by seungyooooong on 1/3/26.
//

import Foundation

final class TodosRepository: TodosProtocol {
private let todosDataSource: TodosDataSource

init(todosDataSource: TodosDataSource = .shared) {
self.todosDataSource = todosDataSource
}

func certifyTodo(todoId: String, certifyTodoRequest: CertifyTodoRequest) async throws {
try await todosDataSource.certifyTodo(todoId: todoId, certifyTodoRequest: certifyTodoRequest)
}

func remindTodo(todoId: String, remindTodoRequest: RemindTodoRequest) async throws {
try await todosDataSource.remindTodo(todoId: todoId, remindTodoRequest: remindTodoRequest)
}
}
15 changes: 15 additions & 0 deletions dogether/Data/Repository/UserRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,21 @@ final class UserRepository: UserProtocol {
return (statsViewDatas, certificationListViewDatas)
}

func getMyCertifications(todoId: Int, sortOption: SortOptions) async throws -> [TodoEntity] {
let response = try await userDataSource.getMyActivityFromTodo(todoId: todoId, sort: sortOption.sortString)
return response.certifications.map {
TodoEntity(
id: $0.id,
content: $0.content,
status: TodoStatus(rawValue: $0.status) ?? .waitCertification,
canRemindReview: $0.canRequestCertificationReview,
certificationContent: $0.certificationContent,
certificationMediaUrl: $0.certificationMediaUrl,
reviewFeedback: $0.reviewFeedback
)
}
}

func getProfileViewDatas() async throws -> ProfileViewDatas {
let response = try await userDataSource.getMyProfile()
return ProfileViewDatas(
Expand Down
Loading