Files
Gnuboard7/modules/_bundled/sirsoft-ecommerce/database/seeders/SequenceSeeder.php
T
2026-05-11 11:29:41 +09:00

96 lines
3.6 KiB
PHP

<?php
namespace Modules\Sirsoft\Ecommerce\Database\Seeders;
use Illuminate\Database\Seeder;
use Modules\Sirsoft\Ecommerce\Enums\SequenceType;
use Modules\Sirsoft\Ecommerce\Models\Sequence;
/**
* 시퀀스 초기 데이터 시더.
*
* 설치 시 각 시퀀스 타입의 기본 설정을 1회 등록한다.
* 재실행(install --force 등) 시 기존 레코드의 `current_value` 는 운영 중 자동 증가한
* counter 이므로 절대 리셋되면 안 된다. `firstOrCreate` 를 사용해 기존 행을
* 완전히 보존하고, 존재하지 않는 경우에만 기본 설정을 삽입한다.
*
* 시더 정의 값의 추후 변경이 필요하면 upgrade step 에서 명시적으로 처리.
*/
class SequenceSeeder extends Seeder
{
public function run(): void
{
$this->command->info('시퀀스 초기 데이터 동기화를 시작합니다.');
// SequenceType::cases() 전체를 순회하여 enum 변경 시 자동 동기화 (drift 방지).
// enum 에 새 멤버를 추가하면 시더가 자동으로 따라간다.
$types = SequenceType::cases();
$created = 0;
$preserved = 0;
foreach ($types as $type) {
$typeLabel = $this->getTypeLabel($type);
$defaultConfig = $type->getDefaultConfig();
[, $wasCreated] = $this->firstOrCreateSequence($type, $defaultConfig);
if ($wasCreated) {
$created++;
$prefixInfo = isset($defaultConfig['prefix']) && $defaultConfig['prefix'] !== null
? ", 접두사: {$defaultConfig['prefix']}"
: ' (채번테이블 미사용)';
$this->command->line(" - {$typeLabel} 시퀀스 생성 완료 (알고리즘: {$defaultConfig['algorithm']->value}{$prefixInfo})");
} else {
$preserved++;
$this->command->line(" - {$typeLabel} 시퀀스 보존 (기존 current_value 유지)");
}
}
$this->command->info("시퀀스 동기화 완료: {$created}건 생성, {$preserved}건 보존");
}
/**
* 시퀀스 레코드를 찾거나 생성합니다 (기존 레코드 보존).
*
* @param SequenceType $type 시퀀스 타입
* @param array<string, mixed> $defaultConfig 기본 설정
* @return array{0: Sequence, 1: bool} [모델, 신규생성여부]
*/
private function firstOrCreateSequence(SequenceType $type, array $defaultConfig): array
{
$existed = Sequence::where('type', $type->value)->exists();
$sequence = Sequence::firstOrCreate(
['type' => $type->value],
[
'algorithm' => $defaultConfig['algorithm']->value,
'prefix' => $defaultConfig['prefix'] ?? null,
'current_value' => 0,
'increment' => 1,
'min_value' => 1,
'max_value' => $defaultConfig['max_value'],
'cycle' => false,
'pad_length' => $defaultConfig['pad_length'],
'max_history_count' => $defaultConfig['max_history_count'] ?? 0,
],
);
return [$sequence, ! $existed];
}
/**
* 시퀀스 타입의 한국어 라벨을 반환합니다.
*/
private function getTypeLabel(SequenceType $type): string
{
return match ($type) {
SequenceType::PRODUCT => '상품',
SequenceType::ORDER => '주문',
SequenceType::SHIPPING => '배송',
SequenceType::CANCEL => '취소',
SequenceType::REFUND => '환불',
};
}
}