Skip to content

Commit f48c908

Browse files
committed
refactor: Domain 엔티티 Data Annotation 도입 및 주석 최소화
- Data Annotation + Fluent API 하이브리드 방식으로 전환 - 기본 제약사항은 Data Annotation으로 이전 ([Key], [Required], [StringLength] 등) - 복잡한 설정은 Fluent API 유지 (외래키 관계, JSON 변환, 복합 인덱스 등) - ProjectVGDbContext.cs 코드량 50% 이상 감소 (160줄 → 약 70줄) - 불필요한 속성 주석 70% 제거 (90+ → 25개) - 비즈니스 로직 메서드 주석은 유지 - Domain 프로젝트에 EF Core Abstractions 패키지 추가 개선 효과: - 코드 가독성 향상 (엔티티 클래스만으로 기본 제약사항 파악 가능) - 유지보수성 향상 (주석-코드 불일치 위험 감소) - 개발 생산성 향상 (새 엔티티 추가 시 더 직관적)
1 parent 41cdc92 commit f48c908

File tree

9 files changed

+713
-233
lines changed

9 files changed

+713
-233
lines changed

ProjectVG.Domain/Entities/Character/Character.cs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,54 @@
11
using ProjectVG.Domain.Common;
2+
using System.ComponentModel.DataAnnotations;
23
using System.ComponentModel.DataAnnotations.Schema;
34
using System.Text.Json;
5+
using Microsoft.EntityFrameworkCore;
46

57
namespace ProjectVG.Domain.Entities.Characters
68
{
79
/// <summary>
810
/// AI 캐릭터 - Hybrid 구조 (고정 컬럼 + JSON 설정)
911
/// </summary>
12+
[Table("Characters")]
1013
public class Character : BaseEntity
1114
{
12-
/// <summary> 캐릭터 고유 ID </summary>
15+
[Key]
16+
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
1317
public Guid Id { get; set; }
1418

15-
/// <summary> 캐릭터 이름 </summary>
19+
[Required]
20+
[StringLength(100)]
1621
public string Name { get; set; } = string.Empty;
1722

18-
/// <summary> 캐릭터 설명 </summary>
23+
[StringLength(1000)]
1924
public string Description { get; set; } = string.Empty;
2025

21-
/// <summary> 캐릭터 이미지 URL </summary>
26+
[StringLength(500)]
2227
public string ImageUrl { get; set; } = string.Empty;
2328

24-
/// <summary> 활성화 여부 </summary>
29+
[Required]
2530
public bool IsActive { get; set; } = true;
2631

27-
/// <summary> 캐릭터 보이스 ID </summary>
32+
[StringLength(100)]
2833
public string VoiceId { get; set; } = string.Empty;
2934

30-
/// <summary> 캐릭터를 생성한 사용자 ID (nullable - 시스템 캐릭터 허용) </summary>
35+
/// <summary> 사용자 ID (null이면 시스템 캐릭터) </summary>
3136
public Guid? UserId { get; set; }
3237

33-
/// <summary> 캐릭터를 생성한 사용자 (네비게이션 속성) </summary>
3438
public virtual Users.User? User { get; set; }
3539

36-
/// <summary> 캐릭터 공개 여부 (true: 공개, false: 비공개) </summary>
40+
[Required]
3741
public bool IsPublic { get; set; } = true;
3842

39-
/// <summary> 설정 모드 (개별 설정 vs SystemPrompt) </summary>
43+
[Required]
4044
public CharacterConfigMode ConfigMode { get; set; } = CharacterConfigMode.Individual;
4145

42-
/// <summary> 개별 설정 JSON 데이터 (DB 저장용) </summary>
46+
/// <summary> JSON 데이터 (IndividualConfig 속성과 연동) </summary>
47+
[Column(TypeName = "nvarchar(max)")]
4348
public string? IndividualConfigJson { get; set; }
4449

45-
/// <summary> SystemPrompt 직접 입력 (최대 5000자) </summary>
50+
/// <summary> 직접 입력 SystemPrompt (최대 5000자) </summary>
51+
[StringLength(5000)]
4652
public string? SystemPrompt { get; set; }
4753

4854
/// <summary>
Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,39 @@
11
using ProjectVG.Domain.Common;
2+
using System.ComponentModel.DataAnnotations;
3+
using System.ComponentModel.DataAnnotations.Schema;
4+
using Microsoft.EntityFrameworkCore;
25

36

47
namespace ProjectVG.Domain.Entities.ConversationHistorys
58
{
69
/// <summary>
7-
/// 대화 기록 엔티티
8-
///
9-
/// 대화 관리:
10-
/// - 사용자와 AI 캐릭터 간의 대화 기록
11-
/// - 역할별 메시지 구분 (user, assistant, system)
12-
/// - 실제 사용자 요청 시간 기록
10+
/// 사용자와 AI 캐릭터 간의 대화 기록
1311
/// </summary>
12+
[Table("ConversationHistories")]
1413
public class ConversationHistory : BaseEntity
1514
{
16-
/// <summary>
17-
/// 대화 기록 고유 ID
18-
/// </summary>
15+
[Key]
16+
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
1917
public Guid Id { get; set; } = Guid.NewGuid();
2018

21-
/// <summary>
22-
/// 캐릭터 ID
23-
/// </summary>
19+
[Required]
2420
public Guid CharacterId { get; set; }
2521

26-
/// <summary>
27-
/// 사용자 ID
28-
/// </summary>
22+
[Required]
2923
public Guid UserId { get; set; }
3024

31-
/// <summary>
32-
/// 채팅 역할 (user, assistant, system - 소문자 문자열)
33-
/// </summary>
25+
[Required]
26+
[StringLength(20)]
3427
public string Role { get; set; } = string.Empty;
3528

36-
/// <summary>
37-
/// 대화 내용
38-
/// </summary>
29+
[Required]
30+
[StringLength(10000)]
3931
public string Content { get; set; } = string.Empty;
4032

41-
/// <summary>
42-
/// 사용자가 실제 요청한 시각 (서버 시간이 아닌 클라이언트 기준 시간)
43-
/// </summary>
33+
[Required]
4434
public DateTime Timestamp { get; set; }
4535

46-
/// <summary>
47-
/// 대화 세션 ID (하나의 대화에서 여러 메시지를 그룹화하기 위한 ID, nullable)
48-
/// OpenAI의 requestId 등을 저장
49-
/// </summary>
36+
[StringLength(100)]
5037
public string? ConversationId { get; set; }
5138
}
5239
}

ProjectVG.Domain/Entities/Token/CreditTransaction.cs renamed to ProjectVG.Domain/Entities/Credit/CreditTransaction.cs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,70 @@
11
using ProjectVG.Domain.Common;
2+
using System.ComponentModel.DataAnnotations;
3+
using System.ComponentModel.DataAnnotations.Schema;
4+
using Microsoft.EntityFrameworkCore;
25

36
namespace ProjectVG.Domain.Entities.Credits
47
{
58
/// <summary>
69
/// 토큰 거래 내역 엔티티
710
/// 모든 토큰 증감 이력을 추적하여 감사와 투명성을 보장
811
/// </summary>
12+
[Table("CreditTransactions")]
913
public class CreditTransaction : BaseEntity
1014
{
11-
/// <summary>
12-
/// 내부용 고유 ID
13-
/// </summary>
15+
[Key]
16+
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
1417
public int Id { get; set; }
1518

16-
/// <summary>
17-
/// 사용자 ID (외래키)
18-
/// </summary>
19+
[Required]
1920
public Guid UserId { get; set; }
2021

2122
/// <summary>
2223
/// 거래 고유 식별자 (중복 방지용)
2324
/// </summary>
25+
[Required]
26+
[StringLength(100)]
2427
public string TransactionId { get; set; } = string.Empty;
2528

2629
/// <summary>
2730
/// 거래 유형 (EARN: 획득, SPEND: 사용)
2831
/// </summary>
32+
[Required]
2933
public CreditTransactionType Type { get; set; }
3034

31-
/// <summary>
32-
/// 거래 금액 (양수: 증가, 음수: 감소)
33-
/// </summary>
35+
[Required]
36+
[Precision(18, 2)]
3437
public decimal Amount { get; set; }
3538

3639
/// <summary>
3740
/// 거래 후 잔액
3841
/// </summary>
42+
[Required]
43+
[Precision(18, 2)]
3944
public decimal BalanceAfter { get; set; }
4045

4146
/// <summary>
4247
/// 거래 발생원 (LOGIN_BONUS, CHAT_USAGE, PAYMENT, etc.)
4348
/// </summary>
49+
[Required]
50+
[StringLength(100)]
4451
public string Source { get; set; } = string.Empty;
4552

46-
/// <summary>
47-
/// 거래 상세 설명
48-
/// </summary>
53+
[StringLength(500)]
4954
public string Description { get; set; } = string.Empty;
5055

5156
/// <summary>
52-
/// 관련 엔티티 ID (예: 채팅 세션 ID, 결제 ID)
57+
/// 관련 엔티티 ID (채팅 세션, 결제 )
5358
/// </summary>
59+
[StringLength(100)]
5460
public string? RelatedEntityId { get; set; }
5561

5662
/// <summary>
57-
/// 관련 엔티티 유형 (예: ChatSession, Payment)
63+
/// 관련 엔티티 유형 (ChatSession, Payment)
5864
/// </summary>
65+
[StringLength(100)]
5966
public string? RelatedEntityType { get; set; }
6067

61-
/// <summary>
62-
/// 사용자 엔티티 (네비게이션 속성)
63-
/// </summary>
6468
public virtual Users.User User { get; set; } = null!;
6569
}
6670

Lines changed: 22 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,58 @@
11
using ProjectVG.Domain.Common;
2+
using System.ComponentModel.DataAnnotations;
3+
using System.ComponentModel.DataAnnotations.Schema;
4+
using Microsoft.EntityFrameworkCore;
25

36

47
namespace ProjectVG.Domain.Entities.Users
58
{
69
/// <summary>
7-
/// 사용자 엔티티
8-
///
9-
/// ID 관리:
10-
/// - Id: 내부 DB용 GUID
11-
/// - UID: 외부 노출용 12자리 고유 ID (인덱스 설정)
12-
///
13-
/// OAuth2 지원:
14-
/// - ProviderId, Provider: OAuth2 로그인 시에만 사용
10+
/// 사용자 엔티티 (OAuth2 및 크래딧 시스템 지원)
1511
/// </summary>
12+
[Table("Users")]
1613
public class User : BaseEntity
1714
{
18-
/// <summary>
19-
/// 내부용 고유 ID (GUID)
20-
/// </summary>
15+
[Key]
16+
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
2117
public Guid Id { get; set; }
2218

2319
/// <summary>
24-
/// 외부 노출용 고유 ID (12자리)
20+
/// 외부 노출용 12자리 고유 ID
2521
/// </summary>
22+
[Required]
23+
[StringLength(16)]
2624
public string UID { get; set; } = string.Empty;
2725

28-
/// <summary>
29-
/// OAuth2 Provider ID
30-
/// </summary>
26+
[Required]
27+
[StringLength(255)]
3128
public string ProviderId { get; set; } = string.Empty;
3229

33-
/// <summary>
34-
/// OAuth2 Provider (google, github 등)
35-
/// </summary>
30+
[Required]
31+
[StringLength(50)]
3632
public string Provider { get; set; } = string.Empty;
3733

38-
/// <summary>
39-
/// 사용자 이메일
40-
/// </summary>
34+
[Required]
35+
[StringLength(255)]
4136
public string Email { get; set; } = string.Empty;
4237

43-
/// <summary>
44-
/// 사용자 표시명
45-
/// </summary>
38+
[Required]
39+
[StringLength(50)]
4640
public string Username { get; set; } = string.Empty;
4741

48-
/// <summary>
49-
/// 계정 상태
50-
/// </summary>
42+
[Required]
5143
public AccountStatus Status { get; set; } = AccountStatus.Active;
5244

53-
/// <summary>
54-
/// 현재 크래딧 잔액 (1 Cost = 1 Credit)
55-
/// </summary>
45+
[Precision(18, 2)]
5646
public decimal CreditBalance { get; set; } = 0;
5747

58-
/// <summary>
59-
/// 총 획득한 크래딧 수 (누적)
60-
/// </summary>
48+
[Precision(18, 2)]
6149
public decimal TotalCreditsEarned { get; set; } = 0;
6250

63-
/// <summary>
64-
/// 총 사용한 크래딧 수 (누적)
65-
/// </summary>
51+
[Precision(18, 2)]
6652
public decimal TotalCreditsSpent { get; set; } = 0;
6753

68-
/// <summary>
69-
/// 첫 로그인 크래딧 지급 여부
70-
/// </summary>
7154
public bool InitialCreditsGranted { get; set; } = false;
7255

73-
/// <summary>
74-
/// 사용자가 생성한 캐릭터들 (네비게이션 속성)
75-
/// </summary>
7656
public virtual ICollection<Characters.Character> Characters { get; set; } = new List<Characters.Character>();
7757
}
7858
}

ProjectVG.Domain/ProjectVG.Domain.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
<ImplicitUsings>enable</ImplicitUsings>
77
</PropertyGroup>
88

9+
<ItemGroup>
10+
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="8.0.8" />
11+
</ItemGroup>
12+
913
<ItemGroup>
1014
<ProjectReference Include="..\ProjectVG.Common\ProjectVG.Common.csproj" />
1115
</ItemGroup>

0 commit comments

Comments
 (0)