create-entity-server 0.0.27 → 0.0.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/package.json +1 -1
  2. package/template/configs/auth/password.json +17 -5
  3. package/template/configs/cache.json +2 -1
  4. package/template/entities/System/Auth/account.json +158 -18
  5. package/template/entities/System/Auth/account_audit.json +11 -3
  6. package/template/entities/System/Auth/account_device.json +13 -12
  7. package/template/entities/System/Auth/account_login_log.json +21 -6
  8. package/template/entities/System/Auth/account_oauth.json +42 -13
  9. package/template/entities/System/Auth/api_keys.json +18 -9
  10. package/template/entities/System/Auth/identity_verification.json +18 -7
  11. package/template/entities/System/Auth/license.json +41 -20
  12. package/template/entities/System/Auth/password_history.json +4 -5
  13. package/template/entities/System/Auth/rbac_roles.json +10 -7
  14. package/template/entities/System/Backup/backup_log.json +11 -7
  15. package/template/entities/System/Email/smtp_log.json +9 -5
  16. package/template/entities/System/Email/smtp_msg.json +5 -5
  17. package/template/entities/System/Notification/alimtalk_log.json +32 -12
  18. package/template/entities/System/Notification/alimtalk_msg.json +23 -9
  19. package/template/entities/System/Notification/friendtalk_log.json +59 -18
  20. package/template/entities/System/Notification/friendtalk_msg.json +43 -15
  21. package/template/entities/System/Notification/sms_log.json +55 -16
  22. package/template/entities/System/Notification/sms_msg.json +45 -15
  23. package/template/entities/System/Notification/sms_verification.json +17 -7
  24. package/template/entities/System/Payment/pg_cancel.json +25 -10
  25. package/template/entities/System/Payment/pg_order.json +40 -13
  26. package/template/entities/System/Payment/pg_webhook_log.json +24 -9
  27. package/template/entities/System/Push/push_log.json +18 -3
  28. package/template/entities/System/Push/push_msg.json +6 -5
  29. package/template/entities/System/Storage/file_backup_log.json +11 -6
  30. package/template/entities/System/Storage/file_download_log.json +7 -5
  31. package/template/entities/System/Storage/file_meta.json +20 -7
  32. package/template/entities/System/system_audit_log.json +38 -34
  33. package/template/entities/company.json +5 -2
  34. package/template/entities/goods.json +10 -3
  35. package/template/entities/todo.json +4 -2
  36. package/template/samples/entities/01_basic_fields.json +15 -2
  37. package/template/samples/entities/02_types_and_defaults.json +15 -5
  38. package/template/samples/entities/03_hash_and_unique.json +18 -3
  39. package/template/samples/entities/04_fk_and_composite_unique.json +18 -3
  40. package/template/samples/entities/05_cache.json +15 -9
  41. package/template/samples/entities/06_history_and_hard_delete.json +19 -6
  42. package/template/samples/entities/07_license_scope.json +18 -3
  43. package/template/samples/entities/08_hook_sql.json +24 -5
  44. package/template/samples/entities/09_hook_entity.json +12 -2
  45. package/template/samples/entities/10_hook_submit_delete.json +14 -5
  46. package/template/samples/entities/11_hook_webhook.json +20 -6
  47. package/template/samples/entities/12_hook_push.json +15 -2
  48. package/template/samples/entities/13_read_only.json +8 -4
  49. package/template/samples/entities/14_optimistic_lock.json +13 -2
  50. package/template/samples/entities/15_reset_defaults.json +7 -1
  51. package/template/samples/entities/16_isolated_license.json +19 -6
  52. package/template/scripts/reset-all.sh +57 -3
  53. package/template/scripts/run.sh +56 -6
  54. package/template/templates/ocr/business_reg.json +145 -0
  55. package/template/templates/ocr/career_cert.json +93 -0
  56. package/template/templates/ocr/driver_license.json +89 -0
  57. package/template/templates/ocr/facility_card.json +82 -0
  58. package/template/templates/ocr/id_card.json +55 -0
  59. package/template/templates/ocr/invoice.json +92 -0
  60. package/template/templates/ocr/namecard.json +116 -0
  61. package/template/templates/ocr/prompts/business_reg.json +14 -0
  62. package/template/templates/ocr/prompts/career_cert.json +16 -0
  63. package/template/templates/ocr/prompts/driver_license.json +14 -0
  64. package/template/templates/ocr/prompts/facility_card.json +15 -0
  65. package/template/templates/ocr/prompts/general.json +13 -0
  66. package/template/templates/ocr/prompts/id_card.json +11 -0
  67. package/template/templates/ocr/prompts/invoice.json +17 -0
  68. package/template/templates/ocr/prompts/namecard.json +15 -0
  69. package/template/templates/ocr/prompts/receipt.json +14 -0
  70. package/template/templates/ocr/receipt.json +79 -0
  71. package/template/configs/auth/identity.json +0 -27
  72. package/template/configs/auth/privacy_policy.json +0 -28
  73. package/template/configs/auth/two_factor.json +0 -12
  74. package/template/configs/extensions/pg.json +0 -37
  75. package/template/configs/extensions/tax-invoice.json +0 -59
  76. package/template/configs/notification/alimtalk.json +0 -75
  77. package/template/configs/notification/sms.json +0 -54
  78. package/template/templates/email/account/dormancy_warning.html +0 -20
  79. package/template/templates/email/account/password_expiry_warning.html +0 -21
  80. package/template/templates/email/auth/email_verification.html +0 -18
  81. package/template/templates/email/auth/force_reset.html +0 -18
  82. package/template/templates/email/auth/password_reset.html +0 -19
  83. package/template/templates/email/auth/verification.html +0 -15
  84. package/template/templates/email/auth/verification_link.html +0 -25
@@ -1,28 +1,18 @@
1
1
  {
2
2
  "name": "system_audit_log",
3
- "description": "시스템 감사 로그. 서버 레벨에서 자동 기록되며 API를 통한 직접 수정은 허용되지 않습니다. JWT 인증 시에만 account_seq 기록. 사용자 환경에 맞게 index·fields를 자유롭게 확장할 수 있습니다.",
4
- "db_group": "system",
3
+ "description": "시스템 감사 로그. 서버 레벨에서 자동 기록되며 API를 통한 직접 수정은 허용되지 않습니다. JWT 인증 시에만 account_seq 기록. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
4
+ "license_scope": false,
5
5
  "hard_delete": true,
6
6
  "history_ttl": 0,
7
7
  "read_only": true,
8
- "license_scope": false,
9
8
  "compress": true,
10
- "index": {
11
- "transaction_id": {
12
- "comment": "요청 트랜잭션 ID. entity_history 테이블과 JOIN 키",
13
- "type": "varchar(64)"
14
- },
15
- "entity_name": {
16
- "comment": "대상 엔티티 이름",
17
- "type": "varchar(100)",
18
- "required": true
19
- },
20
- "entity_seq": {
21
- "comment": "대상 엔티티 레코드 seq. 로그인/로그아웃 등 레코드 없는 경우 NULL",
22
- "type": "bigint",
23
- "nullable": true
9
+ "fields": {
10
+ "account_seq": {
11
+ "index": true,
12
+ "comment": "작업을 수행한 계정 seq. JWT 인증 요청은 account.seq, 비인증/HMAC 요청은 NULL"
24
13
  },
25
14
  "action": {
15
+ "index": true,
26
16
  "comment": "수행된 작업 유형",
27
17
  "type": [
28
18
  "INSERT",
@@ -35,38 +25,52 @@
35
25
  ],
36
26
  "required": true
37
27
  },
38
- "account_seq": {
39
- "comment": "작업을 수행한 계정 seq. JWT 인증 요청은 account.seq, 비인증/HMAC 요청은 NULL",
40
- "type": "bigint",
41
- "nullable": true
28
+ "endpoint": {
29
+ "index": true,
30
+ "comment": "요청 API 엔드포인트",
31
+ "type": "varchar(200)"
32
+ },
33
+ "entity_name": {
34
+ "index": true,
35
+ "comment": "대상 엔티티 이름",
36
+ "required": true
37
+ },
38
+ "entity_seq": {
39
+ "index": true,
40
+ "comment": "대상 엔티티 레코드 seq. 로그인/로그아웃 등 레코드 없는 경우 NULL"
41
+ },
42
+ "error_message": {
43
+ "comment": "실패 시 오류 메시지 요약",
44
+ "type": "varchar(500)"
42
45
  },
43
46
  "ip_address": {
47
+ "index": true,
48
+ "hash": true,
44
49
  "comment": "요청 IP 주소 (IPv4/IPv6)",
45
- "type": "varchar(45)",
46
- "nullable": true
47
- },
48
- "endpoint": {
49
- "comment": "요청 API 엔드포인트",
50
- "type": "varchar(200)",
51
- "nullable": true
50
+ "type": "varchar(45)"
52
51
  },
53
52
  "request_method": {
53
+ "index": true,
54
54
  "comment": "HTTP 메서드 (GET/POST/PUT/DELETE 등)",
55
55
  "type": "varchar(10)"
56
56
  },
57
57
  "request_payload": {
58
58
  "comment": "요청 본문 JSON. 민감 필드(password, token 등) 자동 마스킹 후 저장. ServerConfig.AuditLogPayload = true 일 때만 기록",
59
- "type": "text",
60
- "nullable": true
59
+ "type": "text"
61
60
  },
62
61
  "result_code": {
62
+ "index": true,
63
63
  "comment": "HTTP 응답 코드 (200, 400, 401, 403, 500 등)",
64
64
  "type": "int"
65
65
  },
66
- "error_message": {
67
- "comment": "실패 시 오류 메시지 요약",
68
- "type": "varchar(500)",
69
- "nullable": true
66
+ "transaction_id": {
67
+ "index": true,
68
+ "comment": "요청 트랜잭션 ID. entity_history 테이블과 JOIN 키",
69
+ "type": "varchar(64)"
70
70
  }
71
+ },
72
+ "fk": {
73
+ "account_seq": false,
74
+ "entity_seq": false
71
75
  }
72
76
  }
@@ -1,15 +1,18 @@
1
1
  {
2
2
  "name": "company",
3
- "description": "company Entity. 사용자 환경에 맞게 index·fields를 자유롭게 확장할 수 있습니다.",
4
- "index": {
3
+ "description": "company Entity. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
4
+ "fields": {
5
5
  "company_name": {
6
+ "index": true,
6
7
  "comment": "회사명",
7
8
  "required": true
8
9
  },
9
10
  "industry": {
11
+ "index": true,
10
12
  "comment": "업종"
11
13
  },
12
14
  "tax_id": {
15
+ "index": true,
13
16
  "comment": "사업자번호",
14
17
  "hash": true
15
18
  }
@@ -1,17 +1,24 @@
1
1
  {
2
2
  "name": "goods",
3
- "description": "goods Entity. 사용자 환경에 맞게 index·fields를 자유롭게 확장할 수 있습니다.",
4
- "index": {
3
+ "description": "goods Entity. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
4
+ "fields": {
5
5
  "name": {
6
+ "index": true,
6
7
  "comment": "상품명",
7
8
  "required": true,
8
9
  "unique": true
9
10
  },
10
11
  "category": {
12
+ "index": true,
11
13
  "comment": "카테고리",
12
- "type": ["전자제품", "가구", "생활용품"]
14
+ "type": [
15
+ "전자제품",
16
+ "가구",
17
+ "생활용품"
18
+ ]
13
19
  },
14
20
  "price": {
21
+ "index": true,
15
22
  "comment": "가격"
16
23
  }
17
24
  },
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "todo",
3
- "description": "todo Entity. 사용자 환경에 맞게 index·fields를 자유롭게 확장할 수 있습니다.",
4
- "index": {
3
+ "description": "todo Entity. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
4
+ "fields": {
5
5
  "title": {
6
+ "index": true,
6
7
  "comment": "할 일 제목"
7
8
  },
8
9
  "status": {
10
+ "index": true,
9
11
  "comment": "상태",
10
12
  "type": [
11
13
  "pending",
@@ -1,38 +1,51 @@
1
1
  {
2
2
  "name": "contact",
3
3
  "description": "기본 필드 타입 예제 — 인덱스 필드 자동 추론 패턴 모음",
4
- "index": {
4
+ "fields": {
5
5
  "name": {
6
+ "index": true,
6
7
  "comment": "이름 (*_name → VARCHAR(100) 자동 추론)"
7
8
  },
8
9
  "email": {
10
+ "index": true,
9
11
  "comment": "이메일 (*email* → VARCHAR(255) 자동 추론)",
10
12
  "type": "email"
11
13
  },
12
14
  "phone": {
15
+ "index": true,
13
16
  "comment": "전화번호 (*phone* → VARCHAR(50) 자동 추론)"
14
17
  },
15
18
  "birth_date": {
19
+ "index": true,
16
20
  "comment": "생년월일 (*_date → DATE 자동 추론)"
17
21
  },
18
22
  "joined_at": {
23
+ "index": true,
19
24
  "comment": "가입일시 (*_at → DATETIME 자동 추론)"
20
25
  },
21
26
  "visit_count": {
27
+ "index": true,
22
28
  "comment": "방문 횟수 (*_count → INT 자동 추론)"
23
29
  },
24
30
  "total_amount": {
31
+ "index": true,
25
32
  "comment": "총 금액 (*_amount → DECIMAL(15,2) 자동 추론)"
26
33
  },
27
34
  "is_verified": {
35
+ "index": true,
28
36
  "comment": "인증 여부 (is_* → TINYINT(1) 자동 추론)"
29
37
  },
30
38
  "user_seq": {
39
+ "index": true,
31
40
  "comment": "연결된 사용자 seq (*_seq → BIGINT UNSIGNED 자동 추론)"
32
41
  },
33
42
  "status": {
43
+ "index": true,
34
44
  "comment": "상태 (enum 배열로 허용값 제한)",
35
- "type": ["active", "inactive"],
45
+ "type": [
46
+ "active",
47
+ "inactive"
48
+ ],
36
49
  "default": "active"
37
50
  }
38
51
  }
@@ -1,38 +1,48 @@
1
1
  {
2
2
  "name": "product",
3
3
  "description": "명시적 타입 선언 & defaults 예제 — 자동 추론이 안 되는 필드에 types 사용",
4
- "index": {
4
+ "fields": {
5
5
  "sku": {
6
+ "index": true,
6
7
  "comment": "상품 코드",
7
8
  "required": true,
8
9
  "unique": true
9
10
  },
10
11
  "category": {
12
+ "index": true,
11
13
  "comment": "카테고리",
12
- "type": ["electronics", "furniture", "clothing", "food"],
14
+ "type": [
15
+ "electronics",
16
+ "furniture",
17
+ "clothing",
18
+ "food"
19
+ ],
13
20
  "default": "electronics"
14
21
  },
15
22
  "price": {
23
+ "index": true,
16
24
  "comment": "정가 (decimal — 자동추론 불가, 명시 선언)",
17
25
  "type": "decimal"
18
26
  },
19
27
  "stock_qty": {
28
+ "index": true,
20
29
  "comment": "재고 수량 (*_qty → INT 자동 추론)",
21
30
  "default": 0
22
31
  },
23
32
  "weight": {
33
+ "index": true,
24
34
  "comment": "무게(kg) — 자동추론 없음, types에서 decimal 선언",
25
35
  "type": "decimal"
26
36
  },
27
37
  "is_available": {
38
+ "index": true,
28
39
  "comment": "판매 가능 여부 (is_* → TINYINT(1) 자동 추론)",
29
40
  "default": true
30
41
  },
31
42
  "launched_at": {
43
+ "index": true,
32
44
  "comment": "출시일시 (*_at → DATETIME 자동 추론)"
33
- }
34
- },
35
- "fields": {
45
+ },
36
46
  "description": {
37
47
  "type": "text",
38
48
  "comment": "상품 상세 설명"
@@ -1,33 +1,48 @@
1
1
  {
2
2
  "name": "member",
3
3
  "description": "hash & unique 예제 — 민감 필드 해시 저장 + 단일/복합 유니크",
4
- "index": {
4
+ "fields": {
5
5
  "email": {
6
+ "index": true,
6
7
  "comment": "이메일 (고유 — 중복 불가)",
7
8
  "type": "email",
8
9
  "required": true,
9
10
  "unique": true
10
11
  },
11
12
  "phone": {
13
+ "index": true,
12
14
  "comment": "전화번호 (해시 저장 — 평문 노출 차단)",
13
15
  "hash": true
14
16
  },
15
17
  "resident_id": {
18
+ "index": true,
16
19
  "comment": "주민등록번호 앞 7자리 (해시 + 유니크 — 중복 가입 방지)",
17
20
  "hash": true,
18
21
  "unique": true
19
22
  },
20
23
  "nickname": {
24
+ "index": true,
21
25
  "comment": "닉네임 (unique — 중복 불가)"
22
26
  },
23
27
  "org_seq": {
28
+ "index": true,
24
29
  "comment": "소속 조직 seq"
25
30
  },
26
31
  "status": {
32
+ "index": true,
27
33
  "comment": "상태",
28
- "type": ["active", "inactive", "withdrawn"],
34
+ "type": [
35
+ "active",
36
+ "inactive",
37
+ "withdrawn"
38
+ ],
29
39
  "default": "active"
30
40
  }
31
41
  },
32
- "unique": [["org_seq", "nickname"]]
42
+ "unique": [
43
+ [
44
+ "org_seq",
45
+ "nickname"
46
+ ]
47
+ ]
33
48
  }
@@ -1,28 +1,43 @@
1
1
  {
2
2
  "name": "team_member",
3
3
  "description": "외래키(fk) & 복합 유니크 예제 — 팀-사용자 다대다 중간 테이블",
4
- "index": {
4
+ "fields": {
5
5
  "team_seq": {
6
+ "index": true,
6
7
  "comment": "팀 seq (fk: team.seq)",
7
8
  "required": true
8
9
  },
9
10
  "user_seq": {
11
+ "index": true,
10
12
  "comment": "사용자 seq (fk: user.seq)",
11
13
  "required": true
12
14
  },
13
15
  "role": {
16
+ "index": true,
14
17
  "comment": "팀 내 역할",
15
- "type": ["owner", "admin", "member", "viewer"],
18
+ "type": [
19
+ "owner",
20
+ "admin",
21
+ "member",
22
+ "viewer"
23
+ ],
16
24
  "default": "member"
17
25
  },
18
26
  "invited_by": {
27
+ "index": true,
19
28
  "comment": "초대한 사용자 seq (fk: user.seq, nullable)"
20
29
  },
21
30
  "joined_at": {
31
+ "index": true,
22
32
  "comment": "참가일시 (*_at → DATETIME 자동 추론)"
23
33
  }
24
34
  },
25
- "unique": [["team_seq", "user_seq"]],
35
+ "unique": [
36
+ [
37
+ "team_seq",
38
+ "user_seq"
39
+ ]
40
+ ],
26
41
  "fk": {
27
42
  "invited_by": "user.seq"
28
43
  }
@@ -1,26 +1,28 @@
1
1
  {
2
2
  "name": "config_item",
3
3
  "description": "캐시 예제 — 자주 읽히고 드물게 변경되는 설정값에 엔티티 레벨 캐시 활성화",
4
- "index": {
4
+ "fields": {
5
5
  "key": {
6
+ "index": true,
6
7
  "comment": "설정 키 (고유)",
7
8
  "required": true,
8
9
  "unique": true
9
10
  },
10
11
  "category": {
12
+ "index": true,
11
13
  "comment": "설정 카테고리",
12
- "type": ["system", "ui", "feature_flag", "notification"],
14
+ "type": [
15
+ "system",
16
+ "ui",
17
+ "feature_flag",
18
+ "notification"
19
+ ],
13
20
  "default": "system"
14
21
  },
15
22
  "is_public": {
23
+ "index": true,
16
24
  "comment": "공개 여부 (is_* → TINYINT(1) 자동 추론)"
17
- }
18
- },
19
- "cache": {
20
- "enabled": true,
21
- "ttl_seconds": 600
22
- },
23
- "fields": {
25
+ },
24
26
  "value": {
25
27
  "comment": "설정 값 (문자열 저장, 타입은 애플리케이션에서 해석)",
26
28
  "required": true
@@ -29,6 +31,10 @@
29
31
  "comment": "설정 항목 설명"
30
32
  }
31
33
  },
34
+ "cache": {
35
+ "enabled": true,
36
+ "ttl_seconds": 600
37
+ },
32
38
  "reset_defaults": [
33
39
  {
34
40
  "key": "site.name",
@@ -1,33 +1,46 @@
1
1
  {
2
2
  "name": "article",
3
3
  "description": "이력 보존(history_ttl) & 완전삭제(hard_delete) 예제 — 게시글 수정 이력 3년 보관",
4
- "index": {
4
+ "fields": {
5
5
  "author_seq": {
6
+ "index": true,
6
7
  "comment": "작성자 user seq",
7
8
  "required": true
8
9
  },
9
10
  "title": {
11
+ "index": true,
10
12
  "comment": "제목",
11
13
  "required": true
12
14
  },
13
15
  "category": {
16
+ "index": true,
14
17
  "comment": "카테고리",
15
- "type": ["notice", "blog", "faq", "news"],
18
+ "type": [
19
+ "notice",
20
+ "blog",
21
+ "faq",
22
+ "news"
23
+ ],
16
24
  "default": "blog"
17
25
  },
18
26
  "status": {
27
+ "index": true,
19
28
  "comment": "게시 상태",
20
- "type": ["draft", "published", "archived"],
29
+ "type": [
30
+ "draft",
31
+ "published",
32
+ "archived"
33
+ ],
21
34
  "default": "draft"
22
35
  },
23
36
  "published_at": {
37
+ "index": true,
24
38
  "comment": "게시일시 (*_at → DATETIME 자동 추론)"
25
39
  },
26
40
  "view_count": {
41
+ "index": true,
27
42
  "comment": "조회 수 (*_count → INT 자동 추론)"
28
- }
29
- },
30
- "fields": {
43
+ },
31
44
  "content": {
32
45
  "type": "longtext",
33
46
  "comment": "게시글 본문",
@@ -2,29 +2,38 @@
2
2
  "name": "exchange_rate",
3
3
  "description": "license_scope: false 예제 — 전 라이선스 공용 기준 데이터 (환율). license_seq 컬럼 없이 모든 테넌트가 동일 데이터 공유",
4
4
  "license_scope": false,
5
- "index": {
5
+ "fields": {
6
6
  "base_currency": {
7
+ "index": true,
7
8
  "comment": "기준 통화 (ISO 4217)",
8
9
  "type": "varchar(3)",
9
10
  "required": true
10
11
  },
11
12
  "quote_currency": {
13
+ "index": true,
12
14
  "comment": "환산 통화 (ISO 4217)",
13
15
  "type": "varchar(3)",
14
16
  "required": true
15
17
  },
16
18
  "rate": {
19
+ "index": true,
17
20
  "comment": "환산 비율 (*_rate → 자동추론 없음, decimal 명시)",
18
21
  "type": "decimal",
19
22
  "required": true
20
23
  },
21
24
  "effective_date": {
25
+ "index": true,
22
26
  "comment": "적용일 (*_date → DATE 자동 추론)",
23
27
  "required": true
24
28
  },
25
29
  "source": {
30
+ "index": true,
26
31
  "comment": "환율 출처",
27
- "type": ["ecb", "openexchangerates", "manual"],
32
+ "type": [
33
+ "ecb",
34
+ "openexchangerates",
35
+ "manual"
36
+ ],
28
37
  "default": "manual"
29
38
  }
30
39
  },
@@ -32,7 +41,13 @@
32
41
  "enabled": true,
33
42
  "ttl_seconds": 3600
34
43
  },
35
- "unique": [["base_currency", "quote_currency", "effective_date"]],
44
+ "unique": [
45
+ [
46
+ "base_currency",
47
+ "quote_currency",
48
+ "effective_date"
49
+ ]
50
+ ],
36
51
  "reset_defaults": [
37
52
  {
38
53
  "base_currency": "USD",
@@ -1,22 +1,31 @@
1
1
  {
2
2
  "name": "user_point",
3
3
  "description": "SQL 훅 예제 — INSERT/UPDATE 시 자동 감사 로그 기록 (실행형) + SELECT 결과 주입 (조회형)",
4
- "index": {
4
+ "fields": {
5
5
  "user_seq": {
6
+ "index": true,
6
7
  "comment": "사용자 seq",
7
8
  "required": true,
8
9
  "unique": true
9
10
  },
10
11
  "point": {
12
+ "index": true,
11
13
  "comment": "보유 포인트",
12
14
  "type": "uint"
13
15
  },
14
16
  "grade": {
17
+ "index": true,
15
18
  "comment": "등급",
16
- "type": ["bronze", "silver", "gold", "platinum"],
19
+ "type": [
20
+ "bronze",
21
+ "silver",
22
+ "gold",
23
+ "platinum"
24
+ ],
17
25
  "default": "bronze"
18
26
  },
19
27
  "updated_at": {
28
+ "index": true,
20
29
  "comment": "마지막 포인트 변경일시 (*_at → DATETIME 자동 추론)"
21
30
  }
22
31
  },
@@ -26,7 +35,11 @@
26
35
  "comment": "포인트 생성 이력 기록 (실행형 SQL 훅)",
27
36
  "type": "sql",
28
37
  "query": "INSERT INTO point_history (user_seq, delta, reason, created_time) VALUES (?, ?, ?, NOW())",
29
- "params": ["${new.user_seq}", "${new.point}", "initial_grant"],
38
+ "params": [
39
+ "${new.user_seq}",
40
+ "${new.point}",
41
+ "initial_grant"
42
+ ],
30
43
  "async": false
31
44
  }
32
45
  ],
@@ -35,7 +48,11 @@
35
48
  "comment": "포인트 변경 이력 기록 (실행형 SQL 훅)",
36
49
  "type": "sql",
37
50
  "query": "INSERT INTO point_history (user_seq, delta, reason, created_time) VALUES (?, ?, ?, NOW())",
38
- "params": ["${new.user_seq}", "${new.point}", "update"],
51
+ "params": [
52
+ "${new.user_seq}",
53
+ "${new.point}",
54
+ "update"
55
+ ],
39
56
  "async": true
40
57
  }
41
58
  ],
@@ -44,7 +61,9 @@
44
61
  "comment": "최근 포인트 변경 이력 5건 주입 (조회형 SQL 훅)",
45
62
  "type": "sql",
46
63
  "query": "SELECT delta, reason, created_time FROM point_history WHERE user_seq = ? ORDER BY created_time DESC LIMIT 5",
47
- "params": ["${new.user_seq}"],
64
+ "params": [
65
+ "${new.user_seq}"
66
+ ],
48
67
  "assign_to": "recent_history"
49
68
  }
50
69
  ]
@@ -1,27 +1,37 @@
1
1
  {
2
2
  "name": "post",
3
3
  "description": "entity 훅 예제 — after_get/after_list 시 관련 엔티티 데이터를 자동 주입",
4
- "index": {
4
+ "fields": {
5
5
  "author_seq": {
6
+ "index": true,
6
7
  "comment": "작성자 user seq",
7
8
  "required": true
8
9
  },
9
10
  "title": {
11
+ "index": true,
10
12
  "comment": "제목",
11
13
  "required": true
12
14
  },
13
15
  "status": {
16
+ "index": true,
14
17
  "comment": "상태",
15
- "type": ["draft", "published", "hidden"],
18
+ "type": [
19
+ "draft",
20
+ "published",
21
+ "hidden"
22
+ ],
16
23
  "default": "draft"
17
24
  },
18
25
  "comment_count": {
26
+ "index": true,
19
27
  "comment": "댓글 수 (*_count → INT 자동 추론)"
20
28
  },
21
29
  "like_count": {
30
+ "index": true,
22
31
  "comment": "좋아요 수 (*_count → INT 자동 추론)"
23
32
  },
24
33
  "published_at": {
34
+ "index": true,
25
35
  "comment": "게시일시 (*_at → DATETIME 자동 추론)"
26
36
  }
27
37
  },