Building a Scalable Product Middle Platform to Unify Retail, Hospitality & Education
This article describes how a company transformed its fragmented product systems into a unified, domain‑driven middle platform that supports multiple industries, detailing the architectural philosophy, modular design, service layering, template‑based modeling, and the reverse empowerment of legacy restaurant services.
Introduction
In the evolution of a system, “starting from scratch” is often the fastest remedy for historical debt, but it can also sow new debt. Our smart‑store business began with catering and built a catering product system. When expanding into retail, we avoided the heavy coupling of the catering system by creating a brand‑new “Product 2.0” system, which solved the immediate problem but introduced new challenges: maintaining two independent product systems dramatically increased R&D and maintenance costs.
For example, the same “merchant custom unit” feature had to be developed twice, which is unacceptable. We realized the real solution was not “Product 2.0” but upgrading it to a product middle‑platform that can support future innovative businesses such as supermarkets, hospitality, and education, while also having the ability to “reverse‑empower” the massive legacy catering system and lead us out of siloed development.
Architecture “Dao” and “Technique”
Any successful architectural transformation requires top‑level design guidance. When building the product middle‑platform, we followed both the “Dao” (strategic principles) and the “Technique” (tactical implementations).
Architecture “Dao” is the strategic guideline that answers “why we do this”.
Business‑driven, not technology‑driven : Architecture serves the business. All design decisions stem from a deep understanding of multi‑industry product management.
Embrace change, evolve design : Business is constantly changing; the architecture must be flexible to adapt smoothly.
Divide and conquer, isolate complexity : Decompose the large product domain into independent, high‑cohesion business units to control entropy.
Architecture “Technique” is the tactical layer that answers “how to do it”.
Domain‑Driven Design (DDD) : Use domain modeling, bounded contexts, and domain events to map core business concepts to the system.
Layering and modularization : Strict vertical layers ensure single responsibility, while horizontal business units guarantee high cohesion and low coupling.
Design principles adherence : SOLID, DRY, KISS guide robust, maintainable code.
Middle‑Platform Architecture
Guided by these ideas, we planned the product middle‑platform with the core goal of reshaping the tangled dependencies among business domains into an ordered structure centered on the middle‑platform, with front‑end applications flexibly orchestrating business units.
1. Business Unitization
We first decomposed the entire product domain into clear business units, classified as generic units and industry‑specific units.
Generic units : Core capabilities required by all businesses, such as main product, category, inventory, price, tags, media resources.
Industry units : Differentiated features, e.g., “flavor method” and “add‑ons” for catering, “brand” and “multi‑packaging” for retail.
Each business unit is an independent, deployable service following a four‑layer DDD architecture, with its own domain model, domain services, and repository services. Units communicate via standardized RPC interfaces and domain events, achieving both physical and logical isolation.
2. Service Orchestration
We split each unit into a foundation service layer (stable, atomic core capabilities) and a business scenario layer (flexible, stateful logic). The foundation layer provides atomic APIs such as “create product”, “modify price”, “stock reserve”, etc., which are reusable across scenarios. The scenario layer assembles these primitives to implement features like product import, cloning, or OCR‑based product creation, dramatically accelerating development.
3. Multi‑Industry Template Design
To avoid defining separate product models for each industry, we adopted a template + attribute pool approach. All possible product attributes (e.g., name, barcode, origin) are stored in a shared attribute pool with metadata, front‑end rendering configuration ( component_config) and back‑end validation rules ( rules). Industry templates select relevant attributes to define the data structure and business rules for that industry.
When a merchant creates a product, the system loads the appropriate template, generates the front‑end form, and the back‑end validates and splits the data into “core product info” (persisted in the main product table) and “extended info” (stored as JSON key‑value pairs). This core + extension model keeps the main table stable while allowing new industries to be added by configuring new templates only.
Empowering the Catering Business
With the middle‑platform in place, we “reverse‑empowered” the legacy catering system, enabling rapid development of new features.
1. Product Unit: From Duplicate Development to Capability Reuse
Previously, units were managed by a global DictService. As merchants demanded custom units, we created a new “unit business unit” as a multi‑industry service, adding parameters such as business code, type, and ID to isolate data per tenant.
High reuse : Approximately 80% of the unit service, domain service, repository, and storage can be reused.
Minimal adaptation : Only a few routing adjustments are needed to handle catering‑specific validation, such as checking references before deletion.
The new architecture delivered the “custom unit” feature for catering in less than a week.
2. Inventory Management: From Zero to a Unified Platform
We built an independent “inventory business unit” that encapsulates procurement, returns, stock‑taking, and loss reporting as stable, atomic services. A business gateway handles client access, protocol conversion, and service orchestration for various front‑ends (mobile app, PC, cash register).
To avoid tight coupling between retail and catering inventory systems, we introduced a router that, based on tenant identifiers, forwards requests to the appropriate downstream service, acting as an anti‑corruption layer.
We adopted a “logical unified, physical isolated” strategy: a unified inventory service provides RPC methods such as batchAdd, directDeduct, and queryFlow for both retail and catering, while the repository layer routes calls to separate catering or retail mappers, preserving independent physical tables.
This approach achieves about 80% code reuse with minimal risk to online stability and leaves a clear path for future full data unification.
Conclusion
From siloed systems to a unified product middle‑platform and finally to reverse‑empowering legacy services, we have consistently pursued business‑driven, divide‑and‑conquer goals. Through deep model abstraction, business unitization, and layered services, we isolated the stable core from agile business changes. The platform will continue to expand horizontally, supporting more industries and fueling continuous innovation for smart stores.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
