Files
michaelschiemer/src/Framework/Queue/Services/StepProgressTracker.php
Michael Schiemer 5050c7d73a docs: consolidate documentation into organized structure
- 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
2025-10-05 11:05:04 +02:00

170 lines
5.1 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Framework\Queue\Services;
use App\Framework\Queue\ValueObjects\ProgressStep;
use App\Framework\Core\ValueObjects\Percentage;
/**
* Helper class for tracking progress through multiple steps
*/
final class StepProgressTracker
{
private int $currentStepIndex = 0;
private array $completedSteps = [];
public function __construct(
private readonly string $jobId,
private readonly array $steps,
private readonly ProgressManager $progressManager
) {
if (empty($steps)) {
throw new \InvalidArgumentException('Steps array cannot be empty');
}
// Validate step structure
foreach ($steps as $index => $step) {
if (!is_array($step) || !isset($step['name'], $step['description'])) {
throw new \InvalidArgumentException("Step at index {$index} must have 'name' and 'description' keys");
}
}
}
public function start(string $message = 'Starting multi-step job'): void
{
$this->progressManager->startJob($this->jobId, $message);
}
public function completeCurrentStep(?array $metadata = null): void
{
if ($this->currentStepIndex >= count($this->steps)) {
throw new \RuntimeException('All steps have already been completed');
}
$step = $this->steps[$this->currentStepIndex];
$this->progressManager->completeJobStep(
$this->jobId,
$step['name'],
$step['description'],
$metadata
);
$this->completedSteps[] = $step['name'];
$this->currentStepIndex++;
// Update overall progress percentage
$percentage = ($this->currentStepIndex / count($this->steps)) * 100;
$message = sprintf(
'Completed step %d of %d: %s',
$this->currentStepIndex,
count($this->steps),
$step['description']
);
$this->progressManager->updateJobProgress(
$this->jobId,
$percentage,
$message,
[
'current_step' => $this->currentStepIndex,
'total_steps' => count($this->steps),
'completed_steps' => $this->completedSteps
]
);
}
public function updateCurrentStepProgress(
float $stepPercentage,
string $message,
?array $metadata = null
): void {
if ($this->currentStepIndex >= count($this->steps)) {
throw new \RuntimeException('All steps have already been completed');
}
// Calculate overall percentage: completed steps + current step progress
$completedStepsPercentage = ($this->currentStepIndex / count($this->steps)) * 100;
$currentStepContribution = ($stepPercentage / 100) * (100 / count($this->steps));
$totalPercentage = $completedStepsPercentage + $currentStepContribution;
$step = $this->steps[$this->currentStepIndex];
$fullMessage = sprintf(
'Step %d of %d (%s): %s',
$this->currentStepIndex + 1,
count($this->steps),
$step['name'],
$message
);
$fullMetadata = array_merge($metadata ?? [], [
'current_step' => $this->currentStepIndex + 1,
'total_steps' => count($this->steps),
'step_name' => $step['name'],
'step_percentage' => $stepPercentage,
'completed_steps' => $this->completedSteps
]);
$this->progressManager->updateJobProgress(
$this->jobId,
$totalPercentage,
$fullMessage,
$fullMetadata
);
}
public function complete(string $message = 'All steps completed successfully'): void
{
// Complete any remaining steps if not all were explicitly completed
while ($this->currentStepIndex < count($this->steps)) {
$this->completeCurrentStep();
}
$this->progressManager->completeJob($this->jobId, $message);
}
public function fail(string $message, ?\Throwable $exception = null): void
{
$step = $this->getCurrentStep();
$fullMessage = sprintf(
'Failed on step %d of %d (%s): %s',
$this->currentStepIndex + 1,
count($this->steps),
$step['name'] ?? 'unknown',
$message
);
$this->progressManager->failJob($this->jobId, $fullMessage, $exception);
}
public function getCurrentStep(): ?array
{
if ($this->currentStepIndex >= count($this->steps)) {
return null;
}
return $this->steps[$this->currentStepIndex];
}
public function getRemainingSteps(): array
{
return array_slice($this->steps, $this->currentStepIndex);
}
public function getCompletedSteps(): array
{
return $this->completedSteps;
}
public function isComplete(): bool
{
return $this->currentStepIndex >= count($this->steps);
}
public function getProgress(): float
{
return ($this->currentStepIndex / count($this->steps)) * 100;
}
}