1
0

update api ticket type

This commit is contained in:
Wian Drs
2026-06-25 17:11:48 +07:00
parent ad472a9880
commit af1c98b38b
29 changed files with 1097 additions and 34 deletions
@@ -0,0 +1,40 @@
<?php
namespace App\Http\Controllers\Audit;
use App\Http\Controllers\ApiController;
use App\Http\Requests\Audit\AuditLogFilterRequest;
use App\Http\Resources\Audit\AuditLogResource;
use App\Services\Audit\AuditLogService;
class AuditLogController extends ApiController
{
protected $service;
public function __construct(AuditLogService $service)
{
$this->service = $service;
}
public function index(AuditLogFilterRequest $request)
{
$data = $this->service->list(
$request->validated()
);
return $this->success(
AuditLogResource::collection($data),
'Data audit log berhasil diambil'
);
}
public function show($id)
{
$data = $this->service->detail($id);
return $this->success(
new AuditLogResource($data),
'Detail audit log berhasil diambil'
);
}
}
@@ -18,21 +18,24 @@ class TicketTypeController extends ApiController
public function index(Request $request) public function index(Request $request)
{ {
$data = TicketType::latest()->paginate( $data = $this->service->list(
$request->get('per_page', 10) $request->all()
); );
return $this->success($data); return $this->success(
TicketTypeResource::collection($data),
'Data Ticket Type berhasil diambil'
);
} }
public function store(StoreTicketTypeRequest $request) public function store(StoreTicketTypeRequest $request)
{ {
$type = $this->service->create( $data = $this->service->create(
$request->validated() $request->validated()
); );
return $this->created( return $this->created(
new TicketTypeResource($type), new TicketTypeResource($data),
'Ticket Type berhasil dibuat' 'Ticket Type berhasil dibuat'
); );
} }
@@ -40,7 +43,8 @@ class TicketTypeController extends ApiController
public function show(TicketType $ticket_type) public function show(TicketType $ticket_type)
{ {
return $this->success( return $this->success(
new TicketTypeResource($ticket_type) new TicketTypeResource($ticket_type),
'Detail Ticket Type berhasil diambil'
); );
} }
@@ -48,13 +52,13 @@ class TicketTypeController extends ApiController
UpdateTicketTypeRequest $request, UpdateTicketTypeRequest $request,
TicketType $ticket_type TicketType $ticket_type
) { ) {
$type = $this->service->update( $data = $this->service->update(
$ticket_type, $ticket_type,
$request->validated() $request->validated()
); );
return $this->updated( return $this->updated(
new TicketTypeResource($type), new TicketTypeResource($data),
'Ticket Type berhasil diupdate' 'Ticket Type berhasil diupdate'
); );
} }
@@ -0,0 +1,55 @@
<?php
namespace App\Http\Requests\Audit;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;
class AuditLogFilterRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'module' => [
'nullable',
'string'
],
'action' => [
'nullable',
'string'
],
'user_id' => [
'nullable',
'integer'
],
'tenant_id' => [
'nullable',
'integer'
],
'per_page' => [
'nullable',
'integer',
'min:1',
'max:100'
]
];
}
}
@@ -23,10 +23,81 @@ class StoreTicketTypeRequest extends FormRequest
public function rules(): array public function rules(): array
{ {
return [ return [
'code' => 'required|string|max:50|unique:ticket_types,code',
'name' => 'required|string|max:100', 'code' => [
'need_approval' => 'boolean', 'required',
'sla_minutes' => 'nullable|integer' 'string',
'max:50',
'unique:ticket_types,code'
],
'name' => [
'required',
'string',
'max:100'
],
'need_approval' => [
'nullable',
'boolean'
],
'sla_minutes' => [
'nullable',
'integer',
'min:1'
],
'require_photo' => [
'nullable',
'boolean'
],
'require_material' => [
'nullable',
'boolean'
],
'need_customer' => [
'nullable',
'boolean'
],
'need_incident_type' => [
'nullable',
'boolean'
]
]; ];
} }
protected function prepareForValidation(): void
{
$this->merge([
'need_approval' => filter_var(
$this->need_approval,
FILTER_VALIDATE_BOOLEAN
),
'require_photo' => filter_var(
$this->require_photo,
FILTER_VALIDATE_BOOLEAN
),
'require_material' => filter_var(
$this->require_material,
FILTER_VALIDATE_BOOLEAN
),
'need_customer' => filter_var(
$this->need_customer,
FILTER_VALIDATE_BOOLEAN
),
'need_incident_type' => filter_var(
$this->need_incident_type,
FILTER_VALIDATE_BOOLEAN
)
]);
}
} }
@@ -4,6 +4,7 @@ namespace App\Http\Requests\TicketType;
use Illuminate\Contracts\Validation\ValidationRule; use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class UpdateTicketTypeRequest extends FormRequest class UpdateTicketTypeRequest extends FormRequest
{ {
@@ -23,10 +24,82 @@ class UpdateTicketTypeRequest extends FormRequest
public function rules(): array public function rules(): array
{ {
return [ return [
'code' => 'sometimes|string|max:50|unique:ticket_types,code,' . $this->route('ticket_type'),
'name' => 'sometimes|string|max:100', 'code' => [
'need_approval' => 'sometimes|boolean', 'required',
'sla_minutes' => 'nullable|integer' 'string',
'max:50',
Rule::unique('ticket_types', 'code')
->ignore($this->ticket_type->id)
],
'name' => [
'required',
'string',
'max:100'
],
'need_approval' => [
'nullable',
'boolean'
],
'sla_minutes' => [
'nullable',
'integer',
'min:1'
],
'require_photo' => [
'nullable',
'boolean'
],
'require_material' => [
'nullable',
'boolean'
],
'need_customer' => [
'nullable',
'boolean'
],
'need_incident_type' => [
'nullable',
'boolean'
]
]; ];
} }
protected function prepareForValidation(): void
{
$this->merge([
'need_approval' => filter_var(
$this->need_approval,
FILTER_VALIDATE_BOOLEAN
),
'require_photo' => filter_var(
$this->require_photo,
FILTER_VALIDATE_BOOLEAN
),
'require_material' => filter_var(
$this->require_material,
FILTER_VALIDATE_BOOLEAN
),
'need_customer' => filter_var(
$this->need_customer,
FILTER_VALIDATE_BOOLEAN
),
'need_incident_type' => filter_var(
$this->need_incident_type,
FILTER_VALIDATE_BOOLEAN
)
]);
}
} }
@@ -0,0 +1,39 @@
<?php
namespace App\Http\Resources\Audit;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class AuditLogResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'user_id' => $this->user_id,
'tenant_id' => $this->tenant_id,
'module' => $this->module,
'action' => $this->action,
'table_name' => $this->table_name,
'record_id' => $this->record_id,
'old_values' => $this->old_values,
'new_values' => $this->new_values,
'description' => $this->description,
'ip_address' => $this->ip_address,
'created_at' => $this->created_at,
];
}
}
@@ -20,6 +20,10 @@ class TicketTypeResource extends JsonResource
'name' => $this->name, 'name' => $this->name,
'need_approval' => $this->need_approval, 'need_approval' => $this->need_approval,
'sla_minutes' => $this->sla_minutes, 'sla_minutes' => $this->sla_minutes,
'require_photo' => $this->require_photo,
'require_material' => $this->require_material,
'need_customer' => $this->need_customer,
'need_incident_type' => $this->need_incident_type,
'created_at' => $this->created_at, 'created_at' => $this->created_at,
'updated_at' => $this->updated_at, 'updated_at' => $this->updated_at,
]; ];
+30
View File
@@ -0,0 +1,30 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class AuditLog extends Model
{
public $timestamps = false;
protected $fillable = [
'user_id',
'tenant_id',
'module',
'action',
'table_name',
'record_id',
'old_values',
'new_values',
'ip_address',
'user_agent',
'description'
];
protected $casts = [
'old_values' => 'array',
'new_values' => 'array',
'created_at' => 'datetime'
];
}
+3
View File
@@ -2,10 +2,13 @@
namespace App\Models; namespace App\Models;
use App\Traits\Auditable;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class Ticket extends Model class Ticket extends Model
{ {
use Auditable;
protected $fillable = [ protected $fillable = [
'ticket_no', 'ticket_no',
'ticket_type_id', 'ticket_type_id',
+2
View File
@@ -2,12 +2,14 @@
namespace App\Models; namespace App\Models;
use App\Traits\Auditable;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
class TicketIncidentType extends Model class TicketIncidentType extends Model
{ {
use SoftDeletes; use SoftDeletes;
use Auditable;
protected $fillable = [ protected $fillable = [
'name', 'name',
+5
View File
@@ -2,10 +2,13 @@
namespace App\Models; namespace App\Models;
use App\Traits\Auditable;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class TicketType extends Model class TicketType extends Model
{ {
use Auditable;
protected $table = 'ticket_types'; protected $table = 'ticket_types';
protected $fillable = [ protected $fillable = [
@@ -16,6 +19,7 @@ class TicketType extends Model
'require_photo', 'require_photo',
'require_material', 'require_material',
'need_customer', 'need_customer',
'need_incident_type'
]; ];
protected $casts = [ protected $casts = [
@@ -23,6 +27,7 @@ class TicketType extends Model
'require_photo' => 'boolean', 'require_photo' => 'boolean',
'require_material' => 'boolean', 'require_material' => 'boolean',
'need_customer' => 'boolean', 'need_customer' => 'boolean',
'need_incident_type' => 'boolean'
]; ];
/* /*
+2
View File
@@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable; use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens; use Laravel\Sanctum\HasApiTokens;
// use App\Traits\Auditable;
class User extends Authenticatable class User extends Authenticatable
@@ -14,6 +15,7 @@ class User extends Authenticatable
/** @use HasFactory<\Database\Factories\UserFactory> */ /** @use HasFactory<\Database\Factories\UserFactory> */
use HasFactory, Notifiable; use HasFactory, Notifiable;
use HasApiTokens; use HasApiTokens;
// use Audittable;
/** /**
* The attributes that are mass assignable. * The attributes that are mass assignable.
+70
View File
@@ -0,0 +1,70 @@
<?php
namespace App\Services\Audit;
use App\Models\AuditLog;
class AuditLogService
{
public function list(array $filters = [])
{
$query = AuditLog::query();
if (!empty($filters['module'])) {
$query->where('module', $filters['module']);
}
if (!empty($filters['action'])) {
$query->where('action', $filters['action']);
}
if (!empty($filters['user_id'])) {
$query->where('user_id', $filters['user_id']);
}
if (!empty($filters['tenant_id'])) {
$query->where('tenant_id', $filters['tenant_id']);
}
return $query
->latest('id')
->paginate(
$filters['per_page'] ?? 20
);
}
public function detail($id)
{
return AuditLog::findOrFail($id);
}
public static function log(
string $module,
string $action,
?string $tableName = null,
?int $recordId = null,
?array $oldValues = null,
?array $newValues = null,
?string $description = null
): void {
AuditLog::create([
'user_id' => auth()->id(),
'tenant_id' => request()->header('X-Tenant-Id'),
'module' => $module,
'action' => $action,
'table_name' => $tableName,
'record_id' => $recordId,
'old_values' => $oldValues,
'new_values' => $newValues,
'ip_address' => request()->ip(),
'user_agent' => request()->userAgent(),
'description' => $description,
]);
}
}
+38 -7
View File
@@ -6,19 +6,50 @@ use App\Models\TicketType;
class TicketTypeService class TicketTypeService
{ {
public function list(array $filters = [])
{
return TicketType::query()
->when(
!empty($filters['search']),
fn($q) => $q->where(function ($x) use ($filters) {
$x->where(
'code',
'ILIKE',
"%{$filters['search']}%"
)
->orWhere(
'name',
'ILIKE',
"%{$filters['search']}%"
);
})
)
->latest('id')
->paginate(
$filters['per_page'] ?? 10
);
}
public function create(array $data): TicketType public function create(array $data): TicketType
{ {
return TicketType::create($data); return TicketType::create($data);
} }
public function update(TicketType $type, array $data): TicketType public function update(
{ TicketType $ticketType,
$type->update($data); array $data
return $type->fresh(); ): TicketType {
$ticketType->update($data);
return $ticketType->fresh();
} }
public function delete(TicketType $type): bool public function delete(
{ TicketType $ticketType
return $type->delete(); ): bool {
return $ticketType->delete();
} }
} }
+45
View File
@@ -0,0 +1,45 @@
<?php
namespace App\Traits;
use App\Services\Audit\AuditLogService;
trait Auditable
{
protected static function bootAuditable()
{
static::created(function ($model) {
AuditLogService::log(
module: strtolower(class_basename($model)),
action: 'create',
tableName: $model->getTable(),
recordId: $model->id,
newValues: $model->toArray()
);
});
static::updated(function ($model) {
AuditLogService::log(
module: strtolower(class_basename($model)),
action: 'update',
tableName: $model->getTable(),
recordId: $model->id,
oldValues: $model->getOriginal(),
newValues: $model->getAttributes()
);
});
static::deleted(function ($model) {
AuditLogService::log(
module: strtolower(class_basename($model)),
action: 'delete',
tableName: $model->getTable(),
recordId: $model->id,
oldValues: $model->toArray()
);
});
}
}
@@ -0,0 +1,42 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
if (!Schema::hasColumn('users', 'username')) {
$table->string('username')->nullable()->unique()->after('name');
}
if (!Schema::hasColumn('users', 'status')) {
$table->enum('status', [
'active',
'inactive',
'suspended'
])->default('active');
}
if (!Schema::hasColumn('users', 'last_login_at')) {
$table->timestamp('last_login_at')->nullable();
}
});
}
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn([
'username',
'status',
'last_login_at'
]);
});
}
};
@@ -0,0 +1,44 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('tenants', function (Blueprint $table) {
$table->id();
$table->string('tenant_code')->unique();
$table->string('tenant_name');
$table->string('phone')->nullable();
$table->string('email')->nullable();
$table->text('address')->nullable();
$table->enum('status', [
'active',
'inactive'
])->default('active');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('tenants');
}
};
@@ -0,0 +1,45 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('user_tenants', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')
->constrained()
->cascadeOnDelete();
$table->foreignId('tenant_id')
->constrained()
->cascadeOnDelete();
$table->boolean('is_default')
->default(false);
$table->timestamps();
$table->unique([
'user_id',
'tenant_id'
]);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('user_tenants');
}
};
@@ -0,0 +1,48 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('menu_lists', function (Blueprint $table) {
$table->id();
$table->foreignId('parent_id')
->nullable()
->constrained('menu_lists')
->cascadeOnDelete();
$table->string('name');
$table->string('slug')->unique();
$table->string('url')->nullable();
$table->string('icon')->nullable();
$table->string('component')->nullable();
$table->integer('sort_order')->default(0);
$table->boolean('is_active')->default(true);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('menu_lists');
}
};
@@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('menu_groups', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->text('description')->nullable();
$table->boolean('is_active')->default(true);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('menu_groups');
}
};
@@ -0,0 +1,54 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('menu_group_menus', function (Blueprint $table) {
$table->id();
$table->foreignId('menu_group_id')
->constrained()
->cascadeOnDelete();
$table->foreignId('menu_id')
->constrained('menu_lists')
->cascadeOnDelete();
$table->boolean('can_view')->default(false);
$table->boolean('can_create')->default(false);
$table->boolean('can_update')->default(false);
$table->boolean('can_delete')->default(false);
$table->boolean('can_approve')->default(false);
$table->boolean('can_export')->default(false);
$table->timestamps();
$table->unique([
'menu_group_id',
'menu_id'
]);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('menu_group_menus');
}
};
@@ -0,0 +1,48 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('user_menu_groups', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')
->constrained()
->cascadeOnDelete();
$table->foreignId('menu_group_id')
->constrained()
->cascadeOnDelete();
$table->foreignId('tenant_id')
->nullable()
->constrained()
->cascadeOnDelete();
$table->timestamps();
$table->unique([
'user_id',
'menu_group_id',
'tenant_id'
]);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('user_menu_groups');
}
};
@@ -0,0 +1,48 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('user_profiles', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')
->unique()
->constrained()
->cascadeOnDelete();
$table->string('nik', 30)->nullable();
$table->string('phone', 30)->nullable();
$table->text('address')->nullable();
$table->unsignedBigInteger('provinsi_id')->nullable();
$table->unsignedBigInteger('kabupaten_id')->nullable();
$table->unsignedBigInteger('kecamatan_id')->nullable();
$table->unsignedBigInteger('desa_id')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('user_profiles');
}
};
@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('wilayah_provinsi', function (Blueprint $table) {
$table->id();
$table->string('kode', 20)->unique();
$table->string('nama');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('wilayah_provinsi');
}
};
@@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('wilayah_kabupaten', function (Blueprint $table) {
$table->id();
$table->foreignId('provinsi_id')
->constrained('wilayah_provinsi')
->cascadeOnDelete();
$table->string('kode', 20)->unique();
$table->string('nama');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('wilayah_kabupaten');
}
};
@@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('wilayah_kecamatan', function (Blueprint $table) {
$table->id();
$table->foreignId('kabupaten_id')
->constrained('wilayah_kabupaten')
->cascadeOnDelete();
$table->string('kode', 20)->unique();
$table->string('nama');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('wilayah_kecamatan');
}
};
@@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('wilayah_desa', function (Blueprint $table) {
$table->id();
$table->foreignId('kecamatan_id')
->constrained('wilayah_kecamatan')
->cascadeOnDelete();
$table->string('kode', 20)->unique();
$table->string('nama');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('wilayah_desa');
}
};
@@ -0,0 +1,71 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('audit_logs', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')
->nullable()
->constrained('users')
->nullOnDelete();
$table->foreignId('tenant_id')
->nullable()
->constrained('tenants')
->nullOnDelete();
$table->string('module', 100);
$table->string('action', 50);
$table->string('table_name', 100)
->nullable();
$table->unsignedBigInteger('record_id')
->nullable();
$table->json('old_values')
->nullable();
$table->json('new_values')
->nullable();
$table->string('ip_address', 50)
->nullable();
$table->text('user_agent')
->nullable();
$table->text('description')
->nullable();
$table->timestamp('created_at')
->useCurrent();
$table->index('user_id');
$table->index('tenant_id');
$table->index('module');
$table->index('action');
$table->index('record_id');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('audit_logs');
}
};
+10
View File
@@ -8,6 +8,7 @@ use App\Http\Controllers\Ticket\TicketTypeController;
use App\Http\Controllers\Ticket\TicketWorkflowController; use App\Http\Controllers\Ticket\TicketWorkflowController;
use App\Http\Controllers\Ticket\TicketIncidentTypeController; use App\Http\Controllers\Ticket\TicketIncidentTypeController;
use App\Http\Controllers\Material\MaterialController; use App\Http\Controllers\Material\MaterialController;
use App\Http\Controllers\Audit\AuditLogController;
Route::post('/login', [AuthController::class, 'login']); Route::post('/login', [AuthController::class, 'login']);
@@ -70,5 +71,14 @@ Route::middleware('auth:sanctum')->group(function () {
}); });
Route::prefix('audit-logs')
->controller(AuditLogController::class)
->group(function () {
Route::get('/', 'index');
Route::get('/{id}', 'show');
});
}); });