The storefront was not the hardest part

Leaf Creme started as a bakery commerce system, but a normal product catalog and cart did not describe the real operational problem. Cakes and ingredients expire. A quantity of ten is incomplete information if five units expire tomorrow and five expire next week.

That changed the center of the data model from products to inventory batches.

Why FEFO changes the system

FEFO means first expired, first out. When an order is created, the system allocates available stock from the earliest-expiring batches before later ones.

This rule affects more than one query. The order workflow needs to:

  • validate the requested items,
  • find eligible batches,
  • allocate enough quantity across one or more batches,
  • create order lines,
  • update stock consistently,
  • and fail without leaving partial changes when fulfillment is impossible.

The interface can show a simple checkout button, but the useful engineering work sits behind that button.

Business language should appear in the model

Leaf Creme distinguishes finished products, components, and gift boxes. It also supports POS, online, and pre-order flows. These are not labels added for presentation; they affect availability, fulfillment, and the operations screens staff need.

Modeling those concepts explicitly makes the code easier to discuss with a non-technical stakeholder. “Which batch fulfills this order?” is clearer than “which row should this endpoint decrement?”

That is where business analysis and backend engineering meet: a good entity model preserves the language and constraints of the real workflow.

Payment state cannot drift away from order state

Leaf Creme supports manual payment records, a MoMo API flow, and a MoMo QR flow with confirmation. A successful payment can move an order forward only when recorded payments reach the order total.

Without that rule, the UI could say an order is paid while the ledger says otherwise. The important design goal is not adding more payment buttons. It is making state transitions predictable when callbacks, manual actions, or retries occur.

The same principle applies across the system: one user action may touch several records, but it should still represent one business outcome.

Incomplete features need visible boundaries

The project contains areas that are not production-complete. Voucher and category administration still need dedicated backend CRUD APIs. Some analytics views need additional reporting endpoints. The frontend also has TypeScript cleanup remaining in unrelated admin surfaces.

It is tempting to hide those details in a portfolio. I think the stronger signal is to separate three categories clearly:

  1. backend-backed behavior that works now,
  2. bounded demo surfaces used to explore the interface,
  3. planned work that still needs a contract and implementation.

That distinction makes the completed work more credible.

The lesson I will reuse

Full-stack consistency is a chain:

business rule -> database transaction -> API contract -> interface state

If one link uses a different definition of the workflow, the bug appears somewhere else. A payment bug may begin in an order rule. An inventory bug may appear as an unavailable product. A frontend status mismatch may reveal an incomplete transaction boundary.

Leaf Creme taught me to model the operational rule before polishing the surface. For a system that handles perishable inventory, FEFO is not an optimization added after the features. It is the feature that determines whether the rest of the system is correct.