Skip to content

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) or http://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=RolePermissionSeeder

Installed 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_uuid for advanced features

Permissions

  • permissions - Available permissions
  • roles - Available roles
  • role_has_permissions - Role-permission relationships
  • model_has_roles - User-role relationships
  • model_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 managed

User 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 managed

API Endpoints

Tags API

  • GET /api/tags - List all tags
  • POST /api/tags - Create a new tag
  • GET /api/tags/{id} - Get a specific tag
  • PUT /api/tags/{id} - Update a tag
  • DELETE /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

  1. Tags not saving: Ensure the model uses the HasTags trait
  2. Activity not logging: Check the LogsActivity trait and configuration
  3. Permission denied: Verify role and permission assignments
  4. 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