Skip to content

Commit

Permalink
Add User Actions trait and migration macro
Browse files Browse the repository at this point in the history
  • Loading branch information
WendellAdriel committed Apr 28, 2024
1 parent 99e75d2 commit 325ce2a
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 6 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
* Logs on DB for user logins and for actions made on models
* [Strictus](https://github.com/php-strictus/strictus) for enforcing local variable types
* Models extending from BaseModel use soft deletes by default
* Log actions made by users with the `created_by`, `updated_by` and `deleted_by` fields. Use the `$table->userActions()` in your migrations to add these fields.

## Using the Template

Expand Down Expand Up @@ -223,11 +224,12 @@ Inside the `exa` folder, there are a lot of classes provided by this **skeleton*

### Models

* `BaseModel` - Base class that all your models should extend, already configured with the `CommonQueries` and `LogChanges` Traits.
* `BaseModel` - Base class that all your models should extend, already configured with the `CommonQueries`, `LogChanges`, `SoftDeletes` and `UserActions` Traits.
* `ChangeLog` - Model for the table that logs all changes made on other models.
* `CommonQueries` - This Trait provides a lot of methods for common queries that you can use with your models.
* `HasUuidField` - This Trait provides UUID field support for models that don't want the UUID to be the primary key.
* `LogChanges` - This Trait provides listeners for logging changes on the models. Check the class to know how you can customize your models with the properties of this Trait.
* `UserActions` - This Trait provides listeners for logging changes made by users on the models populating the `created_by`, `updated_by` and `deleted_by` fields. Check the class to know how you can customize your models with the properties of this Trait.

### Services

Expand Down
8 changes: 8 additions & 0 deletions app/Providers/AppServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
namespace App\Providers;

use Exa\Services\SlackClient;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\ServiceProvider;
use Modules\Auth\Models\User;

final class AppServiceProvider extends ServiceProvider
{
Expand All @@ -24,6 +26,12 @@ public function register(): void
public function boot(): void
{
JsonResource::withoutWrapping();

Blueprint::macro('userActions', function () {
$this->foreignId('created_by')->nullable()->constrained(table: User::getModelTable());
$this->foreignId('updated_by')->nullable()->constrained(table: User::getModelTable());
$this->foreignId('deleted_by')->nullable()->constrained(table: User::getModelTable());
});
}

private function registerSlackClient(): void
Expand Down
1 change: 1 addition & 0 deletions database/migrations/0001_create_users_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public function up(): void
$table->rememberToken();
$table->timestamps();
$table->softDeletes();
$table->userActions();
});
}
}
Expand Down
3 changes: 2 additions & 1 deletion exa/Models/BaseModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ abstract class BaseModel extends Model
{
use CommonQueries,
LogChanges,
SoftDeletes;
SoftDeletes,
UserActions;
}
41 changes: 41 additions & 0 deletions exa/Models/UserActions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace Exa\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;

trait UserActions
{
public bool $disableUserActions = false;

public static function bootUserActions()
{
static::creating(function (Model $model) {
if ($model->disableUserActions) {
return;
}

$model->created_by = Auth::id();
});

static::updating(function (Model $model) {
if ($model->disableUserActions) {
return;
}

$model->updated_by = Auth::id();
});

static::softDeleted(function (Model $model) {
if ($model->disableUserActions) {
return;
}

$model->deleted_by = Auth::id();
$model->save();
});
}
}
4 changes: 3 additions & 1 deletion modules/Auth/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Exa\Models\CommonQueries;
use Exa\Models\HasUuidField;
use Exa\Models\LogChanges;
use Exa\Models\UserActions;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
Expand All @@ -24,7 +25,8 @@ final class User extends Authenticatable implements JWTSubject
HasUuidField,
LogChanges,
Notifiable,
SoftDeletes;
SoftDeletes,
UserActions;

protected $fillable = [
'uuid',
Expand Down
2 changes: 2 additions & 0 deletions modules/Auth/Models/UserLogin.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ final class UserLogin extends BaseModel
{
public bool $disableChangeLogs = true;

public bool $disableUserActions = true;

protected $fillable = [
'user_id',
'ip',
Expand Down
4 changes: 3 additions & 1 deletion tests/Feature/Auth/CreateUserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
use Modules\Auth\Support\Role;

it('creates a new user', function () {
expect($this->actingAs(testUser(Role::ADMIN))->post('v1/users', dumbUserData()))
$user = testUser(Role::ADMIN);
expect($this->actingAs($user)->post('v1/users', dumbUserData()))
->assertCreated();

$this->assertDatabaseHas(User::getModelTable(), [
'email' => 'john.doe@example.com',
'created_by' => $user->id,
]);
});

Expand Down
4 changes: 3 additions & 1 deletion tests/Feature/Auth/DeleteUserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@

it('deletes user', function () {
$newUser = testUser(Role::REGULAR);
$adminUser = testUser(Role::ADMIN);

expect($this->actingAs(testUser(Role::ADMIN))->delete("v1/users/{$newUser->uuid}"))
expect($this->actingAs($adminUser)->delete("v1/users/{$newUser->uuid}"))
->assertNoContent();

$this->assertSoftDeleted(User::getModelTable(), [
'email' => $newUser->email,
'deleted_by' => $adminUser->id,
]);
});

Expand Down
5 changes: 4 additions & 1 deletion tests/Feature/Auth/UpdateUserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@
'active' => false,
];

expect($this->actingAs(testUser(Role::ADMIN))->put("v1/users/{$newUser->uuid}", $params))
$adminUser = testUser(Role::ADMIN);
expect($this->actingAs($adminUser)->put("v1/users/{$newUser->uuid}", $params))
->assertOk();

$this->assertDatabaseHas(User::getModelTable(), [
'email' => 'test@test.com',
'role' => Role::VIEWER->value,
'active' => false,
'updated_by' => $adminUser->id,
]);
});

Expand Down Expand Up @@ -53,6 +55,7 @@

$this->assertDatabaseHas(User::getModelTable(), [
'email' => 'test@test.com',
'updated_by' => $user->id,
]);
});

Expand Down

0 comments on commit 325ce2a

Please sign in to comment.