create-entity-server 0.0.27 → 0.2.2

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 (100) hide show
  1. package/package.json +1 -1
  2. package/template/configs/cache.json +2 -1
  3. package/template/configs/database.json +18 -7
  4. package/template/entities/README.md +3 -3
  5. package/template/entities/System/Address/addr_dong.json +10115 -0
  6. package/template/entities/System/Address/addr_sido.json +39 -0
  7. package/template/entities/System/Address/addr_sigungu.json +1398 -0
  8. package/template/entities/System/Auth/account.json +94 -18
  9. package/template/entities/System/Auth/account_audit.json +11 -3
  10. package/template/entities/System/Auth/account_device.json +13 -27
  11. package/template/entities/System/Auth/account_login_log.json +17 -7
  12. package/template/entities/System/Auth/anon_device.json +56 -0
  13. package/template/entities/System/Auth/api_keys.json +18 -9
  14. package/template/entities/System/Auth/license.json +41 -20
  15. package/template/entities/System/Auth/rbac_roles.json +10 -7
  16. package/template/entities/System/Backup/backup_log.json +11 -7
  17. package/template/entities/System/Email/smtp_log.json +9 -5
  18. package/template/entities/System/Email/smtp_msg.json +5 -5
  19. package/template/entities/System/Storage/file_backup_log.json +11 -6
  20. package/template/entities/System/Storage/file_download_log.json +7 -5
  21. package/template/entities/System/Storage/file_meta.json +20 -7
  22. package/template/entities/System/system_audit_log.json +38 -34
  23. package/template/entities/company.json +5 -2
  24. package/template/entities/goods.json +10 -3
  25. package/template/entities/todo.json +4 -2
  26. package/template/samples/entities/01_basic_fields.json +15 -2
  27. package/template/samples/entities/02_types_and_defaults.json +15 -5
  28. package/template/samples/entities/03_hash_and_unique.json +18 -3
  29. package/template/samples/entities/04_fk_and_composite_unique.json +18 -3
  30. package/template/samples/entities/05_cache.json +15 -9
  31. package/template/samples/entities/06_history_and_hard_delete.json +19 -6
  32. package/template/samples/entities/07_license_scope.json +18 -3
  33. package/template/samples/entities/08_hook_sql.json +24 -5
  34. package/template/samples/entities/09_hook_entity.json +12 -2
  35. package/template/samples/entities/10_hook_submit_delete.json +14 -5
  36. package/template/samples/entities/11_hook_webhook.json +20 -6
  37. package/template/samples/entities/12_hook_push.json +15 -2
  38. package/template/samples/entities/13_read_only.json +8 -4
  39. package/template/samples/entities/14_optimistic_lock.json +13 -2
  40. package/template/samples/entities/15_reset_defaults.json +7 -1
  41. package/template/samples/entities/16_isolated_license.json +19 -6
  42. package/template/scripts/reset-all.sh +130 -3
  43. package/template/scripts/run.sh +129 -33
  44. package/template/templates/ocr/business_reg.json +145 -0
  45. package/template/templates/ocr/career_cert.json +93 -0
  46. package/template/templates/ocr/driver_license.json +89 -0
  47. package/template/templates/ocr/facility_card.json +82 -0
  48. package/template/templates/ocr/id_card.json +55 -0
  49. package/template/templates/ocr/invoice.json +92 -0
  50. package/template/templates/ocr/namecard.json +116 -0
  51. package/template/templates/ocr/prompts/business_reg.json +14 -0
  52. package/template/templates/ocr/prompts/career_cert.json +16 -0
  53. package/template/templates/ocr/prompts/driver_license.json +14 -0
  54. package/template/templates/ocr/prompts/facility_card.json +15 -0
  55. package/template/templates/ocr/prompts/general.json +13 -0
  56. package/template/templates/ocr/prompts/id_card.json +11 -0
  57. package/template/templates/ocr/prompts/invoice.json +17 -0
  58. package/template/templates/ocr/prompts/namecard.json +15 -0
  59. package/template/templates/ocr/prompts/receipt.json +14 -0
  60. package/template/templates/ocr/receipt.json +79 -0
  61. package/template/configs/auth/identity.json +0 -27
  62. package/template/configs/auth/oauth.json +0 -40
  63. package/template/configs/auth/password.json +0 -33
  64. package/template/configs/auth/privacy_policy.json +0 -28
  65. package/template/configs/auth/two_factor.json +0 -12
  66. package/template/configs/extensions/pg.json +0 -37
  67. package/template/configs/extensions/tax-invoice.json +0 -59
  68. package/template/configs/keys/apns.p8.example +0 -7
  69. package/template/configs/keys/firebase.pem.example +0 -7
  70. package/template/configs/notification/alimtalk.json +0 -75
  71. package/template/configs/notification/push.json +0 -25
  72. package/template/configs/notification/sms.json +0 -54
  73. package/template/entities/System/Auth/account_oauth.json +0 -45
  74. package/template/entities/System/Auth/identity_verification.json +0 -95
  75. package/template/entities/System/Auth/password_history.json +0 -20
  76. package/template/entities/System/Notification/alimtalk_log.json +0 -45
  77. package/template/entities/System/Notification/alimtalk_msg.json +0 -39
  78. package/template/entities/System/Notification/friendtalk_log.json +0 -48
  79. package/template/entities/System/Notification/friendtalk_msg.json +0 -63
  80. package/template/entities/System/Notification/sms_log.json +0 -26
  81. package/template/entities/System/Notification/sms_msg.json +0 -52
  82. package/template/entities/System/Notification/sms_verification.json +0 -40
  83. package/template/entities/System/Payment/pg_cancel.json +0 -45
  84. package/template/entities/System/Payment/pg_order.json +0 -88
  85. package/template/entities/System/Payment/pg_webhook_log.json +0 -37
  86. package/template/entities/System/Push/push_log.json +0 -71
  87. package/template/entities/System/Push/push_msg.json +0 -55
  88. package/template/templates/email/account/dormancy_warning.html +0 -20
  89. package/template/templates/email/account/password_expiry_warning.html +0 -21
  90. package/template/templates/email/auth/2fa_disabled.html +0 -23
  91. package/template/templates/email/auth/2fa_recovery_regenerated.html +0 -31
  92. package/template/templates/email/auth/2fa_setup_complete.html +0 -43
  93. package/template/templates/email/auth/email_verification.html +0 -18
  94. package/template/templates/email/auth/force_reset.html +0 -18
  95. package/template/templates/email/auth/password_reset.html +0 -19
  96. package/template/templates/email/auth/verification.html +0 -15
  97. package/template/templates/email/auth/verification_link.html +0 -25
  98. package/template/templates/email/auth/welcome.html +0 -18
  99. package/template/templates/email/order/order_confirmation.html +0 -30
  100. /package/template/configs/{notification/smtp.json → smtp.json} +0 -0
@@ -1,52 +0,0 @@
1
- {
2
- "name": "sms_msg",
3
- "description": "SMS/LMS/MMS 발송 트리거 엔티티. insert 시 sms hook으로 비동기 발송. 사용자 환경에 맞게 index·fields를 자유롭게 확장할 수 있습니다.",
4
- "license_scope": false,
5
- "hard_delete": true,
6
- "history": false,
7
- "read_only": true,
8
- "index": {
9
- "status": {
10
- "type": ["queued", "sent", "failed"],
11
- "default": "queued"
12
- },
13
- "msg_type": {
14
- "type": ["sms", "lms", "mms"],
15
- "default": "sms"
16
- },
17
- "receiver": {
18
- "type": "string",
19
- "required": true,
20
- "comment": "수신 전화번호"
21
- }
22
- },
23
- "fields": {
24
- "sender": { "type": "string", "comment": "발신번호" },
25
- "subject": {
26
- "type": "string",
27
- "comment": "LMS/MMS 제목 (SMS는 미사용)"
28
- },
29
- "content": { "type": "string", "comment": "메시지 본문" },
30
- "image_url": { "type": "string", "comment": "MMS 이미지 URL" },
31
- "provider": { "type": "string", "comment": "발송 프로바이더 키" },
32
- "provider_msg_id": {
33
- "type": "string",
34
- "comment": "프로바이더 메시지 ID"
35
- },
36
- "ref_entity": { "type": "string" },
37
- "ref_seq": { "type": "int" },
38
- "error_message": { "type": "string" },
39
- "sent_at": { "type": "string" }
40
- },
41
- "hooks": {
42
- "after_insert": [
43
- {
44
- "type": "sms",
45
- "enabled": true,
46
- "sms_receiver": "${new.receiver}",
47
- "sms_content": "${new.content}",
48
- "sms_subject": "${new.subject}"
49
- }
50
- ]
51
- }
52
- }
@@ -1,40 +0,0 @@
1
- {
2
- "name": "sms_verification",
3
- "description": "SMS 인증번호 검증 엔티티. 인증번호 SHA-256 해시 저장, 시도 횟수 관리. 사용자 환경에 맞게 index·fields를 자유롭게 확장할 수 있습니다.",
4
- "license_scope": false,
5
- "hard_delete": true,
6
- "history": false,
7
- "index": {
8
- "phone": {
9
- "comment": "수신 전화번호",
10
- "type": "varchar(20)",
11
- "required": true
12
- },
13
- "purpose": {
14
- "comment": "인증 목적",
15
- "type": ["signup", "password_reset", "identity"],
16
- "required": true
17
- },
18
- "status": {
19
- "type": ["pending", "verified", "expired"],
20
- "default": "pending",
21
- "required": true
22
- }
23
- },
24
- "fields": {
25
- "code_hash": {
26
- "type": "varchar(64)",
27
- "required": true,
28
- "comment": "인증번호 SHA-256 해시"
29
- },
30
- "expires_at": {
31
- "required": true,
32
- "comment": "만료 시각"
33
- },
34
- "attempts": {
35
- "type": "uint",
36
- "default": 0,
37
- "comment": "검증 시도 횟수"
38
- }
39
- }
40
- }
@@ -1,45 +0,0 @@
1
- {
2
- "name": "pg_cancel",
3
- "description": "PG 결제 취소 이력 엔티티. 부분/전액 취소를 기록합니다. 사용자 환경에 맞게 index·fields를 자유롭게 확장할 수 있습니다.",
4
- "read_only": true,
5
- "index": {
6
- "order_seq": {
7
- "type": "integer",
8
- "required": true,
9
- "comment": "pg_order.seq 참조"
10
- },
11
- "order_id": {
12
- "type": "string",
13
- "required": true,
14
- "comment": "주문번호 (조회 편의)"
15
- },
16
- "cancel_amount": {
17
- "type": "integer",
18
- "required": true,
19
- "comment": "취소 금액"
20
- },
21
- "cancel_reason": {
22
- "type": "string",
23
- "required": true,
24
- "comment": "취소 사유 (최대 200자)"
25
- },
26
- "cancel_status": {
27
- "type": ["done", "failed"],
28
- "default": "done",
29
- "comment": "취소 처리 상태"
30
- },
31
- "transaction_key": {
32
- "type": "string",
33
- "comment": "PG사 취소 거래 키"
34
- }
35
- },
36
- "fields": {
37
- "canceled_time": { "comment": "취소 시각 (ISO 8601)" },
38
- "refundable_amount": { "comment": "취소 후 환불 가능 잔액" },
39
- "tax_free_amount": { "comment": "취소된 금액 중 면세 금액" },
40
- "receipt_key": { "comment": "현금영수증 키 (해당 시)" },
41
- "refund_account": {
42
- "comment": "환불 계좌 정보 JSON (가상계좌 취소 시)"
43
- }
44
- }
45
- }
@@ -1,88 +0,0 @@
1
- {
2
- "name": "pg_order",
3
- "description": "PG 결제 주문 엔티티. 결제 요청/승인/취소 상태를 추적합니다. 사용자 환경에 맞게 index·fields를 자유롭게 확장할 수 있습니다.",
4
- "index": {
5
- "order_id": {
6
- "type": "string",
7
- "required": true,
8
- "unique": true,
9
- "comment": "고유 주문번호 (6~64자, [a-zA-Z0-9_-])"
10
- },
11
- "status": {
12
- "type": [
13
- "created",
14
- "ready",
15
- "in_progress",
16
- "waiting",
17
- "done",
18
- "canceled",
19
- "partial_canceled",
20
- "aborted",
21
- "expired"
22
- ],
23
- "default": "created",
24
- "comment": "결제 상태"
25
- },
26
- "payment_key": {
27
- "type": "string",
28
- "comment": "PG사 결제 키 (승인 후 할당)"
29
- },
30
- "provider": {
31
- "type": "string",
32
- "required": true,
33
- "comment": "PG 프로바이더 키 (toss_payments, kcp, inicis 등)"
34
- },
35
- "method": {
36
- "type": "string",
37
- "comment": "결제수단 (card, virtual_account, transfer, phone, easy_pay)"
38
- },
39
- "amount": {
40
- "type": "integer",
41
- "required": true,
42
- "comment": "총 결제 금액 (원)"
43
- },
44
- "balance_amount": {
45
- "type": "integer",
46
- "comment": "취소 가능 잔액"
47
- },
48
- "currency": {
49
- "type": "string",
50
- "default": "KRW",
51
- "comment": "통화 코드 (ISO 4217)"
52
- },
53
- "account_seq": {
54
- "type": "integer",
55
- "comment": "구매자 계정 seq (로그인 사용자)"
56
- },
57
- "customer_name": {
58
- "type": "string",
59
- "comment": "구매자명"
60
- },
61
- "customer_email": {
62
- "type": "string",
63
- "comment": "구매자 이메일"
64
- }
65
- },
66
- "fields": {
67
- "order_name": { "comment": "주문 상품명 (예: '토스 티셔츠 외 2건')" },
68
- "requested_time": { "comment": "결제 요청 시각 (ISO 8601)" },
69
- "approved_time": { "comment": "결제 승인 시각 (ISO 8601)" },
70
- "card_info": {
71
- "comment": "카드 결제 정보 JSON (마스킹된 카드번호, 카드타입 등)"
72
- },
73
- "virtual_account_info": {
74
- "comment": "가상계좌 정보 JSON (계좌번호, 은행, 입금기한)"
75
- },
76
- "easy_pay_info": {
77
- "comment": "간편결제 정보 JSON (provider, amount, discountAmount)"
78
- },
79
- "receipt_url": { "comment": "영수증 URL" },
80
- "checkout_url": { "comment": "결제창 URL" },
81
- "failure_code": { "comment": "실패 에러 코드" },
82
- "failure_message": { "comment": "실패 에러 메시지" },
83
- "metadata": {
84
- "comment": "상점 커스텀 데이터 JSON (최대 5개 key-value)"
85
- },
86
- "pg_raw_response": { "comment": "PG사 원본 응답 JSON (디버깅용)" }
87
- }
88
- }
@@ -1,37 +0,0 @@
1
- {
2
- "name": "pg_webhook_log",
3
- "description": "PG 웹훅 수신 이력. 모든 수신 이벤트를 기록합니다. 사용자 환경에 맞게 index·fields를 자유롭게 확장할 수 있습니다.",
4
- "hard_delete": true,
5
- "read_only": true,
6
- "compress": true,
7
- "index": {
8
- "event_type": {
9
- "type": "string",
10
- "required": true,
11
- "comment": "웹훅 이벤트 타입 (payment.done, payment.canceled 등)"
12
- },
13
- "order_id": {
14
- "type": "string",
15
- "comment": "관련 주문번호"
16
- },
17
- "payment_key": {
18
- "type": "string",
19
- "comment": "관련 결제 키"
20
- },
21
- "status": {
22
- "type": ["received", "processed", "failed"],
23
- "default": "received",
24
- "comment": "웹훅 처리 상태"
25
- },
26
- "provider": {
27
- "type": "string",
28
- "comment": "PG 프로바이더 키"
29
- }
30
- },
31
- "fields": {
32
- "payload": { "comment": "수신한 웹훅 원본 JSON" },
33
- "processed_time": { "comment": "처리 완료 시각" },
34
- "error_message": { "comment": "처리 실패 시 에러 메시지" },
35
- "signature": { "comment": "웹훅 서명값 (검증용)" }
36
- }
37
- }
@@ -1,71 +0,0 @@
1
- {
2
- "name": "push_log",
3
- "description": "푸시 알림 발송 이력. 발송 결과 추적 및 재시도 관리용. account_seq(JWT) 또는 device_id(HMAC) 중 하나 존재. 사용자 환경에 맞게 index·fields를 자유롭게 확장할 수 있습니다.",
4
- "license_scope": false,
5
- "hard_delete": true,
6
- "history_ttl": 30,
7
- "compress": true,
8
- "index": {
9
- "account_seq": {
10
- "comment": "수신자 account seq (JWT 인증 시. nullable)"
11
- },
12
- "attempt_time": {
13
- "comment": "처리 시작(claim) 시각 — 비정상 종료 감지용"
14
- },
15
- "body": {
16
- "comment": "알림 본문"
17
- },
18
- "device_id": {
19
- "comment": "대상 디바이스 ID (HMAC 인증 시. nullable)",
20
- "type": "varchar(255)"
21
- },
22
- "device_seq": {
23
- "comment": "대상 디바이스 seq (account_device.seq)"
24
- },
25
- "device_token": {
26
- "comment": "발송 시점 디바이스 토큰 스냅샷 (FCM registration token 또는 APNs device token)"
27
- },
28
- "error_message": {
29
- "comment": "실패 시 오류 메시지",
30
- "type": "varchar(500)"
31
- },
32
- "platform": {
33
- "comment": "발송 채널",
34
- "type": ["fcm", "apns", "web"]
35
- },
36
- "push_data": {
37
- "comment": "커스텀 페이로드 JSON 문자열",
38
- "type": "varchar(2000)"
39
- },
40
- "ref_entity": {
41
- "comment": "트리거 엔티티명"
42
- },
43
- "ref_seq": {
44
- "comment": "트리거 레코드 seq"
45
- },
46
- "retry_count": {
47
- "comment": "재시도 횟수",
48
- "type": "uint",
49
- "default": 0
50
- },
51
- "sent_time": {
52
- "comment": "발송 완료 시각"
53
- },
54
- "status": {
55
- "comment": "발송 상태",
56
- "type": [
57
- "pending",
58
- "processing",
59
- "sent",
60
- "delivered",
61
- "failed",
62
- "expired"
63
- ],
64
- "default": "pending",
65
- "required": true
66
- },
67
- "title": {
68
- "comment": "알림 제목"
69
- }
70
- }
71
- }
@@ -1,55 +0,0 @@
1
- {
2
- "name": "push_msg",
3
- "description": "시스템 푸시 트리거 엔티티. insert 시 push hook로 비동기 발송. account_seq(JWT) 또는 device_id(HMAC) 중 하나 필수. 사용자 환경에 맞게 index·fields를 자유롭게 확장할 수 있습니다.",
4
- "index": {
5
- "account_seq": {
6
- "comment": "수신자 account seq (JWT 인증 시 필수. HMAC 인증은 device_id 사용)",
7
- "required": true
8
- },
9
- "device_id": {
10
- "comment": "대상 디바이스 ID (HMAC 인증 시. 기기단위로 account 없이 푸시 발송)",
11
- "type": "varchar(255)"
12
- },
13
- "title": {
14
- "comment": "푸시 제목",
15
- "required": true
16
- }
17
- },
18
- "fields": {
19
- "message": {
20
- "comment": "푸시 본문",
21
- "nullable": true
22
- },
23
- "ref_entity": {
24
- "comment": "참조 엔티티명",
25
- "nullable": true
26
- },
27
- "ref_seq": {
28
- "comment": "참조 레코드 seq",
29
- "nullable": true
30
- },
31
- "msg_data": {
32
- "comment": "추가 데이터(JSON 문자열)",
33
- "type": "varchar(2000)",
34
- "nullable": true
35
- }
36
- },
37
- "hooks": {
38
- "after_insert": [
39
- {
40
- "type": "push",
41
- "target_account_seq": "account_seq",
42
- "target_device_id": "device_id",
43
- "comment": "account_seq 있으면 계정 기반 발송, 없으면 device_id 기반 발송",
44
- "title": "${new.title}",
45
- "push_body": "${new.message}",
46
- "push_data": {
47
- "push_msg_seq": "${new.seq}",
48
- "ref_entity": "${new.ref_entity}",
49
- "ref_seq": "${new.ref_seq}",
50
- "msg_data": "${new.msg_data}"
51
- }
52
- }
53
- ]
54
- }
55
- }
@@ -1,20 +0,0 @@
1
- <h2 style="margin: 0 0 8px; font-size: 22px; font-weight: 700; color: #1a1a2e;">계정 휴면 예정 안내</h2>
2
- <p style="margin: 0 0 24px; font-size: 13px; color: #999;">D-${days_left|30}</p>
3
- <p style="margin: 0 0 20px; font-size: 15px; color: #555; line-height: 1.6;">
4
- 안녕하세요.<br>
5
- <strong>${email}</strong> 계정이 <strong>${days_left|30}일 후</strong> 장기 미접속으로 인해 휴면 상태로 전환될 예정입니다.
6
- </p>
7
- <div style="background-color: #fff8e1; border-left: 4px solid #f59e0b; border-radius: 4px; padding: 16px 20px; margin: 0 0 24px;">
8
- <p style="margin: 0; font-size: 14px; color: #92400e; line-height: 1.6;">
9
- 휴면 계정은 로그인이 제한되며, 서비스 이용을 위해 별도의 본인 인증이 필요합니다.
10
- </p>
11
- </div>
12
- <p style="margin: 0 0 24px; font-size: 15px; color: #555; line-height: 1.6;">
13
- 지금 로그인하면 휴면 전환을 방지할 수 있습니다.
14
- </p>
15
- <div style="text-align: center; margin: 0 0 28px;">
16
- <a href="${login_url|#}" style="display: inline-block; padding: 14px 40px; background-color: #1a1a2e; color: #ffffff; text-decoration: none; border-radius: 6px; font-size: 15px; font-weight: 600;">지금 로그인하기</a>
17
- </div>
18
- <p style="margin: 0; font-size: 13px; color: #aaa; line-height: 1.6;">
19
- 이미 최근에 로그인하셨다면 이 안내는 무시하셔도 됩니다.
20
- </p>
@@ -1,21 +0,0 @@
1
- <h2 style="margin: 0 0 8px; font-size: 22px; font-weight: 700; color: #1a1a2e;">비밀번호 변경 안내</h2>
2
- <p style="margin: 0 0 24px; font-size: 13px; color: #999;">D-${days_left|14}</p>
3
- <p style="margin: 0 0 20px; font-size: 15px; color: #555; line-height: 1.6;">
4
- 안녕하세요.<br>
5
- <strong>${email}</strong> 계정의 비밀번호가 <strong>${days_left|14}일 후</strong> 만료됩니다.
6
- </p>
7
- <div style="background-color: #fef2f2; border-left: 4px solid #ef4444; border-radius: 4px; padding: 16px 20px; margin: 0 0 24px;">
8
- <p style="margin: 0; font-size: 14px; color: #991b1b; line-height: 1.6;">
9
- 만료된 비밀번호로는 로그인 후 즉시 비밀번호 변경이 요구될 수 있습니다.<br>
10
- 정기적인 비밀번호 변경으로 계정을 안전하게 보호하세요.
11
- </p>
12
- </div>
13
- <p style="margin: 0 0 24px; font-size: 15px; color: #555; line-height: 1.6;">
14
- 아래 버튼을 클릭하여 지금 비밀번호를 변경하세요.
15
- </p>
16
- <div style="text-align: center; margin: 0 0 28px;">
17
- <a href="${change_password_url|#}" style="display: inline-block; padding: 14px 40px; background-color: #1a1a2e; color: #ffffff; text-decoration: none; border-radius: 6px; font-size: 15px; font-weight: 600;">비밀번호 변경하기</a>
18
- </div>
19
- <p style="margin: 0; font-size: 13px; color: #aaa; line-height: 1.6;">
20
- 이미 비밀번호를 변경하셨다면 이 안내는 무시하셔도 됩니다.
21
- </p>
@@ -1,23 +0,0 @@
1
- <h2 style="margin: 0 0 16px; font-size: 22px; font-weight: 700; color: #1a1a2e;">2단계 인증이 비활성화되었습니다</h2>
2
- <p style="margin: 0 0 16px; font-size: 15px; color: #555; line-height: 1.6;">
3
- <strong>${email}</strong> 계정의 2단계 인증(TOTP)이 해제되었습니다.<br>
4
- 앞으로 이메일과 비밀번호만으로 로그인됩니다.
5
- </p>
6
-
7
- <div style="margin: 0 0 24px; padding: 20px; background-color: #f8d7da; border-radius: 8px; border-left: 4px solid #dc3545;">
8
- <p style="margin: 0; font-size: 14px; color: #721c24; line-height: 1.6;">
9
- <strong>보안 알림:</strong> 2단계 인증이 해제되면 계정 보안 수준이 낮아집니다.<br>
10
- 가능하면 다시 2단계 인증을 설정하는 것을 권장합니다.
11
- </p>
12
- </div>
13
-
14
- <p style="margin: 0 0 8px; font-size: 14px; color: #888; line-height: 1.6;">
15
- 해제 시각: ${disabled_time}
16
- </p>
17
- <p style="margin: 0 0 8px; font-size: 14px; color: #888; line-height: 1.6;">
18
- 해제 방법: ${disabled_by|본인 요청}
19
- </p>
20
-
21
- <p style="margin: 0; font-size: 13px; color: #aaa; line-height: 1.6;">
22
- 본인이 해제하지 않은 경우, 즉시 비밀번호를 변경하고 관리자에게 문의하세요.
23
- </p>
@@ -1,31 +0,0 @@
1
- <h2 style="margin: 0 0 16px; font-size: 22px; font-weight: 700; color: #1a1a2e;">복구 코드가 재생성되었습니다</h2>
2
- <p style="margin: 0 0 16px; font-size: 15px; color: #555; line-height: 1.6;">
3
- <strong>${email}</strong> 계정의 2단계 인증 복구 코드가 새로 생성되었습니다.<br>
4
- 이전 복구 코드는 모두 <strong>폐기</strong>되었습니다.
5
- </p>
6
-
7
- <div style="margin: 0 0 24px; padding: 20px; background-color: #fff3cd; border-radius: 8px; border-left: 4px solid #ffc107;">
8
- <p style="margin: 0 0 8px; font-size: 14px; font-weight: 700; color: #856404;">⚠ 새 복구 코드를 안전한 곳에 저장하세요</p>
9
- <p style="margin: 0; font-size: 13px; color: #856404; line-height: 1.5;">
10
- 각 코드는 <strong>한 번만</strong> 사용할 수 있으며, 이 이메일 이후에는 다시 확인할 수 없습니다.
11
- </p>
12
- </div>
13
-
14
- <div style="text-align: center; margin: 0 0 24px;">
15
- <table role="presentation" cellpadding="0" cellspacing="0" style="margin: 0 auto;">
16
- <tr>
17
- <td style="padding: 16px 32px; background-color: #f0f0f5; border-radius: 8px;">
18
- <pre style="margin: 0; font-size: 18px; font-weight: 700; color: #1a1a2e; font-family: 'Courier New', monospace; letter-spacing: 2px; line-height: 2;">${recovery_codes}</pre>
19
- </td>
20
- </tr>
21
- </table>
22
- </div>
23
-
24
- <p style="margin: 0 0 16px; font-size: 14px; color: #888; line-height: 1.6;">
25
- 새 복구 코드: <strong>${recovery_count|10}개</strong><br>
26
- 재생성 시각: ${regenerated_time}
27
- </p>
28
-
29
- <p style="margin: 0; font-size: 13px; color: #aaa; line-height: 1.6;">
30
- 본인이 요청하지 않은 경우, 계정이 보안 위협에 노출되었을 수 있습니다. 즉시 비밀번호를 변경하고 관리자에게 문의하세요.
31
- </p>
@@ -1,43 +0,0 @@
1
- <h2 style="margin: 0 0 16px; font-size: 22px; font-weight: 700; color: #1a1a2e;">2단계 인증이 활성화되었습니다</h2>
2
- <p style="margin: 0 0 16px; font-size: 15px; color: #555; line-height: 1.6;">
3
- <strong>${email}</strong> 계정에 2단계 인증(TOTP)이 설정되었습니다.<br>
4
- 앞으로 로그인 시 Authenticator 앱의 인증 코드가 필요합니다.
5
- </p>
6
-
7
- <div style="margin: 0 0 24px; padding: 20px; background-color: #fff3cd; border-radius: 8px; border-left: 4px solid #ffc107;">
8
- <p style="margin: 0 0 8px; font-size: 14px; font-weight: 700; color: #856404;">⚠ 복구 코드를 안전한 곳에 저장하세요</p>
9
- <p style="margin: 0 0 12px; font-size: 13px; color: #856404; line-height: 1.5;">
10
- Authenticator 앱에 접근할 수 없는 경우 아래 복구 코드로 로그인할 수 있습니다.<br>
11
- 각 코드는 <strong>한 번만</strong> 사용할 수 있으며, 이 이메일 이후에는 다시 확인할 수 없습니다.
12
- </p>
13
- </div>
14
-
15
- <div style="text-align: center; margin: 0 0 24px;">
16
- <table role="presentation" cellpadding="0" cellspacing="0" style="margin: 0 auto;">
17
- <tr>
18
- <td style="padding: 16px 32px; background-color: #f0f0f5; border-radius: 8px;">
19
- <pre style="margin: 0; font-size: 18px; font-weight: 700; color: #1a1a2e; font-family: 'Courier New', monospace; letter-spacing: 2px; line-height: 2;">${recovery_codes}</pre>
20
- </td>
21
- </tr>
22
- </table>
23
- </div>
24
-
25
- <p style="margin: 0 0 8px; font-size: 14px; color: #888; line-height: 1.6;">
26
- 남은 복구 코드: <strong>${recovery_count|10}개</strong>
27
- </p>
28
- <p style="margin: 0 0 16px; font-size: 14px; color: #888; line-height: 1.6;">
29
- 설정 시각: ${enabled_time}
30
- </p>
31
-
32
- <div style="margin: 0 0 16px; padding: 16px; background-color: #f8f9fa; border-radius: 6px;">
33
- <p style="margin: 0; font-size: 13px; color: #666; line-height: 1.6;">
34
- 💡 <strong>권장 사항</strong><br>
35
- • 복구 코드를 출력하거나 비밀번호 관리자에 저장하세요<br>
36
- • 복구 코드가 3개 이하로 줄면 재생성하세요<br>
37
- • 본인이 설정하지 않았다면 즉시 비밀번호를 변경하세요
38
- </p>
39
- </div>
40
-
41
- <p style="margin: 0; font-size: 13px; color: #aaa; line-height: 1.6;">
42
- 본인이 설정하지 않은 경우, 계정이 보안 위협에 노출되었을 수 있습니다. 즉시 비밀번호를 변경하고 관리자에게 문의하세요.
43
- </p>
@@ -1,18 +0,0 @@
1
- <h2 style="margin: 0 0 16px; font-size: 22px; font-weight: 700; color: #1a1a2e;">이메일 인증</h2>
2
- <p style="margin: 0 0 24px; font-size: 15px; color: #555; line-height: 1.6;">
3
- 아래 인증 코드를 입력하여 이메일 주소를 인증하세요.
4
- </p>
5
- <div style="text-align: center; margin: 0 0 28px;">
6
- <div style="display: inline-block; padding: 18px 40px; background-color: #f4f4f7; border-radius: 8px; border: 1px solid #e0e0e0;">
7
- <span style="font-size: 32px; font-weight: 700; letter-spacing: 10px; color: #1a1a2e; font-family: 'Courier New', Courier, monospace;">${code|------}</span>
8
- </div>
9
- </div>
10
- <p style="margin: 0 0 8px; font-size: 14px; color: #888; line-height: 1.6;">
11
- 이 코드는 <strong>${expires_in|5분}</strong> 동안 유효합니다.
12
- </p>
13
- <p style="margin: 0 0 8px; font-size: 13px; color: #aaa; line-height: 1.6;">
14
- 인증 대상 이메일: <strong>${email|}</strong>
15
- </p>
16
- <p style="margin: 0; font-size: 13px; color: #aaa; line-height: 1.6;">
17
- 본인이 요청하지 않은 경우 이 이메일을 무시하세요.
18
- </p>
@@ -1,18 +0,0 @@
1
- <h2 style="margin: 0 0 16px; font-size: 22px; font-weight: 700; color: #1a1a2e;">임시 비밀번호 안내</h2>
2
- <p style="margin: 0 0 24px; font-size: 15px; color: #555; line-height: 1.6;">
3
- 관리자에 의해 비밀번호가 초기화되었습니다. 아래 임시 비밀번호로 로그인 후 즉시 비밀번호를 변경하세요.
4
- </p>
5
- <div style="text-align: center; margin: 0 0 28px;">
6
- <div style="display: inline-block; padding: 14px 32px; background-color: #f4f4f7; border-radius: 8px; border: 1px solid #e0e0e0;">
7
- <span style="font-size: 22px; font-weight: 700; letter-spacing: 4px; color: #1a1a2e; font-family: 'Courier New', Courier, monospace;">${temp_password|}</span>
8
- </div>
9
- </div>
10
- <p style="margin: 0 0 16px; font-size: 14px; color: #d9534f; font-weight: 600; line-height: 1.6;">
11
- ⚠ 보안을 위해 로그인 즉시 비밀번호를 변경하시기 바랍니다.
12
- </p>
13
- <p style="margin: 0 0 8px; font-size: 14px; color: #888; line-height: 1.6;">
14
- 이메일: <strong>${email|}</strong>
15
- </p>
16
- <p style="margin: 0; font-size: 13px; color: #aaa; line-height: 1.6;">
17
- 본인이 요청하지 않은 경우 즉시 관리자에게 문의하세요.
18
- </p>
@@ -1,19 +0,0 @@
1
- <h2 style="margin: 0 0 16px; font-size: 22px; font-weight: 700; color: #1a1a2e;">비밀번호 재설정</h2>
2
- <p style="margin: 0 0 24px; font-size: 15px; color: #555; line-height: 1.6;">
3
- 비밀번호 재설정이 요청되었습니다. 아래 버튼을 클릭하여 새 비밀번호를 설정하세요.
4
- </p>
5
- <div style="text-align: center; margin: 0 0 24px;">
6
- <a href="${reset_url|#}" style="display: inline-block; padding: 14px 36px; background-color: #1a1a2e; color: #ffffff; text-decoration: none; border-radius: 6px; font-size: 15px; font-weight: 600;">비밀번호 재설정</a>
7
- </div>
8
- <p style="margin: 0 0 8px; font-size: 14px; color: #888; line-height: 1.6;">
9
- 버튼이 작동하지 않으면 아래 링크를 브라우저에 붙여넣으세요:
10
- </p>
11
- <p style="margin: 0 0 16px; font-size: 13px; color: #4a90d9; word-break: break-all; line-height: 1.6;">
12
- ${reset_url|https://example.com/reset?token=sample}
13
- </p>
14
- <p style="margin: 0 0 8px; font-size: 14px; color: #888; line-height: 1.6;">
15
- 이 링크는 <strong>${expires_in|1시간}</strong> 동안 유효합니다.
16
- </p>
17
- <p style="margin: 0; font-size: 13px; color: #aaa; line-height: 1.6;">
18
- 본인이 요청하지 않은 경우 이 이메일을 무시하세요. 비밀번호는 변경되지 않습니다.
19
- </p>
@@ -1,15 +0,0 @@
1
- <h2 style="margin: 0 0 16px; font-size: 22px; font-weight: 700; color: #1a1a2e;">인증 코드</h2>
2
- <p style="margin: 0 0 24px; font-size: 15px; color: #555; line-height: 1.6;">
3
- 아래 코드를 입력하여 본인 인증을 완료하세요.
4
- </p>
5
- <div style="text-align: center; margin: 0 0 24px;">
6
- <div style="display: inline-block; padding: 16px 40px; background-color: #f0f0f5; border-radius: 8px; letter-spacing: 8px; font-size: 36px; font-weight: 700; color: #1a1a2e; font-family: 'Courier New', monospace;">
7
- ${code|000000}
8
- </div>
9
- </div>
10
- <p style="margin: 0 0 8px; font-size: 14px; color: #888; line-height: 1.6;">
11
- 이 코드는 <strong>${expires_in|10분}</strong> 동안 유효합니다.
12
- </p>
13
- <p style="margin: 0; font-size: 13px; color: #aaa; line-height: 1.6;">
14
- 본인이 요청하지 않은 경우 이 이메일을 무시하세요.
15
- </p>
@@ -1,25 +0,0 @@
1
- ```php
2
- <h2 style="margin: 0 0 16px; font-size: 22px; font-weight: 700; color: #1a1a2e;">이메일 인증</h2>
3
- <p style="margin: 0 0 24px; font-size: 15px; color: #555; line-height: 1.6;">
4
- 아래 버튼을 클릭하여 이메일 인증을 완료하세요.
5
- </p>
6
- <div style="text-align: center; margin: 0 0 24px;">
7
- <a href="${activation_url}" target="_blank" rel="noopener noreferrer"
8
- style="display: inline-block; padding: 14px 40px; background-color: #1a1a2e; color: #ffffff; text-decoration: none; border-radius: 8px; font-size: 16px; font-weight: 600; letter-spacing: 0.5px;">
9
- 이메일 인증하기
10
- </a>
11
- </div>
12
- <p style="margin: 0 0 8px; font-size: 14px; color: #888; line-height: 1.6;">
13
- 이 링크는 <strong>${expires_in|10분}</strong> 동안 유효합니다.
14
- </p>
15
- <p style="margin: 0 0 16px; font-size: 13px; color: #aaa; line-height: 1.6;">
16
- 버튼이 작동하지 않는 경우 아래 링크를 브라우저에 직접 붙여넣으세요:
17
- </p>
18
- <p style="margin: 0; font-size: 12px; color: #999; word-break: break-all; line-height: 1.6;">
19
- ${activation_url}
20
- </p>
21
- <p style="margin: 16px 0 0; font-size: 13px; color: #aaa; line-height: 1.6;">
22
- 본인이 요청하지 않은 경우 이 이메일을 무시하세요.
23
- </p>
24
-
25
- ```