First commit
This commit is contained in:
120
app/Models/ChunkAudit.php
Normal file
120
app/Models/ChunkAudit.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
/**
|
||||
* ChunkAudit
|
||||
*
|
||||
* Audit trail khusus untuk operasi chunk.
|
||||
* Append-only — tiada update atau delete.
|
||||
*
|
||||
* Berbeza dari AuditLog: ChunkAudit menyimpan perubahan teks penuh (old/new final_text)
|
||||
* yang terlalu besar untuk JSON kolum dalam audit_logs.
|
||||
*/
|
||||
class ChunkAudit extends Model
|
||||
{
|
||||
// Append-only — tiada updated_at
|
||||
const UPDATED_AT = null;
|
||||
|
||||
// === Operation constants ===
|
||||
const OP_EDIT_FINAL_TEXT = 'edit_final_text';
|
||||
const OP_EXCLUDE = 'exclude';
|
||||
const OP_INCLUDE = 'include';
|
||||
const OP_REINDEX = 'reindex';
|
||||
const OP_SPLIT_PARENT = 'split_parent';
|
||||
const OP_SPLIT_CHILD = 'split_child';
|
||||
|
||||
protected $fillable = [
|
||||
'document_chunk_id',
|
||||
'user_id',
|
||||
'operation',
|
||||
'old_final_text',
|
||||
'new_final_text',
|
||||
'old_status',
|
||||
'new_status',
|
||||
'metadata',
|
||||
'notes',
|
||||
'ip_address',
|
||||
'created_at',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'metadata' => 'array',
|
||||
'created_at' => 'datetime',
|
||||
];
|
||||
|
||||
// =========================================================================
|
||||
// RELATIONSHIPS
|
||||
// =========================================================================
|
||||
|
||||
public function chunk(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(DocumentChunk::class, 'document_chunk_id');
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// FACTORY METHOD
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* Cipta satu rekod audit dengan data dari request semasa.
|
||||
*
|
||||
* @param int $chunkId ID chunk yang terlibat
|
||||
* @param string $operation Jenis operasi (guna konstant OP_*)
|
||||
* @param array $data Data tambahan (old_final_text, new_status, metadata, dll.)
|
||||
* @param string|null $notes Nota admin
|
||||
*/
|
||||
public static function record(
|
||||
int $chunkId,
|
||||
string $operation,
|
||||
array $data = [],
|
||||
?string $notes = null
|
||||
): static {
|
||||
return static::create(array_merge([
|
||||
'document_chunk_id' => $chunkId,
|
||||
'user_id' => auth()->id(),
|
||||
'operation' => $operation,
|
||||
'notes' => $notes,
|
||||
'ip_address' => request()->ip(),
|
||||
'created_at' => now(),
|
||||
], $data));
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// DISPLAY HELPERS
|
||||
// =========================================================================
|
||||
|
||||
public function getOperationLabel(): string
|
||||
{
|
||||
return match ($this->operation) {
|
||||
self::OP_EDIT_FINAL_TEXT => 'Edit Final Text',
|
||||
self::OP_EXCLUDE => 'Dikecualikan',
|
||||
self::OP_INCLUDE => 'Dikembalikan',
|
||||
self::OP_REINDEX => 'Reindex',
|
||||
self::OP_SPLIT_PARENT => 'Split (asal)',
|
||||
self::OP_SPLIT_CHILD => 'Split (baharu)',
|
||||
default => ucfirst(str_replace('_', ' ', $this->operation)),
|
||||
};
|
||||
}
|
||||
|
||||
public function getOperationBadgeClass(): string
|
||||
{
|
||||
return match ($this->operation) {
|
||||
self::OP_EDIT_FINAL_TEXT => 'bg-primary',
|
||||
self::OP_EXCLUDE => 'bg-secondary',
|
||||
self::OP_INCLUDE => 'bg-success',
|
||||
self::OP_REINDEX => 'bg-info text-dark',
|
||||
self::OP_SPLIT_PARENT => 'bg-warning text-dark',
|
||||
self::OP_SPLIT_CHILD => 'bg-warning text-dark',
|
||||
default => 'bg-light text-dark border',
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user