m0hammadgh92/laravel-core-platform
Composer 安装命令:
composer require m0hammadgh92/laravel-core-platform
包简介
A production-grade, business-agnostic, multi-tenant Core platform for Laravel 11
README 文档
README
A production-grade, business-agnostic, multi-tenant Core platform for Laravel 11, designed to be extracted into a Composer package.
🎯 Overview
This Core platform provides a complete foundation for building multi-tenant SaaS applications with complex business logic. It handles:
- Multi-tenancy with domain-based resolution
- Customer & User separation (authentication ≠ commercial entity)
- Order management with complete lifecycle
- Billing & Invoicing with immutable financial records
- Payment processing with gateway abstraction
- Customer wallet system
- Queue-driven architecture for all side-effects
- Event-driven design for extensibility
- Scoped settings with inheritance
- Activity logging for audit trails
- File management with polymorphic attachments
✨ Key Principles
1. Queue-First Architecture
ALL external operations, slow I/O, emails, notifications, PDFs, payment processing happen via queued jobs ONLY.
2. Event-Driven Core
Business operations emit domain events. Listeners (all queued) respond to events for side-effects.
3. Strict Financial Discipline
- Money stored as INTEGER minor units (cents) - NO FLOATS
- Currency always stored alongside amounts
- Immutable invoice numbers via transactional sequences
- Wallet ledger with balance snapshots
4. Multi-Tenancy by Design
- Every tenant-owned table has
tenant_id - Tenant resolved by request domain
- Global Eloquent scopes prevent cross-tenant data leak
- All queries automatically scoped
5. Customer ≠ User
- Users: Authentication, activity causers
- Customers: Commercial entities, own orders/invoices/payments/wallet
- Orders, invoices, payments NEVER reference users directly
6. Package-Ready from Day One
- No hardcoded business logic
- No direct
env()calls in logic - Everything configurable
- Clear service contracts
📁 Structure
app/
├── Core/
│ ├── Tenancy/ # Multi-tenant infrastructure
│ ├── Identity/ # Users (in app/Models/User.php)
│ ├── CRM/ # Customer management
│ ├── Catalog/ # Products & Variants
│ ├── Sales/ # Orders
│ ├── Billing/ # Invoices, Payments, Wallet, Sequences
│ ├── Pricing/ # Tax Rates, Coupons
│ ├── Settings/ # Scoped settings
│ ├── Notifications/ # Templates & Outbound Messages
│ ├── Files/ # File management
│ └── Audit/ # (uses spatie/activitylog)
├── Support/
│ ├── Money/ # Money value object
│ ├── States/ # (To be created)
│ └── SettingsResolver/ # Settings inheritance resolver
├── Events/ # Domain events (to be created)
├── Listeners/ # Queued event listeners (to be created)
├── Jobs/ # Async jobs (to be created)
└── Policies/ # Authorization (to be created)
modules/ # Future vertical modules (empty)
🚀 Getting Started
Installation
This is already installed! The platform is ready to use.
Environment Setup
-
Configure Database (already using SQLite for development)
-
Configure Redis for queues (production):
QUEUE_CONNECTION=redis REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null REDIS_PORT=6379
- Configure Mail (for notifications):
MAIL_MAILER=smtp MAIL_HOST=mailpit MAIL_PORT=1025 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null MAIL_FROM_ADDRESS="hello@example.com" MAIL_FROM_NAME="${APP_NAME}"
Running the Application
# Run migrations (already done) php artisan migrate # Start Horizon (queue worker) php artisan horizon # Start development server php artisan serve # Access Filament admin panel open http://localhost:8000/admin
🏢 Multi-Tenancy
How It Works
- Request arrives with domain (e.g.,
acme.example.com) ResolveTenantMiddlewareextracts the hostTenantContextqueriestenant_domainstable- Tenant bound to container as
'tenant' - All models with
BelongsToTenanttrait auto-scope to this tenant
Adding a Tenant
php artisan tinker
// Create tenant $tenant = \App\Core\Tenancy\Tenant::create([ 'name' => 'Acme Corporation', 'slug' => 'acme', 'status' => 'active', 'metadata' => [], ]); // Add domain $tenant->domains()->create([ 'domain' => 'acme.test', 'is_primary' => true, ]); // Create default brand (optional) $tenant->brands()->create([ 'name' => 'Acme Brand', 'slug' => 'default', 'is_default' => true, ]); // Create admin user for this tenant $user = \App\Models\User::create([ 'tenant_id' => $tenant->id, 'name' => 'Admin User', 'email' => 'admin@acme.test', 'password' => bcrypt('password'), 'role' => 'admin', 'is_active' => true, ]);
Testing Multi-Tenancy Locally
Add to /etc/hosts:
127.0.0.1 acme.test
127.0.0.1 demo.test
Then access: http://acme.test:8000
💰 Money Handling
All monetary values use the Money value object:
use App\Support\Money\Money; // From minor units (cents) $price = Money::fromMinor(1999, 'USD'); // $19.99 // From major units (dollars) $price = Money::fromMajor(19.99, 'USD'); // $19.99 // Operations $total = $price->multiply(3); // $59.97 $discount = $price->percentage(2000); // 20% = $3.998 → $4.00 $final = $total->subtract($discount); // $55.97 // Display echo $price->format(); // "$19.99"
📋 Order Lifecycle
draft
↓ (OrderSubmitted event)
pending_payment
↓ (PaymentCaptured event → OrderPaid event)
paid
↓ (items fulfilled)
closed
OR
canceled (from draft/pending_payment)
refunded (from paid)
Creating an Order
use App\Core\Sales\Order; use App\Core\Billing\Sequence; $order = Order::create([ 'tenant_id' => $tenant->id, 'customer_id' => $customer->id, 'order_number' => Sequence::nextFor($tenant->id, 'order', 'ORD-'), 'status' => 'draft', 'currency' => 'USD', // Amounts calculated by OrderCalculator service ]); // Add items $order->items()->create([ 'tenant_id' => $tenant->id, 'product_variant_id' => $variant->id, 'product_name' => $variant->product->name, 'variant_name' => $variant->name, 'quantity' => 1, 'unit_price_minor' => $variant->price_minor, 'currency' => 'USD', // Calculate totals ]);
📄 Invoice System
Invoices are immutable financial documents with:
- Unique sequential numbers (thread-safe generation via
Sequence) - Customer snapshot (for legal record)
- Cannot be deleted (only voided)
Creating an Invoice
use App\Core\Billing\Invoice; use App\Core\Billing\Sequence; $invoice = Invoice::create([ 'tenant_id' => $tenant->id, 'customer_id' => $customer->id, 'order_id' => $order->id, 'invoice_number' => Sequence::nextFor($tenant->id, 'invoice', 'INV-'), 'status' => 'draft', 'currency' => 'USD', 'customer_snapshot' => $customer->toArray(), // Immutable record ]); // Generate PDF via queued job GenerateInvoicePdfJob::dispatch($invoice);
👛 Wallet System
Customers can have wallet balances (one per currency):
$wallet = $customer->walletAccounts()->firstOrCreate([ 'currency' => 'USD', ], [ 'balance_minor' => 0, ]); // Credit wallet (via WalletService for transactional safety) app(\App\Core\Billing\Services\WalletService::class) ->credit($wallet, Money::fromMajor(50.00, 'USD'), 'Initial credit'); // Debit wallet app(\App\Core\Billing\Services\WalletService::class) ->debit($wallet, Money::fromMajor(10.00, 'USD'), 'Payment');
⚙️ Settings System
Settings follow this precedence: user → customer → brand → tenant → global
use App\Support\SettingsResolver\SettingsResolver; $resolver = app(SettingsResolver::class); // Get setting with context $value = $resolver->get( key: 'theme.color', default: 'blue', userId: $user->id, customerId: $customer->id ); // Set setting $resolver->set( key: 'theme.color', value: 'red', scopeType: 'customer', scopeId: $customer->id );
🔔 Notifications
All notifications are queued jobs that create OutboundMessage records:
// Listen to event class OrderConfirmationListener { public function handle(OrderSubmitted $event) { SendOrderConfirmationJob::dispatch($event->order); } }
📦 Queue Lanes
Three priority lanes:
critical: Payment callbacks, critical operations (3 workers, timeout 300s)default: Notifications, emails (5 workers, timeout 180s)low: PDFs, exports, background tasks (2 workers, timeout 600s)
Dispatch to specific queue:
GenerateInvoicePdfJob::dispatch($invoice)->onQueue('low'); PaymentCallbackJob::dispatch($payment)->onQueue('critical');
🧩 Extending with Modules
Future vertical modules for your specific business needs should:
- Live in
modules/ModuleName/ - Have own Models, Services, Events, Jobs
- Can extend Core models (Order, Customer, Product)
- Listen to Core events for integration
- Never depend on other modules
Example:
// modules/YourModule/Models/CustomEntity.php class CustomEntity extends Model { public function order() { return $this->belongsTo(\App\Core\Sales\Order::class); } } // modules/YourModule/Listeners/HandleOrderPaid.php class HandleOrderPaid { public function handle(OrderPaid $event) { if ($event->order->hasProductType('your_product_type')) { YourCustomJob::dispatch($event->order); } } }
🔐 Security
Policies (To Be Created)
All Filament resources should use policies:
- Tenant scoping enforced
- Role-based permissions
- Super admin bypass for tenant management
Authentication
Users access Filament admin panel if:
is_active = truerole IN ('super_admin', 'admin')
🧪 Testing
# Run all tests php artisan test # Run specific test suite php artisan test --testsuite=Feature # Run with coverage php artisan test --coverage
Critical test areas:
- Tenant isolation (no cross-tenant data leakage)
- Money calculations (precision)
- Sequence generation (thread-safety)
- Wallet transactions (balance integrity)
- Event/listener flow
📊 Admin Panel (Filament)
Access at /admin with admin credentials.
Resources to create:
- Tenants (super_admin only)
- Users
- Customers
- Products & Variants
- Orders
- Invoices
- Payments
- Wallet Accounts
- Coupons
- Tax Rates
- Settings
- Files
- Outbound Messages
- Activity Log
🔄 Development Workflow
Creating a New Domain Feature
- Create migration in
database/migrations/ - Create model in
app/Core/{Domain}/ - Create event(s) in
app/Events/ - Create listener(s) in
app/Listeners/(queued!) - Create job(s) in
app/Jobs/ - Create service/action in
app/Core/{Domain}/Actions/ - Create Filament resource in
app/Filament/Resources/ - Write tests in
tests/Feature/{Domain}/
Example: Adding Refund Support
// 1. Update migrations (already has refunded_minor) // 2. Create event class RefundCreated { public function __construct(public Payment $payment) {} } // 3. Create listener class UpdateInvoiceAfterRefund { public function handle(RefundCreated $event) { $invoice = $event->payment->invoice; $invoice->increment('refunded_minor', $event->payment->amount_minor); $invoice->save(); } } // 4. Create job class ProcessRefundJob implements ShouldQueue { public $queue = 'critical'; public function handle() { // Process refund via gateway // Fire RefundCreated event } }
🎯 Roadmap
Completed ✅
- Database schema (all 24 migrations)
- Multi-tenancy infrastructure
- Core models (Tenant, Customer, User, Product, Order, Invoice, Payment, Wallet)
- Money value object
- Settings resolver
- Filament & Horizon integration
In Progress 🔨
- Domain events
- Queued listeners
- Background jobs
- Filament resources
- Policies
Planned 📋
- API layer (optional)
- Webhook system
- PDF generation service
- Payment gateway drivers
- Fulfillment system abstraction
- Test suite
- Package extraction
📚 Resources
📄 License
Proprietary. Not for redistribution.
🙏 Credits
Built with:
- Laravel 11
- Filament 3
- Laravel Horizon
- Spatie Laravel Activity Log
Built for production. Designed for extensibility. Ready for extraction.
Testing webhook
m0hammadgh92/laravel-core-platform 适用场景与选型建议
m0hammadgh92/laravel-core-platform 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 3 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 12 月 28 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「payments」 「laravel」 「saas」 「billing」 「wallet」 「multi-tenant」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 m0hammadgh92/laravel-core-platform 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 m0hammadgh92/laravel-core-platform 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 m0hammadgh92/laravel-core-platform 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Laravel Plans is a package for SaaS apps that need management over plans, features, subscriptions, events for plans or limited, countable features.
Dealing with payments through the Egyptian payment gateway PayMob
Librería para la gestión sencilla de pagos mediante TPV Redsys y Paypal
Asaas.com PHP API v3 Wrapper
Adaptaçao Asaas.com PHP API Wrapper para PHP 5.6
Alfabank REST API integration
统计信息
- 总下载量: 3
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 23
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-12-28