High-Level Design
The service layer resides behind an api gateway which handles all the authentication and rate limiting/load balancing etc. All our databases to start of can be Postgres. Postgres is reasonably optimal for both write and read operations and as the system evolves if the reads/writes scale and we deem it to be sub optimal at that point we can shift to either DynamoDB or Cassandra.
- The addMerchant service adds a new merchant that needs to be onboarded and updates the database after running validation checks.
- The addStore service and addProduct service are used to add stores and products and update the database.
- The addItemToCart adds any item to cart after checking the inventory. The inventory should be its own database isolated from the product/store/merchant database. We are still in the OLTP phase of the system and we also wanted to consider avoiding cross tenant leaks. This provides with that. Any time a client selects a product variety to the cart, this service checks the inventory table and updates the cart accordingly. When multiple users try to reach out to the same last remaining product at the same time (concurrent processes) - we can lock out an entire row of the inventory to prevent parallel item additions.
- The removeItemToCart adds an item back to the inventory removing it from the cart.
- Once the cart is finalized and ready to be ordered, the createOrder service creates an order with the potential transaction amount. The transactions/orders reside in their own Database.
- The createPaymentIntent service creates a new payment intent to process the order transaction, and the createPayment service process the transaction interacting with the external payment system.
The cartId would be an idempotent key for the cart. The paymentIntentId would be an idempotent key for a transaction. The paymentIntent table which would capture each stage of the potential transaction will have its own idempotency key for each stage of the process. The inventory system comprises of a redis cache for frequently ordered items with a short TTL - may be an hour or so which could be configured to be lower during the festive or holiday season. This enables the system to respond fast to inventory items being present and Redis provides idempotency with its key value structure provides fast atomic coordination.