create-entity-server 0.0.26 → 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 (98) hide show
  1. package/package.json +1 -1
  2. package/template/.env.example +26 -0
  3. package/template/configs/auth/cors.json +15 -0
  4. package/template/configs/auth/jwt.json +12 -0
  5. package/template/configs/{oauth.json → auth/oauth.json} +7 -4
  6. package/template/configs/auth/password.json +45 -0
  7. package/template/configs/{security.json → auth/security.json} +4 -2
  8. package/template/configs/cache.json +2 -1
  9. package/template/configs/keys/.gitkeep +0 -0
  10. package/template/configs/keys/apns.p8.example +7 -0
  11. package/template/configs/keys/firebase.pem.example +7 -0
  12. package/template/configs/server.json +1 -0
  13. package/template/entities/README.md +13 -16
  14. package/template/entities/System/Auth/account.json +172 -16
  15. package/template/entities/System/Auth/account_audit.json +31 -0
  16. package/template/entities/System/Auth/account_device.json +64 -0
  17. package/template/entities/System/Auth/account_login_log.json +69 -0
  18. package/template/entities/System/Auth/account_oauth.json +74 -0
  19. package/template/entities/System/Auth/api_keys.json +18 -9
  20. package/template/entities/System/Auth/identity_verification.json +106 -0
  21. package/template/entities/System/Auth/license.json +41 -20
  22. package/template/entities/System/Auth/password_history.json +19 -0
  23. package/template/entities/System/Auth/rbac_roles.json +10 -7
  24. package/template/entities/System/Backup/backup_log.json +66 -0
  25. package/template/entities/System/Email/smtp_log.json +87 -0
  26. package/template/entities/System/Email/smtp_msg.json +104 -0
  27. package/template/entities/System/Notification/alimtalk_log.json +65 -0
  28. package/template/entities/System/Notification/alimtalk_msg.json +53 -0
  29. package/template/entities/System/Notification/friendtalk_log.json +89 -0
  30. package/template/entities/System/Notification/friendtalk_msg.json +91 -0
  31. package/template/entities/System/Notification/sms_log.json +65 -0
  32. package/template/entities/System/Notification/sms_msg.json +82 -0
  33. package/template/entities/System/Notification/sms_verification.json +50 -0
  34. package/template/entities/System/Payment/pg_cancel.json +60 -0
  35. package/template/entities/System/Payment/pg_order.json +115 -0
  36. package/template/entities/System/Payment/pg_webhook_log.json +52 -0
  37. package/template/entities/System/Push/push_log.json +86 -0
  38. package/template/entities/System/Push/push_msg.json +56 -0
  39. package/template/entities/System/Storage/file_backup_log.json +51 -0
  40. package/template/entities/System/Storage/file_download_log.json +43 -0
  41. package/template/entities/System/Storage/file_meta.json +72 -0
  42. package/template/entities/System/system_audit_log.json +39 -34
  43. package/template/entities/company.json +5 -2
  44. package/template/entities/{product.json → goods.json} +9 -6
  45. package/template/entities/todo.json +4 -2
  46. package/template/samples/entities/01_basic_fields.json +15 -2
  47. package/template/samples/entities/02_types_and_defaults.json +15 -5
  48. package/template/samples/entities/03_hash_and_unique.json +18 -3
  49. package/template/samples/entities/04_fk_and_composite_unique.json +18 -3
  50. package/template/samples/entities/05_cache.json +15 -9
  51. package/template/samples/entities/06_history_and_hard_delete.json +19 -6
  52. package/template/samples/entities/07_license_scope.json +18 -3
  53. package/template/samples/entities/08_hook_sql.json +24 -5
  54. package/template/samples/entities/09_hook_entity.json +12 -2
  55. package/template/samples/entities/10_hook_submit_delete.json +14 -5
  56. package/template/samples/entities/11_hook_webhook.json +20 -6
  57. package/template/samples/entities/12_hook_push.json +15 -2
  58. package/template/samples/entities/13_read_only.json +8 -4
  59. package/template/samples/entities/14_optimistic_lock.json +13 -2
  60. package/template/samples/entities/15_reset_defaults.json +7 -1
  61. package/template/samples/entities/16_isolated_license.json +19 -6
  62. package/template/scripts/reset-all.sh +57 -3
  63. package/template/scripts/run.sh +56 -6
  64. package/template/templates/email/auth/2fa_disabled.html +23 -0
  65. package/template/templates/email/auth/2fa_recovery_regenerated.html +31 -0
  66. package/template/templates/email/auth/2fa_setup_complete.html +43 -0
  67. package/template/templates/email/auth/welcome.html +18 -0
  68. package/template/templates/email/backup/backup_completed.html +35 -0
  69. package/template/templates/email/backup/backup_failed.html +27 -0
  70. package/template/templates/email/backup/backup_partial.html +31 -0
  71. package/template/templates/email/layout.html +47 -0
  72. package/template/templates/email/order/order_confirmation.html +30 -0
  73. package/template/templates/email/storage/storage_quota_exceeded.html +37 -0
  74. package/template/templates/email/storage/storage_quota_warning.html +37 -0
  75. package/template/templates/ocr/business_reg.json +145 -0
  76. package/template/templates/ocr/career_cert.json +93 -0
  77. package/template/templates/ocr/driver_license.json +89 -0
  78. package/template/templates/ocr/facility_card.json +82 -0
  79. package/template/templates/ocr/id_card.json +55 -0
  80. package/template/templates/ocr/invoice.json +92 -0
  81. package/template/templates/ocr/namecard.json +116 -0
  82. package/template/templates/ocr/prompts/business_reg.json +14 -0
  83. package/template/templates/ocr/prompts/career_cert.json +16 -0
  84. package/template/templates/ocr/prompts/driver_license.json +14 -0
  85. package/template/templates/ocr/prompts/facility_card.json +15 -0
  86. package/template/templates/ocr/prompts/general.json +13 -0
  87. package/template/templates/ocr/prompts/id_card.json +11 -0
  88. package/template/templates/ocr/prompts/invoice.json +17 -0
  89. package/template/templates/ocr/prompts/namecard.json +15 -0
  90. package/template/templates/ocr/prompts/receipt.json +14 -0
  91. package/template/templates/ocr/receipt.json +79 -0
  92. package/template/configs/cors.json +0 -7
  93. package/template/configs/jwt.json +0 -8
  94. package/template/entities/Account/account_audit.json +0 -16
  95. /package/template/configs/{backup.json → extensions/backup.json} +0 -0
  96. /package/template/configs/{storage.json → extensions/storage.json} +0 -0
  97. /package/template/configs/{push.json → notification/push.json} +0 -0
  98. /package/template/configs/{smtp.json → notification/smtp.json} +0 -0
@@ -0,0 +1,86 @@
1
+ {
2
+ "name": "push_log",
3
+ "description": "푸시 알림 발송 이력. 발송 결과 추적 및 재시도 관리용. account_seq(JWT) 또는 device_id(HMAC) 중 하나 존재. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
4
+ "license_scope": false,
5
+ "hard_delete": true,
6
+ "history_ttl": 30,
7
+ "compress": true,
8
+ "fields": {
9
+ "account_seq": {
10
+ "index": true,
11
+ "comment": "수신자 account seq (JWT 인증 시. nullable)"
12
+ },
13
+ "attempt_time": {
14
+ "index": true,
15
+ "comment": "처리 시작(claim) 시각 — 비정상 종료 감지용"
16
+ },
17
+ "body": {
18
+ "comment": "알림 본문"
19
+ },
20
+ "device_id": {
21
+ "index": true,
22
+ "comment": "대상 디바이스 ID (HMAC 인증 시. nullable)",
23
+ "type": "varchar(255)"
24
+ },
25
+ "device_seq": {
26
+ "index": true,
27
+ "comment": "대상 디바이스 seq (account_device.seq)"
28
+ },
29
+ "device_token": {
30
+ "comment": "발송 시점 디바이스 토큰 스냅샷 (FCM registration token 또는 APNs device token)"
31
+ },
32
+ "error_message": {
33
+ "comment": "실패 시 오류 메시지",
34
+ "type": "varchar(500)"
35
+ },
36
+ "platform": {
37
+ "index": true,
38
+ "comment": "발송 채널",
39
+ "type": [
40
+ "fcm",
41
+ "apns",
42
+ "web"
43
+ ]
44
+ },
45
+ "push_data": {
46
+ "comment": "커스텀 페이로드 JSON 문자열",
47
+ "type": "varchar(2000)"
48
+ },
49
+ "ref_entity": {
50
+ "index": true,
51
+ "comment": "트리거 엔티티명"
52
+ },
53
+ "ref_seq": {
54
+ "index": true,
55
+ "comment": "트리거 레코드 seq"
56
+ },
57
+ "retry_count": {
58
+ "index": true,
59
+ "comment": "재시도 횟수",
60
+ "type": "uint",
61
+ "default": 0
62
+ },
63
+ "sent_time": {
64
+ "index": true,
65
+ "comment": "발송 완료 시각"
66
+ },
67
+ "status": {
68
+ "index": true,
69
+ "comment": "발송 상태",
70
+ "type": [
71
+ "pending",
72
+ "processing",
73
+ "sent",
74
+ "delivered",
75
+ "failed",
76
+ "expired"
77
+ ],
78
+ "default": "pending",
79
+ "required": true
80
+ },
81
+ "title": {
82
+ "index": true,
83
+ "comment": "알림 제목"
84
+ }
85
+ }
86
+ }
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "push_msg",
3
+ "description": "시스템 푸시 트리거 엔티티. insert 시 push hook로 비동기 발송. account_seq(JWT) 또는 device_id(HMAC) 중 하나 필수. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
4
+ "fields": {
5
+ "account_seq": {
6
+ "index": true,
7
+ "comment": "수신자 account seq (JWT 인증 시 필수. HMAC 인증은 device_id 사용)",
8
+ "required": true
9
+ },
10
+ "device_id": {
11
+ "index": true,
12
+ "comment": "대상 디바이스 ID (HMAC 인증 시. 기기단위로 account 없이 푸시 발송)",
13
+ "type": "varchar(255)"
14
+ },
15
+ "title": {
16
+ "index": true,
17
+ "comment": "푸시 제목",
18
+ "required": true
19
+ },
20
+ "message": {
21
+ "comment": "푸시 본문",
22
+ "nullable": true
23
+ },
24
+ "ref_entity": {
25
+ "comment": "참조 엔티티명",
26
+ "nullable": true
27
+ },
28
+ "ref_seq": {
29
+ "comment": "참조 레코드 seq",
30
+ "nullable": true
31
+ },
32
+ "msg_data": {
33
+ "comment": "추가 데이터(JSON 문자열)",
34
+ "type": "varchar(2000)",
35
+ "nullable": true
36
+ }
37
+ },
38
+ "hooks": {
39
+ "after_insert": [
40
+ {
41
+ "type": "push",
42
+ "target_account_seq": "account_seq",
43
+ "target_device_id": "device_id",
44
+ "comment": "account_seq 있으면 계정 기반 발송, 없으면 device_id 기반 발송",
45
+ "title": "${new.title}",
46
+ "push_body": "${new.message}",
47
+ "push_data": {
48
+ "push_msg_seq": "${new.seq}",
49
+ "ref_entity": "${new.ref_entity}",
50
+ "ref_seq": "${new.ref_seq}",
51
+ "msg_data": "${new.msg_data}"
52
+ }
53
+ }
54
+ ]
55
+ }
56
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "file_backup_log",
3
+ "description": "파일 백업 작업 로그. 스토리지 간 백업 동기화 이력을 기록합니다. 서버 내부 백업 고루틴이 자동 기록. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
4
+ "license_scope": false,
5
+ "history": false,
6
+ "hard_delete": true,
7
+ "read_only": true,
8
+ "compress": true,
9
+ "fields": {
10
+ "started_time": {
11
+ "index": true,
12
+ "comment": "백업 작업 시작 시각"
13
+ },
14
+ "status": {
15
+ "index": true,
16
+ "comment": "작업 상태",
17
+ "type": [
18
+ "running",
19
+ "completed",
20
+ "partial",
21
+ "failed"
22
+ ],
23
+ "default": "running",
24
+ "required": true
25
+ },
26
+ "error_count": {
27
+ "comment": "실패 파일 수"
28
+ },
29
+ "error_message": {
30
+ "comment": "실패 시 오류 메시지 요약"
31
+ },
32
+ "exec_instance": {
33
+ "comment": "작업을 실행한 서버 인스턴스 식별자 (hostname 등)"
34
+ },
35
+ "file_count": {
36
+ "comment": "처리된 파일 수"
37
+ },
38
+ "finished_time": {
39
+ "comment": "백업 작업 완료 시각"
40
+ },
41
+ "source_key": {
42
+ "comment": "원본 스토리지 키 (storage.json storages 맵의 키)"
43
+ },
44
+ "target_key": {
45
+ "comment": "백업 대상 스토리지 키"
46
+ },
47
+ "total_bytes": {
48
+ "comment": "전송된 총 바이트 수"
49
+ }
50
+ }
51
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "file_download_log",
3
+ "description": "파일 다운로드 이력. 누가 어떤 파일을 언제 다운로드했는지 기록합니다. 감사(audit) 및 통계 목적. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
4
+ "hard_delete": true,
5
+ "history": false,
6
+ "compress": true,
7
+ "fields": {
8
+ "account_seq": {
9
+ "index": true,
10
+ "comment": "다운로드한 계정 seq. JWT 인증 시 기록, 비인증은 NULL"
11
+ },
12
+ "downloaded_time": {
13
+ "index": true,
14
+ "comment": "다운로드 시각"
15
+ },
16
+ "entity_name": {
17
+ "index": true,
18
+ "comment": "파일이 속한 엔티티 이름"
19
+ },
20
+ "file_seq": {
21
+ "index": true,
22
+ "comment": "다운로드한 file_meta seq",
23
+ "required": true
24
+ },
25
+ "ip": {
26
+ "comment": "요청 IP 주소 (IPv4/IPv6)",
27
+ "type": "varchar(45)"
28
+ },
29
+ "thumb": {
30
+ "comment": "썸네일 요청 시 사이즈 (sm, md, lg). 원본 다운로드는 NULL",
31
+ "type": "varchar(10)"
32
+ },
33
+ "user_agent": {
34
+ "comment": "요청 User-Agent 헤더",
35
+ "type": "varchar(500)"
36
+ }
37
+ },
38
+ "fk": {
39
+ "account_seq": false,
40
+ "file_seq": false
41
+ },
42
+ "read_only": true
43
+ }
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "file_meta",
3
+ "description": "파일 메타데이터. 업로드된 파일의 저장 위치·크기·해시·상태를 관리합니다. 파일 핸들러가 자동 기록하며 API를 통한 직접 수정은 허용되지 않습니다. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
4
+ "history": false,
5
+ "hard_delete": true,
6
+ "read_only": true,
7
+ "fields": {
8
+ "backup_status": {
9
+ "index": true,
10
+ "comment": "백업 동기화 상태",
11
+ "type": [
12
+ "none",
13
+ "pending",
14
+ "synced",
15
+ "failed",
16
+ "skipped"
17
+ ],
18
+ "default": "none"
19
+ },
20
+ "size": {
21
+ "index": true,
22
+ "comment": "파일 크기 (bytes)",
23
+ "type": "bigint unsigned"
24
+ },
25
+ "status": {
26
+ "index": true,
27
+ "comment": "파일 상태",
28
+ "type": [
29
+ "active",
30
+ "pending",
31
+ "orphan",
32
+ "deleted"
33
+ ],
34
+ "default": "pending",
35
+ "required": true
36
+ },
37
+ "uuid": {
38
+ "index": true,
39
+ "comment": "파일 고유 식별자 (UUID v4). 저장 경로·다운로드 URL의 키로 사용",
40
+ "type": "varchar(36)",
41
+ "required": true,
42
+ "unique": true
43
+ },
44
+ "backup_retries": {
45
+ "comment": "백업 재시도 횟수"
46
+ },
47
+ "content_hash": {
48
+ "comment": "파일 SHA-256 해시 (중복 탐지·무결성 검증용)"
49
+ },
50
+ "entity_name": {
51
+ "comment": "파일이 첨부된 엔티티 이름"
52
+ },
53
+ "entity_seq": {
54
+ "comment": "파일이 첨부된 엔티티 레코드 seq. 업로드 직후 엔티티 미연결 시 NULL"
55
+ },
56
+ "field_name": {
57
+ "comment": "파일이 첨부된 필드 이름 (file/file[] 타입 필드)"
58
+ },
59
+ "mime_type": {
60
+ "comment": "파일 MIME 타입 (image/jpeg, application/pdf 등)"
61
+ },
62
+ "original_name": {
63
+ "comment": "업로드 시 원본 파일명 (보안 대상 — 암호화 저장)"
64
+ },
65
+ "storage_key": {
66
+ "comment": "스토리지 백엔드 내 상대 경로 (예: 2026/02/27/contact/uuid.jpg)"
67
+ },
68
+ "storage_path": {
69
+ "comment": "라이선스 접두어 포함 전체 경로 (예: 3/2026/02/27/contact/uuid.jpg)"
70
+ }
71
+ }
72
+ }
@@ -1,27 +1,18 @@
1
1
  {
2
2
  "name": "system_audit_log",
3
- "description": "시스템 감사 로그. 서버 레벨에서 자동 기록되며 API를 통한 직접 수정은 허용되지 않습니다. JWT 인증 시에만 account_seq 기록",
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
- "index": {
10
- "transaction_id": {
11
- "comment": "요청 트랜잭션 ID. entity_history 테이블과 JOIN 키",
12
- "type": "varchar(64)"
13
- },
14
- "entity_name": {
15
- "comment": "대상 엔티티 이름",
16
- "type": "varchar(100)",
17
- "required": true
18
- },
19
- "entity_seq": {
20
- "comment": "대상 엔티티 레코드 seq. 로그인/로그아웃 등 레코드 없는 경우 NULL",
21
- "type": "bigint",
22
- "nullable": true
8
+ "compress": true,
9
+ "fields": {
10
+ "account_seq": {
11
+ "index": true,
12
+ "comment": "작업을 수행한 계정 seq. JWT 인증 요청은 account.seq, 비인증/HMAC 요청은 NULL"
23
13
  },
24
14
  "action": {
15
+ "index": true,
25
16
  "comment": "수행된 작업 유형",
26
17
  "type": [
27
18
  "INSERT",
@@ -34,38 +25,52 @@
34
25
  ],
35
26
  "required": true
36
27
  },
37
- "account_seq": {
38
- "comment": "작업을 수행한 계정 seq. JWT 인증 요청은 account.seq, 비인증/HMAC 요청은 NULL",
39
- "type": "bigint",
40
- "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)"
41
45
  },
42
46
  "ip_address": {
47
+ "index": true,
48
+ "hash": true,
43
49
  "comment": "요청 IP 주소 (IPv4/IPv6)",
44
- "type": "varchar(45)",
45
- "nullable": true
46
- },
47
- "endpoint": {
48
- "comment": "요청 API 엔드포인트",
49
- "type": "varchar(200)",
50
- "nullable": true
50
+ "type": "varchar(45)"
51
51
  },
52
52
  "request_method": {
53
+ "index": true,
53
54
  "comment": "HTTP 메서드 (GET/POST/PUT/DELETE 등)",
54
55
  "type": "varchar(10)"
55
56
  },
56
57
  "request_payload": {
57
58
  "comment": "요청 본문 JSON. 민감 필드(password, token 등) 자동 마스킹 후 저장. ServerConfig.AuditLogPayload = true 일 때만 기록",
58
- "type": "text",
59
- "nullable": true
59
+ "type": "text"
60
60
  },
61
61
  "result_code": {
62
+ "index": true,
62
63
  "comment": "HTTP 응답 코드 (200, 400, 401, 403, 500 등)",
63
64
  "type": "int"
64
65
  },
65
- "error_message": {
66
- "comment": "실패 시 오류 메시지 요약",
67
- "type": "varchar(500)",
68
- "nullable": true
66
+ "transaction_id": {
67
+ "index": true,
68
+ "comment": "요청 트랜잭션 ID. entity_history 테이블과 JOIN 키",
69
+ "type": "varchar(64)"
69
70
  }
71
+ },
72
+ "fk": {
73
+ "account_seq": false,
74
+ "entity_seq": false
70
75
  }
71
76
  }
@@ -1,15 +1,18 @@
1
1
  {
2
2
  "name": "company",
3
- "description": "company Entity",
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,13 +1,15 @@
1
1
  {
2
- "name": "product",
3
- "description": "product Entity",
4
- "index": {
2
+ "name": "goods",
3
+ "description": "goods Entity. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
4
+ "fields": {
5
5
  "name": {
6
- "comment": "제품명",
6
+ "index": true,
7
+ "comment": "상품명",
7
8
  "required": true,
8
9
  "unique": true
9
10
  },
10
11
  "category": {
12
+ "index": true,
11
13
  "comment": "카테고리",
12
14
  "type": [
13
15
  "전자제품",
@@ -16,18 +18,19 @@
16
18
  ]
17
19
  },
18
20
  "price": {
21
+ "index": true,
19
22
  "comment": "가격"
20
23
  }
21
24
  },
22
25
  "reset_defaults": [
23
26
  {
24
- "name": "샘플 제품 A",
27
+ "name": "샘플 상품 A",
25
28
  "category": "전자제품",
26
29
  "price": 10000,
27
30
  "stock": 50
28
31
  },
29
32
  {
30
- "name": "샘플 제품 B",
33
+ "name": "샘플 상품 B",
31
34
  "category": "가구",
32
35
  "price": 50000,
33
36
  "stock": 20
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "todo",
3
- "description": "todo Entity",
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
  }