diff --git a/Projects/Domain/AuthenticationDomain/Interface/DI/AuthenticationDomainBuildable.swift b/Projects/Domain/AuthenticationDomain/Interface/DI/AuthenticationDomainBuildable.swift index 289ef321..fe5e5a25 100644 --- a/Projects/Domain/AuthenticationDomain/Interface/DI/AuthenticationDomainBuildable.swift +++ b/Projects/Domain/AuthenticationDomain/Interface/DI/AuthenticationDomainBuildable.swift @@ -1,4 +1,5 @@ public protocol AuthenticationDomainBuildable { var fetchAuthenticationFormUseCase: any FetchAuthenticationFormUseCase { get } var inputAuthenticationUseCase: any InputAuthenticationUseCase { get } + var fetchAuthenticationStateUseCase: any FetchAuthenticationStateUseCase { get } } diff --git a/Projects/Domain/AuthenticationDomain/Interface/DataSource/RemoteAuthenticationDataSource.swift b/Projects/Domain/AuthenticationDomain/Interface/DataSource/RemoteAuthenticationDataSource.swift index 3c62b8d1..0e6c292e 100644 --- a/Projects/Domain/AuthenticationDomain/Interface/DataSource/RemoteAuthenticationDataSource.swift +++ b/Projects/Domain/AuthenticationDomain/Interface/DataSource/RemoteAuthenticationDataSource.swift @@ -4,4 +4,6 @@ public protocol RemoteAuthenticationDataSource { func fetchAuthenticationForm() async throws -> AuthenticationFormEntity func inputAuthentication(req: InputAuthenticationRequestDTO) async throws + + func fetchAuthenticationState() async throws -> AuthenticationStateEntity } diff --git a/Projects/Domain/AuthenticationDomain/Interface/Entity/AuthenticationStateEntity.swift b/Projects/Domain/AuthenticationDomain/Interface/Entity/AuthenticationStateEntity.swift new file mode 100644 index 00000000..624147b8 --- /dev/null +++ b/Projects/Domain/AuthenticationDomain/Interface/Entity/AuthenticationStateEntity.swift @@ -0,0 +1,13 @@ +public struct AuthenticationStateEntity { + public let name: String + public let score: Double + public let grader: String? + public let markingBoardType: MarkingBoardType + + public init(name: String, score: Double, grader: String?, markingBoardType: MarkingBoardType) { + self.name = name + self.score = score + self.grader = grader + self.markingBoardType = markingBoardType + } +} diff --git a/Projects/Domain/AuthenticationDomain/Interface/Enum/MarkingBoardEnum.swift b/Projects/Domain/AuthenticationDomain/Interface/Enum/MarkingBoardEnum.swift new file mode 100644 index 00000000..fe91336a --- /dev/null +++ b/Projects/Domain/AuthenticationDomain/Interface/Enum/MarkingBoardEnum.swift @@ -0,0 +1,6 @@ +public enum MarkingBoardType: String, Codable { + case notSubmitted = "NOT_SUBMITTED" + case pendingReview = "PENDING_REVIEW" + case underReview = "UNDER_REVIEW" + case completed = "COMPLETED" +} diff --git a/Projects/Domain/AuthenticationDomain/Interface/Repository/AuthenticationRepository.swift b/Projects/Domain/AuthenticationDomain/Interface/Repository/AuthenticationRepository.swift index 93ca19f6..e720be1e 100644 --- a/Projects/Domain/AuthenticationDomain/Interface/Repository/AuthenticationRepository.swift +++ b/Projects/Domain/AuthenticationDomain/Interface/Repository/AuthenticationRepository.swift @@ -3,4 +3,5 @@ import Foundation public protocol AuthenticationRepository { func fetchAuthenticationForm() async throws -> AuthenticationFormEntity func inputAuthentication(req: InputAuthenticationRequestDTO) async throws + func fetchAuthenticationState() async throws -> AuthenticationStateEntity } diff --git a/Projects/Domain/AuthenticationDomain/Interface/UseCase/FetchAuthenticationStateUseCase.swift b/Projects/Domain/AuthenticationDomain/Interface/UseCase/FetchAuthenticationStateUseCase.swift new file mode 100644 index 00000000..dec52872 --- /dev/null +++ b/Projects/Domain/AuthenticationDomain/Interface/UseCase/FetchAuthenticationStateUseCase.swift @@ -0,0 +1,5 @@ +import Foundation + +public protocol FetchAuthenticationStateUseCase { + func execute() async throws -> AuthenticationStateEntity +} diff --git a/Projects/Domain/AuthenticationDomain/Sources/DI/AuthenticationDomainComponent.swift b/Projects/Domain/AuthenticationDomain/Sources/DI/AuthenticationDomainComponent.swift index 5de122ee..802d6367 100644 --- a/Projects/Domain/AuthenticationDomain/Sources/DI/AuthenticationDomainComponent.swift +++ b/Projects/Domain/AuthenticationDomain/Sources/DI/AuthenticationDomainComponent.swift @@ -14,6 +14,9 @@ public final class AuthenticationDomainComponent: Component AuthenticationStateEntity { + AuthenticationStateEntity( + name: name, + score: score, + grader: grader, + markingBoardType: markingBoardType + ) + } +} diff --git a/Projects/Domain/AuthenticationDomain/Sources/DataSource/RemoteAuthenticationDataSourceImpl.swift b/Projects/Domain/AuthenticationDomain/Sources/DataSource/RemoteAuthenticationDataSourceImpl.swift index 47bed4fd..1518f954 100644 --- a/Projects/Domain/AuthenticationDomain/Sources/DataSource/RemoteAuthenticationDataSourceImpl.swift +++ b/Projects/Domain/AuthenticationDomain/Sources/DataSource/RemoteAuthenticationDataSourceImpl.swift @@ -9,4 +9,8 @@ final class RemoteAuthenticationDataSourceImpl: BaseRemoteDataSource AuthenticationStateEntity { + try await request(.fetchAuthenticationState, dto: AuthenticationStateResponseDTO.self).toDomain() + } } diff --git a/Projects/Domain/AuthenticationDomain/Sources/Endpoint/AuthenticationEndpoint.swift b/Projects/Domain/AuthenticationDomain/Sources/Endpoint/AuthenticationEndpoint.swift index 8519c27e..3ad9385e 100644 --- a/Projects/Domain/AuthenticationDomain/Sources/Endpoint/AuthenticationEndpoint.swift +++ b/Projects/Domain/AuthenticationDomain/Sources/Endpoint/AuthenticationEndpoint.swift @@ -5,6 +5,7 @@ import Emdpoint enum AuthenticationEndpoint { case fetchAuthenticationForm case inputAuthentication(req: InputAuthenticationRequestDTO) + case fetchAuthenticationState } extension AuthenticationEndpoint: SMSEndpoint { @@ -20,6 +21,8 @@ extension AuthenticationEndpoint: SMSEndpoint { return .get("/form") case .inputAuthentication: return .post("/submit") + case .fetchAuthenticationState: + return .get("/verify") } } @@ -31,6 +34,9 @@ extension AuthenticationEndpoint: SMSEndpoint { case let .inputAuthentication(req): return .requestJSONEncodable(req) + case .fetchAuthenticationState: + return .requestPlain + default: return .requestPlain } @@ -44,6 +50,9 @@ extension AuthenticationEndpoint: SMSEndpoint { case .inputAuthentication: return .accessToken + case .fetchAuthenticationState: + return .accessToken + default: return .none } @@ -59,6 +68,10 @@ extension AuthenticationEndpoint: SMSEndpoint { return [ 500: .internalServerError ] + case .fetchAuthenticationState: + return [ + 500: .internalServerError + ] } } } diff --git a/Projects/Domain/AuthenticationDomain/Sources/Repository/AuthenticationRepositoryImpl.swift b/Projects/Domain/AuthenticationDomain/Sources/Repository/AuthenticationRepositoryImpl.swift index d32410cc..49ea1e79 100644 --- a/Projects/Domain/AuthenticationDomain/Sources/Repository/AuthenticationRepositoryImpl.swift +++ b/Projects/Domain/AuthenticationDomain/Sources/Repository/AuthenticationRepositoryImpl.swift @@ -14,4 +14,8 @@ struct AuthenticationRepositoryImpl: AuthenticationRepository { func inputAuthentication(req: InputAuthenticationRequestDTO) async throws { try await remoteAuthenticationDataSource.inputAuthentication(req: req) } + + func fetchAuthenticationState() async throws -> AuthenticationStateEntity { + try await remoteAuthenticationDataSource.fetchAuthenticationState() + } } diff --git a/Projects/Domain/AuthenticationDomain/Sources/UseCase/FetchAuthenticationStateUseCaseImpl.swift b/Projects/Domain/AuthenticationDomain/Sources/UseCase/FetchAuthenticationStateUseCaseImpl.swift new file mode 100644 index 00000000..baf0a7a2 --- /dev/null +++ b/Projects/Domain/AuthenticationDomain/Sources/UseCase/FetchAuthenticationStateUseCaseImpl.swift @@ -0,0 +1,13 @@ +import AuthenticationDomainInterface + +struct FetchAuthenticationStateUseCaseImpl: FetchAuthenticationStateUseCase { + private let authenticationRepository: any AuthenticationRepository + + init(authenticationRepository: any AuthenticationRepository) { + self.authenticationRepository = authenticationRepository + } + + func execute() async throws -> AuthenticationStateEntity { + try await authenticationRepository.fetchAuthenticationState() + } +} diff --git a/Projects/Domain/AuthenticationDomain/Testing/FetchAuthenticationStateUseCaseSpy.swift b/Projects/Domain/AuthenticationDomain/Testing/FetchAuthenticationStateUseCaseSpy.swift new file mode 100644 index 00000000..cbc3641d --- /dev/null +++ b/Projects/Domain/AuthenticationDomain/Testing/FetchAuthenticationStateUseCaseSpy.swift @@ -0,0 +1,15 @@ +import AuthenticationDomainInterface + +public final class FetchAuthenticationStateUseCaseSpy: FetchAuthenticationStateUseCase { + public var callCount = 0 + public var handler: (() async throws -> AuthenticationStateEntity)? = { + return AuthenticationStateEntity(name: "ASDFsa", score: 0, grader: nil, markingBoardType: .notSubmitted) + } + + public init() {} + + public func execute() async throws -> AuthenticationStateEntity { + guard let handler else { fatalError() } + return try await handler() + } +} diff --git a/Projects/Feature/GSMAuthenticationFormFeature/Demo/Sources/AppDelegate.swift b/Projects/Feature/GSMAuthenticationFormFeature/Demo/Sources/AppDelegate.swift index 3e175930..42ca07e7 100644 --- a/Projects/Feature/GSMAuthenticationFormFeature/Demo/Sources/AppDelegate.swift +++ b/Projects/Feature/GSMAuthenticationFormFeature/Demo/Sources/AppDelegate.swift @@ -85,7 +85,7 @@ final class DemoMakable { model: GSMAuthenticationFormModel(), fetchAuthenticationFormUseCase: FetchAuthenticationFormUseCaseSpy(), inputAuthenticationUseCase: InputAuthenticationUseCaseSpy(), - fileUploadUseCase: FileUploadUseCaseSpy() + fileUploadUseCase: FileUploadUseCaseSpy(), fetchAuthenticationStateUseCase: FetchAuthenticationStateUseCaseSpy() ), uiModel: uiModel ) { _ in diff --git a/Projects/Feature/GSMAuthenticationFormFeature/Sources/DI/GSMAuthenticationComponent.swift b/Projects/Feature/GSMAuthenticationFormFeature/Sources/DI/GSMAuthenticationComponent.swift index fa417ff3..7c81fee6 100644 --- a/Projects/Feature/GSMAuthenticationFormFeature/Sources/DI/GSMAuthenticationComponent.swift +++ b/Projects/Feature/GSMAuthenticationFormFeature/Sources/DI/GSMAuthenticationComponent.swift @@ -18,7 +18,7 @@ public final class GSMAuthenticationComponent: Component some View { + GSMAuthenticationFormBuilderView(intent: intent, uiModel: state.uiModel) { field in + switch field { + case let .fieldChanges(area, section, group, field, fieldChanges): + switch fieldChanges { + case let .text(text): + intent.updateTextField(area: area, sectionIndex: section, groupIndex: group, fieldIndex: field, text: text) + case let .number(number): + intent.updateNumberField(area: area, sectionIndex: section, groupIndex: group, fieldIndex: field, number: number) + case let .boolean(select): + intent.updateBoolField(area: area, sectionIndex: section, groupIndex: group, fieldIndex: field, select: select) + case let .file(file, fileName): + intent.updateFileField(area: area, sectionIndex: section, groupIndex: group, fieldIndex: field, file: file, fileName: fileName) + case let .select(select): + intent.updateSelectField(area: area, sectionIndex: section, groupIndex: group, fieldIndex: field, select: select) + } + case let .groupAdd(area, section, group): + intent.appendField(area: area, sectionIndex: section, groupIndex: group) + case let .groupRemove(area, section, group): + intent.deleteField(area: area, sectionIndex: section, groupIndex: group) + } + } + .padding(.bottom, safeAreaInsets.bottom + 16) + .overlay(alignment: .bottom) { + CTAButton(text: "저장") { + intent.saveButtonDidTap(state: state) + } + .frame(maxWidth: .infinity) + .padding(.horizontal, 20) + } + } }