Portal quản lý bằng cách tải các đơn hàng từ các Woocommerce store định kỳ mỗi x giờ thông qua API. Gồm toàn bộ đơn hàng của hệ thống Wordpress và Lunar
Chi tiết tài liệu cho end user Portal tại: https://portal-docs-9jp.pages.dev/
Hiện tại có 3 instance (được gọi là team, cấu hình trong file .env) của Portal đang được sử dụng:
- TDA
- KDDA
- NDA
Backoffice TDA: https://app.woocommerceinvoice.com/backoffice Repo: https://github.com/swebvn/portal
Architecture & Design
Tech stack
Laravel 9 Laravel Nova v3 (admin)
CI/CI
- CD đang được quản lý bởi FlashPanel, push lên main branch sẽ trigger deploy tự động
Core Components
1. Application Layer (Actions)
Uses Laravel Actions pattern for reusable, testable business logic:
// Example: Actions are single-purpose classes
app/Actions/
├── Orders/
│ ├── SaveOrderFromData.php
│ ├── FetchOrdersFromStore.php
│ └── UpdateOrderStatus.php
├── Invoices/
│ ├── FetchInvoicesFromEnvoice.php
│ └── PairInvoiceWithOrder.php
├── Products/
│ └── FetchProductsFromStore.php
└── Shopify/
├── PushOrderToShopify.php
└── SyncProductToShopify.phpBenefits:
- Single Responsibility Principle
- Easy to test in isolation
- Reusable across jobs, controllers, and commands
- Can be dispatched as jobs or HTTP controllers
2. Admin Panel (Laravel Nova)
Docs: https://github.com/laravel/nova-orion-docs/blob/main/3.x
Custom Nova resources provide a powerful admin interface:
app/Nova/
├── Order.php # Order management
├── Orders/
│ ├── PendingOrder.php # Pending orders view
│ ├── ProcessingOrder.php
│ └── ShippedOrder.php
├── Product.php
├── Invoice.php
├── Store.php
└── Filters/ # Custom filters
Data Flow & Request Lifecycle
1. Order Processing Flow
graph TD A[Schedule every x hours] --> B[Sync orders] B --> C[SaveOrderFromData Action] C --> D[Store in Database] D --> E{Has Invoice?} E -->|No| F[Queue: Fetch Invoice] E -->|Yes| G[Pair Invoice] G --> H[Send Confirmation Email] F --> G H --> I{Shopify Enabled?} I -->|Yes| J[Queue: Push to Shopify] I -->|No| K[Complete] J --> K
2. Invoice Reconciliation Flow (For Envoice)
graph TD A[Scheduled Job] --> B[Fetch Invoices from Envoice] B --> C[For Each Invoice] C --> D{Match Order?} D -->|Found| E[Pair Invoice with Order] D -->|Not Found| F[Log for Manual Review] E --> G[Update Order Status] G --> H[Send Customer Email]
3. Shopify Sync Flow
graph TD A[Order Marked Paid] --> B{Shopify Enabled?} B -->|Yes| C[Queue: PushOrderToShopify] B -->|No| Z[End] C --> D[Create Shopify Order] D --> E{Success?} E -->|Yes| F[Save shopify_id] E -->|No| G[Alert to Telegram] F --> H[Sync Line Items] H --> I[Sync Product Images]
Technology Stack
Backend
| Technology | Version | Purpose |
|---|---|---|
| PHP | 8.1+ | Primary language |
| Laravel | 9.x | Web framework |
| MySQL | 8.0+ | Primary database |
| Redis | 6.x | Cache & queues |
Frontend
| Technology | Purpose |
|---|---|
| Laravel Nova | Admin panel UI |
Third-Party Services
| Service | Purpose |
|---|---|
| AWS SES | Transactional emails |
| BunnyCDN | Image storage & CDN |
| Telegram Bot API | Notifications |
| WooCommerce REST API | Store integration |
| Shopify API | Store sync |
| Envoice API | Invoice processing |
Key Laravel Packages
{
"laravel/nova": "Admin panel",
"laravel/horizon": "Queue monitoring",
"spatie/laravel-activitylog": "Audit logging",
"spatie/laravel-backup": "Database backups",
"spatie/laravel-webhook-client": "Webhook handling",
"lorisleiva/laravel-actions": "Action pattern",
"bensampo/laravel-enum": "Type-safe enums",
"signifly/laravel-shopify": "Shopify SDK",
"maatwebsite/laravel-nova-excel": "Excel exports"
}Design Patterns
1. Action Pattern
Single-purpose classes for business logic:
class SaveOrderFromData extends Action
{
public function handle(array $data, Store $store): Order
{
return Order::updateOrCreate(
['wp_id' => $data['id'], 'store_id' => $store->id],
$this->transformData($data)
);
}
}2. Enum Pattern
Type-safe status values:
use App\Enums\OrderStatus;
$order->status = OrderStatus::Processing;
$order->status->is(OrderStatus::Shipped); // true/falseScalability Considerations
Current Architecture
- Horizontal Scaling - Stateless application servers
- Queue Workers - Multiple workers for background processing
Monitoring & Observability
Logging
- Application Logs -
storage/logs/laravel.log - Activity Logs - Database-based with
spatie/laravel-activitylog - Queue Metrics - Laravel Horizon dashboard
Alerts
- Telegram Notifications - Critical errors and events
- Failed Jobs - Automatic retry with exponential backoff
- API Health Checks - Store API status monitoring