Neetable · SDE2 · Bengaluru · 2022–2024
One trade. Two apps. A schema they both trust.
WorldTradeX is a B2B marketplace, and I was responsible for both sides of it: the buyer app and the seller app. This was the year I started looking at how enterprise software is actually put together. The trade had to live in one place, on AWS. GraphQL was the technology I learned so each app could ask for its own view of that trade.
A marketplace is two jobs
A buyer is searching, comparing, paying, and tracking a shipment. A seller is listing inventory, accepting the order, fulfilling it, and watching the payout. Those are different products. They are also the same trade, seen from opposite ends of the counter. Owning both apps meant I could not treat a checkout screen as finished until the seller's order screen still meant the same thing.
The feature surface was the marketplace itself. Payments, orders, inventory, real-time notifications, search, recommendations, analytics, checkout. The engineering problem under that list was agreement. Two companies, two phones, and an admin dashboard all had to be looking at one order. Enterprise software, as I was learning it, is several clients that have to agree.
One domain, two shells
An order, a payment, and a unit of inventory exist once. The buyer renders them as checkout and tracking. The seller renders them as fulfillment and stock. If that model is written inside the buyer app, the seller app grows a second copy, and the copies drift the first time a status means something slightly different on each side.
So the architecture was two application shells on one domain. The widgets stayed thin. The rules around an order sat outside the screen, in BLoC and GetX, where both apps could share types. A buyer flow could grow a new checkout step, and a seller flow could grow a new fulfillment step, and neither one got to redefine what an order is. Both apps were going to get larger. The trade had to stay one object while they did.
AWS holds the trade
A phone is a bad place to decide a trade. The other party is a different device, usually a different company. Payment, stock, and order status have to commit where both of them can see the result. That place was AWS. I integrated the APIs the apps called, and I worked on the admin dashboard and the backend far enough to test and release with them.
Real-time notifications come from the same rule. A seller confirms, and the buyer has to hear it. A buyer pays, and the seller's inventory view has to move. The event is a consequence of the commit on AWS. Each app is told what happened. It does not decide that it happened.
GraphQL is the question each screen asks
This is where I learned GraphQL. Some of the AWS APIs were already REST: a resource, one payload, the same document for whoever called it. A buyer screen and a seller screen do not want the same document. The buyer needs price, the counterparty, shipping, and payment state. The seller needs quantity, the stock impact, and the payout. Handing both apps the full document makes each of them parse fields it never renders. Cutting the resource into a buyer endpoint and a seller endpoint cuts the contract, and then a status gets renamed on one side only.
GraphQL keeps one type on the server and lets each app write the query for the screen in front of it. The schema is the agreement between the two apps and AWS. The query is typed, so a field the buyer still asks for fails the buyer build when it disappears, and the seller app, which never asked for it, keeps building. I learned the technology on a product where a sloppy contract means two companies are looking at two different trades.
What I walked out with
I shipped both production apps, with the admin dashboard and the backend on the same testing and CI/CD path. The part I keep is the shape. Enterprise software is one fact and several clients. The buyer, the seller, and the admin are the clients. AWS holds the fact. The schema decides what each client is allowed to ask. Owning both phones was what made that visible: a checkout bug and a fulfillment bug are often the same bug, seen from opposite ends.