baks-dev/users-profile-balance
BaksDev Profile Balance — пакет для управления балансом профилей пользователей. Установка через Composer, установка конфигурации и ресурсов командой baks:assets:install, поддержка миграций Doctrine и тестов PHPUnit. Требуется PHP 8.4+.
Install the Package
composer require baks-dev/users-profile-balance
Add auto-scripts to composer.json:
"scripts": {
"post-install-cmd": ["@auto-scripts"],
"post-update-cmd": ["@auto-scripts"],
"auto-scripts": {
"baks:assets:install": "symfony-cmd"
}
}
Run Initial Setup
php artisan baks:assets:install
php artisan doctrine:migrations:diff
php artisan doctrine:migrations:migrate
First Use Case: Create a User Balance
Inject the BalanceService into a controller or command:
use BaksDev\Balance\Services\BalanceService;
public function __construct(private BalanceService $balanceService) {}
public function createBalance(User $user, float $initialAmount) {
$this->balanceService->create($user->id, $initialAmount);
}
Verify with Tests
php artisan test --group=users-profile-balance
Use the service layer for atomic operations:
// Create
$this->balanceService->create($userId, 100.0);
// Update (increment/decrement)
$this->balanceService->increment($userId, 50.0);
$this->balanceService->decrement($userId, 20.0);
// Retrieve
$balance = $this->balanceService->get($userId);
Listen to balance events (if supported) to trigger side effects:
use BaksDev\Balance\Events\BalanceUpdated;
Event::listen(BalanceUpdated::class, function ($event) {
// Send notification, log analytics, etc.
Notification::send($event->user, new BalanceAlert($event->newBalance));
});
Override default validation rules via config (config/baks.php):
'validation' => [
'min_balance' => 0,
'max_balance' => 1000000,
'allow_negative' => false,
],
Extend the Balance model or service to support currency types:
$this->balanceService->create($userId, 100.0, 'points');
$this->balanceService->create($userId, 50.0, 'credits');
Use the package’s console commands for bulk operations:
# Top-up balances for all users
php artisan baks:balance:topup --user-id=1 --amount=50
# Reset balances (careful!)
php artisan baks:balance:reset --user-id=1
Service Provider Binding
Ensure the package’s service is bound in AppServiceProvider:
public function register() {
$this->app->bind(BalanceService::class, function ($app) {
return new BalanceService(
$app->make(BalanceRepository::class),
$app->make(BalanceValidator::class)
);
});
}
Middleware for Balance Checks Protect routes requiring a minimum balance:
public function handle(Request $request, Closure $next) {
$user = $request->user();
$balance = $this->balanceService->get($user->id);
if ($balance < config('baks.min_balance')) {
abort(403, 'Insufficient balance');
}
return $next($request);
}
Queue-Based Balance Updates Offload balance changes to queues for scalability:
Queue::push(new UpdateBalanceJob($userId, -10.0));
Define the job:
class UpdateBalanceJob implements ShouldQueue {
public function handle() {
$this->balanceService->decrement($this->userId, $this->amount);
}
}
API Resource for Balance Data Create a resource to expose balance data securely:
public function toArray($request) {
return [
'amount' => $this->balanceService->get($request->user()->id),
'currency' => 'points',
];
}
Migration Conflicts
profile_balances tables.doctrine:migrations:diff --dry-run first to preview changes. Manually resolve conflicts by:
php artisan make:migration adjust_profile_balances_table --table=profile_balances
Then merge the changes into the package’s migration.Missing Documentation
src/ directory for:
BalanceService.php (core logic).BalanceRepository.php (database interactions).BalanceValidator.php (rules).No Built-in UI
// Livewire Component
public $balance;
public $userId;
public function mount() {
$this->balance = $this->balanceService->get($this->userId);
}
public function topUp($amount) {
$this->balanceService->increment($this->userId, $amount);
$this->balance += $amount;
}
PHP 8.4+ Requirements
.php-version file or Docker to enforce PHP 8.4+:
FROM php:8.4-fpm
No Multi-Tenancy Support
Balance model to include a tenant_id:
public function setTenantAttribute($value) {
$this->attributes['tenant_id'] = $value;
}
Enable Debug Logging
Add to config/logging.php:
'channels' => [
'baks' => [
'driver' => 'single',
'path' => storage_path('logs/baks.log'),
'level' => 'debug',
],
],
Then log balance operations:
\Log::channel('baks')->debug('Balance updated', ['user_id' => $userId, 'new_balance' => $newBalance]);
Database-Level Debugging Use Laravel Debugbar to inspect queries:
if (app()->environment('local')) {
$this->app->register(\Barryvdh\Debugbar\ServiceProvider::class);
}
Check for:
SELECT ... FOR UPDATE locks).user_id or balance_type.Race Condition Handling
DB::transaction(function () use ($userId, $amount) {
$this->balanceService->decrement($userId, $amount);
// Additional logic (e.g., send notification)
});
Testing Edge Cases Write tests for:
allow_negative = false).refreshModel() to simulate race conditions).$this->balanceService->setExpiry($userId, now()->addDays(30));
Custom Balance Types
Extend the Balance model to support custom types (e.g., "loyalty_points", "premium_credits"):
// Add to Balance model
protected $casts = [
'type' => 'string',
];
// Add to migrations
Schema::table('profile_balances', function (Blueprint $table) {
$table->string('type')->default('points');
});
Webhook Triggers Dispatch events to trigger external APIs (e.g., Stripe, third-party services):
Event::listen(BalanceUpdated::class,
How can I help you explore Laravel packages today?