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
@@ -0,0 +1,14 @@
1
+ {
2
+ "doc_type": "business_reg",
3
+ "system_msg": "당신은 OCR 텍스트에서 사업자등록증 정보를 추출하는 AI입니다. 사업자등록번호는 XXX-XX-XXXXX 형식으로 반환하세요. 찾을 수 없는 필드는 빈 문자열로 반환하세요.",
4
+ "user_msg": "아래 OCR 텍스트에서 사업자등록증 정보를 추출하여 다음 JSON 스키마에 맞게 응답하세요.\n\n[OCR 텍스트]\n{{ocr_text}}\n\n[출력 스키마]\n{{schema}}\n\nJSON만 출력하세요.",
5
+ "schema": {
6
+ "corp_num": "string: 사업자등록번호 (XXX-XX-XXXXX)",
7
+ "corp_name": "string: 상호(법인명)",
8
+ "ceo_name": "string: 대표자 성명",
9
+ "address": "string: 사업장 소재지",
10
+ "open_date": "string: 개업연월일 (YYYY-MM-DD)",
11
+ "biz_type": "string: 업태",
12
+ "biz_class": "string: 종목"
13
+ }
14
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "doc_type": "career_cert",
3
+ "system_msg": "당신은 OCR 텍스트에서 경력증명서(재직증명서) 정보를 추출하는 AI입니다. 개인정보 보호를 위해 주민등록번호는 생년월일 6자리와 뒷자리 첫 숫자만 표시하고 나머지는 '*'로 마스킹하세요. 날짜는 YYYY-MM-DD 형식으로 반환하세요. 찾을 수 없는 필드는 빈 문자열로 반환하세요.",
4
+ "user_msg": "아래 OCR 텍스트에서 경력증명서 정보를 추출하여 다음 JSON 스키마에 맞게 응답하세요.\n\n[OCR 텍스트]\n{{ocr_text}}\n\n[출력 스키마]\n{{schema}}\n\nJSON만 출력하세요.",
5
+ "schema": {
6
+ "name": "string: 성명",
7
+ "id_number": "string: 주민등록번호 (마스킹, 예: 900101-1******)",
8
+ "company": "string: 회사(기관)명",
9
+ "department": "string: 부서명",
10
+ "position": "string: 직위 또는 직급",
11
+ "join_date": "string: 입사일 (YYYY-MM-DD)",
12
+ "leave_date": "string: 퇴사일 (YYYY-MM-DD, 재직 중이면 빈 문자열)",
13
+ "issue_date": "string: 증명서 발급일 (YYYY-MM-DD)",
14
+ "issuer": "string: 발급자 (대표이사 성명 또는 기관명)"
15
+ }
16
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "doc_type": "driver_license",
3
+ "system_msg": "당신은 OCR 텍스트에서 운전면허증 데이터를 추출하는 전문 AI입니다. 주민등록번호는 반드시 앞 6자리만 추출하고 뒤 7자리는 *로 마스킹하세요 (예: 901225-*******). 주어진 JSON 스키마에 정확히 맞는 JSON만 출력하세요.",
4
+ "user_msg": "아래 운전면허증 OCR 텍스트에서 필드를 추출하여 다음 JSON 스키마에 맞게 응답하세요.\n\n[OCR 텍스트]\n{{ocr_text}}\n\n[출력 스키마]\n{{schema}}\n\nJSON만 출력하세요.",
5
+ "schema": {
6
+ "name": "string: 성명",
7
+ "id_number": "string: 주민등록번호 (앞 6자리만, 뒤 7자리는 * 마스킹: YYMMDD-*******)",
8
+ "license_num": "string: 면허번호 (XX-XX-XXXXXX-XX 형식)",
9
+ "license_type": "string: 면허종별 (예: 1종보통, 2종보통, 1종대형 등)",
10
+ "issue_date": "string: 발급일자 (YYYY-MM-DD 형식)",
11
+ "expiry_date": "string: 적성검사 만료일 (YYYY-MM-DD 형식)",
12
+ "issuer": "string: 발급 경찰청 이름"
13
+ }
14
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "doc_type": "facility_card",
3
+ "system_msg": "당신은 OCR 텍스트에서 건축물대장(시설물대장) 정보를 추출하는 AI입니다. 면적은 숫자와 단위(㎡)를 포함하여 반환하세요. 찾을 수 없는 필드는 빈 문자열로 반환하세요.",
4
+ "user_msg": "아래 OCR 텍스트에서 건축물대장 정보를 추출하여 다음 JSON 스키마에 맞게 응답하세요.\n\n[OCR 텍스트]\n{{ocr_text}}\n\n[출력 스키마]\n{{schema}}\n\nJSON만 출력하세요.",
5
+ "schema": {
6
+ "building_name": "string: 건물명 또는 건축물명",
7
+ "address": "string: 소재지(대지위치)",
8
+ "building_use": "string: 주용도 (예: 제2종 근린생활시설)",
9
+ "structure": "string: 구조 (예: 철근콘크리트조)",
10
+ "area": "string: 연면적 (예: 1234.56㎡)",
11
+ "floor_count": "string: 층수 (예: 지상 5층 / 지하 1층)",
12
+ "approval_date": "string: 사용승인일 (YYYY-MM-DD)",
13
+ "owner": "string: 소유자(건축주)"
14
+ }
15
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "doc_type": "general",
3
+ "system_msg": "당신은 OCR 텍스트를 분석하여 주요 정보를 추출하는 AI입니다. 주어진 JSON 스키마에 맞게 최대한 정보를 추출하세요. 찾을 수 없는 필드는 빈 문자열로 반환하세요.",
4
+ "user_msg": "아래 OCR 텍스트에서 주요 정보를 추출하여 다음 JSON 스키마에 맞게 응답하세요.\n\n[OCR 텍스트]\n{{ocr_text}}\n\n[출력 스키마]\n{{schema}}\n\nJSON만 출력하세요.",
5
+ "schema": {
6
+ "title": "string: 문서 제목 또는 문서 유형",
7
+ "date": "string: 날짜 (YYYY-MM-DD 형식)",
8
+ "name": "string: 인물 이름 또는 상호명",
9
+ "address": "string: 주소",
10
+ "amount": "string: 금액 (숫자만)",
11
+ "summary": "string: 문서 내용 한 줄 요약"
12
+ }
13
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "doc_type": "id_card",
3
+ "system_msg": "당신은 OCR 텍스트에서 신분증(주민등록증) 정보를 추출하는 AI입니다. 개인정보 보호를 위해 주민등록번호는 반드시 생년월일 6자리와 뒷자리 첫 숫자만 표시하고 나머지는 '*'로 마스킹하세요(예: 900101-1******). 찾을 수 없는 필드는 빈 문자열로 반환하세요.",
4
+ "user_msg": "아래 OCR 텍스트에서 신분증 정보를 추출하여 다음 JSON 스키마에 맞게 응답하세요.\n\n[OCR 텍스트]\n{{ocr_text}}\n\n[출력 스키마]\n{{schema}}\n\nJSON만 출력하세요.",
5
+ "schema": {
6
+ "name": "string: 성명",
7
+ "id_number": "string: 주민등록번호 (YYMMDD-1****** 형식으로 마스킹)",
8
+ "issue_date": "string: 발급일 (YYYY-MM-DD)",
9
+ "issuer": "string: 발급기관 (예: 서대문구청장)"
10
+ }
11
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "doc_type": "invoice",
3
+ "system_msg": "당신은 OCR 텍스트에서 세금계산서(거래명세서) 데이터를 추출하는 AI입니다. 공급자·공급받는자 정보, 날짜, 금액을 정확히 추출하세요. 찾을 수 없는 필드는 빈 문자열로 반환하세요.",
4
+ "user_msg": "아래 OCR 텍스트에서 세금계산서 정보를 추출하여 다음 JSON 스키마에 맞게 응답하세요.\n\n[OCR 텍스트]\n{{ocr_text}}\n\n[출력 스키마]\n{{schema}}\n\nJSON만 출력하세요.",
5
+ "schema": {
6
+ "invoice_num": "string: 세금계산서 번호",
7
+ "write_date": "string: 작성일자 (YYYY-MM-DD)",
8
+ "issuer_name": "string: 공급자 상호",
9
+ "issuer_reg_num": "string: 공급자 사업자등록번호 (XXX-XX-XXXXX)",
10
+ "receiver_name": "string: 공급받는자 상호",
11
+ "receiver_reg_num": "string: 공급받는자 사업자등록번호",
12
+ "supply_amount": "string: 공급가액 (숫자만)",
13
+ "tax_amount": "string: 세액 (숫자만)",
14
+ "total_amount": "string: 합계금액 (숫자만)",
15
+ "items": "array: [{name, qty, unit_price, amount}] 품목 목록"
16
+ }
17
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "doc_type": "namecard",
3
+ "system_msg": "당신은 OCR 텍스트에서 명함 정보를 추출하는 AI입니다. 이름, 직함, 회사, 연락처 등을 정확히 추출하세요. 전화번호·이메일은 복수일 수 있으므로 배열로 반환하세요. 찾을 수 없는 필드는 빈 문자열 또는 빈 배열로 반환하세요.",
4
+ "user_msg": "아래 OCR 텍스트에서 명함 정보를 추출하여 다음 JSON 스키마에 맞게 응답하세요.\n\n[OCR 텍스트]\n{{ocr_text}}\n\n[출력 스키마]\n{{schema}}\n\nJSON만 출력하세요.",
5
+ "schema": {
6
+ "name": "string: 이름",
7
+ "company": "string: 회사(기관)명",
8
+ "department": "string: 부서명",
9
+ "title": "string: 직함(직위)",
10
+ "phone": "array[string]: 전화번호 목록",
11
+ "email": "array[string]: 이메일 주소 목록",
12
+ "address": "string: 주소",
13
+ "website": "string: 웹사이트 URL"
14
+ }
15
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "doc_type": "receipt",
3
+ "system_msg": "당신은 OCR 텍스트에서 영수증 데이터를 추출하는 전문 AI입니다. 주어진 JSON 스키마에 정확히 맞는 JSON만 출력하세요. 값을 찾지 못하면 해당 필드를 빈 문자열로 설정하세요.",
4
+ "user_msg": "아래 영수증 OCR 텍스트에서 필드를 추출하여 다음 JSON 스키마에 맞게 응답하세요.\n\n[OCR 텍스트]\n{{ocr_text}}\n\n[출력 스키마]\n{{schema}}\n\nJSON만 출력하세요.",
5
+ "schema": {
6
+ "store_name": "string: 상호명/가맹점명",
7
+ "store_addr": "string: 주소",
8
+ "corp_num": "string: 사업자등록번호 (XXX-XX-XXXXX 형식)",
9
+ "date": "string: 거래일자 (YYYY-MM-DD 형식)",
10
+ "total_amount": "string: 결제 합계 금액 (숫자만, 콤마 제거)",
11
+ "payment_type": "string: 결제수단 (card/cash/other)",
12
+ "card_number": "string: 카드번호 (마지막 4자리만 또는 마스킹 포함)"
13
+ }
14
+ }
@@ -0,0 +1,79 @@
1
+ {
2
+ "doc_type": "receipt",
3
+ "label": "영수증",
4
+
5
+ "preprocess": {
6
+ "max_slope": 0.05,
7
+ "y_tolerance": 5,
8
+ "x_tolerance": 10,
9
+ "remove_patterns": ["^\\s*$"],
10
+ "merge_patterns": ["\\d{1,3}(,\\d{3})+원?"]
11
+ },
12
+
13
+ "keywords": {
14
+ "store_name": ["상호", "가맹점", "점포명"],
15
+ "corp_num": ["사업자번호", "사업자등록번호"],
16
+ "date": ["거래일시", "승인일시", "일시", "날짜"],
17
+ "total_amount": ["합계", "결제금액", "승인금액", "총금액", "금액"],
18
+ "payment_type": ["결제수단", "결제방법"],
19
+ "card_number": ["카드번호", "카드"]
20
+ },
21
+
22
+ "fields": {
23
+ "store_name": {
24
+ "output_key": "store_name",
25
+ "criteria": [
26
+ { "keyword": "상호", "direction": "RIGHT" },
27
+ { "keyword": "가맹점", "direction": "RIGHT" },
28
+ { "keyword": "점포명", "direction": "RIGHT" }
29
+ ]
30
+ },
31
+ "corp_num": {
32
+ "output_key": "corp_num",
33
+ "criteria": [
34
+ { "keyword": "사업자번호", "direction": "RIGHT" },
35
+ { "keyword": "사업자등록번호", "direction": "RIGHT" }
36
+ ],
37
+ "refine": "biz_num"
38
+ },
39
+ "date": {
40
+ "output_key": "date",
41
+ "mode": "regex_scan",
42
+ "pattern": "(\\d{4}[./-]\\d{2}[./-]\\d{2}(?:[\\s]\\d{2}:\\d{2}(?::\\d{2})?)?)",
43
+ "capture_group": 1,
44
+ "refine": "date"
45
+ },
46
+ "total_amount": {
47
+ "output_key": "total_amount",
48
+ "criteria": [
49
+ { "keyword": "합계", "direction": "RIGHT" },
50
+ { "keyword": "합계", "direction": "DOWN" },
51
+ { "keyword": "결제금액", "direction": "RIGHT" },
52
+ { "keyword": "승인금액", "direction": "RIGHT" }
53
+ ],
54
+ "refine": "number"
55
+ },
56
+ "payment_type": {
57
+ "output_key": "payment_type",
58
+ "criteria": [
59
+ { "keyword": "결제수단", "direction": "RIGHT" },
60
+ { "keyword": "결제방법", "direction": "RIGHT" }
61
+ ]
62
+ },
63
+ "card_number": {
64
+ "output_key": "card_number",
65
+ "mode": "regex_scan",
66
+ "pattern": "([0-9*]{4}[-\\s]?[0-9*]{4}[-\\s]?[0-9*]{4}[-\\s]?[0-9*]{4})",
67
+ "capture_group": 1
68
+ }
69
+ },
70
+
71
+ "required_fields": ["total_amount"],
72
+
73
+ "confidence_weight": {
74
+ "store_name": 0.2,
75
+ "corp_num": 0.15,
76
+ "date": 0.25,
77
+ "total_amount": 0.4
78
+ }
79
+ }
@@ -1,27 +0,0 @@
1
- {
2
- "enabled": false,
3
- "default": "nice",
4
- "request_ttl_sec": 300,
5
- "result_ttl_sec": 600,
6
- "return_url": "/v1/identity/callback",
7
- "success_redirect_url": "/identity/complete",
8
- "failure_redirect_url": "/identity/error",
9
- "duplicate_ci_check": true,
10
- "providers": [
11
- {
12
- "driver": "nice",
13
- "site_code": "${NICE_SITE_CODE}",
14
- "site_password": "${NICE_SITE_PASSWORD}",
15
- "client_id": "${NICE_CLIENT_ID}",
16
- "client_secret": "${NICE_CLIENT_SECRET}",
17
- "product_id": "2101979031",
18
- "api_url": "https://nice.checkplus.co.kr",
19
- "token_url": "https://svc.niceapi.co.kr:22001/digital/niceid/oauth/oauth/token",
20
- "crypto_url": "https://svc.niceapi.co.kr:22001/digital/niceid/api/v1.0/common/crypto/token"
21
- }
22
- ],
23
- "rate_limit": {
24
- "per_ip_per_hour": 10,
25
- "per_account_per_day": 5
26
- }
27
- }
@@ -1,28 +0,0 @@
1
- {
2
- "_comment": "개인정보처리방침 설정 예시. 각 모듈은 독립적으로 enabled 설정 가능. 운영 적용 전 docs/security/privacy-policy-guide.md 를 반드시 확인하세요.",
3
-
4
- "dormancy": {
5
- "_comment": "휴면 계정 전환 정책. 마지막 로그인 기준으로 dormancy_days 경과 시 휴면 처리.",
6
- "enabled": false,
7
- "dormancy_days": 365,
8
- "warning_days": [30, 7],
9
- "email_template": "dormancy_warning",
10
- "check_interval_hours": 24
11
- },
12
-
13
- "data_retention": {
14
- "_comment": "개인정보 보존 기간 정책. action: anonymize(익명화) | delete(삭제).",
15
- "enabled": false,
16
- "retention_days": 1095,
17
- "action": "anonymize",
18
- "check_interval_hours": 24
19
- },
20
-
21
- "password_policy": {
22
- "_comment": "비밀번호 만료/재사용 금지 정책. 복잡도 규칙은 password.json의 password_policy를 공통 사용.",
23
- "enabled": false,
24
- "max_age_days": 180,
25
- "warning_days": [14, 7],
26
- "email_template": "account/password_expiry_warning"
27
- }
28
- }
@@ -1,12 +0,0 @@
1
- {
2
- "enabled": false,
3
- "issuer": "EntityServer",
4
- "enforce_roles": [],
5
- "code_digits": 6,
6
- "period_sec": 30,
7
- "skew": 1,
8
- "recovery_code_count": 10,
9
- "setup_token_ttl_sec": 300,
10
- "max_verify_attempts": 5,
11
- "verify_lockout_sec": 300
12
- }
@@ -1,37 +0,0 @@
1
- {
2
- "enabled": false,
3
- "default": "toss_payments",
4
- "webhook_secret": "${PG_WEBHOOK_SECRET}",
5
- "order_id_prefix": "ORD",
6
- "success_url": "/payment/success",
7
- "fail_url": "/payment/fail",
8
- "webhook_url": "/v1/pg/webhook",
9
- "amount_limit": {
10
- "min": 100,
11
- "max": 10000000
12
- },
13
- "workers": 2,
14
- "providers": [
15
- {
16
- "driver": "toss_payments",
17
- "client_key": "${TOSS_CLIENT_KEY}",
18
- "secret_key": "${TOSS_SECRET_KEY}",
19
- "api_url": "https://api.tosspayments.com",
20
- "api_version": "2022-11-16"
21
- },
22
- {
23
- "_comment": "NHN KCP (Phase 2)",
24
- "driver": "kcp",
25
- "site_cd": "${KCP_SITE_CD}",
26
- "secret_key": "${KCP_SECRET_KEY}",
27
- "api_url": "https://api.pay.kcp.co.kr"
28
- },
29
- {
30
- "_comment": "KG 이니시스 (Phase 2)",
31
- "driver": "inicis",
32
- "store_id": "${INICIS_STORE_ID}",
33
- "sign_key": "${INICIS_SIGN_KEY}",
34
- "api_url": "https://api.inicis.com"
35
- }
36
- ]
37
- }
@@ -1,59 +0,0 @@
1
- {
2
- "enabled": true,
3
- "default": "barobill",
4
- "workers": 2,
5
- "queue_size": 100,
6
- "dispatch_interval_sec": 10,
7
- "max_retries": 3,
8
- "providers": [
9
- {
10
- "driver": "barobill",
11
- "cert_key": "${TAXINVOICE_CERT_KEY}",
12
- "corp_num": "${TAXINVOICE_CORP_NUM}",
13
- "user_id": "${TAXINVOICE_USER_ID}",
14
- "api_endpoint": "https://barobill.co.kr/TAPI/TaxInvoiceService.asmx",
15
- "timeout_sec": 30
16
- },
17
- {
18
- "driver": "popbill",
19
- "link_id": "${TAXINVOICE_LINK_ID}",
20
- "secret_key": "${TAXINVOICE_SECRET_KEY}",
21
- "corp_num": "${TAXINVOICE_CORP_NUM}",
22
- "api_endpoint": "https://taxinvoice.linkhub.co.kr",
23
- "timeout_sec": 30
24
- },
25
- {
26
- "driver": "bolta",
27
- "api_key": "${TAXINVOICE_API_KEY}",
28
- "customer_key": "${TAXINVOICE_CUSTOMER_KEY}",
29
- "api_endpoint": "https://xapi.bolta.io/v1",
30
- "timeout_sec": 30
31
- },
32
- {
33
- "driver": "smartbill",
34
- "api_key": "${TAXINVOICE_API_KEY}",
35
- "corp_num": "${TAXINVOICE_CORP_NUM}",
36
- "api_endpoint": "https://nxapi.smartbill.co.kr",
37
- "timeout_sec": 30
38
- },
39
- {
40
- "driver": "esero",
41
- "corp_num": "${TAXINVOICE_CORP_NUM}",
42
- "cert_path": "/run/secrets/esero_cert.pfx",
43
- "cert_pass": "${TAXINVOICE_CERT_PASS}",
44
- "api_endpoint": "https://esero.go.kr/api/v1",
45
- "timeout_sec": 60
46
- }
47
- ],
48
- "nts": {
49
- "taxation_option": 1,
50
- "taxation_add_tax_allow": 0,
51
- "tax_exemption_option": 1,
52
- "tax_exemption_add_tax_allow": 0
53
- },
54
- "notify": ["log", "smtp", "alimtalk"],
55
- "sync": {
56
- "state_sync_interval_min": 10,
57
- "max_list_days": 200
58
- }
59
- }
@@ -1,75 +0,0 @@
1
- {
2
- "_comment": "알림톡(Kakao Alimtalk) 설정 예시 — 4개 프로바이더 전체 구성",
3
- "enabled": false,
4
- "default": "aligo",
5
- "sender_key": "YOUR_KAKAO_SENDER_KEY",
6
- "workers": 2,
7
- "dispatch_interval_sec": 5,
8
- "queue_size": 200,
9
- "max_retries": 3,
10
- "fallback": {
11
- "enabled": true,
12
- "sender": "01012345678",
13
- "type": "sms"
14
- },
15
- "template_cache_ttl_sec": 300,
16
- "providers": {
17
- "aligo": {
18
- "driver": "aligo",
19
- "api_key": "YOUR_ALIGO_API_KEY",
20
- "user_id": "YOUR_ALIGO_USER_ID",
21
- "sender_key": "YOUR_KAKAO_SENDER_KEY"
22
- },
23
- "solapi": {
24
- "driver": "solapi",
25
- "api_key": "YOUR_SOLAPI_API_KEY",
26
- "api_secret": "YOUR_SOLAPI_API_SECRET",
27
- "pf_id": "YOUR_SOLAPI_PF_ID",
28
- "sender_key": "YOUR_KAKAO_SENDER_KEY"
29
- },
30
- "ppurio": {
31
- "driver": "ppurio",
32
- "account": "YOUR_PPURIO_ACCOUNT",
33
- "api_key": "YOUR_PPURIO_API_KEY",
34
- "sender_key": "YOUR_KAKAO_SENDER_KEY"
35
- },
36
- "nhn": {
37
- "driver": "nhn_cloud",
38
- "app_key": "YOUR_NHN_APP_KEY",
39
- "secret_key": "YOUR_NHN_SECRET_KEY",
40
- "sender_key": "YOUR_KAKAO_SENDER_KEY"
41
- }
42
- },
43
- "templates": [
44
- {
45
- "code": "AUTH_001",
46
- "description": "인증번호 발송",
47
- "variables": ["code", "minutes"],
48
- "fallback_sms": true
49
- },
50
- {
51
- "code": "ORDER_001",
52
- "description": "주문 접수 확인",
53
- "variables": ["name", "order_no", "amount"],
54
- "fallback_sms": true
55
- },
56
- {
57
- "code": "DELIVERY_001",
58
- "description": "배송 시작 알림",
59
- "variables": ["name", "tracking_no", "courier"],
60
- "fallback_sms": true
61
- },
62
- {
63
- "code": "PAYMENT_001",
64
- "description": "결제 완료",
65
- "variables": ["name", "amount", "method"],
66
- "fallback_sms": false
67
- },
68
- {
69
- "code": "NOTICE_001",
70
- "description": "일반 공지",
71
- "variables": ["title", "content"],
72
- "fallback_sms": false
73
- }
74
- ]
75
- }
@@ -1,54 +0,0 @@
1
- {
2
- "enabled": true,
3
- "default": "aligo",
4
- "sender": "01012345678",
5
- "workers": 2,
6
- "queue_size": 200,
7
- "dispatch_interval_sec": 5,
8
- "max_retries": 3,
9
- "auto_lms": true,
10
- "lms_threshold_bytes": 80,
11
- "providers": {
12
- "aligo": {
13
- "driver": "aligo",
14
- "api_key": "${ALIGO_API_KEY}",
15
- "user_id": "${ALIGO_USER_ID}",
16
- "sender": "01012345678"
17
- },
18
- "solapi": {
19
- "driver": "solapi",
20
- "api_key": "${SOLAPI_API_KEY}",
21
- "api_secret": "${SOLAPI_API_SECRET}",
22
- "sender": "01012345678"
23
- },
24
- "ppurio": {
25
- "driver": "ppurio",
26
- "account": "${PPURIO_ACCOUNT}",
27
- "api_key": "${PPURIO_API_KEY}",
28
- "sender": "01012345678"
29
- },
30
- "nhn": {
31
- "driver": "nhn_cloud",
32
- "app_key": "${NHN_SMS_APP_KEY}",
33
- "secret_key": "${NHN_SMS_SECRET_KEY}",
34
- "sender": "01012345678"
35
- },
36
- "aws": {
37
- "driver": "aws_sns",
38
- "region": "ap-northeast-2",
39
- "access_key": "${AWS_ACCESS_KEY}",
40
- "secret_key": "${AWS_SECRET_KEY}"
41
- }
42
- },
43
- "rate_limit": {
44
- "per_number_per_minute": 5,
45
- "per_minute": 60,
46
- "per_hour": 500
47
- },
48
- "verification": {
49
- "code_length": 6,
50
- "ttl_sec": 180,
51
- "max_attempts": 5,
52
- "cooldown_sec": 60
53
- }
54
- }
@@ -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,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>