Spatie Packages Integration
EasyOTC integrates several Spatie packages to provide robust functionality for tagging, activity logging, and other features.
Where this lives
- Repo:
easy-otc-api(GitHub: Eliinova/the-one-otc-api) - Roles enum (used when assigning roles):
app/Enums/RoleEnum.php— values:OTC_ONE_ADMIN,CARRIER_ADMIN,MEMBER,AGENT - Config files:
config/tags.php,config/activitylog.php,config/permission.php - Admin panel (to manage roles/tags/activity):
https://stage-api.easyotc.com/admin(staging) orhttp://localhost:8000/admin(local). See /access.
How to run
bash
# From the easy-otc-api repo root
composer install
php artisan migrate
php artisan db:seed --class=RolePermissionSeederInstalled Spatie Packages
1. Laravel Tags (spatie/laravel-tags)
Purpose: Provides a robust tagging system with multilingual support and polymorphic relationships.
Key Features:
- Multilingual tag names and slugs
- Polymorphic relationships (tags can be attached to any model)
- Tag types for categorization
- Automatic slug generation
- Ordering support
Usage:
php
// Add to models that need tagging
use Spatie\Tags\HasTags;
class Product extends Model
{
use HasTags;
}
// Create and attach tags
$product->attachTag('OTC');
$product->attachTags(['Pain Relief', 'Fever']);
// Query by tags
$products = Product::withAnyTags(['OTC', 'Pain Relief'])->get();Configuration: config/tags.php
2. Laravel Activity Log (spatie/laravel-activitylog)
Purpose: Comprehensive activity tracking and auditing for all model changes.
Key Features:
- Automatic logging of model changes
- Customizable logging options
- Batch operations support
- Detailed change tracking
- User attribution
Usage:
php
// Add to models that need activity logging
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;
class Product extends Model
{
use LogsActivity;
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly(['name', 'price', 'is_available'])
->logOnlyDirty()
->dontSubmitEmptyLogs();
}
}Configuration: config/activitylog.php
3. Laravel Permission (spatie/laravel-permission)
Purpose: Role and permission management system.
Key Features:
- Role-based access control
- Permission-based authorization
- Top-level admin (
OTC_ONE_ADMIN) functionality - Filament integration
Usage:
php
// Assign roles to users
$user->assignRole('CARRIER_ADMIN');
// Check permissions
if ($user->can('edit products')) {
// User can edit products
}
// Check roles
if ($user->hasRole('OTC_ONE_ADMIN')) {
// User is the top-level EasyOTC admin
}Configuration: config/permission.php
Database Tables
Tags System
tags- Stores tag information (name, slug, type, order)taggables- Polymorphic pivot table for tag relationships
Activity Log
activity_log- Stores all activity records- Additional columns:
event,batch_uuidfor advanced features
Permissions
permissions- Available permissionsroles- Available rolesrole_has_permissions- Role-permission relationshipsmodel_has_roles- User-role relationshipsmodel_has_permissions- User-permission relationships
Integration Examples
Product with Tags and Activity Logging
php
class Product extends Model
{
use HasFactory, HasSlug, Searchable, HasCategorizations, LogsActivity, SoftDeletes, HasTags;
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly([
'name', 'price', 'is_available', 'inventory_count',
'requires_prescription', 'strength', 'dosage_form'
])
->logOnlyDirty()
->dontSubmitEmptyLogs()
->logFillable();
}
}
// Usage
$product = Product::create([
'name' => 'Aspirin 500mg',
'price' => 1000, // $10.00
'is_available' => true
]);
// Attach tags
$product->attachTags(['OTC', 'Pain Relief', 'Fever']);
// Activity is automatically logged
// Tags are automatically managedUser with Roles and Activity Logging
php
class User extends Authenticatable
{
use HasFactory, Notifiable, HasApiTokens, HasRoles, SoftDeletes, LogsActivity;
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly(['name', 'email', 'email_verified_at'])
->logOnlyDirty()
->dontSubmitEmptyLogs()
->logFillable();
}
}
// Usage
$user = User::create([
'first_name' => 'John',
'last_name' => 'Doe',
'email' => 'john@example.com'
]);
// Assign role
$user->assignRole('MEMBER');
// Activity is automatically logged
// Role is automatically managedAPI Endpoints
Tags API
GET /api/tags- List all tagsPOST /api/tags- Create a new tagGET /api/tags/{id}- Get a specific tagPUT /api/tags/{id}- Update a tagDELETE /api/tags/{id}- Delete a tag
Activity Log API
Activity logs can be accessed through the admin panel and can be exposed via API endpoints for audit trails.
Admin Panel Integration
Filament Resources
- TagResource - Manage tags through the admin panel
- ActivityResource - View activity logs and audit trails
- RoleResource - Manage roles and permissions
Admin Dashboard
The admin dashboard includes statistics and recent activities from the Spatie packages:
- Recent tag usage
- Activity log summaries
- Role and permission statistics
Best Practices
1. Tag Management
- Use consistent tag naming conventions
- Leverage tag types for categorization
- Use multilingual tags for international support
- Clean up unused tags regularly
2. Activity Logging
- Only log relevant fields to avoid performance issues
- Use
logOnlyDirty()to avoid unnecessary logs - Implement proper log retention policies
- Use batch operations for bulk activities
3. Permission Management
- Follow the principle of least privilege
- Use role-based permissions for common scenarios
- Use direct permissions for specific actions
- Regularly audit permissions and roles
Migration and Seeding
Tags Seeding
php
// Create default tags
Tag::create(['name' => 'OTC', 'type' => 'product_category']);
Tag::create(['name' => 'Prescription', 'type' => 'product_category']);
Tag::create(['name' => 'Pain Relief', 'type' => 'product_type']);Roles and Permissions Seeding
php
// Create roles (values come from app/Enums/RoleEnum.php)
Role::create(['name' => 'OTC_ONE_ADMIN']);
Role::create(['name' => 'CARRIER_ADMIN']);
Role::create(['name' => 'MEMBER']);
Role::create(['name' => 'AGENT']);
// Create permissions
Permission::create(['name' => 'view products']);
Permission::create(['name' => 'edit products']);
Permission::create(['name' => 'delete products']);
// Assign permissions to roles
$carrierAdminRole = Role::findByName('CARRIER_ADMIN');
$carrierAdminRole->givePermissionTo(['view products', 'edit products']);Performance Considerations
Tags
- Tags are cached for better performance
- Use eager loading when querying tagged models
- Consider indexing on frequently queried tag fields
Activity Log
- Implement log rotation and cleanup
- Use database indexing on frequently queried fields
- Consider archiving old activity logs
Permissions
- Permissions are cached by default
- Use role-based checks when possible (faster than permission checks)
- Consider using gates for complex authorization logic
Troubleshooting
Common Issues
- Tags not saving: Ensure the model uses the
HasTagstrait - Activity not logging: Check the
LogsActivitytrait and configuration - Permission denied: Verify role and permission assignments
- Performance issues: Check caching configuration and database indexes
Debugging
php
// Check if a model has tags
dd($product->tags);
// Check activity logs
dd(Activity::forSubject($product)->get());
// Check user permissions
dd($user->getAllPermissions());Future Enhancements
- Implement tag suggestions based on usage patterns
- Add advanced activity log filtering and export features
- Create role-based dashboard views
- Implement audit trail reporting
- Add real-time activity notifications