Skip to content
Merged
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
25 changes: 25 additions & 0 deletions Projects/DataSource/Sources/DTO/RoutineCreationDTO.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,34 @@
// Created by 이동현 on 8/3/25.
//

import Domain

struct RoutineCreationDTO: Codable {
let routineId: String?
let updateApplyDate: String?
let routineName: String
let repeatDay: [String]
let routineStartDate: String
let routineEndDate: String
let executionTime: String
let subRoutineName: [String]
let recommendedRoutineType: String?
}

extension RoutineCreationDTO {
func toRoutineCreationEntity() -> RoutineCreationEntity {
let weeks = repeatDay.compactMap { Week(rawValue: $0) }
let routineCategoryType = RoutineCategoryType(rawValue: recommendedRoutineType ?? "")

return RoutineCreationEntity(
id: routineId,
name: routineName,
repeatDay: weeks,
startDate: routineStartDate,
endDate: routineEndDate,
executionTime: executionTime,
subroutines: subRoutineName,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요기서는 왜 subroutines의 r이 소문자인가용 ???
사실 PR 넘 완벽해서 사소한게 보이는 것일 뿐 ~~ 나중 수정두 괜찮슴니다 !!!

@taipaise taipaise Aug 18, 2025

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

루틴 리스트 작업하실때 일단 이번 작업 내용이 있는게 편하실거 같아서!!! 일단 머지 하구 오늘 따로 pr 올리겠습니다!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

완존 정답 ..........

recommendedRoutineType: routineCategoryType,
applyDateType: nil)
}
}
9 changes: 7 additions & 2 deletions Projects/DataSource/Sources/Endpoint/RoutineEndpoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,20 @@ enum RoutineEndpoint {
case createRoutine(routine: RoutineCreationDTO)
case fetchRoutine(routineId: String)
case fetchRoutines(startDate: String, endDate: String)
case updateRoutine(routine: RoutineUpdateDTO)
case updateRoutine(routine: RoutineCreationDTO)
case deleteAllRoutine(routineId: String)
case deleteDailyRoutine(routine: DeleteRoutineDTO)
case updateRoutineCompletion(routines: RoutineCompletionListDTO)
}

extension RoutineEndpoint: Endpoint {
var baseURL: String {
return AppProperties.baseURL + "/api/v1/routines"
switch self {
case .createRoutine, .updateRoutine:
return AppProperties.baseURL + "/api/v2/routines"
default:
return AppProperties.baseURL + "/api/v1/routines"
}
}

var path: String {
Expand Down
45 changes: 22 additions & 23 deletions Projects/DataSource/Sources/Repository/RoutineRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,18 @@ import Domain
final class RoutineRepository: RoutineRepositoryProtocol {
private let networkService = NetworkService.shared

func createRoutine(routineSummary: RoutineSummaryEntity, subRoutineSummaries: [SubRoutineSummaryEntity]) async throws {
let subRoutineNames = subRoutineSummaries.compactMap { $0.subRoutineName }

func createRoutine(routine: RoutineCreationEntity) async throws {
let routineCreationDTO = RoutineCreationDTO(
routineName: routineSummary.routineName,
repeatDay: routineSummary.repeatDay.map { $0.rawValue },
executionTime: routineSummary.executionTime,
subRoutineName: subRoutineNames)
routineId: nil,
updateApplyDate: routine.applyDateType?.rawValue,
routineName: routine.name,
repeatDay: routine.repeatDay.map { $0.rawValue },
routineStartDate: routine.startDate,
routineEndDate: routine.endDate,
executionTime: routine.executionTime,
subRoutineName: routine.subroutines,
recommendedRoutineType: routine.recommendedRoutineType?.rawValue)

let endpoint = RoutineEndpoint.createRoutine(routine: routineCreationDTO)

_ = try await networkService.request(endpoint: endpoint, type: EmptyResponseDTO.self)
Expand All @@ -42,22 +46,17 @@ final class RoutineRepository: RoutineRepositoryProtocol {
return result
}

func updateRoutine(routineSummary: RoutineSummaryEntity, subRoutineSummaries: [SubRoutineSummaryEntity]) async throws {
guard let routineId = routineSummary.routineId else { return }

let subRoutineDTO = subRoutineSummaries.map {
SubRoutineUpdateDTO(
subRoutineId: $0.subRoutineId,
subRoutineName: $0.subRoutineName,
sortOrder: $0.sortOrder)
}

let routineUpdateDTO = RoutineUpdateDTO(
routineId: routineId,
routineName: routineSummary.routineName,
repeatDay: routineSummary.repeatDay.map { $0.rawValue },
executionTime: routineSummary.executionTime,
subRoutineInfos: subRoutineDTO)
func updateRoutine(routine: RoutineCreationEntity) async throws {
let routineUpdateDTO = RoutineCreationDTO(
routineId: routine.id,
updateApplyDate: routine.applyDateType?.rawValue,
routineName: routine.name,
repeatDay: routine.repeatDay.map { $0.rawValue },
routineStartDate: routine.startDate,
routineEndDate: routine.endDate,
executionTime: routine.executionTime,
subRoutineName: routine.subroutines,
recommendedRoutineType: routine.recommendedRoutineType?.rawValue)
let endpoint = RoutineEndpoint.updateRoutine(routine: routineUpdateDTO)

_ = try await networkService.request(endpoint: endpoint, type: EmptyResponseDTO.self)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// RoutineUpdateApplyDateType.swift
// Domain
//
// Created by 이동현 on 8/18/25.
//


public enum RoutineUpdateApplyDateType: String {
case today = "TODAY"
case tomorrow = "TOMORROW"
}
42 changes: 42 additions & 0 deletions Projects/Domain/Sources/Entity/RoutineCreationEntity.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// RoutineCreationEntity.swift
// Domain
//
// Created by 이동현 on 8/18/25.
//
import Foundation


public struct RoutineCreationEntity {
public let id: String?
public let name: String
public let repeatDay: [Week]
public let startDate: String
public let endDate: String
public let executionTime: String
public let subroutines: [String]
public let recommendedRoutineType: RoutineCategoryType?
public let applyDateType: RoutineUpdateApplyDateType?

public init(
id: String?,
name: String,
repeatDay: [Week],
startDate: String,
endDate: String,
executionTime: String,
subroutines: [String],
recommendedRoutineType: RoutineCategoryType?,
applyDateType: RoutineUpdateApplyDateType?
) {
self.id = id
self.name = name
self.repeatDay = repeatDay
self.startDate = startDate
self.endDate = endDate
self.executionTime = executionTime
self.subroutines = subroutines
self.recommendedRoutineType = recommendedRoutineType
self.applyDateType = applyDateType
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@
public protocol RoutineRepositoryProtocol {
/// 루틴을 생성합니다.
/// - Parameters:
/// - routineSummary: 루틴 요약 정보
/// - subRoutineSummaries: 서브 루틴 요약 정보 배열
func createRoutine(routineSummary: RoutineSummaryEntity, subRoutineSummaries: [SubRoutineSummaryEntity]) async throws
/// - routine: 생성할 루틴 엔티티
func createRoutine(routine: RoutineCreationEntity) async throws

/// 루틴을 조회합니다.
/// - Parameter routineId: 조회할 루틴 id
Expand All @@ -26,9 +25,8 @@ public protocol RoutineRepositoryProtocol {

/// 루틴을 수정합니다.
/// - Parameters:
/// - routineSummary: 루틴 요약 정보
/// - subRoutineSummaries: 서브 루틴 요약 정보 배열
func updateRoutine(routineSummary: RoutineSummaryEntity, subRoutineSummaries: [SubRoutineSummaryEntity]) async throws
/// - routine: 수정할 루틴
func updateRoutine(routine: RoutineCreationEntity) async throws

/// 반복되는 루틴을 모두 제거합니다.
/// - Parameter routineId: 삭제할 루틴 id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@ public protocol RoutineUseCaseProtocol {

func fetchRoutines(startDate: Date, endDate: Date) async throws -> [String: [RoutineEntity]]

func saveRoutine(
routineSummary: RoutineSummaryEntity,
subRoutineSummaries: [SubRoutineSummaryEntity],
deletedSubRoutineSummaries: [SubRoutineSummaryEntity]
) async throws
func saveRoutine(routine: RoutineCreationEntity) async throws

func deleteAllRoutine(routineId: String) async throws

Expand Down
54 changes: 19 additions & 35 deletions Projects/Domain/Sources/UseCase/Routine/RoutineUseCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,47 +28,31 @@ public final class RoutineUseCase: RoutineUseCaseProtocol {
return routineEntities
}

public func saveRoutine(
routineSummary: RoutineSummaryEntity,
subRoutineSummaries: [SubRoutineSummaryEntity],
deletedSubRoutineSummaries: [SubRoutineSummaryEntity]
) async throws {
if routineSummary.routineId == nil { // 루틴 아이디가 있으면 수정, 없으면 생성
try await createRoutine(routineSummary: routineSummary, subRoutinesSummaries: subRoutineSummaries)
public func saveRoutine(routine: RoutineCreationEntity) async throws {
let routine = RoutineCreationEntity(
id: routine.id,
name: routine.name,
repeatDay: routine.repeatDay,
startDate: routine.startDate,
endDate: routine.endDate,
executionTime: routine.executionTime,
subroutines: routine.subroutines.filter { !$0.isEmpty },
recommendedRoutineType: routine.recommendedRoutineType,
applyDateType: routine.applyDateType)

if routine.id == nil { // 루틴 아이디가 있으면 수정, 없으면 생성
try await createRoutine(routine: routine)
} else {
try await updateRoutine(
routineSummary: routineSummary,
subRoutineSummaries: subRoutineSummaries,
deletedSubRoutineSummaries: deletedSubRoutineSummaries)
try await updateRoutine(routine: routine)
}
}

private func createRoutine(routineSummary: RoutineSummaryEntity, subRoutinesSummaries: [SubRoutineSummaryEntity]) async throws {
try await routineRepository.createRoutine(routineSummary: routineSummary, subRoutineSummaries: subRoutinesSummaries)
private func createRoutine(routine: RoutineCreationEntity) async throws {
try await routineRepository.createRoutine(routine: routine)
}

private func updateRoutine(
routineSummary: RoutineSummaryEntity,
subRoutineSummaries: [SubRoutineSummaryEntity],
deletedSubRoutineSummaries: [SubRoutineSummaryEntity]
) async throws {
let updatedSubRoutines = subRoutineSummaries
.enumerated()
.map {
SubRoutineSummaryEntity(
subRoutineId: $1.subRoutineId,
subRoutineName: $1.subRoutineName,
sortOrder: $0 + 1)
}
let deletedSubRoutines = deletedSubRoutineSummaries.map {
SubRoutineSummaryEntity(
subRoutineId: $0.subRoutineId,
subRoutineName: nil,
sortOrder: nil)
}
let finalSubRoutines = updatedSubRoutines + deletedSubRoutines

try await routineRepository.updateRoutine(routineSummary: routineSummary, subRoutineSummaries: finalSubRoutines)
private func updateRoutine(routine: RoutineCreationEntity) async throws {
try await routineRepository.updateRoutine(routine: routine)
}

public func deleteAllRoutine(routineId: String) async throws {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,8 @@ final class RoutineCreationCardView<ContentView: UIView & RoutineCreationExpanda
setNeedsLayout()
}

func configure(dependencies: ContentView.Dependency) {
contentView.configure(dependency: dependencies)
func configure(dependency: ContentView.Dependency) {
contentView.configure(dependency: dependency)
}

@objc private func handleTap(_ gestureRecognizer: UIGestureRecognizer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ final class RoutinePeriodContentView: UIView, RoutineCreationExpandable {
}

struct Dependency {
let dates: (start: Date, end: Date)
let dates: (start: Date?, end: Date?)
}

private let startLabel = UILabel()
Expand Down Expand Up @@ -65,17 +65,19 @@ final class RoutinePeriodContentView: UIView, RoutineCreationExpandable {
}

func configure(dependency: Dependency) {
let startString = dependency
.dates
.start
.convertToString(dateType: .yearMonthDate)
let endString = dependency
.dates
.end
.convertToString(dateType: .yearMonthDate)

startButton.setTitle(startString, for: .normal)
endButton.setTitle(endString, for: .normal)
if let startDate = dependency.dates.start {
let startString = startDate.convertToString(dateType: .yearMonthDate)
startButton.setTitle(startString, for: .normal)
} else {
startButton.setTitle("시작 일자 설정", for: .normal)
}

if let endDate = dependency.dates.end {
let endString = endDate.convertToString(dateType: .yearMonthDate)
endButton.setTitle(endString, for: .normal)
} else {
endButton.setTitle("종료 일자 설정", for: .normal)
}
}

private func configureAttribute() {
Expand Down
Loading
Loading