create-entity-server 0.0.31 → 0.2.5
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.
- package/bin/create.js +4 -0
- package/package.json +1 -1
- package/template/configs/database.json +2 -2
- package/template/entities/README.md +3 -3
- package/template/entities/System/Address/addr_dong.json +10115 -0
- package/template/entities/System/Address/addr_sido.json +39 -0
- package/template/entities/System/Address/addr_sigungu.json +1398 -0
- package/template/entities/System/Auth/account.json +0 -64
- package/template/entities/System/Auth/account_device.json +7 -22
- package/template/entities/System/Auth/account_login_log.json +3 -8
- package/template/entities/System/Auth/anon_device.json +56 -0
- package/template/scripts/api-key.sh +5 -2
- package/template/scripts/cleanup-history.sh +9 -4
- package/template/scripts/cli.sh +5 -2
- package/template/scripts/entity.sh +9 -4
- package/template/scripts/install-systemd.sh +7 -3
- package/template/scripts/normalize-entities.sh +9 -4
- package/template/scripts/rbac-role.sh +5 -2
- package/template/scripts/reset-all.sh +91 -13
- package/template/scripts/run.sh +73 -27
- package/template/scripts/sync.sh +9 -4
- package/template/configs/auth/oauth.json +0 -40
- package/template/configs/auth/password.json +0 -45
- package/template/configs/keys/apns.p8.example +0 -7
- package/template/configs/keys/firebase.pem.example +0 -7
- package/template/configs/notification/push.json +0 -25
- package/template/entities/System/Auth/account_oauth.json +0 -74
- package/template/entities/System/Auth/identity_verification.json +0 -106
- package/template/entities/System/Auth/password_history.json +0 -19
- package/template/entities/System/Notification/alimtalk_log.json +0 -65
- package/template/entities/System/Notification/alimtalk_msg.json +0 -53
- package/template/entities/System/Notification/friendtalk_log.json +0 -89
- package/template/entities/System/Notification/friendtalk_msg.json +0 -91
- package/template/entities/System/Notification/sms_log.json +0 -65
- package/template/entities/System/Notification/sms_msg.json +0 -82
- package/template/entities/System/Notification/sms_verification.json +0 -50
- package/template/entities/System/Payment/pg_cancel.json +0 -60
- package/template/entities/System/Payment/pg_order.json +0 -115
- package/template/entities/System/Payment/pg_webhook_log.json +0 -52
- package/template/entities/System/Push/push_log.json +0 -86
- package/template/entities/System/Push/push_msg.json +0 -56
- package/template/templates/email/auth/2fa_disabled.html +0 -23
- package/template/templates/email/auth/2fa_recovery_regenerated.html +0 -31
- package/template/templates/email/auth/2fa_setup_complete.html +0 -43
- package/template/templates/email/auth/welcome.html +0 -18
- package/template/templates/email/order/order_confirmation.html +0 -30
- /package/template/configs/{notification/smtp.json → smtp.json} +0 -0
package/template/scripts/run.sh
CHANGED
|
@@ -54,6 +54,70 @@ get_server_value() {
|
|
|
54
54
|
fi
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
get_database_default_group() {
|
|
58
|
+
local value
|
|
59
|
+
value=$(grep -E '"default"[[:space:]]*:' "$DATABASE_CONFIG" | head -n 1 | sed -E 's/.*:[[:space:]]*"([^"]+)".*/\1/')
|
|
60
|
+
echo "$value"
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
list_database_groups() {
|
|
64
|
+
grep -E '^[[:space:]]*"[^"]+"[[:space:]]*:[[:space:]]*\{' "$DATABASE_CONFIG" \
|
|
65
|
+
| sed -E 's/^[[:space:]]*"([^"]+)"[[:space:]]*:[[:space:]]*\{.*/\1/' \
|
|
66
|
+
| grep -v '^groups$' \
|
|
67
|
+
| awk 'BEGIN { first = 1 } { if (!first) printf ", "; printf "%s", $0; first = 0 } END { printf "\n" }'
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
print_missing_database_group_error() {
|
|
71
|
+
local expected_group="$1"
|
|
72
|
+
local line_no="$2"
|
|
73
|
+
local current_default
|
|
74
|
+
local available_groups
|
|
75
|
+
|
|
76
|
+
current_default=$(get_database_default_group)
|
|
77
|
+
available_groups=$(list_database_groups)
|
|
78
|
+
|
|
79
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
80
|
+
echo "❌ database group '$expected_group' not found"
|
|
81
|
+
echo " at: scripts/run.sh:$line_no"
|
|
82
|
+
echo " config: $DATABASE_CONFIG"
|
|
83
|
+
echo " current default: ${current_default:-<empty>}"
|
|
84
|
+
echo " available groups: ${available_groups:-<none>}"
|
|
85
|
+
echo " cause: run.sh $MODE hardcodes '$expected_group' as the target default group."
|
|
86
|
+
else
|
|
87
|
+
echo "❌ configs/database.json에 '$expected_group' 그룹이 없습니다"
|
|
88
|
+
echo " 위치: scripts/run.sh:$line_no"
|
|
89
|
+
echo " 설정파일: $DATABASE_CONFIG"
|
|
90
|
+
echo " 현재 default: ${current_default:-<empty>}"
|
|
91
|
+
echo " 사용 가능한 groups: ${available_groups:-<none>}"
|
|
92
|
+
echo " 원인: run.sh $MODE 모드는 '$expected_group' 그룹을 기본 DB 그룹으로 강제하도록 작성되어 있습니다."
|
|
93
|
+
fi
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
sync_database_default_for_environment() {
|
|
97
|
+
local environment_value
|
|
98
|
+
environment_value=$(get_server_value "environment" "development")
|
|
99
|
+
|
|
100
|
+
if [ "$environment_value" != "production" ]; then
|
|
101
|
+
return 0
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
# 현재 default 그룹이 database.json 안에 존재하면 그대로 유지
|
|
105
|
+
local current_default
|
|
106
|
+
current_default=$(get_database_default_group)
|
|
107
|
+
if [ -n "$current_default" ] && grep -Eq "\"${current_default}\"[[:space:]]*:" "$DATABASE_CONFIG"; then
|
|
108
|
+
return 0
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
# 현재 default 그룹이 없을 때만 production으로 fallback
|
|
112
|
+
if ! grep -Eq '"production"[[:space:]]*:' "$DATABASE_CONFIG"; then
|
|
113
|
+
print_missing_database_group_error "production" "$1"
|
|
114
|
+
return 1
|
|
115
|
+
fi
|
|
116
|
+
|
|
117
|
+
sed -E -i 's/("default"[[:space:]]*:[[:space:]]*")[^"]+(")/\1production\2/' "$DATABASE_CONFIG"
|
|
118
|
+
return 0
|
|
119
|
+
}
|
|
120
|
+
|
|
57
121
|
is_running() {
|
|
58
122
|
local port_pid
|
|
59
123
|
port_pid=$(find_pid_by_port)
|
|
@@ -146,7 +210,7 @@ stop_pid_with_confirm() {
|
|
|
146
210
|
read -r -p "이 프로세스를 중지할까요? [y/N]: " input
|
|
147
211
|
fi
|
|
148
212
|
input=$(echo "$input" | tr '[:upper:]' '[:lower:]')
|
|
149
|
-
if [ "$input" != "y" ] && [ "$input" != "yes" ]; then
|
|
213
|
+
if [ "$input" != "y" ] && [ "$input" != "yes" ] && [ "$input" != "ㅛ" ]; then
|
|
150
214
|
if [ "$LANGUAGE" = "en" ]; then
|
|
151
215
|
echo "Canceled."
|
|
152
216
|
else
|
|
@@ -273,13 +337,13 @@ if [ $# -eq 0 ]; then
|
|
|
273
337
|
echo "Entity Server - Run Script"
|
|
274
338
|
echo "=========================="
|
|
275
339
|
echo ""
|
|
276
|
-
echo "
|
|
340
|
+
echo "Adjust configs/server.json environment as needed, then start the compiled server binary."
|
|
277
341
|
echo ""
|
|
278
342
|
echo "Usage: $0 <mode>"
|
|
279
343
|
echo ""
|
|
280
344
|
echo "Modes:"
|
|
281
|
-
echo " dev environment=development, database.default
|
|
282
|
-
echo " start environment=production, database.default=production, then run in background"
|
|
345
|
+
echo " dev environment=development, keep database.default, then run binary"
|
|
346
|
+
echo " start environment=production, use database.default=production only in production, then run in background"
|
|
283
347
|
echo " stop stop background server started by this script"
|
|
284
348
|
echo " status show server status"
|
|
285
349
|
echo ""
|
|
@@ -292,13 +356,13 @@ if [ $# -eq 0 ]; then
|
|
|
292
356
|
echo "Entity Server - 실행 스크립트"
|
|
293
357
|
echo "==========================="
|
|
294
358
|
echo ""
|
|
295
|
-
echo "configs/server.json의 environment
|
|
359
|
+
echo "configs/server.json의 environment를 기준으로 필요한 경우에만 database.default를 조정한 뒤 바이너리를 실행합니다."
|
|
296
360
|
echo ""
|
|
297
361
|
echo "사용법: $0 <모드>"
|
|
298
362
|
echo ""
|
|
299
363
|
echo "모드:"
|
|
300
|
-
echo " dev environment=development
|
|
301
|
-
echo " start environment=production
|
|
364
|
+
echo " dev environment=development로 설정하고 database.default는 유지한 채 바이너리 실행"
|
|
365
|
+
echo " start environment=production으로 설정하고 production일 때만 database.default=production으로 맞춘 뒤 백그라운드 실행"
|
|
302
366
|
echo " stop run.sh로 백그라운드 실행한 서버 중지"
|
|
303
367
|
echo " status 서버 상태 조회"
|
|
304
368
|
echo ""
|
|
@@ -357,17 +421,8 @@ case "$MODE" in
|
|
|
357
421
|
exit 1
|
|
358
422
|
fi
|
|
359
423
|
|
|
360
|
-
if ! grep -Eq '"development"[[:space:]]*:' "$DATABASE_CONFIG"; then
|
|
361
|
-
if [ "$LANGUAGE" = "en" ]; then
|
|
362
|
-
echo "❌ database group 'development' not found in configs/database.json"
|
|
363
|
-
else
|
|
364
|
-
echo "❌ configs/database.json에 'development' 그룹이 없습니다"
|
|
365
|
-
fi
|
|
366
|
-
exit 1
|
|
367
|
-
fi
|
|
368
|
-
|
|
369
424
|
sed -E -i 's/("environment"[[:space:]]*:[[:space:]]*")[^"]+(")/\1development\2/' "$SERVER_CONFIG"
|
|
370
|
-
|
|
425
|
+
sync_database_default_for_environment "$LINENO" || exit 1
|
|
371
426
|
"$SERVER_BIN"
|
|
372
427
|
;;
|
|
373
428
|
|
|
@@ -387,17 +442,8 @@ case "$MODE" in
|
|
|
387
442
|
exit 1
|
|
388
443
|
fi
|
|
389
444
|
|
|
390
|
-
if ! grep -Eq '"production"[[:space:]]*:' "$DATABASE_CONFIG"; then
|
|
391
|
-
if [ "$LANGUAGE" = "en" ]; then
|
|
392
|
-
echo "❌ database group 'production' not found in configs/database.json"
|
|
393
|
-
else
|
|
394
|
-
echo "❌ configs/database.json에 'production' 그룹이 없습니다"
|
|
395
|
-
fi
|
|
396
|
-
exit 1
|
|
397
|
-
fi
|
|
398
|
-
|
|
399
445
|
sed -E -i 's/("environment"[[:space:]]*:[[:space:]]*")[^"]+(")/\1production\2/' "$SERVER_CONFIG"
|
|
400
|
-
|
|
446
|
+
sync_database_default_for_environment "$LINENO" || exit 1
|
|
401
447
|
|
|
402
448
|
"$SERVER_BIN" banner
|
|
403
449
|
nohup "$SERVER_BIN" >> "$STDOUT_LOG" 2>&1 &
|
package/template/scripts/sync.sh
CHANGED
|
@@ -7,6 +7,11 @@ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
|
7
7
|
|
|
8
8
|
cd "$PROJECT_ROOT"
|
|
9
9
|
|
|
10
|
+
ENTITY_CLI_BIN="$PROJECT_ROOT/bin/entity-cli"
|
|
11
|
+
if [ ! -f "$ENTITY_CLI_BIN" ] && [ -f "$PROJECT_ROOT/entity-cli" ]; then
|
|
12
|
+
ENTITY_CLI_BIN="$PROJECT_ROOT/entity-cli"
|
|
13
|
+
fi
|
|
14
|
+
|
|
10
15
|
# Load language from .env
|
|
11
16
|
if [ -f .env ]; then
|
|
12
17
|
LANGUAGE=$(grep '^LANGUAGE=' .env | cut -d '=' -f2)
|
|
@@ -70,11 +75,11 @@ if [ $# -eq 0 ]; then
|
|
|
70
75
|
fi
|
|
71
76
|
|
|
72
77
|
# Require prebuilt CLI binary
|
|
73
|
-
if [ ! -f "$
|
|
78
|
+
if [ ! -f "$ENTITY_CLI_BIN" ]; then
|
|
74
79
|
if [ "$LANGUAGE" = "en" ]; then
|
|
75
|
-
echo "❌ bin/entity-cli
|
|
80
|
+
echo "❌ entity-cli not found (bin/entity-cli or ./entity-cli)"
|
|
76
81
|
else
|
|
77
|
-
echo "❌ bin/entity-cli
|
|
82
|
+
echo "❌ entity-cli 파일이 없습니다 (bin/entity-cli 또는 ./entity-cli)"
|
|
78
83
|
fi
|
|
79
84
|
exit 1
|
|
80
85
|
fi
|
|
@@ -115,7 +120,7 @@ fi
|
|
|
115
120
|
|
|
116
121
|
build_cmd() {
|
|
117
122
|
local entity_name="$1"
|
|
118
|
-
local cmd=("$
|
|
123
|
+
local cmd=("$ENTITY_CLI_BIN" sync-index --entity="$entity_name")
|
|
119
124
|
if [ "$APPLY_MODE" = "--apply" ]; then
|
|
120
125
|
cmd+=(--apply)
|
|
121
126
|
fi
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_comment": "OAuth 2.0 설정 예시. 사용할 프로바이더만 남기고 실제 값으로 교체하세요.",
|
|
3
|
-
"enabled": false,
|
|
4
|
-
|
|
5
|
-
"state_secret": "${OAUTH_STATE_SECRET}",
|
|
6
|
-
"state_ttl_sec": 600,
|
|
7
|
-
"success_redirect_url": "/auth/callback",
|
|
8
|
-
"failure_redirect_url": "/auth/error",
|
|
9
|
-
|
|
10
|
-
"providers": {
|
|
11
|
-
"google": {
|
|
12
|
-
"client_id": "${GOOGLE_CLIENT_ID}",
|
|
13
|
-
"client_secret": "${GOOGLE_CLIENT_SECRET}",
|
|
14
|
-
"redirect_url": "/v1/oauth/google/callback",
|
|
15
|
-
"scopes": ["openid", "email", "profile"]
|
|
16
|
-
},
|
|
17
|
-
"github": {
|
|
18
|
-
"client_id": "${GITHUB_CLIENT_ID}",
|
|
19
|
-
"client_secret": "${GITHUB_CLIENT_SECRET}",
|
|
20
|
-
"redirect_url": "/v1/oauth/github/callback"
|
|
21
|
-
},
|
|
22
|
-
"naver": {
|
|
23
|
-
"client_id": "${NAVER_CLIENT_ID}",
|
|
24
|
-
"client_secret": "${NAVER_CLIENT_SECRET}",
|
|
25
|
-
"redirect_url": "/v1/oauth/naver/callback"
|
|
26
|
-
},
|
|
27
|
-
"kakao": {
|
|
28
|
-
"_comment": "Kakao — 커스텀 엔드포인트 예시",
|
|
29
|
-
"client_id": "${KAKAO_CLIENT_ID}",
|
|
30
|
-
"client_secret": "${KAKAO_CLIENT_SECRET}",
|
|
31
|
-
"redirect_url": "/v1/oauth/kakao/callback",
|
|
32
|
-
"auth_url": "https://kauth.kakao.com/oauth/authorize",
|
|
33
|
-
"token_url": "https://kauth.kakao.com/oauth/token",
|
|
34
|
-
"user_info_url": "https://kapi.kakao.com/v2/user/me",
|
|
35
|
-
"scopes": ["profile_nickname", "account_email"],
|
|
36
|
-
"email_field": "kakao_account.email",
|
|
37
|
-
"name_field": "properties.nickname"
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"password_policy": {
|
|
3
|
-
"min_length": 8,
|
|
4
|
-
"max_length": 128,
|
|
5
|
-
"require_mixed_case": false,
|
|
6
|
-
"require_number": false,
|
|
7
|
-
"require_special": false,
|
|
8
|
-
"history_count": 5,
|
|
9
|
-
"forbidden_patterns": {
|
|
10
|
-
"sequential_digits": true,
|
|
11
|
-
"repeated_chars": true,
|
|
12
|
-
"keyboard_patterns": false,
|
|
13
|
-
"sequential_length": 4
|
|
14
|
-
},
|
|
15
|
-
"pii_check": {
|
|
16
|
-
"enabled": false,
|
|
17
|
-
"entity": "user",
|
|
18
|
-
"fields": ["phone", "birthday"]
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
"admin_force_reset": {
|
|
22
|
-
"temp_password_length": 12,
|
|
23
|
-
"require_change": true,
|
|
24
|
-
"notify_email": true
|
|
25
|
-
},
|
|
26
|
-
"password_reset": {
|
|
27
|
-
"enabled": true,
|
|
28
|
-
"temp_password_ttl_sec": 300,
|
|
29
|
-
"temp_password_length": 12,
|
|
30
|
-
"rate_limit": {
|
|
31
|
-
"per_email_per_hour": 5,
|
|
32
|
-
"per_ip_per_minute": 10
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
"email_verification": {
|
|
36
|
-
"enabled": true,
|
|
37
|
-
"required": false,
|
|
38
|
-
"code_length": 6,
|
|
39
|
-
"code_ttl_sec": 300,
|
|
40
|
-
"max_attempts": 5,
|
|
41
|
-
"rate_limit": {
|
|
42
|
-
"per_email_per_hour": 5
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"workers": 2,
|
|
3
|
-
"queue_size": 500,
|
|
4
|
-
"fcm": {
|
|
5
|
-
"enabled": false,
|
|
6
|
-
"type": "service_account",
|
|
7
|
-
"project_id": "your-firebase-project-id",
|
|
8
|
-
"private_key_id": "abc123def456...",
|
|
9
|
-
"private_key_file": "./configs/keys/firebase.pem",
|
|
10
|
-
"client_email": "firebase-adminsdk-xxxxx@your-firebase-project-id.iam.gserviceaccount.com",
|
|
11
|
-
"client_id": "123456789012345678901",
|
|
12
|
-
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
|
13
|
-
"token_uri": "https://oauth2.googleapis.com/token",
|
|
14
|
-
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
|
15
|
-
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-xxxxx%40your-firebase-project-id.iam.gserviceaccount.com"
|
|
16
|
-
},
|
|
17
|
-
"apns": {
|
|
18
|
-
"enabled": false,
|
|
19
|
-
"key_file": "./configs/keys/apns.p8",
|
|
20
|
-
"key_id": "ABCDE12345",
|
|
21
|
-
"team_id": "FGHIJ67890",
|
|
22
|
-
"bundle_id": "com.example.myapp",
|
|
23
|
-
"production": false
|
|
24
|
-
}
|
|
25
|
-
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "account_oauth",
|
|
3
|
-
"description": "소셜 로그인 OAuth 프로바이더 연동 정보. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
|
|
4
|
-
"history": false,
|
|
5
|
-
"hard_delete": true,
|
|
6
|
-
"fields": {
|
|
7
|
-
"account_seq": {
|
|
8
|
-
"index": true,
|
|
9
|
-
"required": true,
|
|
10
|
-
"comment": "계정 seq"
|
|
11
|
-
},
|
|
12
|
-
"provider": {
|
|
13
|
-
"index": true,
|
|
14
|
-
"type": [
|
|
15
|
-
"google",
|
|
16
|
-
"github",
|
|
17
|
-
"naver",
|
|
18
|
-
"kakao",
|
|
19
|
-
"apple"
|
|
20
|
-
],
|
|
21
|
-
"required": true
|
|
22
|
-
},
|
|
23
|
-
"provider_id": {
|
|
24
|
-
"index": true,
|
|
25
|
-
"type": "string",
|
|
26
|
-
"required": true,
|
|
27
|
-
"comment": "프로바이더 고유 사용자 ID"
|
|
28
|
-
},
|
|
29
|
-
"status": {
|
|
30
|
-
"index": true,
|
|
31
|
-
"type": [
|
|
32
|
-
"active",
|
|
33
|
-
"unlinked"
|
|
34
|
-
],
|
|
35
|
-
"default": "active"
|
|
36
|
-
},
|
|
37
|
-
"email": {
|
|
38
|
-
"type": "email",
|
|
39
|
-
"comment": "프로바이더에서 제공한 이메일"
|
|
40
|
-
},
|
|
41
|
-
"name": {
|
|
42
|
-
"type": "string",
|
|
43
|
-
"comment": "프로바이더에서 제공한 이름"
|
|
44
|
-
},
|
|
45
|
-
"profile_image": {
|
|
46
|
-
"type": "string",
|
|
47
|
-
"comment": "프로필 이미지 URL"
|
|
48
|
-
},
|
|
49
|
-
"access_token": {
|
|
50
|
-
"type": "string",
|
|
51
|
-
"comment": "OAuth access token (암호화 저장)"
|
|
52
|
-
},
|
|
53
|
-
"refresh_token": {
|
|
54
|
-
"type": "string",
|
|
55
|
-
"comment": "OAuth refresh token (암호화 저장)"
|
|
56
|
-
},
|
|
57
|
-
"token_expires_at": {
|
|
58
|
-
"type": "string",
|
|
59
|
-
"comment": "access token 만료 시각 (RFC3339)"
|
|
60
|
-
},
|
|
61
|
-
"raw": {
|
|
62
|
-
"type": "json",
|
|
63
|
-
"comment": "프로바이더 원본 응답 (디버깅용)"
|
|
64
|
-
},
|
|
65
|
-
"linked_at": {
|
|
66
|
-
"type": "string",
|
|
67
|
-
"comment": "연결 시각"
|
|
68
|
-
},
|
|
69
|
-
"unlinked_at": {
|
|
70
|
-
"type": "string",
|
|
71
|
-
"comment": "연결 해제 시각"
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "identity_verification",
|
|
3
|
-
"description": "휴대폰 본인인증 요청 및 결과 저장. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
|
|
4
|
-
"history": false,
|
|
5
|
-
"hard_delete": false,
|
|
6
|
-
"compress": true,
|
|
7
|
-
"fields": {
|
|
8
|
-
"request_id": {
|
|
9
|
-
"index": true,
|
|
10
|
-
"type": "string",
|
|
11
|
-
"required": true,
|
|
12
|
-
"unique": true,
|
|
13
|
-
"comment": "인증 요청 고유 ID (32바이트 hex)"
|
|
14
|
-
},
|
|
15
|
-
"status": {
|
|
16
|
-
"index": true,
|
|
17
|
-
"type": [
|
|
18
|
-
"pending",
|
|
19
|
-
"verified",
|
|
20
|
-
"failed",
|
|
21
|
-
"expired"
|
|
22
|
-
],
|
|
23
|
-
"default": "pending"
|
|
24
|
-
},
|
|
25
|
-
"purpose": {
|
|
26
|
-
"index": true,
|
|
27
|
-
"type": [
|
|
28
|
-
"signup",
|
|
29
|
-
"find_account",
|
|
30
|
-
"password_reset",
|
|
31
|
-
"adult_verify",
|
|
32
|
-
"identity_change"
|
|
33
|
-
],
|
|
34
|
-
"required": true
|
|
35
|
-
},
|
|
36
|
-
"provider": {
|
|
37
|
-
"index": true,
|
|
38
|
-
"type": [
|
|
39
|
-
"nice",
|
|
40
|
-
"kmc",
|
|
41
|
-
"danal"
|
|
42
|
-
],
|
|
43
|
-
"required": true
|
|
44
|
-
},
|
|
45
|
-
"ci_hash": {
|
|
46
|
-
"type": "string",
|
|
47
|
-
"comment": "CI의 SHA-256 해시 (중복 조회용)"
|
|
48
|
-
},
|
|
49
|
-
"di": {
|
|
50
|
-
"type": "string",
|
|
51
|
-
"comment": "DI 원문 (암호화 저장)"
|
|
52
|
-
},
|
|
53
|
-
"name": {
|
|
54
|
-
"type": "string",
|
|
55
|
-
"comment": "인증된 실명"
|
|
56
|
-
},
|
|
57
|
-
"birth_date": {
|
|
58
|
-
"type": "string",
|
|
59
|
-
"comment": "생년월일 (YYYYMMDD)"
|
|
60
|
-
},
|
|
61
|
-
"gender": {
|
|
62
|
-
"type": "string",
|
|
63
|
-
"comment": "성별 (M/F)"
|
|
64
|
-
},
|
|
65
|
-
"carrier": {
|
|
66
|
-
"type": "string",
|
|
67
|
-
"comment": "통신사 코드"
|
|
68
|
-
},
|
|
69
|
-
"phone": {
|
|
70
|
-
"type": "string",
|
|
71
|
-
"comment": "인증 휴대폰 번호"
|
|
72
|
-
},
|
|
73
|
-
"nationality": {
|
|
74
|
-
"type": "string",
|
|
75
|
-
"comment": "내/외국인 (local/foreign)"
|
|
76
|
-
},
|
|
77
|
-
"account_seq": {
|
|
78
|
-
"type": "int",
|
|
79
|
-
"comment": "연결된 계정 seq (인증 완료 후 설정)"
|
|
80
|
-
},
|
|
81
|
-
"ip_address": {
|
|
82
|
-
"type": "string",
|
|
83
|
-
"comment": "요청 IP 주소"
|
|
84
|
-
},
|
|
85
|
-
"user_agent": {
|
|
86
|
-
"type": "string",
|
|
87
|
-
"comment": "요청 User-Agent"
|
|
88
|
-
},
|
|
89
|
-
"verified_at": {
|
|
90
|
-
"type": "string",
|
|
91
|
-
"comment": "인증 완료 시각 (RFC3339)"
|
|
92
|
-
},
|
|
93
|
-
"expires_at": {
|
|
94
|
-
"type": "string",
|
|
95
|
-
"comment": "요청 만료 시각 (RFC3339)"
|
|
96
|
-
},
|
|
97
|
-
"error_message": {
|
|
98
|
-
"type": "string",
|
|
99
|
-
"comment": "실패 시 에러 메시지"
|
|
100
|
-
},
|
|
101
|
-
"raw_response": {
|
|
102
|
-
"type": "json",
|
|
103
|
-
"comment": "중계사 원본 응답 (디버깅용, 암호화)"
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "password_history",
|
|
3
|
-
"description": "비밀번호 변경 이력 (재사용 금지 정책용) 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
|
|
4
|
-
"hard_delete": true,
|
|
5
|
-
"fields": {
|
|
6
|
-
"account_seq": {
|
|
7
|
-
"index": true,
|
|
8
|
-
"comment": "계정 seq",
|
|
9
|
-
"type": "integer",
|
|
10
|
-
"required": true
|
|
11
|
-
},
|
|
12
|
-
"passwd_hash": {
|
|
13
|
-
"comment": "변경 시점의 비밀번호 해시 (salt 포함)"
|
|
14
|
-
},
|
|
15
|
-
"changed_time": {
|
|
16
|
-
"comment": "비밀번호 변경 시각"
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "alimtalk_log",
|
|
3
|
-
"description": "알림톡 발송 로그 — 워커가 소비하는 DB 큐 역할을 합니다. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
|
|
4
|
-
"history": false,
|
|
5
|
-
"read_only": true,
|
|
6
|
-
"compress": true,
|
|
7
|
-
"fields": {
|
|
8
|
-
"status": {
|
|
9
|
-
"index": true,
|
|
10
|
-
"type": [
|
|
11
|
-
"pending",
|
|
12
|
-
"processing",
|
|
13
|
-
"sent",
|
|
14
|
-
"delivered",
|
|
15
|
-
"failed",
|
|
16
|
-
"expired"
|
|
17
|
-
],
|
|
18
|
-
"default": "pending",
|
|
19
|
-
"comment": "발송 상태 (delivered = 프로바이더 수신 확인)"
|
|
20
|
-
},
|
|
21
|
-
"template_code": {
|
|
22
|
-
"index": true,
|
|
23
|
-
"comment": "카카오 알림톡 템플릿 코드",
|
|
24
|
-
"required": true
|
|
25
|
-
},
|
|
26
|
-
"receiver": {
|
|
27
|
-
"index": true,
|
|
28
|
-
"hash": true,
|
|
29
|
-
"comment": "수신자 전화번호",
|
|
30
|
-
"required": true
|
|
31
|
-
},
|
|
32
|
-
"alimtalk_msg_seq": {
|
|
33
|
-
"index": true,
|
|
34
|
-
"comment": "alimtalk_msg 참조 seq"
|
|
35
|
-
},
|
|
36
|
-
"template_name": {
|
|
37
|
-
"comment": "내부 템플릿 이름"
|
|
38
|
-
},
|
|
39
|
-
"variables_json": {
|
|
40
|
-
"type": "text",
|
|
41
|
-
"comment": "템플릿 변수 JSON"
|
|
42
|
-
},
|
|
43
|
-
"provider": {
|
|
44
|
-
"comment": "사용 프로바이더"
|
|
45
|
-
},
|
|
46
|
-
"provider_msg_id": {
|
|
47
|
-
"comment": "프로바이더 메시지 ID"
|
|
48
|
-
},
|
|
49
|
-
"error_message": {
|
|
50
|
-
"type": "text",
|
|
51
|
-
"comment": "오류 메시지"
|
|
52
|
-
},
|
|
53
|
-
"retry_count": {
|
|
54
|
-
"type": "uint",
|
|
55
|
-
"default": 0
|
|
56
|
-
},
|
|
57
|
-
"sent_at": {
|
|
58
|
-
"type": "string"
|
|
59
|
-
},
|
|
60
|
-
"delivered_at": {
|
|
61
|
-
"type": "string",
|
|
62
|
-
"comment": "프로바이더 수신 확인 시각"
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "alimtalk_msg",
|
|
3
|
-
"description": "알림톡 발송 트리거 엔티티 — Hook 또는 API를 통해 생성되면 알림톡 발송이 시작됩니다. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
|
|
4
|
-
"history": false,
|
|
5
|
-
"fields": {
|
|
6
|
-
"template_code": {
|
|
7
|
-
"index": true,
|
|
8
|
-
"comment": "카카오 알림톡 템플릿 코드",
|
|
9
|
-
"required": true
|
|
10
|
-
},
|
|
11
|
-
"receiver": {
|
|
12
|
-
"index": true,
|
|
13
|
-
"hash": true,
|
|
14
|
-
"comment": "수신자 전화번호",
|
|
15
|
-
"required": true
|
|
16
|
-
},
|
|
17
|
-
"status": {
|
|
18
|
-
"index": true,
|
|
19
|
-
"type": [
|
|
20
|
-
"pending",
|
|
21
|
-
"processing",
|
|
22
|
-
"sent",
|
|
23
|
-
"delivered",
|
|
24
|
-
"failed"
|
|
25
|
-
],
|
|
26
|
-
"default": "pending",
|
|
27
|
-
"comment": "발송 상태 (delivered = 프로바이더 수신 확인)"
|
|
28
|
-
},
|
|
29
|
-
"variables_json": {
|
|
30
|
-
"type": "text",
|
|
31
|
-
"comment": "템플릿 변수 JSON (#{key} 바인딩)"
|
|
32
|
-
},
|
|
33
|
-
"provider": {
|
|
34
|
-
"comment": "프로바이더 키 (빈 값이면 default)"
|
|
35
|
-
},
|
|
36
|
-
"ref_entity": {
|
|
37
|
-
"comment": "참조 엔티티 이름"
|
|
38
|
-
},
|
|
39
|
-
"ref_seq": {
|
|
40
|
-
"type": "int"
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
"hooks": {
|
|
44
|
-
"after_insert": [
|
|
45
|
-
{
|
|
46
|
-
"type": "alimtalk",
|
|
47
|
-
"alimtalk_receiver": "${new.receiver}",
|
|
48
|
-
"alimtalk_template_code": "${new.template_code}",
|
|
49
|
-
"alimtalk_variables": "${new.variables_json}"
|
|
50
|
-
}
|
|
51
|
-
]
|
|
52
|
-
}
|
|
53
|
-
}
|