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: 16 additions & 0 deletions FLINT/Data/Sources/DTO/Auth/LogoutRequestDTO.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// LogoutRequestDTO.swift
// Data
//
// Created by 소은 on 6/19/26.
//

import Foundation

public struct LogoutRequestDTO: Encodable {
public let refreshToken: String

public init(refreshToken: String) {
self.refreshToken = refreshToken
}
}
14 changes: 14 additions & 0 deletions FLINT/Data/Sources/DTO/Auth/WithdrawRequestDTO.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// WithdrawRequestDTO.swift
// Data
//

import Foundation

public struct WithdrawRequestDTO: Encodable {
public let agreedTermsIds: [String]

public init(agreedTermsIds: [String]) {
self.agreedTermsIds = agreedTermsIds
}
}
16 changes: 16 additions & 0 deletions FLINT/Data/Sources/DTO/Collection/ReportRequestDTO.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// ReportRequestDTO.swift
// Data
//

import Foundation

public struct ReportRequestDTO: Encodable {
public let reasons: [String]
public let otherDetail: String?

public init(reasons: [String], otherDetail: String?) {
self.reasons = reasons
self.otherDetail = otherDetail
}
}
14 changes: 10 additions & 4 deletions FLINT/Data/Sources/Networking/API/AuthAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,22 @@ import Moya
import DTO

public enum AuthAPI {
case logout
case logout(refreshToken: String)
case logoutAll
case refresh
case signup(userInfo: SignupRequestDTO)
case socialVerify(socialAuthCredential: SocialVerifyRequestDTO)
case withdraw
case withdraw(agreedTermsIds: [String])
}

extension AuthAPI: TargetType {
public var path: String {
switch self {
case .signup:
return "/api/v1/auth/signup"
case .logout, .logoutAll, .refresh:
case .logout:
return "/api/v1/auth/logout"
case .logoutAll, .refresh:
#warning("TODO: - 나중에 구현할 것")
return "TODO"
case .socialVerify:
Expand All @@ -50,8 +52,12 @@ extension AuthAPI: TargetType {
return .requestJSONEncodable(userInfo)
case let .socialVerify(socialAuthCredential):
return .requestJSONEncodable(socialAuthCredential)
case .logout, .logoutAll, .refresh, .withdraw:
case let .logout(refreshToken):
return .requestJSONEncodable(LogoutRequestDTO(refreshToken: refreshToken))
case .logoutAll, .refresh:
return .requestPlain
case let .withdraw(agreedTermsIds):
return .requestJSONEncodable(WithdrawRequestDTO(agreedTermsIds: agreedTermsIds))
}
}
}
17 changes: 9 additions & 8 deletions FLINT/Data/Sources/Networking/API/CollectionAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Foundation
import Moya

import Domain
import DTO

public enum CollectionAPI {
case fetchCollections(cursor: Int64?, size: Int32)
Expand All @@ -18,6 +19,7 @@ public enum CollectionAPI {
case deleteCollection(collectionId: Int64)
case fetchCollectionDetail(collectionId: Int64)
case fetchRecentViewedCollections
case reportCollection(collectionId: Int64, reasons: [String], otherDetail: String?)
}

extension CollectionAPI: TargetType {
Expand All @@ -33,14 +35,16 @@ extension CollectionAPI: TargetType {
return "/api/v1/collections/\(collectionId)"
case .fetchRecentViewedCollections:
return "/api/v1/collections/recent"
case let .reportCollection(collectionId, _, _):
return "/api/v1/collections/\(collectionId)/reports"
}
}

public var method: Moya.Method {
switch self {
case .fetchCollections, .fetchCollectionDetail, .fetchRecentViewedCollections:
return .get
case .createCollection:
case .createCollection, .reportCollection:
return .post
case .updateCollection:
return .put
Expand All @@ -52,22 +56,19 @@ extension CollectionAPI: TargetType {
public var task: Moya.Task {
switch self {
case let .fetchCollections(cursor, size):
var parameters: [String: Any] = [
"size": size,
]
var parameters: [String: Any] = ["size": size]
if let cursor {
parameters["cursor"] = cursor
}
return .requestParameters(
parameters: parameters,
encoding: URLEncoding.queryString
)
return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
case let .createCollection(collectionInfo):
return .requestJSONEncodable(collectionInfo)
case let .updateCollection(_, collectionInfo):
return .requestJSONEncodable(collectionInfo)
case .deleteCollection, .fetchCollectionDetail, .fetchRecentViewedCollections:
return .requestPlain
case let .reportCollection(_, reasons, otherDetail):
return .requestJSONEncodable(ReportRequestDTO(reasons: reasons, otherDetail: otherDetail))
}
}
}
25 changes: 20 additions & 5 deletions FLINT/Data/Sources/Networking/Service/AuthService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import DTO
public protocol AuthService {
func signup(userInfo: SignupInfoEntity) -> AnyPublisher<SignupDTO, Error>
func socialVerify(socialAuthCredential: SocialVerifyRequestDTO) -> AnyPublisher<SocialVerifyResponseDTO, Error>
func withDraw() -> AnyPublisher<Void, Error>
func logout() -> AnyPublisher<Void, Error>
func withDraw(agreedTermsIds: [String]) -> AnyPublisher<Void, Error>
}

public final class DefaultAuthService: AuthService {
Expand Down Expand Up @@ -67,10 +68,24 @@ public final class DefaultAuthService: AuthService {
.eraseToAnyPublisher()
}

public func withDraw() -> AnyPublisher<Void, Error> {
authAPIProvider.requestPublisher(.withdraw)
.mapBaseResponseData(BlankData.self)
.map({ _ in })
public func logout() -> AnyPublisher<Void, Error> {
guard let refreshToken = tokenStorage.load(type: .refreshToken) else {
return Fail(error: TokenError.noToken).eraseToAnyPublisher()
}
return authAPIProvider.requestPublisher(.logout(refreshToken: refreshToken))
.logged()
.tryMap { [weak self] response in
guard (200..<300).contains(response.statusCode) else {
throw MoyaError.statusCode(response)
}
self?.tokenStorage.clearAll()
}
.eraseToAnyPublisher()
}

public func withDraw(agreedTermsIds: [String]) -> AnyPublisher<Void, Error> {
return authAPIProvider.requestPublisher(.withdraw(agreedTermsIds: agreedTermsIds))
.logged()
.mapBaseResponseEmpty()
}
}
8 changes: 8 additions & 0 deletions FLINT/Data/Sources/Networking/Service/CollectionService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public protocol CollectionService {
func deleteCollection(collectionId: Int64) -> AnyPublisher<Void, Error>
func fetchCollectionDetail(collectionId: Int64) -> AnyPublisher<CollectionDetailDTO, Error>
func fetchRecentViewedCollections() -> AnyPublisher<CollectionsDTO, Error>
func reportCollection(collectionId: Int64, reasons: [String], otherDetail: String?) -> AnyPublisher<Void, Error>
}

public final class DefaultCollectionService: CollectionService {
Expand Down Expand Up @@ -60,4 +61,11 @@ public final class DefaultCollectionService: CollectionService {
return collectionAPIProvider.requestPublisher(.fetchRecentViewedCollections)
.mapBaseResponseData(CollectionsDTO.self)
}

public func reportCollection(collectionId: Int64, reasons: [String], otherDetail: String?) -> AnyPublisher<Void, Error> {
return collectionAPIProvider.requestPublisher(.reportCollection(collectionId: collectionId, reasons: reasons, otherDetail: otherDetail))
.mapBaseResponseData(BlankData.self)
.map { _ in }
.eraseToAnyPublisher()
}
}
8 changes: 6 additions & 2 deletions FLINT/Data/Sources/RepositoryImpl/AuthRepositoryImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ public final class DefaultAuthRepository: AuthRepository {
.eraseToAnyPublisher()
}

public func withDraw() -> AnyPublisher<Void, Error> {
return authService.withDraw()
public func logout() -> AnyPublisher<Void, Error> {
return authService.logout()
}

public func withDraw(agreedTermsIds: [String]) -> AnyPublisher<Void, Error> {
return authService.withDraw(agreedTermsIds: agreedTermsIds)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,8 @@ public final class DefaultCollectionRepository: CollectionRepository {
.tryMap { try $0.entities }
.eraseToAnyPublisher()
}

public func reportCollection(collectionId: Int64, reasons: [String], otherDetail: String?) -> AnyPublisher<Void, Error> {
return collectionService.reportCollection(collectionId: collectionId, reasons: reasons, otherDetail: otherDetail)
}
}
3 changes: 2 additions & 1 deletion FLINT/Domain/Sources/Repository/AuthRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ import Entity
public protocol AuthRepository {
func signup(userInfo: SignupInfoEntity) -> AnyPublisher<String, Error>
func socialVerify(socialAuthCredential: SocialVerifyEntity) -> AnyPublisher<SocialVerifyResultEntity, Error>
func withDraw() -> AnyPublisher<Void, Error>
func logout() -> AnyPublisher<Void, Error>
func withDraw(agreedTermsIds: [String]) -> AnyPublisher<Void, Error>
}
1 change: 1 addition & 0 deletions FLINT/Domain/Sources/Repository/CollectionRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ public protocol CollectionRepository {
func deleteCollection(collectionId: Int64) -> AnyPublisher<Void, Error>
func fetchCollectionDetail(collectionId: Int64) -> AnyPublisher<CollectionDetailEntity, Error>
func fetchRecentViewedCollections() -> AnyPublisher<[CollectionEntity], Error>
func reportCollection(collectionId: Int64, reasons: [String], otherDetail: String?) -> AnyPublisher<Void, Error>
}
28 changes: 28 additions & 0 deletions FLINT/Domain/Sources/UseCase/Auth/LogoutUseCase.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// LogoutUseCase.swift
// Domain
//
// Created by 소은 on 6/19/26.
//

import Combine
import Foundation

import Repository

public protocol LogoutUseCase {
func callAsFunction() -> AnyPublisher<Void, Error>
}

public final class DefaultLogoutUseCase: LogoutUseCase {

private let authRepository: AuthRepository

public init(authRepository: AuthRepository) {
self.authRepository = authRepository
}

public func callAsFunction() -> AnyPublisher<Void, Error> {
return authRepository.logout()
}
}
6 changes: 3 additions & 3 deletions FLINT/Domain/Sources/UseCase/Auth/WithDrawUseCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Entity
import Repository

public protocol WithDrawUseCase {
func callAsFunction() -> AnyPublisher<Void, Error>
func callAsFunction(agreedTermsIds: [String]) -> AnyPublisher<Void, Error>
}

public final class DefaultWithDrawUseCase: WithDrawUseCase {
Expand All @@ -23,7 +23,7 @@ public final class DefaultWithDrawUseCase: WithDrawUseCase {
self.authRepository = authRepository
}

public func callAsFunction() -> AnyPublisher<Void, Error> {
return authRepository.withDraw()
public func callAsFunction(agreedTermsIds: [String]) -> AnyPublisher<Void, Error> {
return authRepository.withDraw(agreedTermsIds: agreedTermsIds)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// ReportCollectionUseCase.swift
// Domain
//
// Created by 소은 on 6/21/26.
//

import Combine
import Foundation

import Repository

public protocol ReportCollectionUseCase {
func callAsFunction(collectionId: Int64, reasons: [String], otherDetail: String?) -> AnyPublisher<Void, Error>
}

public final class DefaultReportCollectionUseCase: ReportCollectionUseCase {

private let collectionRepository: CollectionRepository

public init(collectionRepository: CollectionRepository) {
self.collectionRepository = collectionRepository
}

public func callAsFunction(collectionId: Int64, reasons: [String], otherDetail: String?) -> AnyPublisher<Void, Error> {
return collectionRepository.reportCollection(collectionId: collectionId, reasons: reasons, otherDetail: otherDetail)
}
}
3 changes: 3 additions & 0 deletions FLINT/FLINT/Dependency/DIContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ typealias DependencyFactory = ViewControllerFactory &
FetchOTTPlatformsForContentUseCaseFactory &
ExploreViewModelFactory &
ProfileViewModelFactory &

SettingViewModelFactory &
WithdrawViewModelFactory &

CreateCollectionViewModelFactory &
AddContentSelectViewModelFactory &
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// LogoutUseCaseFactory..swift
// FLINT
//
// Created by 소은 on 6/19/26.
//

import Foundation

import Domain

protocol LogoutUseCaseFactory: AuthRepositoryFactory {
func makeLogoutUseCase() -> LogoutUseCase
}

extension LogoutUseCaseFactory {
func makeLogoutUseCase() -> LogoutUseCase {
return DefaultLogoutUseCase(authRepository: makeAuthRepository())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// ReportCollectionUseCaseFactory.swift
// FLINT
//
// Created by 소은 on 6/21/26.
//

import Foundation

import Domain

protocol ReportCollectionUseCaseFactory: CollectionRepositoryFactory {
func makeReportCollectionUseCase() -> ReportCollectionUseCase
}

extension ReportCollectionUseCaseFactory {
func makeReportCollectionUseCase() -> ReportCollectionUseCase {
return DefaultReportCollectionUseCase(collectionRepository: makeCollectionRepository())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// ReportViewControllerFactory+.swift
// FLINT
//

import Foundation

import Presentation

extension ReportViewControllerFactory where Self: ReportViewModelFactory & ViewControllerFactory {
func makeReportViewController(collectionId: Int64) -> ReportViewController {
return ReportViewController(
viewModel: makeReportViewModel(collectionId: collectionId),
viewControllerFactory: self
)
}
}
Loading