feat: 소프트삭제 및 타임스탬프 감사 컬럼 추가

- deleted_at이 있는 30개 테이블에 deleted_by 추가
- created_at이 있는 38개 비즈니스 테이블에 created_by, updated_by 추가
- 시스템 테이블 제외
- nullable, COMMENT 포함
- 롤백(down) 메서드 구현
This commit is contained in:
2025-11-24 19:30:23 +09:00
parent 1b7fbdd96e
commit 80ca551026
3 changed files with 383 additions and 3610 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,179 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* created_by, updated_by 컬럼 추가
*
* 시스템 테이블 제외, 비즈니스 테이블만 추가
*/
public function up(): void
{
// 시스템 테이블 제외 목록
$excludeTables = [
'jobs',
'job_batches',
'password_reset_tokens',
'personal_access_tokens',
'taggables',
'tags',
];
$tables = [
'api_keys',
'archived_record_relations',
'archived_records',
'audit_logs',
'board_comments',
'board_files',
'board_settings',
'boards',
'bom_template_items',
'bom_templates',
'classifications',
'clients',
'common_codes',
'demo_links',
'department_user',
'file_share_links',
'main_request_flows',
'model_versions',
'models',
'order_histories',
'order_items',
'orders',
'payments',
'permission_overrides',
'permissions',
'plans',
'post_custom_field_values',
'posts',
'prospects',
'roles',
'setting_field_defs',
'subscriptions',
'tenant_bootstrap_runs',
'tenant_user_profiles',
'tenants',
'user_roles',
'user_tenants',
'users',
];
foreach ($tables as $tableName) {
if (!Schema::hasTable($tableName) || in_array($tableName, $excludeTables)) {
continue;
}
Schema::table($tableName, function (Blueprint $table) use ($tableName) {
// created_by 추가
if (!Schema::hasColumn($tableName, 'created_by')) {
// updated_at 다음에 추가
if (Schema::hasColumn($tableName, 'updated_at')) {
$table->foreignId('created_by')
->nullable()
->after('updated_at')
->comment('생성자 사용자 ID');
} else {
$table->foreignId('created_by')
->nullable()
->comment('생성자 사용자 ID');
}
}
// updated_by 추가
if (!Schema::hasColumn($tableName, 'updated_by')) {
// created_by 다음에 추가
if (Schema::hasColumn($tableName, 'created_by')) {
$table->foreignId('updated_by')
->nullable()
->after('created_by')
->comment('수정자 사용자 ID');
} else {
$table->foreignId('updated_by')
->nullable()
->comment('수정자 사용자 ID');
}
}
});
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
$excludeTables = [
'jobs',
'job_batches',
'password_reset_tokens',
'personal_access_tokens',
'taggables',
'tags',
];
$tables = [
'api_keys',
'archived_record_relations',
'archived_records',
'audit_logs',
'board_comments',
'board_files',
'board_settings',
'boards',
'bom_template_items',
'bom_templates',
'classifications',
'clients',
'common_codes',
'demo_links',
'department_user',
'file_share_links',
'main_request_flows',
'model_versions',
'models',
'order_histories',
'order_items',
'orders',
'payments',
'permission_overrides',
'permissions',
'plans',
'post_custom_field_values',
'posts',
'prospects',
'roles',
'setting_field_defs',
'subscriptions',
'tenant_bootstrap_runs',
'tenant_user_profiles',
'tenants',
'user_roles',
'user_tenants',
'users',
];
foreach ($tables as $tableName) {
if (!Schema::hasTable($tableName) || in_array($tableName, $excludeTables)) {
continue;
}
Schema::table($tableName, function (Blueprint $table) use ($tableName) {
// updated_by 먼저 제거
if (Schema::hasColumn($tableName, 'updated_by')) {
$table->dropColumn('updated_by');
}
// created_by 제거
if (Schema::hasColumn($tableName, 'created_by')) {
$table->dropColumn('created_by');
}
});
}
}
};

View File

@@ -0,0 +1,115 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* 소프트 삭제 테이블에 deleted_by 컬럼 추가
*
* deleted_at이 있지만 deleted_by가 없는 테이블 30개에 추가
*/
public function up(): void
{
$tables = [
'board_comments',
'bom_templates',
'classifications',
'common_codes',
'department_user',
'lot_sales',
'lots',
'main_requests',
'material_inspection_items',
'material_inspections',
'material_receipts',
'materials',
'model_versions',
'models',
'order_item_components',
'order_items',
'orders',
'payments',
'permission_overrides',
'plans',
'posts',
'price_histories',
'product_components',
'products',
'roles',
'subscriptions',
'tenants',
'user_roles',
'user_tenants',
'users',
];
foreach ($tables as $tableName) {
if (!Schema::hasTable($tableName)) {
continue;
}
Schema::table($tableName, function (Blueprint $table) use ($tableName) {
if (!Schema::hasColumn($tableName, 'deleted_by')) {
$table->foreignId('deleted_by')
->nullable()
->after('deleted_at')
->comment('삭제자 사용자 ID');
}
});
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
$tables = [
'board_comments',
'bom_templates',
'classifications',
'common_codes',
'department_user',
'lot_sales',
'lots',
'main_requests',
'material_inspection_items',
'material_inspections',
'material_receipts',
'materials',
'model_versions',
'models',
'order_item_components',
'order_items',
'orders',
'payments',
'permission_overrides',
'plans',
'posts',
'price_histories',
'product_components',
'products',
'roles',
'subscriptions',
'tenants',
'user_roles',
'user_tenants',
'users',
];
foreach ($tables as $tableName) {
if (!Schema::hasTable($tableName)) {
continue;
}
Schema::table($tableName, function (Blueprint $table) use ($tableName) {
if (Schema::hasColumn($tableName, 'deleted_by')) {
$table->dropColumn('deleted_by');
}
});
}
}
};