MTS AI Commerce Assistant
AI Sales & Product Recommendation Engine for Adobe Commerce / Magento 2.
MTS AI Commerce Assistant is a modular, scalable Magento 2 extension that delivers personalized product recommendations using machine learning, vector embeddings, and behavioral analytics. It supports OpenAI as the primary AI provider with graceful fallback to rule-based algorithms.
Package
magetech/module-ai-recommendation
License
Proprietary — MageTech Solutions
Requirements
Magento 2.4.7+ · PHP 8.2+ · MySQL 8.0+ · Redis
Total Files
169 source files · ~15,000 LOC
Technology Stack
| Layer | Technology | Version | Purpose |
| Platform | Adobe Commerce / Magento 2 | 2.4.7+ | E-commerce framework |
| Language | PHP | 8.2+ | Server-side logic |
| Database | MySQL | 8.0+ | Persistent storage |
| Cache | Redis | 6.0+ | Recommendation & session cache |
| Queue | AMQP (RabbitMQ) | 3.9+ | Async message processing |
| AI Provider | OpenAI API | v1 | Embeddings & completions |
| Embedding Model | text-embedding-3-small | - | Product vector embeddings |
| Completion Model | gpt-4o | - | Natural language recommendations |
| Frontend | RequireJS + jQuery | - | Luma theme JS modules |
| Hyva | Alpine.js + Tailwind CSS | - | Hyva theme compatibility |
| API | GraphQL + REST | - | Headless commerce support |
| Search | Elasticsearch / OpenSearch | 7.x / 2.x | Catalog search (Magento native) |
System Architecture
High-Level Architecture Diagram
┌─────────────────────────────────────────────────────────────────────────────┐
│ FRONTEND LAYER │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Luma Theme │ │ Hyva Theme │ │ PWA Studio │ │ Headless │ │
│ │ (.phtml) │ │ (Alpine.js) │ │ (React) │ │ (GraphQL) │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │ │
│ └────────────┬────┴─────────────────┴─────────────────┘ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ API LAYER │ │
│ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │
│ │ │ GraphQL │ │ REST │ │ AJAX │ │ Widget │ │ │
│ │ │ Queries │ │ /V1/ │ │ Controller│ │ Block │ │ │
│ │ └─────┬──────┘ └─────┬──────┘ └─────┬──────┘ └─────┬──────┘ │ │
│ │ └────────────────┴───────────────┴───────────────┘ │ │
│ └───────────────────────────────┬───────────────────────────────────┘ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ SERVICE LAYER │ │
│ │ ┌─────────────────────┐ ┌─────────────────────┐ │ │
│ │ │ RecommendationService│ │ AiProcessor │ │ │
│ │ │ - getRecommendations│ │ - generateEmbedding │ │ │
│ │ │ - trackEvent │ │ - generateAI │ │ │
│ │ │ - refreshCache │ │ - cosineSimilarity │ │ │
│ │ └──────────┬──────────┘ └──────────┬──────────┘ │ │
│ │ │ │ │ │
│ │ └───────────┬───────────────┘ │ │
│ │ ▼ │ │
│ │ ┌──────────────────────────────────────────────────────────┐ │ │
│ │ │ ENGINE LAYER (Strategy Pattern) │ │ │
│ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │
│ │ │ │ FBT │ │ CrossSell│ │ UpSell │ │ Similar │ │ │ │
│ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ │
│ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │
│ │ │ │ Predict │ │ Purchase │ │ Dynamic │ │ │ │
│ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ │
│ │ └──────────────────────────────────────────────────────────┘ │ │
│ └───────────────────────────────┬───────────────────────────────────┘ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ DATA LAYER │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐│ │
│ │ │ MySQL │ │ Redis │ │ Queue │ │ OpenAI │ │ Events ││ │
│ │ │ (6 tbl) │ │ (cache) │ │ (RabbitMQ)│ │ (API) │ │ (CRUD) ││ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └────────┘│ │
│ └───────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
Layer Responsibilities
| Layer | Components | Responsibility |
| Frontend | Luma templates, Hyva Alpine.js, RequireJS modules, CSS | Render recommendation widgets, handle user interactions, send tracking events |
| API | GraphQL resolvers, REST controllers, AJAX controller | Expose recommendation data to external consumers, validate input, delegate to service layer |
| Service | RecommendationService, AiProcessor | Orchestrate engine selection, manage caching, coordinate AI calls, track analytics |
| Engine | 7 concrete engines behind AbstractRecommendationEngine | Execute specific recommendation algorithms (collaborative filtering, content-based, hybrid) |
| Data | MySQL tables, Redis cache, RabbitMQ queues, OpenAI API | Persist entities, cache results, process async jobs, generate embeddings |
Module Structure
MageTech_AIRecommendation/
├── Api/ # Service contracts
│ ├── Data/ # Data transfer object interfaces
│ ├── Rest/V1/ # REST API implementations
│ ├── AiProcessorInterface.php
│ ├── RecommendationServiceInterface.php
│ └── *RepositoryInterface.php
├── Block/ # Block classes
│ ├── Adminhtml/ # Admin grid & form blocks
│ ├── Tracking/ # Tracking pixel block
│ └── Widget/ # Frontend widget blocks (8)
├── Controller/ # Request handlers
│ ├── Adminhtml/ # 14 admin controllers
│ └── Ajax/ # Frontend AJAX endpoint
├── Cron/ # 5 scheduled tasks
├── etc/ # Module configuration
│ ├── adminhtml/ # Admin DI, routes, system.xml
│ └── frontend/ # Frontend DI, routes, events
├── GraphQL/Resolver/ # 5 GraphQL resolvers
├── i18n/ # Translation CSV
├── MessageQueue/ # Async processing
│ ├── Consumer/ # 3 message consumers
│ ├── Message/ # 3 message DTOs
│ └── Publisher/ # 3 message publishers
├── Model/ # Domain models & logic
│ ├── Config/ # AiConfigProvider
│ │ └── Source/ # 6 source models
│ ├── Engine/ # AI engine classes
│ └── ResourceModel/ # DB resource models (6 + 6 collections)
├── Observer/ # 6 event observers
├── Plugin/ # 4 interceptor plugins
├── Test/ # Unit & integration tests
├── view/ # Frontend, admin, GraphQL views
│ ├── frontend/
│ │ ├── layout/ # 6 layout XML files
│ │ ├── templates/ # PHTML templates (Luma + Hyva)
│ │ └── web/ # JS modules, CSS
│ └── graphql/ # schema.graphqls
├── composer.json
├── registration.php
└── docs/ # Documentation & landing page
Database Schema
6 custom tables with foreign key constraints and indexed columns for query performance.
Entity Relationship Diagram
catalog_product_entity (Magento Core)
│
├──FK──▶ magetech_ai_recommendation
│ ├── product_id → catalog_product_entity (CASCADE)
│ ├── recommended_product_id → catalog_product_entity (CASCADE)
│ └──PK──▶ magetech_ai_recommendation_analytics
│ └── recommendation_id → magetech_ai_recommendation (CASCADE)
│
├──UNIQUE─▶ magetech_ai_vector_embedding
│ └── product_id (UNIQUE, one embedding per product)
│
└──FK──▶ magetech_ai_tracking_event
└── product_id (indexed, no FK — events survive product deletion)
magetech_ai_customer_preference
└── customer_id (UNIQUE, one profile per customer)
magetech_ai_prompt_template
└── engine_type (indexed, multiple templates per engine type)
Table: magetech_ai_recommendation
Core recommendation entity. Stores AI-generated and rule-based recommendation pairs.
| Column | Type | Constraints | Description |
entity_id | INT(10) UNSIGNED | PK, AUTO_INCREMENT | Unique identifier |
customer_id | INT(10) UNSIGNED | DEFAULT 0, INDEX | Target customer (0 = global) |
product_id | INT(10) UNSIGNED | FK → catalog_product_entity, CASCADE | Source product |
recommended_product_id | INT(10) UNSIGNED | FK → catalog_product_entity, CASCADE | Recommended product |
engine_type | VARCHAR(50) | INDEX | Engine that generated this |
placement | VARCHAR(50) | INDEX | Display placement zone |
score | DECIMAL(12,4) | DEFAULT 0 | Confidence score (0-1) |
metadata | TEXT | NULLABLE, JSON | Additional engine-specific data |
is_active | SMALLINT(5) UNSIGNED | DEFAULT 1, INDEX | Soft-delete flag |
created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Creation time |
updated_at | TIMESTAMP | AUTO UPDATE | Last modification time |
Table: magetech_ai_vector_embedding
Stores product vector embeddings for semantic similarity search via cosine distance.
| Column | Type | Constraints | Description |
entity_id | INT(10) UNSIGNED | PK | Unique identifier |
product_id | INT(10) UNSIGNED | UNIQUE | One embedding per product |
embedding | TEXT | JSON array | 1536-dimensional float vector |
model_version | VARCHAR(100) | INDEX | OpenAI model identifier |
source_text | TEXT | NULLABLE | Text used to generate embedding |
created_at | TIMESTAMP | | Generation timestamp |
updated_at | TIMESTAMP | AUTO UPDATE | Regeneration timestamp |
Table: magetech_ai_tracking_event
Raw behavioral tracking events. High-volume write table for user interaction signals.
| Column | Type | Constraints | Description |
event_id | INT(10) UNSIGNED | PK | Unique identifier |
customer_id | INT(10) UNSIGNED | INDEX | Logged-in customer ID |
session_id | VARCHAR(255) | NULLABLE | Browser session identifier |
event_type | VARCHAR(50) | INDEX | view | add_to_cart | purchase |
product_id | INT(10) UNSIGNED | INDEX | Product involved |
recommendation_id | INT(10) UNSIGNED | DEFAULT 0 | Source recommendation (if any) |
placement | VARCHAR(50) | NULLABLE | Widget placement zone |
metadata | TEXT | NULLABLE, JSON | Contextual data (SKU, price, qty) |
event_time | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP, INDEX | Event timestamp |
Remaining Tables
| Table | Purpose | Key Columns |
magetech_ai_prompt_template | Configurable AI prompt templates per engine type | engine_type, prompt_template, system_prompt, is_default |
magetech_ai_recommendation_analytics | Recommendation interaction events (impression, click, purchase) | recommendation_id (FK), event_type, event_time |
magetech_ai_customer_preference | Customer behavioral preference profiles | customer_id (UNIQUE), category_affinity, brand_affinity, avg_order_value |
API Contracts
All service contracts follow Magento 2 conventions. Interfaces are in Api/, data interfaces in Api/Data/.
Data Transfer Object Interfaces
All extend Magento\Framework\Api\ExtensibleDataInterface for custom attribute support.
| Interface | Key Properties |
RecommendationInterface | entity_id, customer_id, product_id, recommended_product_id, engine_type, placement, score, metadata, is_active |
PromptTemplateInterface | entity_id, name, engine_type, prompt_template, system_prompt, is_active, is_default, sort_order |
VectorEmbeddingInterface | entity_id, product_id, embedding, model_version, source_text |
RecommendationAnalyticsInterface | entity_id, recommendation_id, customer_id, event_type, product_id, metadata, event_time |
TrackingEventInterface | event_id, customer_id, session_id, event_type, product_id, recommendation_id, placement, metadata |
CustomerPreferenceInterface | entity_id, customer_id, preference_data, category_affinity, brand_affinity, avg_order_value, total_orders |
Repository Interfaces
| Interface | Methods |
RecommendationRepositoryInterface | save, get, getByCustomerAndProduct, delete, deleteById, getList, getRecommendationsByPlacement |
PromptTemplateRepositoryInterface | save, get, delete, deleteById, getList, getDefaultByEngineType |
VectorEmbeddingRepositoryInterface | save, get, getByProductId, delete, getList, getEmbeddingsByIds |
RecommendationAnalyticsRepositoryInterface | save, get, delete, getList, getAnalyticsByRecommendation, getAnalyticsSummary |
Service Interfaces
| Interface | Methods |
RecommendationServiceInterface | getRecommendations, getFrequentlyBoughtTogether, getCrossSell, getUpSell, getSimilarProducts, getRecentlyViewedPrediction, getPurchasePrediction, trackEvent, refreshRecommendations, flushCache |
AiProcessorInterface | generateEmbedding, generateRecommendations, computeCosineSimilarity, findSimilarByEmbedding |
Dependency Injection
Interface Preferences (Global)
<preference for="Api\RecommendationRepositoryInterface"
type="Model\RecommendationRepository"/>
<preference for="Api\PromptTemplateRepositoryInterface"
type="Model\PromptTemplateRepository"/>
<preference for="Api\RecommendationAnalyticsRepositoryInterface"
type="Model\RecommendationAnalyticsRepository"/>
<preference for="Api\VectorEmbeddingRepositoryInterface"
type="Model\VectorEmbeddingRepository"/>
<preference for="Api\RecommendationServiceInterface"
type="Model\RecommendationService"/>
<preference for="Api\AiProcessorInterface"
type="Model\Engine\AiProcessor"/>
Virtual Types
<virtualType name="MageTechAIRecommendationLogger"
type="Magento\Framework\Logger\Monolog">
<arguments>
<argument name="name" xsi:type="string">magetech_ai_recommendation</argument>
<argument name="handlers" xsi:type="array">
<item name="system" xsi:type="object">
Magento\Framework\Logger\Handler\System
</item>
</argument>
</arguments>
</virtualType>
Frontend Plugins
| Target Class | Plugin | Method | Sort Order |
Magento\Catalog\Model\Product | Plugin\ProductPlugin | afterGetProductUrl | 10 |
Magento\Checkout\Model\Cart | Plugin\CartPlugin | afterAddProduct | 10 |
Magento\Catalog\Block\ProductList | Plugin\CategoryPagePlugin | afterGetLoadedProductCollection | 10 |
Magento\Checkout\Block\Onepage | Plugin\CheckoutPlugin | afterGetCheckoutStepCount | 10 |
Recommendation Engines
7 engines behind the Strategy pattern, selected at runtime via EngineFactory.
Engine Hierarchy
AbstractRecommendationEngine (abstract)
├── getCachedRecommendations() # Redis cache lookup
├── cacheRecommendations() # Redis cache write
├── loadProductsByIds() # Product repository batch load
├── getProductCollection() # Filtered product collection
├── getCacheKey() # Unique cache key generation
│
├── FrequentlyBoughtTogetherEngine
│ └── Algorithm: Frequency counting on purchase events (last 100)
│
├── CrossSellEngine
│ └── Algorithm: Magento native cross-sell → random fallback
│
├── UpSellEngine
│ └── Algorithm: Magento native up-sell → price-greater fallback
│
├── SimilarProductsEngine
│ └── Algorithm: Vector embedding cosine similarity → category fallback
│
├── RecentlyViewedPredictionEngine
│ └── Algorithm: Browsing history + category affinity (last 20 views)
│
├── PurchasePredictionEngine
│ └── Algorithm: Weighted behavioral scoring (purchase=3, cart=2, view=1)
│
└── DynamicWidgetEngine
└── Algorithm: Parameterized query (sort_by, order from request)
Engine Details
| Engine | Algorithm | Data Source | Cache TTL |
| Frequently Bought Together |
Frequency counting — counts co-occurrence in purchase events, returns top-N by frequency |
magetech_ai_tracking_event (last 100 purchase events) |
Configurable |
| Cross-Sell |
Rule-based — uses Magento native getCrossSellProductIds(), random fallback |
Product entity (cross-sell links) |
Configurable |
| Up-Sell |
Rule-based — uses Magento native getUpSellProductIds(), price-greater fallback |
Product entity (up-sell links) |
Configurable |
| Similar Products |
Vector embedding cosine similarity — dot(a,b) / (|a| * |b|) |
magetech_ai_vector_embedding + OpenAI API |
Configurable |
| Recently Viewed Prediction |
Browsing history analysis — finds same-category products from top-5 viewed items |
magetech_ai_tracking_event (last 20 view events) |
Configurable |
| Purchase Prediction |
Weighted scoring — aggregates event weights over last 50 events per customer |
magetech_ai_tracking_event (last 50 events) |
Configurable |
| Dynamic Widget |
Parameterized query — reads sort_by, order from HTTP request |
Catalog product collection |
Configurable |
AI Processor
Central AI service that interfaces with OpenAI API for embeddings and completions.
Capabilities
| Method | API Endpoint | Model | Purpose |
generateEmbedding() | POST /v1/embeddings | text-embedding-3-small | Convert product text to 1536-dim vector |
generateRecommendations() | POST /v1/chat/completions | gpt-4o | Generate natural language recommendation rationale |
computeCosineSimilarity() | Local computation | - | Calculate vector distance: dot(a,b) / (|a| * |b|) |
findSimilarByEmbedding() | Local DB query | - | Find nearest neighbors by embedding distance |
Fallback Behavior
When OpenAI API is unavailable or times out (configurable timeout, default 30s), the processor falls back to rule-based engines. The fallback_to_rules config toggle controls this behavior.
Vector Embeddings
Generation Pipeline
Product Save Event
│
▼
ProductSaveObserver ──publish──▶ EmbeddingPublisher
│
▼ (async via RabbitMQ)
EmbeddingConsumer
│
├── Build source text: "{name} {description} {sku}"
├── Call AiProcessor::generateEmbedding()
├── POST /v1/embeddings (text-embedding-3-small)
├── Receive 1536-dimensional float array
└── Save to magetech_ai_vector_embedding
SimilarProductsEngine
│
├── Load embedding for target product
├── Load ALL other product embeddings
├── Compute pairwise cosine similarity
├── Sort by similarity DESC
└── Return top-N
Cosine Similarity Formula
cosine_similarity(A, B) = dot(A, B) / (magnitude(A) * magnitude(B))
where:
dot(A, B) = Σ(Ai * Bi) for i = 0 to 1535
magnitude(A) = sqrt(Σ(Ai²)) for i = 0 to 1535
Design Patterns
| Pattern | Category | Implementation | Classes |
| Factory |
Creational |
Maps engine type strings to concrete classes, validates config, instantiates via ObjectManager |
EngineFactory |
| Template Method |
Behavioral |
Abstract engine defines skeleton: cache check → algorithm → cache write. Subclasses implement algorithm only |
AbstractRecommendationEngine + 7 subclasses |
| Strategy |
Behavioral |
7 interchangeable algorithms behind common interface, selected at runtime |
All concrete engines |
| Repository |
Structural |
Abstracts data persistence. 4 repositories with SearchCriteria/SearchResults |
RecommendationRepository, PromptTemplateRepository, VectorEmbeddingRepository, RecommendationAnalyticsRepository |
| Observer |
Behavioral |
6 observers listen to Magento events, perform side effects (tracking, embedding generation) |
ProductViewObserver, AddToCartObserver, OrderCompleteObserver, etc. |
| Plugin / Interceptor |
Behavioral |
4 after-plugins on Magento core classes for method interception |
ProductPlugin, CartPlugin, CheckoutPlugin, CategoryPagePlugin |
| Service Contract |
Architectural |
All API interfaces follow Magento 2 service contracts. DI preferences map to implementations |
All Api/*Interface.php |
| Publisher-Subscriber |
Behavioral |
3 message topics with publishers, consumers, and DTOs via AMQP |
AiProcessingPublisher/Consumer, AnalyticsPublisher/Consumer, EmbeddingPublisher/Consumer |
| Provider / Configuration |
Creational |
Centralized config reader abstracts Magento system config access |
AiConfigProvider |
| Data Object (DTO) |
Structural |
6 models extend AbstractExtensibleModel, implement data interfaces with extension attributes |
All Model/*.php |
| Source Model |
Creational |
6 option arrays for admin config dropdowns |
Model/Config/Source/* |
Event System (Observers)
6 observers hooked to Magento core events for behavioral tracking and async processing.
| Observer | Event | Trigger | Action |
ProductViewObserver |
catalog_controller_product_view |
Customer views a product page |
Creates view tracking event with customer_id, session_id, product SKU in metadata |
AddToCartObserver |
checkout_cart_add_product_complete |
Product added to cart |
Creates add_to_cart event with SKU and quantity in metadata |
OrderCompleteObserver |
sales_order_save_after |
Order status changes to complete |
Creates purchase events for every item in the order with order ID, SKU, qty, price |
CategoryBrowseObserver |
catalog_controller_category_init_after |
Customer browses a category |
Creates view event with category ID and name (product_id=0) |
CustomerLoginObserver |
customer_account_login_after |
Customer logs in |
Stub — intended for recommendation refresh trigger |
ProductSaveObserver |
catalog_product_save_after |
Admin saves a product |
Publishes EmbeddingRequest to message queue for async embedding generation |
All observers wrap logic in try-catch to prevent frontend disruption on errors.
Plugins (Interceptors)
4 after-plugins on Magento core classes, registered in etc/frontend/di.xml.
| Plugin | Target | Method | Purpose |
ProductPlugin |
Magento\Catalog\Model\Product |
afterGetProductUrl |
Extension point for URL tracking parameters |
CartPlugin |
Magento\Checkout\Model\Cart |
afterAddProduct |
Extension point for add-to-cart recommendation tracking |
CategoryPagePlugin |
Magento\Catalog\Block\ProductList |
afterGetLoadedProductCollection |
Extension point for category page recommendation injection |
CheckoutPlugin |
Magento\Checkout\Block\Onepage |
afterGetCheckoutStepCount |
Extension point for checkout recommendation injection |
All plugins are scaffolded stubs — they pass through $result unchanged but inject RecommendationServiceInterface for future use.
Message Queues
Asynchronous processing via AMQP (RabbitMQ) with 3 topics, publishers, consumers, and message DTOs.
Queue Topology
Exchange: magetech_ai_exchange (topic, durable)
│
├── magetech.ai.processing
│ Queue: magetech_ai_processing_queue (max: 100)
│ Consumer: AiProcessingConsumer
│ Message: AiProcessingRequest
│
├── magetech.ai.analytics
│ Queue: magetech_ai_analytics_queue (max: 200)
│ Consumer: AnalyticsConsumer
│ Message: AnalyticsEvent
│
└── magetech.ai.embedding
Queue: magetech_ai_embedding_queue (max: 50)
Consumer: EmbeddingConsumer
Message: EmbeddingRequest
Message DTOs
| Message Class | Topic | Properties | Consumer Action |
AiProcessingRequest |
magetech.ai.processing |
request_type, data, callback_url |
Logs request (stub) |
AnalyticsEvent |
magetech.ai.analytics |
event_type, recommendation_id, customer_id, metadata |
Logs event (stub) |
EmbeddingRequest |
magetech.ai.embedding |
product_id, product_name, product_description, sku |
Generates embedding via OpenAI, saves to DB |
Cron Jobs
5 scheduled tasks for maintenance, embedding generation, and cache warming.
| Job | Schedule | Class | Purpose |
magetech_ai_generate_embeddings |
0 */6 * * * (every 6h) |
Cron\GenerateEmbeddings |
Batch-generates OpenAI embeddings for products missing embeddings (50/batch) |
magetech_ai_refresh_recommendations |
0 */4 * * * (every 4h) |
Cron\RefreshRecommendations |
Clears recommendation cache for regeneration |
magetech_ai_aggregate_analytics |
0 */1 * * * (hourly) |
Cron\AggregateAnalytics |
Aggregates analytics data (stub) |
magetech_ai_warm_cache |
*/30 * * * * (every 30m) |
Cron\WarmCache |
Pre-fetches recommendations for all 5 placement zones |
magetech_ai_cleanup_data |
0 3 * * * (daily 3AM) |
Cron\CleanupExpiredData |
Deletes tracking events >90 days, analytics >180 days |
Cache System
Cache Layers
| Layer | Backend | Key Pattern | TTL |
| Engine Cache |
Redis |
magetech_ai_engine_{type}_{id}_{limit} |
Configurable (default 3600s) |
| Service Cache |
Redis |
magetech_ai_{placement}_{customer}_{product}_{limit} |
Configurable (default 3600s) |
| Config Cache |
Magento Config |
System config values |
Per Magento config cache |
Cache Flush
- Admin controller:
Controller\Adminhtml\Cache\Flush
- Service method:
RecommendationService::flushCache()
- Cron:
RefreshRecommendations clears cache every 4 hours
- Config toggle:
magetech/airecommendation/cache/enabled
GraphQL API
Schema defined in view/graphql/schema.graphqls with 5 resolvers.
Queries
| Query | Arguments | Return Type | Resolver |
productRecommendations |
placement: String!, limit: Int = 6, productId: Int |
ProductRecommendationsOutput |
RecommendationsResolver |
similarProducts |
productId: Int!, limit: Int = 6 |
ProductRecommendationsOutput |
SimilarProductsResolver |
frequentlyBoughtTogether |
productId: Int!, limit: Int = 6 |
ProductRecommendationsOutput |
FrequentlyBoughtTogetherResolver |
Mutations
| Mutation | Arguments | Return Type | Resolver |
trackRecommendationEvent |
eventType: String!, productId: Int!, recommendationId: Int, placement: String |
TrackEventOutput |
TrackEventResolver |
Response Types
type ProductRecommendationsOutput {
success: Boolean!
message: String
items: [RecommendedProduct]
}
type RecommendedProduct {
product_id: Int
sku: String
name: String
url: String
image_url: String
price: Float
special_price: Float
}
REST API
| Method | Route | Auth | Service Interface |
| GET |
/V1/magetech/recommendations/:placement |
Anonymous |
GetByPlacementInterface::execute($placement, $limit, $customerId, $productId) |
| POST |
/V1/magetech/tracking |
Anonymous |
TrackEventInterface::execute($eventType, $productId, $recommendationId, $placement) |
Request/Response Examples
// GET /V1/magetech/recommendations/homepage?limit=6
{
"success": true,
"recommendations": [
{
"entity_id": 123,
"product_id": 456,
"recommended_product_id": 789,
"engine_type": "similar_products",
"score": 0.8542,
"product": { "sku": "ABC-123", "name": "..." }
}
]
}
// POST /V1/magetech/tracking
// Request body:
{
"event_type": "click",
"product_id": 789,
"recommendation_id": 123,
"placement": "homepage"
}
// Response: true
Frontend Architecture
Theme Compatibility
| Theme | Technology | Templates | JS Approach |
| Luma / Default |
PHTML + RequireJS + jQuery |
8 widget templates in view/frontend/templates/widget/ |
tracking.js, recommendation-widget.js |
| Hyva |
PHTML + Alpine.js + Tailwind CSS |
2 templates in view/frontend/templates/hyva/ |
tracking-alpine.js, recommendation-alpine.js |
| PWA Studio |
React + GraphQL |
Custom React components (via GraphQL queries) |
GraphQL queries + React hooks |
Layout XML Mapping
| Layout | Block | Placement | Position |
default.xml | Tracking\Pixel | All pages | content (before=-) |
cms_index_index.xml | HomepageRecommendations | Homepage | content (after content) |
catalog_product_view.xml | SimilarProductsWidget | Product page | after product.info.upsell |
catalog_product_view.xml | FrequentlyBoughtTogether | Product page | after similar products |
catalog_category_view.xml | CategoryRecommendations | Category page | after category.products |
checkout_cart_index.xml | CartRecommendations | Cart page | after checkout.cart |
checkout_index_index.xml | CheckoutRecommendations | Checkout page | after content |
JavaScript Modules
| Module | Type | Purpose |
tracking.js | RequireJS | Click tracking (event delegation), impression tracking (IntersectionObserver), sends POST to AJAX endpoint |
recommendation-widget.js | RequireJS | AJAX widget fetching recommendations, dynamically renders product HTML into containers |
tracking-alpine.js | Alpine.js | Hyva-compatible click and impression tracking via IntersectionObserver |
recommendation-alpine.js | Alpine.js | Hyva-compatible recommendation fetcher with loading state management |
CSS Architecture
Single stylesheet: view/frontend/web/css/mage-tech-ai-recommendation.css
- CSS Grid layout:
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr))
- Carousel with horizontal scroll and overflow hidden
- Product card hover effects with transform scale
- Responsive breakpoint at 768px
- Hyva-specific border radius and shadow overrides
Admin Panel
Admin Controllers (12)
| Controller | Purpose |
Index\Index | Dashboard landing page |
Analytics\Dashboard | Analytics dashboard |
Analytics\CtrReport | Click-through rate report |
Analytics\ConversionReport | Conversion rate report |
Cache\Flush | Flush AI recommendation cache |
Recommendation\Index | Recommendation grid listing |
Recommendation\NewAction | New recommendation form |
Recommendation\Edit | Edit recommendation |
Recommendation\Save | Save recommendation |
Recommendation\Delete | Delete single recommendation |
Recommendation\MassDelete | Mass delete recommendations |
PromptTemplate\* | Full CRUD for prompt templates (5 controllers) |
ACL Hierarchy
MageTech_AIRecommendation::admin
├── MageTech_AIRecommendation::config
├── MageTech_AIRecommendation::recommendation
│ ├── ::recommendation_view
│ ├── ::recommendation_new
│ ├── ::recommendation_edit
│ └── ::recommendation_delete
├── MageTech_AIRecommendation::prompt_template
│ ├── ::prompt_template_view
│ ├── ::prompt_template_new
│ ├── ::prompt_template_edit
│ └── ::prompt_template_delete
├── MageTech_AIRecommendation::analytics
│ ├── ::analytics_dashboard
│ ├── ::analytics_ctr
│ └── ::analytics_conversion
└── MageTech_AIRecommendation::cache_management
Configuration Reference
Admin path: Stores > Configuration > MageTech > AI Recommendations
Default Values
| Group | Setting | Default | Description |
| General | enabled | 0 | Module disabled by default |
| title | AI Recommendations | Widget title prefix |
| log_events | 1 | Enable event logging |
| AI Provider | provider | openai | AI provider selection |
| api_key | - | Obscured field |
| embedding_model | text-embedding-3-small | OpenAI embedding model |
| completion_model | gpt-4o | OpenAI completion model |
| max_tokens | 1000 | Max completion tokens |
| temperature | 0.7 | Completion temperature |
| Cache | enabled | 1 | Cache enabled |
| ttl | 3600 | Cache TTL in seconds |
| cache_type | redis | Cache backend |
| Async | queue_enabled | 1 | Message queue enabled |
| cron_enabled | 1 | Cron jobs enabled |
Security
- API Key Storage: OpenAI API key stored as obscured field in Magento config (encrypted at rest)
- ACL: Full admin ACL hierarchy with granular permissions per entity type
- Input Validation: All API endpoints validate input types and ranges
- SQL Injection: Prevented via Magento ORM (prepared statements)
- XSS: All output escaped via PHTML
$escaper->escapeHtml()
- CSRF: Admin forms use Magento CSRF tokens
- Rate Limiting: OpenAI API calls respect configurable timeout (default 30s)
- Fallback: Graceful degradation to rule-based algorithms when API unavailable
- Observer Error Handling: All observers catch exceptions silently to prevent frontend disruption