-
Notifications
You must be signed in to change notification settings - Fork 0
[PC-1614] Billing 모듈 의존성 리팩토링 #201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
- domain 모듈 의존성 제거 - analytics 사용하는 부분 제거
📝 WalkthroughWalkthroughThis PR reorganizes billing-related models into the billing package, adds a Billing DI module, removes analytics calls from BillingHelperImpl, moves payment network sources into core/billing, updates imports across feature modules, and removes some cross-module dependencies. Changes
Sequence Diagram(s)(omitted — changes are refactors and package/DI updates; no new multi-component sequential flow introduced) Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
core/billing/src/main/java/com/puzzle/billing/data/BillingHelperImpl.kt (1)
100-113: Revenue tracking has been removed - consider alternative observability solution.The removal of
AnalyticsHelper.trackRevenueEvent()eliminates revenue tracking for successful purchases. This impacts business metrics, attribution, and monitoring of payment flows.While removing the dependency aligns with the module independence goal, consider:
- Implementing an event callback interface that the Billing module can expose
- Moving analytics tracking to a higher layer that depends on both Billing and Analytics modules
- Using a publish-subscribe pattern to decouple tracking from the core billing logic
Would you like me to suggest an implementation pattern for decoupled event tracking?
🤖 Fix all issues with AI agents
In
@core/billing/src/main/java/com/puzzle/billing/mapper/payment/ProductMapper.kt:
- Around line 35-38: The mapping uses UNKNOWN_INT as a sentinel for missing
reward (VerifyPurchaseProductResponse.toDomain -> rewardPuzzleCount =
rewardPuzzleCount ?: UNKNOWN_INT) but downstream code treats that value
inconsistently; fix this by normalizing the sentinel before returning final
results: update fetchPurchaseReward() to treat UNKNOWN_INT (and any non-positive
value) as "no reward" and either return 0 or null (so callers can handle it
consistently), or alternatively modify handleSinglePurchase() to check the
reward returned and if reward <= 0 (including UNKNOWN_INT) convert it to the
same behavior as batch purchases (e.g., do not return
PurchaseResult.Success(-1); return Success(0) or the appropriate non-reward
path). Ensure you update the code paths that construct PurchaseResult.Success to
never be passed UNKNOWN_INT and reference
VerifyPurchaseProductResponse.toDomain, fetchPurchaseReward(),
handleSinglePurchase(), and PurchaseResult.Success when making the change.
In @core/network/src/main/java/com/puzzle/network/model/ApiResponse.kt:
- Around line 25-27: The unwrapData function performs an unsafe cast (data ?:
Unit as T) that can throw ClassCastException; change its contract to safely
propagate nulls by making the function return a nullable T (fun <T>
ApiResponse<T>.unwrapData(): T? = data) so callers handle absence explicitly, or
alternatively provide an explicit throwing variant (e.g., unwrapDataOrThrow()
that throws a clear IllegalStateException when data is null) and update any
callers of ApiResponse.unwrapData accordingly; locate the function
ApiResponse.unwrapData and replace the unsafe cast with a safe nullable return
or add the explicit throwing helper.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (32)
core/billing/build.gradle.ktscore/billing/src/main/java/com/puzzle/billing/data/BillingHelperImpl.ktcore/billing/src/main/java/com/puzzle/billing/data/PaymentRepositoryImpl.ktcore/billing/src/main/java/com/puzzle/billing/di/BillingModule.ktcore/billing/src/main/java/com/puzzle/billing/domain/BillingHelper.ktcore/billing/src/main/java/com/puzzle/billing/domain/PaymentRepository.ktcore/billing/src/main/java/com/puzzle/billing/mapper/payment/ProductMapper.ktcore/billing/src/main/java/com/puzzle/billing/model/billing/PieceProduct.ktcore/billing/src/main/java/com/puzzle/billing/model/billing/PurchaseResult.ktcore/billing/src/main/java/com/puzzle/billing/model/payment/BasicCashProduct.ktcore/billing/src/main/java/com/puzzle/billing/model/payment/PurchaseProduct.ktcore/billing/src/main/java/com/puzzle/billing/model/payment/VerifyPurchaseProduct.ktcore/billing/src/main/java/com/puzzle/billing/network/source/payment/PaymentDataSource.ktcore/billing/src/main/java/com/puzzle/billing/network/source/payment/PaymentDataSourceImpl.ktcore/billing/src/main/java/com/puzzle/billing/testing/FakeBillingHelper.ktcore/data/build.gradle.ktscore/data/src/main/java/com/puzzle/data/di/DataModule.ktcore/domain/src/main/java/com/puzzle/domain/model/payment/PurchaseProduct.ktcore/network/src/main/java/com/puzzle/network/di/NetworkModule.ktcore/network/src/main/java/com/puzzle/network/model/ApiResponse.ktcore/network/src/main/java/com/puzzle/network/model/payment/GetAvailableProductResponse.ktcore/network/src/main/java/com/puzzle/network/model/payment/VerifyPurchaseProductRequest.ktcore/network/src/main/java/com/puzzle/network/model/payment/VerifyPurchaseProductResponse.ktfeature/matching/src/main/java/com/puzzle/matching/graph/main/MatchingViewModel.ktfeature/store/src/main/java/com/puzzle/store/StoreViewModel.ktfeature/store/src/main/java/com/puzzle/store/contract/StoreIntent.ktfeature/store/src/main/java/com/puzzle/store/contract/StoreSideEffect.ktfeature/store/src/main/java/com/puzzle/store/contract/StoreState.ktfeature/store/src/main/java/com/puzzle/store/ui/list/NormalProductList.ktfeature/store/src/main/java/com/puzzle/store/ui/list/PromotionProductList.ktfeature/store/src/main/java/com/puzzle/store/ui/page/CompactStoreScreen.ktfeature/store/src/main/java/com/puzzle/store/ui/page/ExpandedStoreScreen.kt
💤 Files with no reviewable changes (6)
- core/data/build.gradle.kts
- core/network/src/main/java/com/puzzle/network/di/NetworkModule.kt
- core/network/src/main/java/com/puzzle/network/model/payment/VerifyPurchaseProductRequest.kt
- core/billing/build.gradle.kts
- core/data/src/main/java/com/puzzle/data/di/DataModule.kt
- core/domain/src/main/java/com/puzzle/domain/model/payment/PurchaseProduct.kt
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (27)
core/billing/src/main/java/com/puzzle/billing/model/payment/BasicCashProduct.kt (1)
1-1: LGTM! Clean package relocation.The package has been correctly updated to align with the billing module restructuring.
core/billing/src/main/java/com/puzzle/billing/network/source/payment/PaymentDataSourceImpl.kt (2)
1-3: Package and import updates look correct.The package relocation and updated PurchaseProduct import align with the billing module refactoring.
15-16: Code is correct —toDto()exists as a member function onPurchaseProduct.
PurchaseProductincore/billing/src/main/java/com/puzzle/billing/model/payment/PurchaseProduct.ktdefinestoDto()as a member function (lines 10-14), which returnsVerifyPurchaseProductRequest. The call at line 16 is valid.core/billing/src/main/java/com/puzzle/billing/model/billing/PurchaseResult.kt (1)
1-1: LGTM! Package reorganization aligns with module structure.Moving PurchaseResult to the
billingsubpackage improves organization within the billing module.core/billing/src/main/java/com/puzzle/billing/network/source/payment/PaymentDataSource.kt (1)
1-3: LGTM! Interface relocated to billing module.The package and import updates correctly move
PaymentDataSourceinto the billing module's network layer.feature/store/src/main/java/com/puzzle/store/StoreViewModel.kt (1)
5-7: LGTM! Import paths updated correctly.The import paths have been correctly updated to reflect the new billing module package structure (
com.puzzle.billing.model.billing). No logic changes required.core/network/src/main/java/com/puzzle/network/model/payment/VerifyPurchaseProductResponse.kt (1)
6-10: LGTM! Domain mapping correctly moved to billing mapper.The removal of
toDomain()from this network DTO aligns with the refactoring goal of separating concerns. The mapping logic has been relocated to the billing module's mapper, which improves modularity and keeps network models focused on serialization.feature/matching/src/main/java/com/puzzle/matching/graph/main/MatchingViewModel.kt (1)
5-5: LGTM! Import path updated correctly.The import path has been correctly updated to
com.puzzle.billing.model.billing.PurchaseResult, aligning with the billing module package restructuring.feature/store/src/main/java/com/puzzle/store/ui/list/NormalProductList.kt (1)
11-12: LGTM! Import paths updated correctly.The import paths for
NormalProductandPieceProducthave been correctly updated tocom.puzzle.billing.model.billing, consistent with the billing module restructuring.core/billing/src/main/java/com/puzzle/billing/model/payment/PurchaseProduct.kt (1)
5-15: Confirm the store name format matches backend API expectations.The
toDto()method usesstore.namewhich produces uppercase strings ("PLAY_STORE", "APP_STORE"). Verify with your backend API documentation or contract that it expects this exact uppercase enum format, as REST APIs typically use lowercase (e.g., "play_store") or other conventions.feature/store/src/main/java/com/puzzle/store/ui/page/ExpandedStoreScreen.kt (1)
15-15: LGTM!Import path correctly updated to reflect the new billing model package structure.
feature/store/src/main/java/com/puzzle/store/contract/StoreState.kt (1)
3-3: LGTM!Import paths correctly updated for NormalProduct and PromotionProduct to reflect the new billing model package structure.
Also applies to: 5-5
feature/store/src/main/java/com/puzzle/store/ui/page/CompactStoreScreen.kt (1)
11-11: LGTM!Import path correctly updated to reflect the new billing model package structure.
feature/store/src/main/java/com/puzzle/store/ui/list/PromotionProductList.kt (1)
12-13: LGTM!Import paths correctly updated for PieceProduct and PromotionProduct to reflect the new billing model package structure.
feature/store/src/main/java/com/puzzle/store/contract/StoreIntent.kt (1)
3-3: Import paths successfully updated across the codebase.All billing model imports have been correctly migrated to the new
com.puzzle.billing.model.billingpackage. Verification confirms no old import paths remain in the codebase and all 21 references across feature/store, feature/matching, and core/billing modules use the correct new paths.core/billing/src/main/java/com/puzzle/billing/model/billing/PieceProduct.kt (1)
1-1: LGTM: Clean package relocation.The move to
com.puzzle.billing.model.billingcreates better organization for billing-specific models and aligns with the PR's goal of modularizing the billing component.core/billing/src/main/java/com/puzzle/billing/domain/BillingHelper.kt (1)
4-6: LGTM: Import updates reflect new package structure.The updated import paths correctly reference the relocated model classes while maintaining the existing interface contract.
core/billing/src/main/java/com/puzzle/billing/testing/FakeBillingHelper.kt (1)
5-7: LGTM: Test fake updated consistently.The import updates maintain compatibility with the
BillingHelperinterface while reflecting the new package structure.feature/store/src/main/java/com/puzzle/store/contract/StoreSideEffect.kt (1)
3-3: LGTM: Cross-module import updated correctly.The feature/store module correctly references the relocated
PieceProductfrom the newbilling.model.billingpackage.core/billing/src/main/java/com/puzzle/billing/model/payment/VerifyPurchaseProduct.kt (1)
1-1: LGTM: Model correctly relocated to billing module with all imports updated.Moving
VerifyPurchaseProductfrom the domain module tocom.puzzle.billing.model.paymentaligns with the PR's decoupling objective. All imports have been properly updated across the codebase:
ProductMapper.ktimports and uses it for mappingVerifyPurchaseProductResponsePaymentRepository.ktuses it in theverifyPurchaseProductmethod signatureNo stale imports from the old domain package exist.
core/billing/src/main/java/com/puzzle/billing/domain/PaymentRepository.kt (1)
3-5: LGTM! Import path migration aligns with module decoupling.The imports have been correctly updated to reference the billing module's own model package, supporting the goal of removing domain module dependencies.
core/network/src/main/java/com/puzzle/network/model/payment/GetAvailableProductResponse.kt (1)
9-26: Excellent separation of concerns!Removing
toDomain()mappings from network DTOs is a solid architectural improvement. The network layer now focuses purely on serialization, while domain mapping responsibility has been properly relocated to the billing module's mapper layer.core/billing/src/main/java/com/puzzle/billing/data/PaymentRepositoryImpl.kt (1)
4-17: Clean repository implementation with proper mapper integration.The implementation correctly uses the new mapper layer and updated import paths. The repository pattern is well-structured, delegating to the data source and applying domain mapping via
toDomain()extensions.core/billing/src/main/java/com/puzzle/billing/di/BillingModule.kt (1)
15-35: DI module structure is correct with all implementations properly configured.All three implementation classes have
@Injectconstructors as required:
PaymentDataSourceImplinjectsPieceApiPaymentRepositoryImplinjectsPaymentDataSourceBillingHelperImplinjectsPaymentRepositoryand@ApplicationContext ContextThe bindings follow standard patterns with appropriate singleton scoping.
core/billing/src/main/java/com/puzzle/billing/data/BillingHelperImpl.kt (3)
42-45: LGTM! Constructor simplified correctly.The removal of the
AnalyticsHelperdependency aligns with the PR objective to make the Billing module independent. The constructor signature is cleaner and correctly maintains the required dependencies.
42-277: Overall refactoring structure is well-executed.The billing implementation maintains correct concurrency handling, proper error management, and clean integration with Google Play Billing. The refactoring successfully decouples the module from external dependencies while preserving the core functionality.
18-24: The new package structure is correctly in place and all imports are valid.All seven imported classes (
NormalProduct,PieceProduct,PromotionProduct,PurchaseResult,CashProduct,Product,PurchaseProduct) are properly defined in their respective packages:
com.puzzle.billing.model.billing: ContainsPieceProduct,NormalProduct,PromotionProduct, andPurchaseResultcom.puzzle.billing.model.payment: ContainsCashProduct,Product, andPurchaseProduct
| internal fun VerifyPurchaseProductResponse.toDomain(): VerifyPurchaseProduct = | ||
| VerifyPurchaseProduct( | ||
| rewardPuzzleCount = rewardPuzzleCount ?: UNKNOWN_INT | ||
| ) No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check how UNKNOWN_INT is used across the codebase and verify it's a valid sentinel
echo "=== UNKNOWN_INT definition ==="
rg -n "const val UNKNOWN_INT" --type=kt
echo -e "\n=== VerifyPurchaseProduct usage (check if UNKNOWN_INT is handled) ==="
rg -n "rewardPuzzleCount" --type=kt -A 2 -B 2 -g '!**/test/**'Repository: Piece-Puzzly/Piece-Android
Length of output: 242
🏁 Script executed:
#!/bin/bash
# Check how UNKNOWN_INT is used across the codebase and verify it's a valid sentinel
echo "=== UNKNOWN_INT definition ==="
rg -n "const val UNKNOWN_INT" --glob="*.kt"
echo -e "\n=== UNKNOWN_INT all usages ==="
rg -n "UNKNOWN_INT" --glob="*.kt" -B 1 -A 1
echo -e "\n=== VerifyPurchaseProduct class definition ==="
rg -n "class VerifyPurchaseProduct" --glob="*.kt" -A 5
echo -e "\n=== rewardPuzzleCount property usage ==="
rg -n "rewardPuzzleCount" --glob="*.kt" -B 2 -A 2Repository: Piece-Puzzly/Piece-Android
Length of output: 22812
🏁 Script executed:
#!/bin/bash
echo "=== BillingHelperImpl full context around rewardPuzzleCount ==="
rg -n "rewardPuzzleCount" --glob="*.kt" -B 10 -A 5 core/billing/src/main/java/com/puzzle/billing/data/BillingHelperImpl.kt
echo -e "\n=== BillingHelperImpl interface/contract ==="
rg -n "interface|fun.*rewardPuzzleCount" --glob="*.kt" core/billing/ -B 2 -A 3
echo -e "\n=== How verifyResult is used after return ==="
rg -n "verifyResult" --glob="*.kt" core/billing/Repository: Piece-Puzzly/Piece-Android
Length of output: 4439
🏁 Script executed:
#!/bin/bash
echo "=== handleSinglePurchase full implementation ==="
rg -n "handleSinglePurchase" --glob="*.kt" -A 20 core/billing/
echo -e "\n=== Reward usage in context ==="
rg -n "val reward|fetchPurchaseReward" --glob="*.kt" -B 2 -A 8 core/billing/Repository: Piece-Puzzly/Piece-Android
Length of output: 11213
Address inconsistent handling of UNKNOWN_INT sentinel in purchase reward flow.
The mapper correctly uses UNKNOWN_INT as a fallback, but downstream handling is inconsistent. While batch purchases filter out non-positive rewards (line 221: if (totalReward > 0)), single purchases directly return the reward value without validation (line 118). This means a null rewardPuzzleCount would result in PurchaseResult.Success(-1), which is likely unintended.
Either validate the reward in fetchPurchaseReward() (e.g., filter UNKNOWN_INT before returning) or ensure handleSinglePurchase() handles negative values consistently with batch processing.
🤖 Prompt for AI Agents
In
@core/billing/src/main/java/com/puzzle/billing/mapper/payment/ProductMapper.kt
around lines 35 - 38, The mapping uses UNKNOWN_INT as a sentinel for missing
reward (VerifyPurchaseProductResponse.toDomain -> rewardPuzzleCount =
rewardPuzzleCount ?: UNKNOWN_INT) but downstream code treats that value
inconsistently; fix this by normalizing the sentinel before returning final
results: update fetchPurchaseReward() to treat UNKNOWN_INT (and any non-positive
value) as "no reward" and either return 0 or null (so callers can handle it
consistently), or alternatively modify handleSinglePurchase() to check the
reward returned and if reward <= 0 (including UNKNOWN_INT) convert it to the
same behavior as batch purchases (e.g., do not return
PurchaseResult.Success(-1); return Success(0) or the appropriate non-reward
path). Ensure you update the code paths that construct PurchaseResult.Success to
never be passed UNKNOWN_INT and reference
VerifyPurchaseProductResponse.toDomain, fetchPurchaseReward(),
handleSinglePurchase(), and PurchaseResult.Success when making the change.
| fun <T> ApiResponse<T>.unwrapData(): T { | ||
| return data ?: Unit as T | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: Unsafe cast will cause runtime crashes.
Line 26 contains an unsafe cast: data ?: Unit as T. When data is null and T is not Unit, this will compile but throw a ClassCastException at runtime.
Example failure:
val response = ApiResponse<String>(status = "ok", message = null, data = null)
val result = response.unwrapData() // Returns Unit cast as String → ClassCastExceptionNow that this function is public (accessible from the billing module), the risk of misuse increases.
🔒 Proposed fix
-fun <T> ApiResponse<T>.unwrapData(): T {
- return data ?: Unit as T
+fun <T> ApiResponse<T>.unwrapData(): T {
+ return data ?: throw IllegalStateException("ApiResponse data is null")
}Alternative: Return a nullable type or use a Result wrapper to handle the null case safely.
🤖 Prompt for AI Agents
In @core/network/src/main/java/com/puzzle/network/model/ApiResponse.kt around
lines 25 - 27, The unwrapData function performs an unsafe cast (data ?: Unit as
T) that can throw ClassCastException; change its contract to safely propagate
nulls by making the function return a nullable T (fun <T>
ApiResponse<T>.unwrapData(): T? = data) so callers handle absence explicitly, or
alternatively provide an explicit throwing variant (e.g., unwrapDataOrThrow()
that throws a clear IllegalStateException when data is null) and update any
callers of ApiResponse.unwrapData accordingly; locate the function
ApiResponse.unwrapData and replace the unsafe cast with a safe nullable return
or add the explicit throwing helper.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고생하셨습니다.
둘 다 장단점이 있을 거 같긴 한데 제 생각엔 piece 단일 제품이라 현재 구조도 괜찮지 않을까 싶습니다
| ) | ||
|
|
||
| internal fun VerifyPurchaseProductResponse.toDomain(): VerifyPurchaseProduct = | ||
| VerifyPurchaseProduct( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
최근에 정한 대로 단일 값이면 VerifyPurchaseProduct 만들지 말고 Int로 처리해 주시면 좋을 거 같아요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
7261d61 수정했습니다
| } | ||
|
|
||
| if (verifyResult.rewardPuzzleCount > 0) { | ||
| analyticsHelper.trackRevenueEvent( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
구매 검증 성공 시 로깅은 빼기로 정해졌나요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IOS 는 추가를 일단안한거같기도하고, 정확한 price 가 아니고 퍼즐값이라 일단 제거했어요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
core/billing/src/main/java/com/puzzle/billing/data/BillingHelperImpl.kt (1)
42-45: Analytics tracking for purchase events is missing.The removal of
AnalyticsHelperfrom the constructor eliminated revenue tracking at the billing layer. WhileAnalyticsHelper.trackRevenueEvent()is still available in the codebase, it is never called when purchases succeed. ThePurchaseResult.Successis collected inStoreViewModelandMatchingViewModel, but neither location triggers any revenue or purchase analytics.This results in lost visibility into purchase completions and revenue events, which impacts business intelligence. Either add analytics tracking to the ViewModels that handle
PurchaseResult.Success, or restoreAnalyticsHelpertoBillingHelperImplto track revenue at the source.
🤖 Fix all issues with AI agents
In @core/billing/src/main/java/com/puzzle/billing/domain/PaymentRepository.kt:
- Line 8: Change the repository method signature and mapper to use the domain
model VerifyPurchaseProduct instead of Int: update the suspend fun
verifyPurchaseProduct(purchaseProduct: PurchaseProduct) declaration in
PaymentRepository (and any implementing classes) to return
VerifyPurchaseProduct, then modify the mapping in ProductMapper (the conversion
from VerifyPurchaseProductResponse) to produce a VerifyPurchaseProduct instance
rather than an Int, and adjust callers to consume the domain object; ensure all
compile-time types and imports are updated accordingly.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
core/billing/src/main/java/com/puzzle/billing/data/BillingHelperImpl.ktcore/billing/src/main/java/com/puzzle/billing/domain/PaymentRepository.ktcore/billing/src/main/java/com/puzzle/billing/mapper/payment/ProductMapper.kt
🚧 Files skipped from review as they are similar to previous changes (1)
- core/billing/src/main/java/com/puzzle/billing/mapper/payment/ProductMapper.kt
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (3)
core/billing/src/main/java/com/puzzle/billing/domain/PaymentRepository.kt (1)
3-4: LGTM! Import refactoring aligns with module independence goal.The migration of
CashProductandPurchaseProductfrom the domain module to the billing module successfully decouples the Billing module from external domain dependencies.core/billing/src/main/java/com/puzzle/billing/data/BillingHelperImpl.kt (2)
18-24: LGTM! Clean package reorganization.The import updates reflect the billing module's new independent structure. The namespace changes are consistent with the PR's modularization objectives.
100-113: LGTM! Improved variable naming.The rename from
verifyResulttorewardPuzzleCountmakes the variable's purpose clearer. The simplified return logic is also cleaner.
| interface PaymentRepository { | ||
| suspend fun getAvailableProduct(): CashProduct | ||
| suspend fun verifyPurchaseProduct(purchaseProduct: PurchaseProduct): VerifyPurchaseProduct | ||
| suspend fun verifyPurchaseProduct(purchaseProduct: PurchaseProduct): Int |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if VerifyPurchaseProduct exists in the billing module
echo "=== Searching for VerifyPurchaseProduct in billing module ==="
find core/billing -type f -name "*.kt" | xargs grep -l "VerifyPurchaseProduct" 2>/dev/null || echo "Not found in files"
# Search for definition of VerifyPurchaseProduct
echo -e "\n=== Searching for VerifyPurchaseProduct definition ==="
rg "class|data class|enum|sealed class|object|typealias.*VerifyPurchaseProduct" --type=kotlin
# Check the PaymentRepository file
echo -e "\n=== Content of PaymentRepository.kt ==="
find core/billing -name "PaymentRepository.kt" -type f -exec cat {} \;
# Search for usages of verifyPurchaseProduct method
echo -e "\n=== Finding callers of verifyPurchaseProduct ==="
rg -n "verifyPurchaseProduct" --type=kotlin -B2 -A2Repository: Piece-Puzzly/Piece-Android
Length of output: 50382
🏁 Script executed:
#!/bin/bash
# Get the PaymentRepository.kt file content
echo "=== PaymentRepository.kt content ==="
cat core/billing/src/main/java/com/puzzle/billing/domain/PaymentRepository.kt
echo -e "\n=== VerifyPurchaseProduct.kt content ==="
cat core/billing/src/main/java/com/puzzle/billing/model/payment/VerifyPurchaseProduct.kt
echo -e "\n=== Usages of verifyPurchaseProduct method ==="
rg "verifyPurchaseProduct" --type=kotlin -B3 -A3Repository: Piece-Puzzly/Piece-Android
Length of output: 4815
🏁 Script executed:
#!/bin/bash
# Get PaymentRepositoryImpl to see what toDomain() actually does
echo "=== PaymentRepositoryImpl.kt content ==="
cat core/billing/src/main/java/com/puzzle/billing/data/PaymentRepositoryImpl.kt
# Check for toDomain extension functions
echo -e "\n=== Searching for toDomain extension on VerifyPurchaseProductResponse ==="
rg "fun.*VerifyPurchaseProductResponse.*toDomain" --type=kotlin -A5
# Check ProductMapper which likely has the mapping logic
echo -e "\n=== ProductMapper.kt content ==="
cat core/billing/src/main/java/com/puzzle/billing/mapper/payment/ProductMapper.ktRepository: Piece-Puzzly/Piece-Android
Length of output: 2542
Return type should be VerifyPurchaseProduct instead of Int—this is an architectural inconsistency.
The domain model VerifyPurchaseProduct exists but is not being used. The repository currently returns a raw Int value, which:
- Loses type safety: Primitive
Intlacks semantic meaning; callers cannot distinguish this from other integer values. - Violates clean architecture: Domain repositories should return domain models, not primitives.
- Breaks consistency: Other repository methods (e.g.,
getAvailableProduct()) correctly return domain models (CashProduct).
The current mapper in ProductMapper.kt explicitly converts VerifyPurchaseProductResponse to Int. Update it to return VerifyPurchaseProduct instead, and change the repository interface return type accordingly.
🤖 Prompt for AI Agents
In @core/billing/src/main/java/com/puzzle/billing/domain/PaymentRepository.kt at
line 8, Change the repository method signature and mapper to use the domain
model VerifyPurchaseProduct instead of Int: update the suspend fun
verifyPurchaseProduct(purchaseProduct: PurchaseProduct) declaration in
PaymentRepository (and any implementing classes) to return
VerifyPurchaseProduct, then modify the mapping in ProductMapper (the conversion
from VerifyPurchaseProductResponse) to produce a VerifyPurchaseProduct instance
rather than an Int, and adjust callers to consume the domain object; ensure all
compile-time types and imports are updated accordingly.
1. ⭐️ 변경된 내용
2. 🖼️ 스크린샷(선택)
전
후
전체비교
전


후
3. 💡 알게된 부분
4. 📌 이 부분은 꼭 봐주세요!
Billing module 에서 Retrofit을 사용해서 자체적으로 api 호출까지 수행하고, 완전한 독립모듈로 만드는게 나을지,
현재 구조처럼 기존의 호출부(network) 는 연결하되, 나머지 부분만 독립적으로 진행할지. 의견 부탁드립니다 ~!
@tgyuuAn @comst19
Summary by CodeRabbit
Bug Fixes
Refactor
Behavior Change
✏️ Tip: You can customize this high-level summary in your review settings.