This repository is a reference architecture showcase extracted from a real, long-running production system. It focuses on architectural structure, execution boundaries, and ongoing modernization work --- not on business-specific logic or a ready-to-deploy application.
The broader system context is described in the corresponding case study: 👉 https://rocketdeploy.dev/en/case-studies/commerce-platform-modernization/
Architectural evolution of this showcase is documented separately in: 👉 docs/showcase-evolution-log.md
Business rules, proprietary workflows, customer data, and sensitive identifiers have been removed or anonymized. This repository is provided for technical architecture review and educational purposes only.
- Overview
- System Context
- Start Here
- Architecture at a Glance
- Architecture Boundaries
- Module / Component Map
- External Integrations
- Execution Flows
- State & Data Management
- Reliability & Failure Handling
- Security Model
- Key Engineering Decisions & Trade-offs
- How to Evaluate This Codebase
- AI- and Tool-Facing Consumers
- Current State & Evolution
- Closing Note
This system is a long-running PHP-based monolith built on an MVC framework and continuously used in production for approximately a decade.
In its current state, it is best described as a legacy modular monolith evolving toward contract-driven platform boundaries.
The architecture combines:
- server-rendered operational workflows,
- module-level JSON and internal API endpoints,
- append-only and projection-based read models in selected domains,
- scheduler-driven and long-running background execution,
- direct external-provider integrations,
- Core API and MCP-facing contracts for new consumers,
- AI-assisted operational workflows,
- relational persistence,
- object-storage-backed runtime artifacts.
The current engineering objective is controlled architectural evolution:
Preserve operational continuity while progressively introducing explicit module boundaries, application-layer contracts, read-model APIs, safer runtime patterns, AI-facing tool seams, and extraction-ready boundaries for future service decomposition.
This document focuses on architecture, boundaries, and modernization trajectory --- not on business logic.
At runtime, the platform exposes:
- a primary backend application surface,
- dedicated UI and API endpoints for selected operational domains,
- internal integration endpoints,
- cyclic and long-running background processes,
- direct integrations with external systems.
The repository also contains infrastructure/runtime elements for containerized execution and job orchestration.
The system remains a single deployable runtime, but the internal structure now shows clearer domain and execution boundaries than a flat legacy monolith.
For architectural analysis, review in this order:
- runtime bootstrap and dependency wiring,
- registered modules and route surface,
- HTTP controllers as transport entry points,
- application use-cases and orchestration services,
- repository and integration adapter boundaries,
- background job runtime wrappers,
- artifact and persistence handling.
A useful reading strategy is to compare older legacy orchestration paths with newer module-owned flows where explicit contracts are already visible.
The current system can be described as a stabilized legacy monolith moving toward explicit modular architecture:
- single-process application runtime,
- shared relational database,
- MVC-based presentation layer,
- mixed legacy Active Record and newer module-oriented application flows,
- embedded provider integrations,
- script-triggered and containerized background execution,
- partial movement from local filesystem assumptions toward object storage.
Some responsibilities remain tightly coupled, but selected areas now show clearer contracts, ports, adapters, and dedicated use-case layers.
Modernization is therefore not only planned --- it is already visible in the codebase. Several areas now expose contracts, read models, and runtime seams that make them realistic candidates for future service extraction.
A newer architectural signal is the gradual move toward a polyglot runtime
model. The legacy application remains PHP/Yii2-based, while new backend
services and planned extracted domain services are primarily designed
around Node.js / TypeScript / NestJS / Fastify. This includes core platform
services such as comers-core-api, as well as BFF, MCP, gateway-style
services, and planned domain services such as orders and messages.
The frontend direction is intentionally split: the main SPA direction remains Angular-based, while selected micro-frontend surfaces, such as the current AI chat micro-frontend, can use React/Vite. Specialized runtimes are introduced where they provide a better fit, such as Python for the backend-controlled ChatKit runtime.
Logical boundaries currently identifiable:
- Presentation Boundary --- backend controllers, views, layouts, and UI endpoints
- Application Boundary --- use-cases, orchestration services, command/result contracts
- Domain / Persistence Boundary --- entities, repositories, projections, workflow state
- Integration Boundary --- provider clients, transport logic, credential resolution, adapter implementations
- Execution Boundary --- request/response lifecycle versus cyclic or long-running background execution
- Artifact Boundary --- temporary local processing versus durable object-storage-backed artifacts
Physical deployment remains single-unit, but logical separation is now more explicit in selected domains.
The repository now contains visible module-oriented structure rather than only implicit functional grouping.
Examples of identifiable component areas:
- core application configuration and shared runtime wiring,
- marketplace integration boundary,
- listings-oriented application and ingestion flows,
- messaging/thread synchronization, translation, and reply-assistance boundary,
- activities read-model and audit-log boundary,
- orders synchronization and read-model boundary,
- shipping/integration registry boundary,
- operator-facing notification surface and tool-facing notification operations,
- background job runtime wrappers and lock helpers,
- object-storage-backed artifact handling.
This is still not runtime isolation, but it creates clearer internal seams for future extraction.
Integration strategies visible in the system include:
- direct HTTP invocation,
- XML-based request/response handling,
- provider-specific transport logic,
- environment-configured credentials and runtime behavior,
- adapter-based integration access in selected domains.
A key modernization indicator is the appearance of explicit integration-facing application contracts in some areas, reducing the need for controllers or legacy models to talk directly to provider clients.
This shows movement away from integration sprawl toward better-defined boundary ownership.
- HTTP request enters controller
- Application runtime resolves dependencies and route
- Access and session context are applied
- Controller delegates to legacy orchestration or module-level application flow
- Domain mutation and optional integration work occur
- HTML or JSON response is returned
- UI or internal caller invokes a module endpoint
- Controller acts as transport adapter
- Use-case/service handles orchestration
- Structured payload is returned
- Long-running container or scheduler invokes a job wrapper
- Wrapper applies jitter, lock acquisition, and timeout policy
- Target script executes
- Structured runtime events are emitted
- Loop sleeps and repeats
- External payload is fetched
- Raw payload is durably stored
- Projection updates internal state
- Reprocess path can replay stored payload without re-fetching source
This combination of legacy and newer execution styles is central to the current transitional architecture.
Primary persistence remains:
- relational database,
- entity-driven workflow state,
- module or legacy repository access patterns.
Additional state layers now include:
- append-stored raw external payloads in selected domains,
- deferred and cyclic processing state,
- object-storage-backed generated artifacts,
- temporary local workspace usage for bounded processing only.
This is an important modernization step because durable system state is being separated more clearly from node-local execution details.
Reliability mechanisms visible in the current system include:
- application and runtime logging,
- inline integration error handling,
- timeout-bound background execution,
- advisory locking for cyclic jobs,
- jitter to reduce synchronized restarts,
- reprocess/replay support for selected ingestion paths,
- safer artifact persistence patterns in selected workflows.
The system is not yet fully centralized in observability or retry policies, but the codebase already shows stronger operational safeguards than a typical legacy cron-based monolith.
High-level security and safety controls include:
- session and role-sensitive backend context,
- controller-level access checks,
- request validation,
- environment-based credential handling,
- stricter ownership checks in selected operational flows,
- signed-access patterns for some stored artifacts.
The broader architectural direction is toward more explicit trust and policy boundaries rather than implicit controller- or model-level enforcement only.
Historical strengths of this architecture:
- single deployable unit simplified operations,
- shared runtime reduced duplication,
- in-process evolution enabled long-term delivery continuity.
Trade-offs:
- legacy orchestration still spans multiple layers,
- integration density creates coupling pressure,
- mixed architectural styles coexist during refactoring,
- some module boundaries are clearer than others.
This is not a clean-slate architecture. It is a hybrid transitional state, which is exactly what makes it realistic.
Recommended review approach:
- inventory entry points,
- distinguish transport adapters from orchestration logic,
- identify where explicit contracts already exist,
- locate integration-dense areas,
- compare legacy and newer execution paths,
- evaluate extraction readiness by coupling and runtime ownership.
The most valuable review question is not “Is this already fully modularized?” but rather:
Which architectural boundaries are already explicit, and which are still implicit legacy coupling zones?
The showcased architecture now includes AI-assisted operational consumers. These consumers are not modeled as direct shortcuts into the legacy system. They depend on explicit API, Core API, MCP, and gateway capability seams.
Visible patterns include message-thread translation, translation language preference, reply draft suggestion, reply composition, user-scoped notification actions, order read access, and activity/audit read models.
The important architectural point is that AI-facing operations are represented as bounded contracts rather than unrestricted access to the legacy application.
The repository currently represents a transition from:
- legacy operational monolith
- to stabilized modular monolith
- to selective boundary formalization in high-change and high-integration domains
- to contract-driven consumers and AI-facing capability seams
The current showcase should be read as a transitional architecture with several consumer-facing boundary types. The legacy application remains an important runtime unit, but selected domains are increasingly exposed through explicit contracts instead of direct coupling to controllers, Active Record models, or provider-specific integration code.
Current indicators of evolution include:
- explicit module registration,
- application ports and adapter-based access in selected domains,
- use-case-driven orchestration in newer areas,
- raw-first ingestion and reprocessing support,
- hardened background runtime behavior,
- object-storage-backed artifact direction,
- append-only/current-state models in selected domains,
- internal v1 APIs for activities, orders, and messages,
- Core API facades that shield new consumers from legacy implementation details,
- MCP tools that expose selected domain operations to AI-assisted workflows,
- AI-assisted message translation and reply-composition flows,
- AI gateway capabilities that hide provider-specific request shapes behind internal contracts,
- explicit job containers for background processing such as synchronization and translation,
- separated infrastructure/runtime repositories for AI and legacy stacks.
This does not mean the system is already a microservices platform.
It means the codebase now contains concrete seams through which future extraction can happen with less risk:
- module APIs stabilize access before runtime extraction,
- append-only logs and projections make selected domains safer to read and replay,
- Core API and MCP provide controlled access for new consumers,
- AI-facing operations are represented as bounded contracts,
- runtime repositories make background workers and deployment topology explicit.
Planned evolution remains incremental and extraction-driven rather than rewrite-driven.
This repository reflects a realistic modernization stage:
A production-proven legacy system that is being systematically evolved toward clearer boundaries, safer execution, and better extraction readiness --- while preserving continuity of an active operational platform.
The transformation is incremental, contract-oriented, and grounded in what is already visible in code.
If you are dealing with a similar challenge --- modernizing a long-lived operational monolith, introducing explicit boundaries without a full rewrite, or preparing a production system for future service extraction