feat: Phase 5 API 개발 완료 (사용자 초대, 알림설정, 계정관리, 거래명세서)

5.1 사용자 초대 기능:
- UserInvitation 마이그레이션, 모델, 서비스, 컨트롤러, Swagger
- 초대 발송/수락/취소/재발송 API

5.2 알림설정 확장:
- NotificationSetting 마이그레이션, 모델, 서비스, 컨트롤러, Swagger
- 채널별/유형별 알림 설정 관리

5.3 계정정보 수정 API:
- 회원탈퇴, 사용중지, 약관동의 관리
- AccountService, AccountController, Swagger

5.4 매출 거래명세서 API:
- 거래명세서 조회/발행/이메일발송
- SaleService 확장, Swagger 문서화
This commit is contained in:
2025-12-19 14:52:53 +09:00
parent c7b25710a0
commit 3020026abf
31 changed files with 2735 additions and 8 deletions

View File

@@ -30,4 +30,4 @@ public function down(): void
{
Schema::dropIfExists('admin_api_deprecations');
}
};
};

View File

@@ -0,0 +1,41 @@
<?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('user_invitations', function (Blueprint $table) {
$table->id();
$table->foreignId('tenant_id')->constrained()->cascadeOnDelete()->comment('테넌트 ID');
$table->string('email', 255)->comment('초대 대상 이메일');
$table->foreignId('role_id')->nullable()->constrained('roles')->nullOnDelete()->comment('부여할 역할 ID');
$table->text('message')->nullable()->comment('초대 메시지');
$table->string('token', 64)->unique()->comment('초대 토큰');
$table->string('status', 20)->default('pending')->index()->comment('상태 (pending/accepted/expired/cancelled)');
$table->foreignId('invited_by')->constrained('users')->cascadeOnDelete()->comment('초대한 사용자 ID');
$table->timestamp('expires_at')->comment('만료 일시');
$table->timestamp('accepted_at')->nullable()->comment('수락 일시');
$table->timestamps();
// 복합 인덱스: 테넌트별 이메일 검색
$table->index(['tenant_id', 'email']);
// 복합 인덱스: 상태별 만료 일시 (스케줄러용)
$table->index(['status', 'expires_at']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('user_invitations');
}
};

View File

@@ -0,0 +1,47 @@
<?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('notification_settings', function (Blueprint $table) {
$table->id();
$table->foreignId('tenant_id')->constrained()->cascadeOnDelete()->comment('테넌트 ID');
$table->foreignId('user_id')->constrained()->cascadeOnDelete()->comment('사용자 ID');
// 알림 유형별 채널 설정
$table->string('notification_type', 50)->comment('알림 유형 (approval, order, deposit, withdrawal, notice, system 등)');
// 채널별 활성화 여부
$table->boolean('push_enabled')->default(true)->comment('푸시 알림 활성화');
$table->boolean('email_enabled')->default(true)->comment('이메일 알림 활성화');
$table->boolean('sms_enabled')->default(false)->comment('SMS 알림 활성화');
$table->boolean('in_app_enabled')->default(true)->comment('인앱 알림 활성화');
$table->boolean('kakao_enabled')->default(false)->comment('카카오 알림톡 활성화');
// 추가 설정
$table->json('settings')->nullable()->comment('추가 설정 (우선순위, 알림 시간대 등)');
$table->timestamps();
// 복합 유니크 인덱스
$table->unique(['tenant_id', 'user_id', 'notification_type'], 'notification_settings_unique');
$table->index(['user_id', 'notification_type']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('notification_settings');
}
};