fix(finance): resolve bulk MB dependency ordering, null scan crash, and job status contract - #178
Merged
Merged
Conversation
…d contract The parent job's internal job.Status only knows SUCCESS/FAILED, but the GetBulkMBHeadJobStatusResponse.status field is documented as QUEUED/PROCESSING/DONE/FAILED/PARTIAL. A batch with at least one successful child was reported as raw "SUCCESS" even when some children failed, so frontend polling never recognized the batch as a terminal partial-success state. This maps SUCCESS with FailedChildren() > 0 to PARTIAL and otherwise to DONE, using the same FailedChildren() counter ListBulkMBHeadJobFailures already relies on. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…x NULL scan crash Two guards against the same problem class: cross-head ordering within a bulk transition batch. The mb_bulk_transition worker is a single sequential consumer, so publish order determines processing order — if a batch contains both an MB head and another head it references as a nested RM input, the dependent could be validated before its dependency finished, hitting mbResolveRefProductSysID with mbh_cost_product_id still NULL and crashing on a bare int64 scan. This adds a Kahn's-algorithm topological sort (dependency_order.go) that reorders each batch using a new ListMBRefEdgesForBatch query (mbcomposition.Repository / MBCompositionRepository) before publishing children, falling back to original order on any lookup failure or cycle, and separately hardens mbResolveRefProductSysID to scan mbh_cost_product_id into sql.NullInt64 and return a clear domain error instead of panicking when the referenced head hasn't generated its cost product yet. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
golangci-lint (gocognit) flagged kahnTopoSort at complexity 32 (>20) in CI. Split it into four small helpers (buildDependsOn, isReady, appendReadyNodes, appendStalledInOriginalOrder) with identical logic and iteration order — behavior and tests are unchanged. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This pull request addresses two critical reliability and correctness issues in bulk Material Balance (MB) head processing within the Finance Service:
SUCCESSto eitherPARTIAL(ifFailedChildren() > 0) orDONE, matching the documentedGetBulkMBHeadJobStatusResponse.statuscontract so frontend polling properly recognizes terminal partial-success states.ListMBRefEdgesForBatch), ensuring upstream referenced heads finish prior to dependents. Additionally hardensmbResolveRefProductSysIDto scanmbh_cost_product_idintosql.NullInt64, returning a clean domain error instead of panicking on ungenerated cost products.Type of Change
Service(s) Affected
Changes Made
GetBulkMBHeadJobStatusResponsetranslation to mapjob.Status == SUCCESStoPARTIALwhenFailedChildren() > 0andDONEotherwise, utilizing the existing counter fromListBulkMBHeadJobFailures.dependency_order.gousingListMBRefEdgesForBatch(mbcomposition.Repository) to sequence published transitions in dependency order, with a graceful fallback to original batch order upon cyclic dependencies or lookup errors.mbResolveRefProductSysIDto scanmbh_cost_product_idintosql.NullInt64, safely returning a domain error when cost product reference has not yet been populated.Related Issues
Fixes #
Related to #
API Changes (if applicable)
Proto Changes
# No protobuf changes required; fixes contract adherence to existing proto specificationBreaking Changes
None.
Testing Performed
Unit Tests
Integration Tests
Manual Testing
Lint & Build
golangci-lint run ./...passesgo build ./...succeedsgo test -race ./...passesDatabase (if applicable)
Documentation
Rollback Plan
Revert this PR commit and redeploy
finance-service.Screenshots/Logs (if applicable)
N/A
Pre-merge Checklist
Reviewer Notes
dependency_order.go.mbResolveRefProductSysIDare mapped properly upstream to job failure records.