create-entity-server 0.0.26 → 0.0.27

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 (76) 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/identity.json +27 -0
  5. package/template/configs/auth/jwt.json +12 -0
  6. package/template/configs/{oauth.json → auth/oauth.json} +7 -4
  7. package/template/configs/auth/password.json +33 -0
  8. package/template/configs/auth/privacy_policy.json +28 -0
  9. package/template/configs/{security.json → auth/security.json} +4 -2
  10. package/template/configs/auth/two_factor.json +12 -0
  11. package/template/configs/extensions/pg.json +37 -0
  12. package/template/configs/extensions/tax-invoice.json +59 -0
  13. package/template/configs/keys/.gitkeep +0 -0
  14. package/template/configs/keys/apns.p8.example +7 -0
  15. package/template/configs/keys/firebase.pem.example +7 -0
  16. package/template/configs/notification/alimtalk.json +75 -0
  17. package/template/configs/notification/sms.json +54 -0
  18. package/template/configs/server.json +1 -0
  19. package/template/entities/README.md +13 -16
  20. package/template/entities/System/Auth/account.json +17 -1
  21. package/template/entities/System/Auth/account_audit.json +23 -0
  22. package/template/entities/System/Auth/account_device.json +63 -0
  23. package/template/entities/System/Auth/account_login_log.json +54 -0
  24. package/template/entities/System/Auth/account_oauth.json +45 -0
  25. package/template/entities/System/Auth/api_keys.json +1 -1
  26. package/template/entities/System/Auth/identity_verification.json +95 -0
  27. package/template/entities/System/Auth/license.json +1 -1
  28. package/template/entities/System/Auth/password_history.json +20 -0
  29. package/template/entities/System/Auth/rbac_roles.json +1 -1
  30. package/template/entities/System/Backup/backup_log.json +62 -0
  31. package/template/entities/System/Email/smtp_log.json +83 -0
  32. package/template/entities/System/Email/smtp_msg.json +104 -0
  33. package/template/entities/System/Notification/alimtalk_log.json +45 -0
  34. package/template/entities/System/Notification/alimtalk_msg.json +39 -0
  35. package/template/entities/System/Notification/friendtalk_log.json +48 -0
  36. package/template/entities/System/Notification/friendtalk_msg.json +63 -0
  37. package/template/entities/System/Notification/sms_log.json +26 -0
  38. package/template/entities/System/Notification/sms_msg.json +52 -0
  39. package/template/entities/System/Notification/sms_verification.json +40 -0
  40. package/template/entities/System/Payment/pg_cancel.json +45 -0
  41. package/template/entities/System/Payment/pg_order.json +88 -0
  42. package/template/entities/System/Payment/pg_webhook_log.json +37 -0
  43. package/template/entities/System/Push/push_log.json +71 -0
  44. package/template/entities/System/Push/push_msg.json +55 -0
  45. package/template/entities/System/Storage/file_backup_log.json +46 -0
  46. package/template/entities/System/Storage/file_download_log.json +41 -0
  47. package/template/entities/System/Storage/file_meta.json +59 -0
  48. package/template/entities/System/system_audit_log.json +2 -1
  49. package/template/entities/company.json +1 -1
  50. package/template/entities/{product.json → goods.json} +6 -10
  51. package/template/entities/todo.json +1 -1
  52. package/template/templates/email/account/dormancy_warning.html +20 -0
  53. package/template/templates/email/account/password_expiry_warning.html +21 -0
  54. package/template/templates/email/auth/2fa_disabled.html +23 -0
  55. package/template/templates/email/auth/2fa_recovery_regenerated.html +31 -0
  56. package/template/templates/email/auth/2fa_setup_complete.html +43 -0
  57. package/template/templates/email/auth/email_verification.html +18 -0
  58. package/template/templates/email/auth/force_reset.html +18 -0
  59. package/template/templates/email/auth/password_reset.html +19 -0
  60. package/template/templates/email/auth/verification.html +15 -0
  61. package/template/templates/email/auth/verification_link.html +25 -0
  62. package/template/templates/email/auth/welcome.html +18 -0
  63. package/template/templates/email/backup/backup_completed.html +35 -0
  64. package/template/templates/email/backup/backup_failed.html +27 -0
  65. package/template/templates/email/backup/backup_partial.html +31 -0
  66. package/template/templates/email/layout.html +47 -0
  67. package/template/templates/email/order/order_confirmation.html +30 -0
  68. package/template/templates/email/storage/storage_quota_exceeded.html +37 -0
  69. package/template/templates/email/storage/storage_quota_warning.html +37 -0
  70. package/template/configs/cors.json +0 -7
  71. package/template/configs/jwt.json +0 -8
  72. package/template/entities/Account/account_audit.json +0 -16
  73. /package/template/configs/{backup.json → extensions/backup.json} +0 -0
  74. /package/template/configs/{storage.json → extensions/storage.json} +0 -0
  75. /package/template/configs/{push.json → notification/push.json} +0 -0
  76. /package/template/configs/{smtp.json → notification/smtp.json} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-entity-server",
3
- "version": "0.0.26",
3
+ "version": "0.0.27",
4
4
  "description": "Create a new entity-server project in one command — like create-react-app or create-vite.",
5
5
  "keywords": [
6
6
  "entity-server",
@@ -41,3 +41,29 @@ DB_PASSWORD_PRODUCTION=your-production-db-password
41
41
 
42
42
  # 푸시 알림 (push.json에서 ${FCM_PROJECT_ID} 등으로 참조 가능)
43
43
  # FCM_PROJECT_ID=your-firebase-project-id
44
+
45
+ # OAuth 소셜 로그인 (configs/auth/oauth.json)
46
+ # OAUTH_STATE_SECRET=your-random-oauth-state-secret
47
+ # OAUTH_SUCCESS_REDIRECT_URL=https://your-frontend.example.com/auth/success
48
+ # OAUTH_FAILURE_REDIRECT_URL=https://your-frontend.example.com/auth/fail
49
+ # GOOGLE_CLIENT_ID=your-google-client-id
50
+ # GOOGLE_CLIENT_SECRET=your-google-client-secret
51
+ # GITHUB_CLIENT_ID=your-github-client-id
52
+ # GITHUB_CLIENT_SECRET=your-github-client-secret
53
+ # NAVER_CLIENT_ID=your-naver-client-id
54
+ # NAVER_CLIENT_SECRET=your-naver-client-secret
55
+ # KAKAO_CLIENT_ID=your-kakao-client-id
56
+ # KAKAO_CLIENT_SECRET=your-kakao-client-secret
57
+
58
+ # SMS (configs/notification/sms.json)
59
+ # SMS_SENDER_NUMBER=029302266
60
+ # ALIGO_USER_ID=your-aligo-user-id
61
+ # ALIGO_API_KEY=your-aligo-api-key
62
+ # AWS_SNS_ACCESS_KEY=your-aws-access-key
63
+ # AWS_SNS_SECRET_KEY=your-aws-secret-key
64
+ # AWS_SNS_REGION=ap-northeast-2
65
+
66
+ # 카카오 알림톡 (configs/notification/alimtalk.json)
67
+ # ALIMTALK_SENDER_KEY=your-kakao-sender-key
68
+ # ALIGO_USER_ID=your-aligo-user-id
69
+ # ALIGO_API_KEY=your-aligo-api-key
@@ -0,0 +1,15 @@
1
+ {
2
+ "_comment": "CORS 설정 예시. cors_allow_origins 는 프로덕션에서 반드시 구체적인 도메인으로 제한하세요.",
3
+ "cors_enabled": true,
4
+ "cors_allow_credentials": false,
5
+ "cors_allow_headers": "Origin,Content-Type,Accept,Authorization,X-API-Key,X-Signature,X-Timestamp,X-Nonce,X-Transaction-ID",
6
+ "cors_allow_methods": "GET,POST,PUT,PATCH,DELETE,OPTIONS",
7
+ "cors_allow_origins": "https://your-domain.com",
8
+
9
+ "environments": {
10
+ "development": {
11
+ "_comment": "개발 환경에서만 와일드카드 허용",
12
+ "cors_allow_origins": "*"
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,27 @@
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
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "_comment": "JWT 설정 예시. secret 은 반드시 환경변수로 주입하세요. access_ttl_sec 은 보안 수준에 맞게 조정하세요.",
3
+ "enabled": true,
4
+ "secret": "${JWT_SECRET}",
5
+ "access_ttl_sec": 3600,
6
+ "refresh_ttl_sec": 1209600,
7
+ "issuer": "entity-server",
8
+ "algorithm": "HS256",
9
+
10
+ "_comment_algorithm": "지원 알고리즘: HS256 | HS384 | HS512 | RS256 | RS384 | RS512",
11
+ "_comment_ttl": "access_ttl_sec=3600(1시간), refresh_ttl_sec=1209600(14일) 기본값"
12
+ }
@@ -1,31 +1,34 @@
1
1
  {
2
2
  "_comment": "OAuth 2.0 설정 예시. 사용할 프로바이더만 남기고 실제 값으로 교체하세요.",
3
+ "enabled": false,
3
4
 
4
5
  "state_secret": "${OAUTH_STATE_SECRET}",
5
6
  "state_ttl_sec": 600,
7
+ "success_redirect_url": "/auth/callback",
8
+ "failure_redirect_url": "/auth/error",
6
9
 
7
10
  "providers": {
8
11
  "google": {
9
12
  "client_id": "${GOOGLE_CLIENT_ID}",
10
13
  "client_secret": "${GOOGLE_CLIENT_SECRET}",
11
- "redirect_url": "https://your-domain.com/v1/oauth/google/callback",
14
+ "redirect_url": "/v1/oauth/google/callback",
12
15
  "scopes": ["openid", "email", "profile"]
13
16
  },
14
17
  "github": {
15
18
  "client_id": "${GITHUB_CLIENT_ID}",
16
19
  "client_secret": "${GITHUB_CLIENT_SECRET}",
17
- "redirect_url": "https://your-domain.com/v1/oauth/github/callback"
20
+ "redirect_url": "/v1/oauth/github/callback"
18
21
  },
19
22
  "naver": {
20
23
  "client_id": "${NAVER_CLIENT_ID}",
21
24
  "client_secret": "${NAVER_CLIENT_SECRET}",
22
- "redirect_url": "https://your-domain.com/v1/oauth/naver/callback"
25
+ "redirect_url": "/v1/oauth/naver/callback"
23
26
  },
24
27
  "kakao": {
25
28
  "_comment": "Kakao — 커스텀 엔드포인트 예시",
26
29
  "client_id": "${KAKAO_CLIENT_ID}",
27
30
  "client_secret": "${KAKAO_CLIENT_SECRET}",
28
- "redirect_url": "https://your-domain.com/v1/oauth/kakao/callback",
31
+ "redirect_url": "/v1/oauth/kakao/callback",
29
32
  "auth_url": "https://kauth.kakao.com/oauth/authorize",
30
33
  "token_url": "https://kauth.kakao.com/oauth/token",
31
34
  "user_info_url": "https://kapi.kakao.com/v2/user/me",
@@ -0,0 +1,33 @@
1
+ {
2
+ "password_policy": {
3
+ "min_length": 8,
4
+ "require_mixed_case": false,
5
+ "require_number": false,
6
+ "require_special": false,
7
+ "history_count": 5
8
+ },
9
+ "admin_force_reset": {
10
+ "temp_password_length": 12,
11
+ "require_change": true,
12
+ "notify_email": true
13
+ },
14
+ "password_reset": {
15
+ "enabled": false,
16
+ "token_ttl_sec": 300,
17
+ "base_url": "/password-reset",
18
+ "rate_limit": {
19
+ "per_email_per_hour": 5,
20
+ "per_ip_per_minute": 10
21
+ }
22
+ },
23
+ "email_verification": {
24
+ "enabled": false,
25
+ "required": false,
26
+ "code_length": 6,
27
+ "code_ttl_sec": 300,
28
+ "max_attempts": 5,
29
+ "rate_limit": {
30
+ "per_email_per_hour": 5
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,28 @@
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,10 +1,12 @@
1
1
  {
2
- "enable_hmac": false,
2
+ "enable_hmac": true,
3
3
  "enable_rbac": true,
4
+ "enable_data_encryption": true,
4
5
  "enable_packet_encryption": false,
5
- "packet_magic_len": 4,
6
6
  "timestamp_skew_sec": 300,
7
7
  "nonce_ttl_sec": 300,
8
+ "auth_fail_limit_per_min": 120,
9
+ "auth_block_sec": 60,
8
10
  "nonce_store": {
9
11
  "driver": "redis",
10
12
  "memcache_servers": ["localhost:11211"],
@@ -0,0 +1,12 @@
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
+ }
@@ -0,0 +1,37 @@
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
+ }
@@ -0,0 +1,59 @@
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
+ }
File without changes
@@ -0,0 +1,7 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ (샘플) Apple Developer Console → Certificates, Identifiers & Profiles
3
+ → Keys → "+" 버튼으로 APNs 키 생성 후 다운로드한 .p8 파일 내용을 여기에 붙여넣으세요.
4
+
5
+ 실제 키는 아래와 같은 형식입니다:
6
+ MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg...
7
+ -----END PRIVATE KEY-----
@@ -0,0 +1,7 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ (샘플) Firebase Console → 프로젝트 설정 → 서비스 계정 → 새 비공개 키 생성
3
+ 으로 다운로드한 JSON 파일의 private_key 값을 여기에 붙여넣으세요.
4
+
5
+ 실제 키는 아래와 같은 형식입니다:
6
+ MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC...
7
+ -----END PRIVATE KEY-----
@@ -0,0 +1,75 @@
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
+ }
@@ -0,0 +1,54 @@
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,5 +1,6 @@
1
1
  {
2
2
  "namespace": "entity-prod",
3
+ "public_url": "https://api.example.com",
3
4
  "default_email_domain": "example.com",
4
5
  "language": "ko",
5
6
  "timezone": "Asia/Seoul",
@@ -4,16 +4,15 @@
4
4
 
5
5
  ## 예제 엔티티 목록
6
6
 
7
- | 파일 | 설명 | 주요 특징 |
8
- | -------------------------------------------------------------------------- | -------------- | ------------------------------------------------------------------------- |
9
- | [todo.json](#1-todojson) | 할 일 목록 | 기본 인덱스, 해시 필드 |
10
- | [product.json](#2-productjson) | 제품 관리 | 유니크 제약, reset_defaults 시딩 |
11
- | [examples/Auth/account.json](#3-examplesauthaccountjson) | 사용자 관리 | rbac_role, 인증 훅 / **JWT 사용 시 필수** |
12
- | [examples/Auth/rbac_roles.json](#4-examplesauthrbac_rolesjson) | RBAC 역할 정의 | permissions 포함 5개 역할, reset-all 시 자동 시딩 / **RBAC 사용 시 필수** |
13
- | [examples/Auth/api_keys.json](#5-examplesauthauthapi_keysjson) | API 키 관리 | HMAC 인증 키, 역할 연결, user_seq 연결 / **HMAC 사용 시 필수** |
14
- | [license.json](#6-licensejson) | 라이선스 관리 | 계약/만료일, 유니크 제약, 자동 시딩 |
15
- | [company.json](#7-companyjson) | 회사 정보 | license_scope, 사업자번호 해시, 캐시 |
16
- | [examples/Account/account_audit.json](#8-examplesaccountaccount_auditjson) | 감사 로그 | INSERT 전용, 훅으로 자동 기록 |
7
+ | 파일 | 설명 | 주요 특징 |
8
+ | -------------------------------------------------------------- | -------------- | ------------------------------------------------------------------------- |
9
+ | [todo.json](#1-todojson) | 할 일 목록 | 기본 인덱스, 해시 필드 |
10
+ | [goods.json](#2-goodsjson) | 상품 관리 | 유니크 제약, reset_defaults 시딩 |
11
+ | [examples/Auth/account.json](#3-examplesauthaccountjson) | 사용자 관리 | rbac_role, 인증 훅 / **JWT 사용 시 필수** |
12
+ | [examples/Auth/rbac_roles.json](#4-examplesauthrbac_rolesjson) | RBAC 역할 정의 | permissions 포함 5개 역할, reset-all 시 자동 시딩 / **RBAC 사용 시 필수** |
13
+ | [examples/Auth/api_keys.json](#5-examplesauthauthapi_keysjson) | API 키 관리 | HMAC 인증 키, 역할 연결, user_seq 연결 / **HMAC 사용 시 필수** |
14
+ | [license.json](#6-licensejson) | 라이선스 관리 | 계약/만료일, 유니크 제약, 자동 시딩 |
15
+ | [company.json](#7-companyjson) | 회사 정보 | license_scope, 사업자번호 해시, 캐시 |
17
16
 
18
17
  ## 문서 바로가기
19
18
 
@@ -38,7 +37,7 @@
38
37
  - 기본 인덱스 필드 (`title`, `status`, `created_time`)
39
38
  - 해시 필드 (`user_id`) - 암호화되어 저장
40
39
 
41
- ### 2. product.json
40
+ ### 2. goods.json
42
41
 
43
42
  제품 관리 엔티티
44
43
 
@@ -50,7 +49,7 @@
50
49
 
51
50
  ### 3. examples/Auth/account.json
52
51
 
53
- 사용자 관리 엔티티 (`entities/examples/Auth/` 에 위치 → 배포 시 `dist/entities/System/Auth/account.json`)
52
+ 사용자 관리 엔티티 (`entities-example/Auth/` 에 위치 → 배포 시 `dist/entities/System/Auth/account.json`)
54
53
 
55
54
  > **⚠️ JWT 인증을 사용하려면 필수입니다.**
56
55
  > HMAC 인증만 사용하는 경우에는 필요하지 않습니다.
@@ -68,7 +67,7 @@
68
67
 
69
68
  ### 4. examples/Auth/rbac_roles.json
70
69
 
71
- RBAC 역할 정의 엔티티 (`entities/examples/Auth/` 에 위치 → 배포 시 `dist/entities/System/Auth/rbac_roles.json`)
70
+ RBAC 역할 정의 엔티티 (`entities-example/Auth/` 에 위치 → 배포 시 `dist/entities/System/Auth/rbac_roles.json`)
72
71
 
73
72
  > **⚠️ RBAC 인증을 사용하려면 필수입니다.**
74
73
  > `reset-all` 실행 시 `reset_defaults`의 5개 역할이 자동 시딩됩니다.
@@ -84,7 +83,7 @@ RBAC 역할 정의 엔티티 (`entities/examples/Auth/` 에 위치 → 배포
84
83
 
85
84
  ### 5. examples/Auth/api_keys.json
86
85
 
87
- API 키 관리 엔티티 (`entities/examples/Auth/` 에 위치 → 배포 시 `dist/entities/System/Auth/api_keys.json`)
86
+ API 키 관리 엔티티 (`entities-example/Auth/` 에 위치 → 배포 시 `dist/entities/System/Auth/api_keys.json`)
88
87
 
89
88
  > **⚠️ HMAC 인증을 사용하려면 필수입니다.**
90
89
  > `reset-all` 실행 시 admin 역할의 API 키 1개가 자동 생성되며 `key_value`와 `hmac_secret`이 출력됩니다.
@@ -130,8 +129,6 @@ API_KEY=<admin-key> ./scripts/api-keys.sh delete 3
130
129
  - 해시 필드 (`tax_id`) - 사업자번호 암호화
131
130
  - 캐시 활성화 (TTL 300초)
132
131
 
133
- ### 8. examples/Account/account_audit.json
134
-
135
132
  사용자 감사 로그 엔티티
136
133
 
137
134
  **특징**:
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "account",
3
- "description": "JWT 로그인/인증 계정 예제",
3
+ "description": "JWT 로그인/인증 계정 예제. 사용자 환경에 맞게 index·fields를 자유롭게 확장할 수 있습니다.",
4
4
  "index": {
5
5
  "user_seq": {
6
6
  "comment": "사용자번호"
@@ -41,6 +41,22 @@
41
41
  "params": ["${new.seq}", "INSERT", "${new.email}"],
42
42
  "async": false
43
43
  }
44
+ ],
45
+ "after_update": [
46
+ {
47
+ "type": "sql",
48
+ "query": "INSERT INTO account_audit (account_seq, action, email, created_time) VALUES (?, ?, ?, NOW())",
49
+ "params": ["${new.seq}", "UPDATE", "${new.email}"],
50
+ "async": false
51
+ }
52
+ ],
53
+ "after_delete": [
54
+ {
55
+ "type": "sql",
56
+ "query": "INSERT INTO account_audit (account_seq, action, email, created_time) VALUES (?, ?, ?, NOW())",
57
+ "params": ["${old.seq}", "DELETE", "${old.email}"],
58
+ "async": false
59
+ }
44
60
  ]
45
61
  }
46
62
  }
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "account_audit",
3
+ "description": "account 감사 로그. account.json 훅(after_insert/after_update/after_delete)에 의해 자동 기록됩니다. 사용자 환경에 맞게 index·fields를 자유롭게 확장할 수 있습니다.",
4
+ "hard_delete": true,
5
+ "read_only": true,
6
+ "compress": true,
7
+ "index": {
8
+ "account_seq": {
9
+ "comment": "계정 seq (JWT 인증 시 account.seq 참조. HMAC은 nullable)",
10
+ "type": "bigint",
11
+ "nullable": true
12
+ },
13
+ "action": {
14
+ "comment": "작업 유형 (after_insert → INSERT, after_update → UPDATE, after_delete → DELETE)",
15
+ "type": ["INSERT", "UPDATE", "DELETE"],
16
+ "required": true
17
+ },
18
+ "email": {
19
+ "comment": "작업 대상 계정 이메일",
20
+ "nullable": true
21
+ }
22
+ }
23
+ }