MarianaDmytrivBinariks commented on PR #6477:
URL: https://github.com/apache/fineract/pull/6477#issuecomment-5793276419

   > > @mariiaKraievska Please review my concerns / findings:
   > > 
   > > 1. updateFrom resolves the bucket before the change check
   > > 
   > > WorkingCapitalLoanAssemblerImpl.java:420-429
   > > if (fromApiJsonHelper.parameterExists(delinquencyBucketIdParamName, 
element)) { final Long bucketId = ...; final DelinquencyBucket bucket = 
resolver.findWorkingCapitalBucketByIdIfProvided(bucketId); // always runs final 
Long existingBucketId = ...; if (!Objects.equals(bucketId, existingBucketId)) { 
... } }
   > > The lookup + type validation runs unconditionally, outside the 
!Objects.equals(...) guard. The three sibling blocks around it (breachId, 
nearBreachId, delinquencyGraceDays) all gate the lookup on the change check. 
Consequence: a WC loan created before this PR with a REGULAR bucket (the old 
code was findById(bucketId).orElse(null) with no type check, so this was 
reachable) can no longer be modified at all if the client resends the unchanged 
delinquencyBucketId — it 400s on a no-op. Same shape for a since-deleted id, 
which used to be silently ignored and now throws 
DelinquencyBucketNotFoundException.
   > > Moving the resolve inside the if fixes both and matches the surrounding 
style. The WC product update path already does this correctly via 
isChangeInLongParameterNamed 
(WorkingCapitalLoanProductWritePlatformServiceImpl.java:276), as does the LP 
update path.
   > > 
   > > 2. Error codes and unused message args
   > > 
   > > Both new errors pass the bucket id as a defaultUserMessageArgs value, 
but neither message has a {0} placeholder, so it's never rendered. The codes 
also drop the entity segment that the rest of the codebase uses 
(validation.msg.delinquencyBucketId.must.be.regular.type vs. the conventional 
validation.msg.loanproduct.delinquencyBucketId.…). The two messages are 
otherwise near-identical — one code parameterized by expected type would do.
   > > 
   > > 3. retrieveWorkingCapitalDelinquencyBucketOptions() returns null when 
empty
   > > 
   > > WorkingCapitalDelinquencyBucketResolver.java:46-50. This preserves the 
old serialization behaviour, but it pushes null-returning into a shared service 
method that now has two callers (WC product template and, transitively, the WC 
loan template). Returning List.of() and keeping the null-ing at the 
response-building boundary would be safer.
   > > 
   > > 4. Duplication
   > > 
   > > retrieveAllDelinquencyBuckets() and retrieveDelinquencyBucketsByType() 
are identical apart from the finder 
(DelinquencyReadPlatformServiceImpl.java:105-119). Also 
validateIsWorkingCapitalType is public but only called from within its own 
class.
   > > 
   > > 5. Test-side nits
   > > 
   > > DelinquencyBucketResolver.resolveBucketId calls resolve(...) on this, so 
Spring's @Cacheable proxy is bypassed — every resolution re-fetches all 
buckets. Not a correctness issue. WorkingCapitalLoanAccount.feature still 
hardcodes delinquencyBucketId | 1 in three existing scenarios. Harmless today 
(buildCreateLoanRequest ignores column 7, and the negative scenario fails in 
the validator before the assembler), but the seeded bucket ids are genuinely 
nondeterministic — DelinquencyGlobalInitializerStep.initialize() creates 
BASIC_DELINQUENCY_BUCKET and WC_DELINQUENCY_BUCKET via 
ParallelExecutionHelper.runInParallel. Now that resolveBucketId accepts names, 
those literals are worth converting before someone wires column 7 up. 
LoanProduct.feature C106741 creates a loan product and leaves it behind; the WC 
counterpart C106744 deletes its product.
   > 
   > From 1-4 addressed, thanks:
   > 
   > 1. moved bucket validation inside `isChangeInLongParameterNamed`, same 
pattern as breach/nearBreach and WC product update
   > 2. Error codes — shared message template parameterized by expected type
   > 3. null from resolver— `retrieveWorkingCapitalDelinquencyBucketOptions()` 
returns the list as-is. empty → `null` only at the product template response.
   > 4. Duplication — `retrieveAll` / `byType` share `mapAndEnrich`. 
`validateIsWorkingCapitalType` is private.
   > 
   > @MarianaDmytrivBinariks told me she is working on 5th. Please correct me 
if I`m wrong
   
   @mariiaKraievska yes, you're right
   5. 
    - DelinquencyBucketResolver.resolveBucketId calls resolve(...) on this, so 
Spring's @Cacheable proxy is bypassed — every resolution re-fetches all 
buckets. Not a correctness issue.  - fixed
    - WorkingCapitalLoanAccount.feature still hardcodes delinquencyBucketId | 1 
in three existing scenarios. - fixed
    - LoanProduct.feature C106741 creates a loan product and leaves it behind; 
the WC counterpart C106744 deletes its product. - regular loan product have no 
delete endpoint at all, so it can't be done


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to