Project Overview¶
What is villaCalculateCost4¶
villaCalculateCost4 is a cost calculation engine for Villa Market e-commerce. It replaces the legacy calculatecost2 and calculatecost3 systems with a clean, testable, dependency-injected architecture.
The service processes customer orders end-to-end through the following pipeline:
- Product price lookup from DynamoDB (compressed feather data per branch)
- Weight retrieval from the product master table
- Controlled product check via HTTP API
- Shipping fee calculation with three routing paths:
- Bangkok polygon API for REGULAR and EXPRESS modes
- Lambda invocation for NATIONWIDE mode
- EXPRESS adds a 50 THB surcharge on the first schedule
- PICKUP mode has zero cost
- Coupon discount validation via Lambda (
coupon3-checker-dev) - Voucher validation via Lambda (
get-voucher-master) - Financial totals computation (subtotal, discounts, delivery fees, grand total)
- Response serialization with enriched product data, shipping breakdown, and financial summary
The result is an enriched order with complete financial breakdowns that downstream systems use for checkout, payment, and order placement.
Goals¶
1. Clean architecture with a pure Python core¶
The core business logic (calculatecost4/core/) contains zero AWS imports. No boto3, no pynamodb, no requests. All external I/O is abstracted behind Protocol interfaces. The core can be packaged and shared as a standalone Python library.
2. Dependency injection via Protocol interfaces¶
Every external service is defined as a Python Protocol in calculatecost4/interfaces/. There are six protocol interfaces:
PricingService-- product price lookupsProductLookupService-- product master data (weight)ControlledProductService-- controlled product listShippingPriceService-- delivery fee calculation (regular + nationwide)CouponService-- coupon validation and discount computationVoucherService-- voucher retrieval and validation
Each protocol has one or more concrete adapters in calculatecost4/adapters/. Tests inject mock implementations that require no network access or AWS credentials.
3. Cross-account deployment¶
The service runs in the villa-ecommerce AWS account (017176210331) but accesses DynamoDB tables in the source account (394922924679). Cross-account access is managed through STS AssumeRole, implemented in calculatecost4/adapters/cross_account.py. The assumed role provides read-only access to:
price-database-2-dev-manual(product prices)product-table-dev-manual(product master data)
4. Output equivalence¶
villaCalculateCost4 produces identical results to the original deployed calculatecost2 endpoint. This is proven through 27 integration tests that run against 10 real paid production orders. Each test submits the original order payload to both the legacy endpoint and the new endpoint, then compares every field in the response.
5. TDD with 100% coverage target¶
All code is written test-first using the RED-GREEN-REFACTOR cycle. The current test suite contains over 200 unit tests covering models, formulas, weight calculation, shipping routing, coupon payload building, and the full calculator orchestration.
6. Comprehensive documentation¶
The project maintains a full documentation site at docs.villaecommerce.com, built with MkDocs Material and deployed via GitHub Actions from the villa-ecommerce-docs repository.
7. Future roadmap¶
- Internalize coupon logic (currently delegated to an external Lambda)
- Add structured error codes for all failure modes
- Migrate to a faster runtime (Rust) for lower latency and memory usage
- Batch and parallelize downstream service calls
Project Status¶
| Component | Status | Details |
|---|---|---|
| Core business logic | Complete | 200+ unit tests, pure Python, zero AWS imports |
| Protocol interfaces | Complete | 6 protocols defined |
| Adapters | Complete | 7 real implementations + cross-account STS |
| Integration tests | Complete | 27/27 pass against deployed original |
| Deployment | Live | api.villaecommerce.com/calculatecost4 |
| Documentation site | Live | docs.villaecommerce.com |
| Test UI | Live | test.villaecommerce.com |
| Pull request | Open | github.com/thanakijwanavit/villaCalculateCost4/pull/1 |
Tech Stack¶
| Category | Technology |
|---|---|
| Language | Python 3.12 |
| Runtime | Docker Lambda (AWS SAM) |
| Database | DynamoDB (PynamoDB-compatible via boto3) |
| Data processing | pandas, pyarrow (feather decompression for price tables) |
| AWS SDK | boto3 (Lambda invocations, STS AssumeRole, DynamoDB access) |
| HTTP client | requests (polygon shipping API, controlled products API) |
| Caching | diskcache (adapter-level, /tmp/ with TTL) |
| Testing | pytest, pytest-cov |
| Documentation | MkDocs Material |
| CI/CD | GitHub Actions (docs deployment) |
| IaC | AWS SAM (template.yaml) |
Repository Structure¶
villaCalculateCost4/
calculatecost4/ # Application code
core/ # Pure Python business logic (no AWS imports)
models/ # Data models
product.py # Product line item
order.py # Order container
shipping.py # Shipping, Schedule, enums
voucher.py # Voucher with validity checks
discount.py # Discount, DiscountResult
summary.py # TotalSummary
types.py # Semantic type aliases
calculator.py # CostCalculator orchestrator
totals.py # Financial formula functions
weight.py # Weight accumulation per schedule
shipping_calc.py # Shipping fee routing (mode dispatch)
coupon.py # CouponOrder payload builder
exceptions.py # All custom exceptions
interfaces/ # Protocol definitions (6 services)
pricing.py # PricingService protocol
product_lookup.py # ProductLookupService protocol
controlled_products.py # ControlledProductService protocol
shipping_price.py # ShippingPriceService protocol
coupon.py # CouponService protocol
voucher.py # VoucherService protocol
adapters/ # AWS/HTTP implementations
dynamodb_pricing.py # DynamoDB price lookup
dynamodb_product.py # DynamoDB product master lookup
http_controlled_products.py # HTTP controlled product list
http_regular_price.py # HTTP polygon shipping API
lambda_nationwide.py # Lambda nationwide shipping
lambda_coupon.py # Lambda coupon validation
lambda_voucher.py # Lambda voucher retrieval
cross_account.py # STS AssumeRole session management
handler.py # Lambda entry point
app.py # Docker CMD target
Dockerfile
requirements.txt
test/ # All tests
core/ # Unit tests (no AWS needed)
models/ # Model tests
test_calculator.py # Calculator orchestration tests
test_totals.py # Formula tests
test_weight.py # Weight calculation tests
test_shipping_calc.py # Shipping routing tests
test_coupon.py # Coupon payload tests
interfaces/ # Protocol conformance tests
test_protocols.py
adapters/ # Adapter tests (mocked boto3/requests)
test_adapters.py
integration/ # E2E tests (real AWS + deployed endpoints)
fixtures/ # 10 real production order fixtures
test_cross_account_e2e.py # YAML fixtures vs deployed endpoints
test_real_orders_e2e.py # Real paid orders vs deployed endpoints
testData/ # YAML test fixtures (11 files)
test_handler.py # Lambda handler wiring tests
requirements/ # Source documentation (markdown)
test-ui/ # Browser-based API test interface
template.yaml # SAM deployment template
URLs¶
| Resource | URL |
|---|---|
| API Endpoint | https://api.villaecommerce.com/calculatecost4 |
| Documentation | https://docs.villaecommerce.com |
| Test UI | https://test.villaecommerce.com |
| Source Code | https://github.com/thanakijwanavit/villaCalculateCost4 |
| Docs Repo | https://github.com/thanakijwanavit/villa-ecommerce-docs |