DEV Community

Cover image for I'm Building a Unified Freight Platform at My Part-Time Job and the Architecture Is Genuinely Interesting
Sidharth Sangelia
Sidharth Sangelia

Posted on

I'm Building a Unified Freight Platform at My Part-Time Job and the Architecture Is Genuinely Interesting

Let me tell you about what I have been building at my part time job, because the architecture problem at the center of it is one of the more interesting things I have worked on.

I am a Pricing and Tech Associate at an international freight forwarding company. Part time. And in that capacity I am essentially responsible for the entire tech layer of the business.

Quick Context: What Has Already Shipped

Before I get into the big thing, the smaller deliverables first.

I built the founder's personal portfolio website with a full blog system backed by Sanity CMS. He can add posts and categories without touching a single line of code. That is live and actively being used.

Multiple pitch and company profile decks. The XGBoost price predictor I wrote about a few weeks back, meant to speed up freight quoting which currently happens manually. And some LinkedIn content strategy and data analytics work which I will get to.

But the project I am most focused on right now is different in scale.

The Platform

A customer facing dashboard. Clients log in, add a booking, compare rates across multiple vendors, track shipments, and manage a wallet.

The CRUD layer and the auth and the wallet are all standard enough. Solvable problems with clear paths.

The genuinely hard part is the vendor integration layer.

The Actual Problem

We work with multiple vendors. Some specialise in specific trade lanes. Some are channel partners of UPS or FedEx, meaning they can offer better rates on certain routes.

Each vendor has their own API. Their own request structure for rates. Their own response shape for booking confirmations. Their own webhook format for tracking updates. Their own error codes and edge cases.

And I need to build one unified platform on top of all of it.

From the customer side: one clean interface. They enter shipment details, see a comparison, book, track. Clean and simple.

From behind the scenes: potentially five different APIs with five completely different structures being called, normalised, and returned in a consistent shape.

This is not a toy project. Real bookings, real money, real shipments. The stakes are not tutorial level.

Why the Adapter Pattern

I have been thinking through the architecture for a while and I keep landing in the same place.

A typed master interface in TypeScript. One canonical shape for everything.

interface FreightVendorAdapter {
  getRates(input: CanonicalRateRequest): Promise<CanonicalRateResponse[]>
  createBooking(input: CanonicalBookingRequest): Promise<CanonicalBookingConfirmation>
  getTracking(trackingNumber: string): Promise<CanonicalTrackingEvent[]>
}
Enter fullscreen mode Exit fullscreen mode

Each vendor gets its own adapter class that implements this interface. The adapter does two things: translates canonical input into whatever that vendor's API actually expects, and translates whatever comes back into the canonical response shape.

From the platform's perspective, every vendor behaves identically. You call getRates and you get back CanonicalRateResponse[]. What the adapter does internally is fully encapsulated.

The TypeScript interface is not optional decoration here. It is the contract that holds the whole system together. If an adapter does not satisfy the interface, it does not compile. That is a hard guarantee, not a convention.

Adding a new vendor later becomes a well defined task: implement the interface, write the translation logic, plug it in. The rest of the platform does not change.

How I Am Thinking About the Rollout

Not building everything at once. That is how you build nothing.

Phase one: tracking. Bookings are still made manually on vendor platforms for now. But if I can surface tracking through our own interface, clients see our UI every time they check their shipment. Builds trust. Makes the platform feel real before it is fully real. Also the most self contained piece, I can implement the adapter, wire up one or two vendors, and have something useful without needing the full booking system done.

Phase two: rate comparison. Internal only first. The team uses it to quote faster. Once there is real confidence in accuracy and reliability, it opens to clients. You do not show clients something you have not stress tested yourself.

Phase three: booking and wallet. Later.

The Things I Did Not Expect to Be Doing

I have been doing data analytics in Excel.

I say this with full awareness of what that sounds like coming from a developer. But here is what actually happened.

We exported the founder's LinkedIn connection data. Thousands of connections. The goal is to segment them for a targeted email campaign. Different message for a logistics professional versus a startup founder versus a procurement manager.

I learned VLOOKUP on the spot. Built filtering logic to create clean segments. And now I am looking into data enrichment tools because the raw LinkedIn export is shallow and a good email campaign needs more context than just name, company, and title.

I also pushed three LinkedIn posts as part of the founder's personal content strategy. LinkedIn is its own craft. The feed is brutal and if the first line does not stop the scroll nothing else lands. I am learning this by doing it.

Being Inside an Industry vs Building For One

This is the part that is hardest to convey but I think matters most.

There is a real difference between building something because you theorised that a problem might exist, and building something because you watched the problem happen in front of you on a spreadsheet it should not be running on.

I have been going to meetings. Visiting shipment hubs. Sitting in rooms where the operational friction is not hypothetical.

When you are properly calibrated to a real context the engineering instincts feel different. You are not guessing at what matters. You can see it.

Where Things Are

Exams from 26th May through mid June, so there is a pause coming. But the foundation is solid and the thinking is clear.

By the end of June the tracking feature should be live. Rate comparison internals after that.

I will write about the adapter implementation as it comes together. There are some genuinely interesting problems in the data normalisation layer, especially around how different vendors model the same concepts (a trade lane, a weight break, an accessorial charge) in completely different ways.

More on that soon.


If you have built something similar with multiple third party APIs and a unified abstraction layer, I would genuinely love to hear how you structured it. Drop a comment or find me on thesidharth.com.

Top comments (0)