dry run migration
This commit is contained in:
@@ -3,76 +3,28 @@
|
||||
# @SEMANTICS: Finance, ACID, Transfer, Ledger
|
||||
# @PURPOSE: Core banking transaction processor with ACID guarantees.
|
||||
# @LAYER: Domain (Core)
|
||||
# @RELATION: DEPENDS_ON -> [DEF:Infra:PostgresDB]
|
||||
# @RELATION: DEPENDS_ON -> [DEF:Infra:AuditLog]
|
||||
# @RELATION: DEPENDS_ON ->[DEF:Infra:PostgresDB]
|
||||
#
|
||||
# @INVARIANT: Total system balance must remain constant (Double-Entry Bookkeeping).
|
||||
# @INVARIANT: Negative transfers are strictly forbidden.
|
||||
# @INVARIANT: No partial commit must occur under failure (ACID Atomicity).
|
||||
|
||||
# @TEST_CONTRACT: TransferInput ->
|
||||
# {
|
||||
# required_fields: {
|
||||
# sender_id: str,
|
||||
# receiver_id: str,
|
||||
# amount: Decimal
|
||||
# },
|
||||
# invariants: [
|
||||
# "amount > 0",
|
||||
# "sender_id != receiver_id"
|
||||
# ],
|
||||
# constraints: [
|
||||
# "sender must exist",
|
||||
# "receiver must exist"
|
||||
# ]
|
||||
# }
|
||||
# --- Test Specifications (The "What" and "Why", not the "Data") ---
|
||||
# @TEST_CONTRACT: Input -> TransferInputDTO, Output -> TransferResultDTO
|
||||
|
||||
# @TEST_CONTRACT: TransferResult ->
|
||||
# {
|
||||
# required_fields: {
|
||||
# tx_id: str,
|
||||
# status: str,
|
||||
# new_balance: Decimal
|
||||
# },
|
||||
# invariants: [
|
||||
# "status == COMPLETED implies balance mutation occurred"
|
||||
# ]
|
||||
# }
|
||||
# Happy Path
|
||||
# @TEST_SCENARIO: sufficient_funds -> Returns COMPLETED, balances updated.
|
||||
# @TEST_FIXTURE: sufficient_funds -> file:./__tests__/fixtures/transfers.json#happy_path
|
||||
|
||||
# @TEST_FIXTURE: sufficient_funds ->
|
||||
# {
|
||||
# sender_balance: 500.00,
|
||||
# receiver_balance: 100.00,
|
||||
# amount: 100.00
|
||||
# }
|
||||
# Edge Cases (CRITICAL)
|
||||
# @TEST_SCENARIO: insufficient_funds -> Throws BusinessRuleViolation("INSUFFICIENT_FUNDS").
|
||||
# @TEST_SCENARIO: negative_amount -> Throws BusinessRuleViolation("Transfer amount must be positive.").
|
||||
# @TEST_SCENARIO: self_transfer -> Throws BusinessRuleViolation("Cannot transfer to self.").
|
||||
# @TEST_SCENARIO: audit_failure -> Throws RuntimeError("TRANSACTION_ABORTED").
|
||||
# @TEST_SCENARIO: concurrency_conflict -> Throws DBTransactionError.
|
||||
|
||||
# @TEST_EDGE: insufficient_funds ->
|
||||
# {
|
||||
# sender_balance: 50.00,
|
||||
# receiver_balance: 100.00,
|
||||
# amount: 100.00
|
||||
# }
|
||||
#
|
||||
# @TEST_EDGE: negative_amount ->
|
||||
# {
|
||||
# sender_balance: 500.00,
|
||||
# receiver_balance: 100.00,
|
||||
# amount: -10.00
|
||||
# }
|
||||
#
|
||||
# @TEST_EDGE: self_transfer ->
|
||||
# {
|
||||
# sender_id: "acc_A",
|
||||
# receiver_id: "acc_A",
|
||||
# amount: 10.00
|
||||
# }
|
||||
|
||||
# @TEST_EDGE: audit_failure -> raises Exception
|
||||
# @TEST_EDGE: concurrency_conflict -> special: concurrent_execution
|
||||
|
||||
# @TEST_INVARIANT: total_balance_constant -> verifies: [sufficient_funds, concurrency_conflict]
|
||||
# @TEST_INVARIANT: no_partial_commit -> verifies: [audit_failure]
|
||||
# @TEST_INVARIANT: negative_transfer_forbidden -> verifies: [negative_amount]
|
||||
# Linking Tests to Invariants
|
||||
# @TEST_INVARIANT: total_balance_constant -> VERIFIED_BY: [sufficient_funds, concurrency_conflict]
|
||||
# @TEST_INVARIANT: negative_transfer_forbidden -> VERIFIED_BY: [negative_amount]
|
||||
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
Reference in New Issue
Block a user