feat: Phase 5.2 - Global Search with Laravel Scout
Code Style & Quality / Laravel Pint (push) Waiting to run
Code Style & Quality / PHPStan Static Analysis (push) Waiting to run
Code Style & Quality / Test Suite (push) Waiting to run
Code Style & Quality / Browser Tests (Dusk) (push) Waiting to run

- Install laravel/scout with database driver
- Add Searchable trait to Feature, Issue, Task, Inspection models
- Create GlobalSearch Livewire component with Blade view
- Configure scout.php for database driver + queued syncing
- Add SCOUT_DRIVER=database to .env.example

Tests: 101 passing (319 assertions)
This commit is contained in:
Javier Braña
2026-09-01 13:49:16 +02:00
parent c50a1a2080
commit 55b1a9276a
10 changed files with 686 additions and 5 deletions
+21 -1
View File
@@ -7,10 +7,11 @@ use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Laravel\Scout\Searchable;
class Feature extends Model
{
use LogsActivity, SoftDeletes;
use LogsActivity, SoftDeletes, Searchable;
const STATUSES = ['planned', 'started', 'in_progress', 'completed', 'verified'];
@@ -156,4 +157,23 @@ class Feature extends Model
return $spi >= 0.95;
}
public function toSearchableArray(): array
{
return [
'id' => $this->id,
'name' => $this->name,
'description' => $this->description,
'project_id' => $this->layer->phase->project_id ?? null,
'phase_id' => $this->layer->phase_id ?? null,
'layer_id' => $this->layer_id ?? null,
'status' => $this->status,
'progress' => $this->progress,
];
}
public function getScoutKey(): string
{
return (string) $this->id;
}
}
+23 -1
View File
@@ -5,10 +5,11 @@ namespace App\Models;
use App\Traits\LogsActivity;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Laravel\Scout\Searchable;
class Inspection extends Model
{
use LogsActivity, SoftDeletes;
use LogsActivity, SoftDeletes, Searchable;
protected static function booted(): void
{
@@ -87,4 +88,25 @@ class Inspection extends Model
{
return $q->where('status', 'rejected');
}
public function toSearchableArray(): array
{
return [
'id' => $this->id,
'project_id' => $this->project_id,
'layer_id' => $this->layer_id,
'feature_id' => $this->feature_id,
'template_id' => $this->template_id,
'user_id' => $this->user_id,
'inspector_user_id' => $this->inspector_user_id,
'status' => $this->status,
'result' => $this->result,
'notes' => $this->notes,
];
}
public function getScoutKey(): string
{
return (string) $this->id;
}
}
+24 -1
View File
@@ -5,10 +5,11 @@ namespace App\Models;
use App\Traits\LogsActivity;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Laravel\Scout\Searchable;
class Issue extends Model
{
use LogsActivity, SoftDeletes;
use LogsActivity, SoftDeletes, Searchable;
const STATUSES = ['open', 'in_review', 'resolved', 'closed'];
@@ -141,4 +142,26 @@ class Issue extends Model
default => '#6b7280',
};
}
public function toSearchableArray(): array
{
return [
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
'project_id' => $this->project_id,
'feature_id' => $this->feature_id,
'inspection_id' => $this->inspection_id,
'status' => $this->status,
'priority' => $this->priority,
'type' => $this->type,
'reported_by' => $this->reported_by,
'assigned_to' => $this->assigned_to,
];
}
public function getScoutKey(): string
{
return (string) $this->id;
}
}
+25 -1
View File
@@ -11,10 +11,11 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Laravel\Scout\Searchable;
class Task extends Model
{
use HasFactory, LogsActivity, SoftDeletes;
use HasFactory, LogsActivity, SoftDeletes, Searchable;
protected $fillable = [
'project_id',
@@ -328,4 +329,27 @@ class Task extends Model
'critical' => 'Crítica',
];
}
public function toSearchableArray(): array
{
return [
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
'project_id' => $this->project_id,
'phase_id' => $this->phase_id,
'parent_task_id' => $this->parent_task_id,
'status' => $this->status,
'priority' => $this->priority,
'assigned_to' => $this->assigned_to,
'due_date' => $this->due_date?->toDateString(),
'start_date' => $this->start_date?->toDateString(),
'completed_at' => $this->completed_at?->toDateTimeString(),
];
}
public function getScoutKey(): string
{
return (string) $this->id;
}
}