First commit
This commit is contained in:
124
app/Models/DocumentVersion.php
Normal file
124
app/Models/DocumentVersion.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class DocumentVersion extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'document_id',
|
||||
'version_number',
|
||||
'original_filename',
|
||||
'stored_path',
|
||||
'mime_type',
|
||||
'file_size',
|
||||
'file_hash',
|
||||
'page_count',
|
||||
'processing_status',
|
||||
'processing_error',
|
||||
'processing_started_at',
|
||||
'processing_completed_at',
|
||||
'is_current',
|
||||
'change_notes',
|
||||
'uploaded_by',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'is_current' => 'boolean',
|
||||
'file_size' => 'integer',
|
||||
'page_count' => 'integer',
|
||||
'processing_started_at' => 'datetime',
|
||||
'processing_completed_at' => 'datetime',
|
||||
];
|
||||
|
||||
// Status constants
|
||||
const STATUS_PENDING = 'pending';
|
||||
const STATUS_PROCESSING = 'processing';
|
||||
const STATUS_EXTRACTING = 'extracting';
|
||||
const STATUS_CHUNKING = 'chunking';
|
||||
const STATUS_EMBEDDING = 'embedding';
|
||||
const STATUS_INDEXED = 'indexed';
|
||||
const STATUS_FAILED = 'failed';
|
||||
const STATUS_EXTRACTION_FAILED = 'extraction_failed';
|
||||
|
||||
// === Relationships ===
|
||||
|
||||
public function document(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Document::class);
|
||||
}
|
||||
|
||||
public function chunks(): HasMany
|
||||
{
|
||||
return $this->hasMany(DocumentChunk::class)->orderBy('chunk_index');
|
||||
}
|
||||
|
||||
public function uploader(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'uploaded_by');
|
||||
}
|
||||
|
||||
// === Scopes ===
|
||||
|
||||
public function scopeCurrent(Builder $query): Builder
|
||||
{
|
||||
return $query->where('is_current', true);
|
||||
}
|
||||
|
||||
public function scopeIndexed(Builder $query): Builder
|
||||
{
|
||||
return $query->where('processing_status', self::STATUS_INDEXED);
|
||||
}
|
||||
|
||||
// === Helpers ===
|
||||
|
||||
public function getStorageUrl(): string
|
||||
{
|
||||
return Storage::url($this->stored_path);
|
||||
}
|
||||
|
||||
public function getFileSizeFormattedAttribute(): string
|
||||
{
|
||||
$bytes = $this->file_size;
|
||||
if ($bytes < 1024) return $bytes . ' B';
|
||||
if ($bytes < 1048576) return round($bytes / 1024, 1) . ' KB';
|
||||
return round($bytes / 1048576, 1) . ' MB';
|
||||
}
|
||||
|
||||
public function isProcessed(): bool
|
||||
{
|
||||
return $this->processing_status === self::STATUS_INDEXED;
|
||||
}
|
||||
|
||||
public function hasFailed(): bool
|
||||
{
|
||||
return in_array($this->processing_status, [
|
||||
self::STATUS_FAILED,
|
||||
self::STATUS_EXTRACTION_FAILED,
|
||||
]);
|
||||
}
|
||||
|
||||
public function updateStatus(string $status, ?string $error = null): void
|
||||
{
|
||||
$data = ['processing_status' => $status];
|
||||
|
||||
if ($status === self::STATUS_PROCESSING) {
|
||||
$data['processing_started_at'] = now();
|
||||
}
|
||||
|
||||
if ($status === self::STATUS_INDEXED) {
|
||||
$data['processing_completed_at'] = now();
|
||||
}
|
||||
|
||||
if ($error !== null) {
|
||||
$data['processing_error'] = $error;
|
||||
}
|
||||
|
||||
$this->update($data);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user