feat: complete Epic 0 — foundation migration & infrastructure setup

Stories 0.2-0.5: rename folders→declarations (backend+frontend), configure
Redis for cache/queue/sessions, add foundation database migrations
(permissions, archived_at), replace DeclarationStatus enum with architecture
lifecycle values, create DeclarationObserver for status transition validation
and auto-archive, fix controller status transitions to respect observer rules.

93 tests pass (240 assertions).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-12 18:25:32 +00:00
parent d380df4074
commit fd43a6f429
105 changed files with 3899 additions and 1558 deletions

View File

@@ -0,0 +1,42 @@
<?php
namespace App\Observers;
use App\Enums\DeclarationStatus;
use App\Models\Declaration;
use Illuminate\Validation\ValidationException;
class DeclarationObserver
{
/**
* Handle the Declaration "updating" event.
*
* Validates status transitions and auto-archives when status becomes "ferme".
*/
public function updating(Declaration $declaration): void
{
if (! $declaration->isDirty('status')) {
return;
}
$oldStatus = $declaration->getOriginal('status');
$newStatus = $declaration->status;
// Handle both string and enum values
$oldValue = $oldStatus instanceof DeclarationStatus ? $oldStatus->value : (string) $oldStatus;
$newValue = $newStatus instanceof DeclarationStatus ? $newStatus->value : (string) $newStatus;
$allowed = DeclarationStatus::allowedTransitions()[$oldValue] ?? [];
if (! in_array($newValue, $allowed)) {
throw ValidationException::withMessages([
'status' => "Invalid status transition from '{$oldValue}' to '{$newValue}'.",
]);
}
// Auto-archive when status becomes "ferme"
if ($newValue === DeclarationStatus::Ferme) {
$declaration->archived_at = now();
}
}
}