- documents 테이블 생성 (문서 기본 정보, 상태, 다형성 연결) - document_approvals 테이블 생성 (결재 처리) - document_data 테이블 생성 (EAV 패턴 데이터 저장) - document_attachments 테이블 생성 (파일 첨부) - SAM 규칙 준수 (tenant_id, 감사 컬럼, softDeletes, comment) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
116 lines
5.2 KiB
PHP
116 lines
5.2 KiB
PHP
<?php
|
|
|
|
use Illuminate\Database\Migrations\Migration;
|
|
use Illuminate\Database\Schema\Blueprint;
|
|
use Illuminate\Support\Facades\Schema;
|
|
|
|
return new class extends Migration
|
|
{
|
|
/**
|
|
* Run the migrations.
|
|
*/
|
|
public function up(): void
|
|
{
|
|
// 실제 문서
|
|
Schema::create('documents', function (Blueprint $table) {
|
|
$table->id()->comment('ID');
|
|
$table->foreignId('tenant_id')->constrained()->cascadeOnDelete()->comment('테넌트 ID');
|
|
$table->foreignId('template_id')->constrained('document_templates')->comment('템플릿 ID');
|
|
|
|
// 문서 정보
|
|
$table->string('document_no', 50)->comment('문서번호');
|
|
$table->string('title', 255)->comment('문서 제목');
|
|
$table->enum('status', ['DRAFT', 'PENDING', 'APPROVED', 'REJECTED', 'CANCELLED'])
|
|
->default('DRAFT')->comment('상태 (DRAFT:임시저장, PENDING:결재중, APPROVED:승인, REJECTED:반려, CANCELLED:취소)');
|
|
|
|
// 연결 정보 (다형성)
|
|
$table->string('linkable_type', 100)->nullable()->comment('연결 모델 타입');
|
|
$table->unsignedBigInteger('linkable_id')->nullable()->comment('연결 모델 ID');
|
|
|
|
// 결재 정보
|
|
$table->timestamp('submitted_at')->nullable()->comment('결재 요청일');
|
|
$table->timestamp('completed_at')->nullable()->comment('결재 완료일');
|
|
|
|
// 감사 컬럼
|
|
$table->foreignId('created_by')->nullable()->constrained('users')->comment('생성자 ID');
|
|
$table->foreignId('updated_by')->nullable()->constrained('users')->comment('수정자 ID');
|
|
$table->foreignId('deleted_by')->nullable()->constrained('users')->comment('삭제자 ID');
|
|
$table->timestamps();
|
|
$table->softDeletes();
|
|
|
|
// 인덱스
|
|
$table->index(['tenant_id', 'status']);
|
|
$table->index('document_no');
|
|
$table->index(['linkable_type', 'linkable_id']);
|
|
});
|
|
|
|
// 문서 결재
|
|
Schema::create('document_approvals', function (Blueprint $table) {
|
|
$table->id()->comment('ID');
|
|
$table->foreignId('document_id')->constrained()->cascadeOnDelete()->comment('문서 ID');
|
|
$table->foreignId('user_id')->constrained()->comment('결재자 ID');
|
|
|
|
$table->unsignedTinyInteger('step')->default(1)->comment('결재 순서');
|
|
$table->string('role', 50)->comment('역할 (작성/검토/승인)');
|
|
$table->enum('status', ['PENDING', 'APPROVED', 'REJECTED'])
|
|
->default('PENDING')->comment('상태 (PENDING:대기, APPROVED:승인, REJECTED:반려)');
|
|
|
|
$table->text('comment')->nullable()->comment('결재 의견');
|
|
$table->timestamp('acted_at')->nullable()->comment('결재 처리일');
|
|
|
|
// 감사 컬럼
|
|
$table->foreignId('created_by')->nullable()->constrained('users')->comment('생성자 ID');
|
|
$table->foreignId('updated_by')->nullable()->constrained('users')->comment('수정자 ID');
|
|
$table->timestamps();
|
|
|
|
// 인덱스
|
|
$table->index(['document_id', 'step']);
|
|
$table->index(['user_id', 'status']);
|
|
});
|
|
|
|
// 문서 데이터 (EAV 패턴)
|
|
Schema::create('document_data', function (Blueprint $table) {
|
|
$table->id()->comment('ID');
|
|
$table->foreignId('document_id')->constrained()->cascadeOnDelete()->comment('문서 ID');
|
|
|
|
$table->unsignedBigInteger('section_id')->nullable()->comment('섹션 ID (document_template_sections 참조)');
|
|
$table->unsignedBigInteger('column_id')->nullable()->comment('컬럼 ID (document_template_columns 참조)');
|
|
$table->unsignedSmallInteger('row_index')->default(0)->comment('행 인덱스 (테이블 데이터용)');
|
|
|
|
$table->string('field_key', 100)->comment('필드 키');
|
|
$table->text('field_value')->nullable()->comment('필드 값');
|
|
|
|
$table->timestamps();
|
|
|
|
// 인덱스
|
|
$table->index(['document_id', 'section_id']);
|
|
$table->index(['document_id', 'field_key']);
|
|
});
|
|
|
|
// 문서 첨부파일
|
|
Schema::create('document_attachments', function (Blueprint $table) {
|
|
$table->id()->comment('ID');
|
|
$table->foreignId('document_id')->constrained()->cascadeOnDelete()->comment('문서 ID');
|
|
$table->foreignId('file_id')->constrained('files')->comment('파일 ID');
|
|
|
|
$table->string('attachment_type', 50)->default('general')->comment('첨부 유형 (general, signature, image 등)');
|
|
$table->string('description', 255)->nullable()->comment('설명');
|
|
|
|
// 감사 컬럼
|
|
$table->foreignId('created_by')->nullable()->constrained('users')->comment('생성자 ID');
|
|
$table->timestamps();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Reverse the migrations.
|
|
*/
|
|
public function down(): void
|
|
{
|
|
Schema::dropIfExists('document_attachments');
|
|
Schema::dropIfExists('document_data');
|
|
Schema::dropIfExists('document_approvals');
|
|
Schema::dropIfExists('documents');
|
|
}
|
|
};
|