Migration Guide: calculatecost2 to calculatecost4¶
Import mapping, deleted modules, and validation procedure for migrating from the
legacy src.calculateCost2 package to calculatecost4.
Import Mapping¶
Handler¶
| Old import | New import |
|---|---|
src.calculateCost2.calculatecost2Lambda.calculatecost2Lambda |
calculatecost4.handler.calculatecost4Lambda |
Core Models¶
| Old import | New import |
|---|---|
src.calculateCost2.schema.order.Order |
calculatecost4.core.models.order.Order |
src.calculateCost2.schema.product.Product |
calculatecost4.core.models.product.Product |
src.calculateCost2.schema.shipping.* |
calculatecost4.core.models.shipping.* |
src.calculateCost2.schema.voucher.Voucher |
calculatecost4.core.models.voucher.Voucher |
src.calculateCost2.coupon.discount.* |
calculatecost4.core.models.discount.* |
Adapters (DB and Service Calls)¶
| Old import | New import |
|---|---|
src.calculateCost2.product.getPrice.* |
calculatecost4.adapters.dynamodb_pricing.* |
src.calculateCost2.product.getProduct.* |
calculatecost4.adapters.dynamodb_product.* |
src.calculateCost2.shipping.shippingCalculator.* |
calculatecost4.core.shipping_calc.* |
src.calculateCost2.voucher.getVoucher.* |
calculatecost4.adapters.lambda_voucher.* |
src.calculateCost2.coupon.couponCalculator.* |
calculatecost4.adapters.lambda_coupon.* |
Deleted¶
| Old import | Status |
|---|---|
src.calculateCost2.pipeThrough.* |
DELETED |
What Was Deleted¶
pipeThrough.py¶
The pipeThrough module was an HTTP proxy that forwarded requests to the legacy
calculatecost API endpoint. It existed as a fallback during the calculatecost2
migration period. In calculatecost4, the handler processes requests directly.
There is no proxy layer.
resolve-coupon-master Fallback¶
The legacy handler had a fallback path that invoked resolve-coupon-master when
the primary coupon Lambda failed. This fallback is removed. Coupon service failures
now propagate as errors.
What Changed¶
DB Calls Moved from Model Properties to Injected Services¶
In calculatecost2, models made direct AWS calls from within their properties:
# Old: Product.price was a property that called DynamoDB
class Product:
@property
def price(self):
return getPrice(self.cprcode, self.branchId)
In calculatecost4, models are plain data containers. AWS calls are made by adapter classes that implement Protocol interfaces. The handler wires adapters into the calculation pipeline at Lambda startup:
# New: Price is injected by the calculator
product.inject_price(pricing_service.get_price(cprcode, branch_id))
This separation enables: - Unit testing with mock services (no AWS credentials needed) - Swapping adapters (DynamoDB -> in-memory, Lambda -> local) - Clear dependency boundaries between core logic and infrastructure
Validation Procedure¶
Run the equivalence test to verify that calculatecost4 produces identical output to calculatecost2 for all test fixtures:
The equivalence test:
1. Loads each YAML fixture from test/testData/
2. Runs the fixture through both calculatecost2 and calculatecost4 handlers
3. Compares the response bodies field by field
4. Fails on any difference in computed fields (passthrough fields are excluded)
Fields compared:
| Field | Tolerance |
|---|---|
grandTotal |
Exact |
subTotal |
Exact |
cartDiscount |
Exact |
bogoDiscount |
Exact |
deliveryFee |
Exact |
voucherDiscount |
Exact |
shippingDiscount |
Exact |
expressShippingCost |
Exact |
totalWeight |
Exact |
discountedDeliveryFee |
Exact |
Per-product price |
Exact |
Per-product rowTotal |
Exact |
Per-product weight |
Exact |
Per-schedule deliveryFee |
Exact |
Per-schedule expressFee |
Exact |