- Move 12 markdown files from root to docs/ subdirectories - Organize documentation by category: • docs/troubleshooting/ (1 file) - Technical troubleshooting guides • docs/deployment/ (4 files) - Deployment and security documentation • docs/guides/ (3 files) - Feature-specific guides • docs/planning/ (4 files) - Planning and improvement proposals Root directory cleanup: - Reduced from 16 to 4 markdown files in root - Only essential project files remain: • CLAUDE.md (AI instructions) • README.md (Main project readme) • CLEANUP_PLAN.md (Current cleanup plan) • SRC_STRUCTURE_IMPROVEMENTS.md (Structure improvements) This improves: ✅ Documentation discoverability ✅ Logical organization by purpose ✅ Clean root directory ✅ Better maintainability
105 lines
2.8 KiB
PHP
105 lines
2.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Framework\Queue\ValueObjects;
|
|
|
|
/**
|
|
* Value Object representing a single step in job progress tracking
|
|
*/
|
|
final readonly class ProgressStep
|
|
{
|
|
public function __construct(
|
|
public string $stepName,
|
|
public string $description,
|
|
public bool $completed = false,
|
|
public ?string $completedAt = null,
|
|
public ?array $metadata = null
|
|
) {
|
|
$this->validate();
|
|
}
|
|
|
|
public static function create(string $stepName, string $description, ?array $metadata = null): self
|
|
{
|
|
return new self(
|
|
stepName: $stepName,
|
|
description: $description,
|
|
metadata: $metadata
|
|
);
|
|
}
|
|
|
|
public static function completed(string $stepName, string $description, ?array $metadata = null): self
|
|
{
|
|
return new self(
|
|
stepName: $stepName,
|
|
description: $description,
|
|
completed: true,
|
|
completedAt: date('Y-m-d H:i:s'),
|
|
metadata: $metadata
|
|
);
|
|
}
|
|
|
|
public function markAsCompleted(?array $additionalMetadata = null): self
|
|
{
|
|
$metadata = $this->metadata ?? [];
|
|
if ($additionalMetadata) {
|
|
$metadata = array_merge($metadata, $additionalMetadata);
|
|
}
|
|
|
|
return new self(
|
|
stepName: $this->stepName,
|
|
description: $this->description,
|
|
completed: true,
|
|
completedAt: date('Y-m-d H:i:s'),
|
|
metadata: $metadata
|
|
);
|
|
}
|
|
|
|
public function withMetadata(array $metadata): self
|
|
{
|
|
return new self(
|
|
stepName: $this->stepName,
|
|
description: $this->description,
|
|
completed: $this->completed,
|
|
completedAt: $this->completedAt,
|
|
metadata: array_merge($this->metadata ?? [], $metadata)
|
|
);
|
|
}
|
|
|
|
public function getDisplayName(): string
|
|
{
|
|
return $this->stepName;
|
|
}
|
|
|
|
public function getStatus(): string
|
|
{
|
|
return $this->completed ? 'completed' : 'pending';
|
|
}
|
|
|
|
public function toArray(): array
|
|
{
|
|
return [
|
|
'step_name' => $this->stepName,
|
|
'description' => $this->description,
|
|
'completed' => $this->completed,
|
|
'completed_at' => $this->completedAt,
|
|
'status' => $this->getStatus(),
|
|
'metadata' => $this->metadata
|
|
];
|
|
}
|
|
|
|
private function validate(): void
|
|
{
|
|
if (empty(trim($this->stepName))) {
|
|
throw new \InvalidArgumentException('Step name cannot be empty');
|
|
}
|
|
|
|
if (empty(trim($this->description))) {
|
|
throw new \InvalidArgumentException('Step description cannot be empty');
|
|
}
|
|
|
|
if ($this->completed && !$this->completedAt) {
|
|
throw new \InvalidArgumentException('Completed steps must have a completion timestamp');
|
|
}
|
|
}
|
|
} |