A sanitized write-up of a production internal operations system I designed and built as the sole developer for a manufacturing and e-commerce company. This covers the order-to-shipment half of the platform; the warehouse and shop-floor half runs on the same database and has its own write-up. Company names, product details, and proprietary code are omitted. It describes the architecture and engineering decisions only.
The company already had an internal system, but it was slow: common queries and reports could take a long time to run, and it covered only part of the operational workflow, so significant gaps were still filled with spreadsheets and manual data entry. There was also no reliable record of who changed what.
As the sole developer, I designed and built a replacement platform that was both more complete and substantially faster. It covers the full order-to-shipment lifecycle, and over time grew into a codebase of roughly 100,000 lines backed by a 50+ table relational schema.
The platform has two halves. This write-up covers the order-to-shipment side: orders, builds, shipments, and reporting. The warehouse and shop-floor side - receiving, scan-driven picking, physical counts, and lot-level material traceability - is built on this same schema and is covered in a separate write-up.
A deliberately monolithic, three-tier design. The application layer renders the UI and holds the business logic, with SQL Server as the single source of truth and the local filesystem for attachments.
Why a monolith rather than microservices? A small internal user base, a one-person team, and no strict uptime SLA. Microservices would have added operational overhead with no payoff at this scale. The guiding principle was to optimize for development speed and maintainability, while remaining clear on which parts would need to change first as the system grows.
Two operators editing the same work order would silently overwrite each other's changes. I introduced a lock table: opening an order checks for an existing lock and acquires one if it is free, and the save releases it. A scheduled job clears stale locks left by abandoned sessions. Pessimistic locking is the appropriate choice when conflicts are costly, whereas optimistic version-number locking suits low-conflict, higher-throughput scenarios.
Internal operations require full traceability. Every create, update, and delete writes to a single audit table capturing actor, timestamp, object type, object ID, and a human-readable note. A single table across all modules makes cross-module "who changed this record" queries straightforward. The trade-off is that a high write volume will eventually make a single table a bottleneck; the scale path is asynchronous audit writes or monthly partitioning.
Reports query SQL Server directly and render charts in the browser from server-emitted JSON. This is real-time and requires no additional infrastructure, at the cost of heavy report queries competing with live operations. The scale path is a read replica for reporting and asynchronous generation for the heaviest reports.
Two roles, Admin and normal user, enforced at the top of every page via server-side sessions. The model is simple, fast, and easy to reason about. Its limitation is that it cannot express per-record rules; the upgrade path is attribute-based access control with a centralized session store for a multi-server deployment.
All queries are parameterized rather than built from concatenated strings, which prevents SQL injection. Lot-number duplicate detection, negative-stock alerts, and reconciliation reports catch operational data errors before they compound.