Skip to content

Architecture

calculatecost4 uses a two-layer architecture separating pure business logic from AWS infrastructure.


System Overview

flowchart TB
  Client["Client\nPOST /calculatecost4"]
  APIGW["API Gateway\napi.villaecommerce.com"]
  Handler["handler.py\nLambda entry point\nAccount 017176210331"]

  subgraph core_group ["Core -- Pure Python"]
    Calc[CostCalculator]
    OrderModel[Order]
    ProductModel[Product]
    Totals[totals.py]
    ShipCalc[shipping_calc.py]
    WeightCalc[weight.py]
  end

  subgraph iface_group [Interfaces -- Protocols]
    IP[PricingService]
    IPL[ProductLookupService]
    IS[ShippingPriceService]
    IC[CouponService]
    IV[VoucherService]
    ICL[ControlledProductService]
  end

  subgraph adapter_group ["Adapters -- AWS/HTTP"]
    DDBPrice[DynamoDBPricingService]
    DDBProd[DynamoDBProductLookup]
    HTTPShip[CompositeShippingPrice]
    LCoup[LambdaCouponService]
    LVouch[LambdaVoucherService]
    HTTPCtrl[HTTPControlledProducts]
  end

  subgraph source_account ["Source Account -- 394922924679"]
    DDB1["DynamoDB\nprice-database-2"]
    DDB2["DynamoDB\nproduct-table"]
    Lamb1["Lambda\ncoupon3-checker-dev"]
    Lamb2["Lambda\nget-voucher-master"]
    Lamb3["Lambda\nnationwide-delivery"]
    PolygonAPI["HTTP\nPolygon API"]
  end

  STS["cross_account.py\nSTS AssumeRole"]

  Client --> APIGW --> Handler
  Handler --> core_group
  core_group --> iface_group
  adapter_group -.->|implements| iface_group
  DDBPrice --> DDB1
  DDBProd --> DDB2
  LCoup --> Lamb1
  LVouch --> Lamb2
  HTTPShip --> Lamb3
  HTTPShip --> PolygonAPI
  adapter_group --> STS
  STS --> source_account

Request Flow

sequenceDiagram
    participant C as Client
    participant AG as API Gateway
    participant H as handler.py
    participant CC as CostCalculator
    participant P as PricingService
    participant S as ShippingPriceService
    participant Cp as CouponService
    participant V as VoucherService

    C->>AG: POST /calculatecost4
    AG->>H: Lambda event
    H->>CC: calculate(order_dict)
    CC->>P: get_price(cprcode, brcode)
    P-->>CC: price
    CC->>S: get_regular_price(lat, lon, brcode)
    S-->>CC: shipping fee
    CC->>Cp: check_coupons(order_dict)
    Cp-->>CC: DiscountResult
    CC->>V: get_voucher(voucher_id)
    V-->>CC: Voucher
    CC-->>H: order.to_dict()
    H-->>AG: {statusCode: 200, body: ...}
    AG-->>C: JSON response

Layer Responsibilities

Core (calculatecost4/core/)

Pure Python. Zero AWS imports. Contains:

  • Models: Order, Product, Shipping, Schedule, Voucher, Discount, DiscountResult, TotalSummary
  • Calculator: CostCalculator orchestrates the full pipeline
  • Formulas: totals.py (grand total, subtotal, discount aggregation)
  • Shipping: shipping_calc.py (per-schedule fee calculation)
  • Weight: weight.py (product weight lookup and schedule aggregation)
  • Coupon: coupon.py (CouponOrder payload builder)

Interfaces (calculatecost4/interfaces/)

Python Protocol classes defining abstract contracts:

Interface Methods
PricingService get_price, get_original_price
ProductLookupService get_product
ControlledProductService get_controlled_product_list
ShippingPriceService get_regular_price, get_nationwide_price
CouponService check_coupons
VoucherService get_voucher

Adapters (calculatecost4/adapters/)

Concrete implementations using AWS services:

Adapter Interface External Service
DynamoDBPricingService PricingService DynamoDB: price-database-2-dev-manual
DynamoDBProductLookup ProductLookupService DynamoDB: product-table-dev-manual
HTTPControlledProducts ControlledProductService HTTP: shop.villamarket.com
CompositeShippingPrice ShippingPriceService HTTP: Polygon API + Lambda: nationwide
LambdaCouponService CouponService Lambda: coupon3-checker-dev
LambdaVoucherService VoucherService Lambda: get-voucher-master

Cross-Account Access

All adapters use cross_account.py which performs STS AssumeRole to access resources in the source account (394922924679) from the villa-ecommerce account (017176210331).


Interactive Diagram

Download the architecture.excalidraw file and open it in Excalidraw for an interactive, editable version of the architecture diagram.