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

@@ -5,7 +5,7 @@ namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class StoreFolderMentionRequest extends FormRequest
class StoreDeclarationMentionRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.

View File

@@ -6,7 +6,7 @@ use App\Enums\MessageType;
use BenSampo\Enum\Rules\EnumValue;
use Illuminate\Foundation\Http\FormRequest;
class StoreFolderMessageRequest extends FormRequest
class StoreDeclarationMessageRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.

View File

@@ -2,15 +2,15 @@
namespace App\Http\Requests;
use App\Enums\FolderPriority;
use App\Enums\FolderStatus;
use App\Enums\FolderType;
use App\Enums\DeclarationPriority;
use App\Enums\DeclarationStatus;
use App\Enums\DeclarationType;
use BenSampo\Enum\Rules\EnumValue;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Validator;
class StoreFolderRequest extends FormRequest
class StoreDeclarationRequest extends FormRequest
{
/**
* Prepare the data for validation.
@@ -59,13 +59,13 @@ class StoreFolderRequest extends FormRequest
Rule::exists('clients', 'id')->where('workspace_id', $workspaceId),
],
'title' => ['required', 'string', 'max:255'],
'type' => ['required', new EnumValue(FolderType::class)],
'type' => ['required', new EnumValue(DeclarationType::class)],
'period_year' => ['required', 'integer', 'min:2000', 'max:2100'],
'period_month' => ['nullable', 'integer', 'min:1', 'max:12'],
'period_quarter' => ['nullable', 'integer', 'min:1', 'max:4'],
'due_date' => ['nullable', 'date'],
'status' => ['nullable', Rule::in(FolderStatus::getValues())],
'priority' => ['nullable', Rule::in(FolderPriority::getValues())],
'status' => ['nullable', Rule::in(DeclarationStatus::getValues())],
'priority' => ['nullable', Rule::in(DeclarationPriority::getValues())],
'assigned_to' => [
'nullable',
'integer',

View File

@@ -31,7 +31,7 @@ class StoreWorkspaceRequest extends FormRequest
'user_ids' => ['array'],
'user_ids.*' => ['integer', 'exists:users,id'],
'user_roles' => ['nullable', 'array'],
'user_roles.*' => ['string', 'in:' . implode(',', WorkspaceUserRole::getValues())],
'user_roles.*' => ['string', 'in:'.implode(',', WorkspaceUserRole::getValues())],
];
}
}

View File

@@ -2,15 +2,15 @@
namespace App\Http\Requests;
use App\Enums\FolderPriority;
use App\Enums\FolderStatus;
use App\Enums\FolderType;
use App\Enums\DeclarationPriority;
use App\Enums\DeclarationStatus;
use App\Enums\DeclarationType;
use BenSampo\Enum\Rules\EnumValue;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Validator;
class UpdateFolderRequest extends FormRequest
class UpdateDeclarationRequest extends FormRequest
{
/**
* Prepare the data for validation.
@@ -59,13 +59,13 @@ class UpdateFolderRequest extends FormRequest
Rule::exists('clients', 'id')->where('workspace_id', $workspaceId),
],
'title' => ['required', 'string', 'max:255'],
'type' => ['required', new EnumValue(FolderType::class)],
'type' => ['required', new EnumValue(DeclarationType::class)],
'period_year' => ['required', 'integer', 'min:2000', 'max:2100'],
'period_month' => ['nullable', 'integer', 'min:1', 'max:12'],
'period_quarter' => ['nullable', 'integer', 'min:1', 'max:4'],
'due_date' => ['nullable', 'date'],
'status' => ['nullable', Rule::in(FolderStatus::getValues())],
'priority' => ['nullable', Rule::in(FolderPriority::getValues())],
'status' => ['nullable', Rule::in(DeclarationStatus::getValues())],
'priority' => ['nullable', Rule::in(DeclarationPriority::getValues())],
'assigned_to' => [
'nullable',
'integer',

View File

@@ -34,7 +34,7 @@ class UpdateWorkspaceRequest extends FormRequest
'user_ids' => ['array'],
'user_ids.*' => ['integer', 'exists:users,id'],
'user_roles' => ['nullable', 'array'],
'user_roles.*' => ['string', 'in:' . implode(',', WorkspaceUserRole::getValues())],
'user_roles.*' => ['string', 'in:'.implode(',', WorkspaceUserRole::getValues())],
];
}
}