Laravel과 Inertia.js로 다부서 워크플로우 라우팅 시스템을 구축한 방법

발행: (2026년 5월 3일 PM 10:54 GMT+9)
4 분 소요
원문: Dev.to

Source: Dev.to

The Problem I Was Trying to Solve

제가 VMMS — 바우처 관리 시스템 — 를 만들기 시작했을 때 가장 큰 도전은 워크플로 라우팅이었습니다.
바우처 요청은 한 사무실에만 전달되는 것이 아니라 여러 부서를 거칩니다. 어느 시점에서든 부서는 다음을 할 수 있습니다:

  • 자신의 단계를 완료하고 요청을 다음 부서로 전달
  • 전체 요청을 거부
  • 문서 누락을 표시하고 처리를 일시 중지

저는 이러한 모든 상황을 깔끔하게 처리할 수 있는 시스템이 필요했습니다.

Configurable Processing Flow

각 바우처 유형은 transaction_flows 테이블에 저장된 구성 가능한 처리 흐름을 가집니다:

Schema::create('transaction_flows', function (Blueprint $table) {
    $table->id();
    $table->foreignId('voucher_id')->constrained()->cascadeOnDelete();
    $table->string('department');
    $table->integer('order_number');
    $table->timestamps();
});

클라이언트가 요청을 제출하면 시스템은 이 테이블을 읽어 부서 순서를 결정합니다.

Audit Trails

부서가 요청을 처리할 때마다 audit_trails 테이블에 감사 레코드가 생성됩니다:

Schema::create('audit_trails', function (Blueprint $table) {
    $table->id();
    $table->foreignId('transaction_id')->constrained()->cascadeOnDelete();
    $table->string('processing_offices');
    $table->timestamp('process_initiate')->nullable();
    $table->timestamp('process_accomplished')->nullable();
    $table->date('deadline')->nullable();
    $table->timestamps();
});
  • process_initiate는 부서가 처리를 시작할 때 설정됩니다.
  • process_accomplished는 부서가 처리를 완료했을 때 설정됩니다.

Determining the Current Step

활성 부서(또는 다음 부서)를 찾는 로직은 다음과 같습니다:

$activeAudit = $auditTrails->first(
    fn($a) => $a->process_initiate && !$a->process_accomplished
);

if ($activeAudit) {
    return $activeAudit->processing_offices;
}

// If no active audit, find the next step
$doneOrders = $auditTrails
    ->filter(fn($a) => $a->process_accomplished)
    ->map(fn($a) => $flow->firstWhere('department', $a->processing_offices)?->order_number ?? 0);

$lastDone = $doneOrders->max() ?? 0;
$nextStep = $flow->firstWhere('order_number', $lastDone + 1);

return $nextStep?->department ?? 'Completed';

Edge Cases Handled

  • Skipped department – 코드는 다음 순번을 찾습니다.
  • Missing documents – 필요한 문서가 제공될 때까지 요청이 일시 중지됩니다.
  • Final department completed'Completed'를 반환합니다.

Vue 3 Stepper Component

프론트‑엔드에서는 진행 상황을 시각화하기 위해 스테퍼 컴포넌트를 만들었습니다:

const stepStatus = (req, step, stepIndex) => {
    const audits = req.audit_trails ?? [];
    const accomplishedCount = audits.filter(
        a => a.process_accomplished !== null
    ).length;

    if (stepIndex whereNull('resume_transaction')
    ->pluck('transaction_id')
    ->toArray();

resume_transaction가 채워지면 워크플로가 자동으로 재개됩니다.

Key Takeaways

  1. Model the flow separately from the transactiontransaction_flowsvoucher_transactions와 구분하면 라우팅 로직을 쉽게 수정할 수 있습니다.
  2. Audit trails are essential – 현재 상태와 이력을 신뢰할 수 있는 진실의 원천을 제공합니다.
  3. Plan for edge cases – 건너뛴 단계, 문서 일시 중지, 최종 완료 등을 명시적으로 처리해야 합니다.

Demo & Availability

  • Live demo: 🔴
  • Purchase VMMS: Gumroad에서 이용 가능 –

댓글에 언제든지 질문을 남겨 주세요!

0 조회
Back to Blog

관련 글

더 보기 »

Laravel에 SB Admin 2 통합

Laravel 11 요구사항 bash php -v >= 8.2 composer -v node -v >= v14.16 npm -v 웹 서버에서 Apache와 MySQL를 시작합니다. Laravel 11을 설치합니다. bash composer create…