---
name: oro-architect
description: OroCommerce architecture reference covering tech stack, application structure, extension points, customization patterns, scalability, caching, deployment, and design principles. Use when making architectural decisions, evaluating extension strategies, planning infrastructure, designing integrations, or reviewing system design for OroCommerce applications.
---

# OroCommerce Architect

Architecture and design reference for OroCommerce/OroPlatform.
Full docs: https://doc.oroinc.com/backend/architecture/

## Technology Stack

**This project runs on OroCloud Enterprise.** All EE components are always available.

| Layer | Component | Notes |
|---|---|---|
| Language | PHP >= 8.4 | CLI + FPM |
| Framework | Symfony 6.4 | |
| ORM | Doctrine | |
| Database | PostgreSQL >= 16.1 | HA failover on OroCloud |
| Search | Elasticsearch >= 8.4.1 | Cluster on OroCloud |
| Message Queue | RabbitMQ 3.12.x | Cluster on OroCloud |
| Cache | Redis 7.2.x (Sentinel) | Always available |
| Session | Redis | |
| File Storage | GridFS (MongoDB) | Clustered on OroCloud |
| Web Server | Nginx | Load-balanced web nodes |
| CDN | GCP CDN or Cloudflare | Managed by Oro |
| Assets | Node.js >= 22, NPM > 10 | Build-time only |
| PDF | Gotenberg >= 8.5 | Optional |

## Application Structure

```
config/              # Symfony config (services, routing, security)
src/                 # Custom bundles (Acme namespace)
templates/           # Global Twig overrides
translations/        # Global translation overrides
public/              # Web root (index.php, built assets)
var/                 # Cache, logs, sessions
vendor/              # Composer dependencies (Oro core lives here)
bin/console          # Symfony console
```

Custom code goes in `src/` only. Never modify `vendor/`.

## Key Architectural Patterns

### Bundle System

Oro uses an enhanced Symfony bundle system with auto-registration via
`Resources/config/oro/bundles.yml`. Each bundle can contribute:
- Entities, migrations, config
- Routes, controllers, templates
- Datagrids, navigation, workflows
- API resources, MQ processors
- Feature toggles, system config

Bundle priority controls load order (higher = later = can override).

### Entity Extension System

`EntityExtendBundle` enables adding fields to any entity without modifying
its source. Uses migration-time column definitions with `oro_options` and
generates proxy classes at cache warmup. Two ownership levels:
- `OWNER_SYSTEM`: developer controls all rendering
- `OWNER_CUSTOM`: framework auto-renders in grids, forms, views

### Cumulative Resources

Oro's `CumulativeResourceManager` merges YAML config from all bundles
(datagrids.yml, navigation.yml, workflows.yml, etc.) into a unified config.
Later bundles can override earlier ones via priority.

### Event-Driven Architecture

Symfony events + Oro-specific events for:
- Entity lifecycle (Doctrine events)
- Workflow transitions
- Import/export processing
- Page rendering (layout events)

### Message Queue Architecture

Async processing for heavy operations. Key patterns:
- Topic-based routing (topic name -> processor)
- Job uniqueness via `JobRunner::createUnique()`
- Delayed messages via `Message::setDelay()`
- Consumer scaling: multiple processes, multiple servers
- DBAL transport polls DB; RabbitMQ uses AMQP push model

### Scope System

Scopes provide multi-dimensional context resolution (customer, website,
customer group). The `ScopeManager` evaluates registered criteria providers
by priority to deliver context-specific data for visibility, pricing, content
variants, and similar features. Scopes decouple bundle logic from contextual
criteria it cannot evaluate on its own.

### Operations (ActionBundle)

Operations are the primary UI interaction mechanism for entity actions.
Defined in `actions.yml`, they bind to entities, routes, or datagrid rows.
Support preconditions, conditions, form dialogs, and chained actions.
Default CRUD operations (UPDATE, DELETE) can be extended, substituted,
or disabled per entity/datagrid.

### Processes

Processes automate tasks on entity lifecycle events (create/update/delete)
or cron schedules. Defined in `processes.yml` with triggers that can execute
immediately or deferred via MQ. Different from workflows: processes react to
Doctrine events, workflows model multi-step state transitions.

### Search Architecture

Oro supports two search backends:
- **DB full-text** (CE): PostgreSQL `tsvector`/`tsquery`
- **Elasticsearch** (EE): cluster-capable, real-time indexing

Entity search configuration via `search.yml` maps entity fields to
virtual search fields with typed indexing (text, integer, double, datetime).
Relation fields are flattened into the index.

## Caching Strategy

| Type | Purpose | Shared in cluster? | Backend |
|---|---|---|---|
| Data cache | Runtime-generated data (ACL, catalog) | Yes | Redis |
| System cache | Deploy-time (DI container, annotations) | No | Filesystem + OPcache |
| Content cache | HTML render cache | No | Redis (local) |

## Scalability Patterns

### Horizontal Scaling
- Multiple web server instances behind load balancer
- Multiple MQ consumer processes (scale independently)
- Shared Redis for data cache + sessions
- Shared PostgreSQL (primary-replica for reads)
- Shared Elasticsearch cluster

### Vertical Scaling
- Minimum: 2 CPU, 2GB RAM, SSD
- Typical production: 4+ CPU, 8GB+ RAM
- Separate DB server for large datasets

## Extension Points Summary

| What to customize | Mechanism |
|---|---|
| Add fields to Oro entities | EntityExtendBundle migrations |
| New entity with full CRUD | Bundle with entity + controller + datagrid |
| Business logic hooks | Event listeners / subscribers |
| Async processing | MQ topics + processors |
| Checkout flow | Workflow configuration + checkout events |
| Payment/shipping | Payment/Shipping method integrations |
| API endpoints | api.yml configuration |
| Admin UI | Twig overrides + placeholders |
| Storefront UI | Layout updates + theme SCSS/JS |
| Feature flags | FeatureToggleBundle |
| Scheduled tasks | CronBundle commands |
| Access control | ACL annotations + ownership config |
| System settings | ConfigBundle + system_configuration.yml |
| Search | SearchBundle configuration |
| Context-dependent behavior | ScopeBundle (criteria providers) |
| Entity action buttons | ActionBundle operations (actions.yml) |
| Dashboard widgets | DashboardBundle (dashboards.yml) |
| Entity field config | #[ConfigField] attribute |
| Change audit logging | DataAuditBundle (#[Config] auditable) |
| File/media storage | GaufretteBundle (public/private, GridFS) |
| Reports | Datagrid-based reports in navigation |
| Data segments | SegmentBundle (dynamic/static filters) |
| Seed/demo data | Fixture classes in Migrations/Data/ORM/ |
| Entity search | SearchBundle (search.yml) |
| Entity lifecycle automation | Processes (processes.yml) |
| Integration error logging | NotificationBundle alerts |
| Back-office UI injection | Placeholders (placeholders.yml) |
| Query-level access filtering | Access Rules (AccessRuleInterface) |
| Field-level permissions | Field ACL (#[ConfigField] security) |

## Extending OroCommerce

Specific commerce extension points:
- **Checkout**: extend `b2b_flow_checkout` workflow via YAML import/as/replace,
  add steps, transfer custom data between shopping list/checkout/order
  (https://doc.oroinc.com/backend/extend-commerce/checkout-customization-methods/)
- **Payment methods**: Settings entity extending Transport + PaymentMethodInterface +
  Provider + ViewProvider, all registered via integration channel
  (https://doc.oroinc.com/backend/extend-commerce/payment/)
- **Shipping methods**: Settings entity extending Transport + ShippingMethodInterface +
  ShippingMethodTypeInterface (per service level) + Provider
  (https://doc.oroinc.com/backend/extend-commerce/shipping/)
- **WebSockets**: WAMP protocol via OroSyncBundle for real-time admin notifications
  (https://doc.oroinc.com/backend/websockets/)
- **Emails**: template system with entity binding + notification alerts on entity events
  (https://doc.oroinc.com/backend/emails/)

## Organization Types (EE)

Define organization types in `Resources/config/oro/organization_types.yml` to
restrict features per organization. Two strategies: `exclude_list` (default,
everything enabled except listed) and `include_list` (everything disabled except
listed). Useful for multi-brand/multi-tenant setups.

## Differences from Standard Symfony

- Auto-registration of bundles (no manual Kernel registration)
- Routing loaded from `Resources/config/oro/routing.yml` per bundle
- ACL system replaces Symfony voters for entity access
- Entity config system (`#[Config]`) manages entity metadata
- Cumulative resources merge YAML across bundles
- Console commands auto-discovered from bundles

## OroCloud Deployment

Production deployments use `orocloud-cli` (not direct server access):
- `orocloud-cli upgrade` / `upgrade:rolling` / `upgrade:source`
- `orocloud-cli app:package:build` + `app:package:deploy` (faster)
- Backups: automatic hourly/weekly/monthly + on-demand
- Config via `orocloud.yaml` (env vars, webserver, etc.)
- See `oro-cloud` skill for full reference

## Testing Strategy

| Level | Framework | What it covers |
|---|---|---|
| Unit | PHPUnit | Classes, services, business logic |
| Functional | PHPUnit + WebTestCase | Controllers, API, DB interactions |
| Integration (BDD) | Behat | User workflows, full-stack scenarios |
| E2E | Custom (Selenium/k6) | Performance, cross-browser |
| Performance | k6 | Load testing, response times |

Docs: https://doc.oroinc.com/backend/automated-tests/
