schemaVersion: 1
suiteId: loan-funding-resilience
owners:
  business: loan-operations-owner
  technical: loan-platform
graph:
  source: ../../../main/resources/bloge/loan-funding.bloge
tags: [critical, starter, resilience]
cases:
  - caseId: funding-success
    title: 放款完成后通知借款人
    requirementRefs: [LOAN-FUNDING-001]
    oracle: {type: APPROVED_EXAMPLE, sourceRef: starter-policy:funding-success, owner: loan-operations-owner}
    given:
      context: {applicationId: LA-FUND-1, caseName: success}
    when: {action: EXECUTE}
    then:
      outcome: SUCCESS
      expectations:
        - expectationId: funding-notified
          scope: BUSINESS_CONTRACT
          actual: {kind: BUSINESS_OUTPUT, outputId: fundingStatus}
          matcher: EQUALS
          expected: notified
  - caseId: transient-booking-retried
    title: 账务预订瞬时失败后重试成功
    requirementRefs: [LOAN-FUNDING-002]
    oracle: {type: APPROVED_EXAMPLE, sourceRef: starter-policy:funding-retry, owner: loan-operations-owner}
    given:
      context: {applicationId: LA-FUND-2, caseName: retry}
    when: {action: EXECUTE}
    then:
      outcome: SUCCESS
      expectations:
        - expectationId: retried-funding-notified
          scope: BUSINESS_CONTRACT
          actual: {kind: BUSINESS_OUTPUT, outputId: fundingStatus}
          matcher: EQUALS
          expected: notified
        - expectationId: first-booking-attempt-retried
          scope: STRUCTURAL_CONTRACT
          actual: {kind: INVOCATION, nodeId: bookDisbursement, attempt: 0, pointer: /terminal/retryDisposition}
          matcher: EQUALS
          expected: RETRY_SCHEDULED
        - expectationId: second-booking-attempt-completed
          scope: STRUCTURAL_CONTRACT
          actual: {kind: INVOCATION, nodeId: bookDisbursement, attempt: 1, pointer: /terminal/outcome}
          matcher: EQUALS
          expected: SUCCESS
  - caseId: booking-fallback-used
    title: 账务预订重试耗尽后采用受控降级结果
    requirementRefs: [LOAN-FUNDING-002]
    oracle: {type: APPROVED_EXAMPLE, sourceRef: starter-policy:funding-fallback, owner: loan-operations-owner}
    given:
      context: {applicationId: LA-FUND-4, caseName: fallback}
    when: {action: EXECUTE}
    then:
      outcome: SUCCESS
      expectations:
        - expectationId: fallback-funding-notified
          scope: BUSINESS_CONTRACT
          actual: {kind: BUSINESS_OUTPUT, outputId: fundingStatus}
          matcher: EQUALS
          expected: notified
        - expectationId: booking-fallback-was-applied
          scope: STRUCTURAL_CONTRACT
          actual: {kind: INVOCATION, nodeId: bookDisbursement, attempt: 2, pointer: /terminal/retryDisposition}
          matcher: EQUALS
          expected: FALLBACK_APPLIED
  - caseId: notification-failure-compensated
    title: 通知失败后撤销账务预订并释放资金
    requirementRefs: [LOAN-FUNDING-003]
    oracle: {type: APPROVED_EXAMPLE, sourceRef: starter-policy:funding-compensation, owner: loan-operations-owner}
    given:
      context: {applicationId: LA-FUND-5, caseName: compensate}
    when: {action: EXECUTE}
    then:
      outcome: FAILURE
      expectations:
        - expectationId: notification-failure-is-terminal
          scope: BUSINESS_CONTRACT
          actual: {kind: GRAPH_ERROR, nodeId: notifyBorrower, pointer: /errorType}
          matcher: EQUALS
          expected: com.leanowtech.bloge.core.exception.NonRetryableException
        - expectationId: booking-was-reversed
          scope: STRUCTURAL_CONTRACT
          actual: {kind: COMPENSATION, nodeId: bookDisbursement, pointer: /success}
          matcher: EQUALS
          expected: true
        - expectationId: funds-were-released
          scope: STRUCTURAL_CONTRACT
          actual: {kind: COMPENSATION, nodeId: reserveFunds, pointer: /success}
          matcher: EQUALS
          expected: true
