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
|
@@ -22,10 +22,6 @@
|
|
|
22
22
|
"type": ["active", "inactive", "blocked", "dormant"],
|
|
23
23
|
"default": "active"
|
|
24
24
|
},
|
|
25
|
-
"user_seq": {
|
|
26
|
-
"index": true,
|
|
27
|
-
"comment": "사용자번호"
|
|
28
|
-
},
|
|
29
25
|
"max_session_cnt": {
|
|
30
26
|
"type": "uint"
|
|
31
27
|
},
|
|
@@ -50,26 +46,6 @@
|
|
|
50
46
|
"type": "bool",
|
|
51
47
|
"default": false,
|
|
52
48
|
"comment": "다음 로그인 시 비밀번호 변경 강제"
|
|
53
|
-
},
|
|
54
|
-
"name": {
|
|
55
|
-
"no_store": true,
|
|
56
|
-
"comment": "가입 요청 시 전달되는 이름. account에는 저장되지 않고 after_insert 훅(user 엔티티 생성 등)에서만 사용됩니다."
|
|
57
|
-
},
|
|
58
|
-
"phone": {
|
|
59
|
-
"no_store": true,
|
|
60
|
-
"comment": "가입 요청 시 전달되는 전화번호. no_store."
|
|
61
|
-
},
|
|
62
|
-
"birth_date": {
|
|
63
|
-
"no_store": true,
|
|
64
|
-
"comment": "가입 요청 시 전달되는 생년월일. no_store."
|
|
65
|
-
},
|
|
66
|
-
"gender": {
|
|
67
|
-
"no_store": true,
|
|
68
|
-
"comment": "가입 요청 시 전달되는 성별. no_store."
|
|
69
|
-
},
|
|
70
|
-
"profile_image": {
|
|
71
|
-
"no_store": true,
|
|
72
|
-
"comment": "가입 요청 시 전달되는 프로필 이미지. no_store."
|
|
73
49
|
}
|
|
74
50
|
},
|
|
75
51
|
"reset_defaults": [
|
|
@@ -129,21 +105,6 @@
|
|
|
129
105
|
"query": "INSERT INTO account_audit (account_seq, action, email, created_time) VALUES (?, ?, ?, NOW())",
|
|
130
106
|
"params": ["${new.seq}", "INSERT", "${new.email}"],
|
|
131
107
|
"required": true
|
|
132
|
-
},
|
|
133
|
-
{
|
|
134
|
-
"_comment": "가입 시 user 엔티티 자동 생성. enabled: true로 바꾸면 활성화됩니다. assign_seq_to로 account.user_seq에 자동 반영됩니다.",
|
|
135
|
-
"type": "submit",
|
|
136
|
-
"enabled": false,
|
|
137
|
-
"entity": "user",
|
|
138
|
-
"data": {
|
|
139
|
-
"account_seq": "${new.seq}",
|
|
140
|
-
"name": "${new.name}",
|
|
141
|
-
"phone": "${new.phone}",
|
|
142
|
-
"birth_date": "${new.birth_date}",
|
|
143
|
-
"gender": "${new.gender}",
|
|
144
|
-
"profile_image": "${new.profile_image}"
|
|
145
|
-
},
|
|
146
|
-
"assign_seq_to": "user_seq"
|
|
147
108
|
}
|
|
148
109
|
],
|
|
149
110
|
"after_update": [
|
|
@@ -152,22 +113,6 @@
|
|
|
152
113
|
"query": "INSERT INTO account_audit (account_seq, action, email, created_time) VALUES (?, ?, ?, NOW())",
|
|
153
114
|
"params": ["${new.seq}", "UPDATE", "${new.email}"],
|
|
154
115
|
"required": true
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
"_comment": "계정 업데이트 시 user 프로필 동기화. enabled: true로 바꾸면 활성화됩니다.",
|
|
158
|
-
"type": "submit",
|
|
159
|
-
"enabled": false,
|
|
160
|
-
"entity": "user",
|
|
161
|
-
"match": {
|
|
162
|
-
"account_seq": "${new.seq}"
|
|
163
|
-
},
|
|
164
|
-
"data": {
|
|
165
|
-
"name": "${new.name}",
|
|
166
|
-
"phone": "${new.phone}",
|
|
167
|
-
"birth_date": "${new.birth_date}",
|
|
168
|
-
"gender": "${new.gender}",
|
|
169
|
-
"profile_image": "${new.profile_image}"
|
|
170
|
-
}
|
|
171
116
|
}
|
|
172
117
|
],
|
|
173
118
|
"after_delete": [
|
|
@@ -179,15 +124,6 @@
|
|
|
179
124
|
}
|
|
180
125
|
],
|
|
181
126
|
"after_get": [
|
|
182
|
-
{
|
|
183
|
-
"type": "entity",
|
|
184
|
-
"entity": "user",
|
|
185
|
-
"action": "find",
|
|
186
|
-
"conditions": {
|
|
187
|
-
"seq": "${new.user_seq}"
|
|
188
|
-
},
|
|
189
|
-
"assign_to": "user_profile"
|
|
190
|
-
},
|
|
191
127
|
{
|
|
192
128
|
"type": "entity",
|
|
193
129
|
"entity": "account_device",
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "account_device",
|
|
3
|
-
"description": "계정 기기 정보 및 푸시 토큰 관리.
|
|
3
|
+
"description": "회원 계정 기기 정보 및 푸시 토큰 관리. account_seq로 계정과 연결되며 회원 전용으로 사용합니다. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
|
|
4
4
|
"license_scope": false,
|
|
5
5
|
"fields": {
|
|
6
6
|
"account_seq": {
|
|
7
7
|
"index": true,
|
|
8
|
-
"
|
|
8
|
+
"required": true,
|
|
9
|
+
"comment": "계정seq (회원 계정 필수)"
|
|
9
10
|
},
|
|
10
11
|
"id": {
|
|
11
12
|
"index": true,
|
|
@@ -19,24 +20,12 @@
|
|
|
19
20
|
},
|
|
20
21
|
"device_type": {
|
|
21
22
|
"comment": "기기유형",
|
|
22
|
-
"type": [
|
|
23
|
-
"mobile",
|
|
24
|
-
"tablet",
|
|
25
|
-
"desktop",
|
|
26
|
-
"watch"
|
|
27
|
-
],
|
|
23
|
+
"type": ["mobile", "tablet", "desktop", "watch"],
|
|
28
24
|
"default": "mobile"
|
|
29
25
|
},
|
|
30
26
|
"platform": {
|
|
31
27
|
"comment": "플랫폼",
|
|
32
|
-
"type": [
|
|
33
|
-
"android",
|
|
34
|
-
"ios",
|
|
35
|
-
"web",
|
|
36
|
-
"windows",
|
|
37
|
-
"macos",
|
|
38
|
-
"linux"
|
|
39
|
-
]
|
|
28
|
+
"type": ["android", "ios", "web", "windows", "macos", "linux"]
|
|
40
29
|
},
|
|
41
30
|
"browser": {
|
|
42
31
|
"comment": "브라우저"
|
|
@@ -55,10 +44,6 @@
|
|
|
55
44
|
"comment": "마지막IP주소"
|
|
56
45
|
}
|
|
57
46
|
},
|
|
58
|
-
"unique": [
|
|
59
|
-
|
|
60
|
-
"id",
|
|
61
|
-
"account_seq"
|
|
62
|
-
]
|
|
63
|
-
]
|
|
47
|
+
"unique": [["id", "account_seq"]],
|
|
48
|
+
"history": false
|
|
64
49
|
}
|
|
@@ -41,19 +41,14 @@
|
|
|
41
41
|
"language": {
|
|
42
42
|
"comment": "언어"
|
|
43
43
|
},
|
|
44
|
-
"
|
|
44
|
+
"account_seq": {
|
|
45
45
|
"index": true,
|
|
46
|
-
"comment": "
|
|
46
|
+
"comment": "계정번호"
|
|
47
47
|
},
|
|
48
48
|
"auth_method": {
|
|
49
49
|
"index": true,
|
|
50
50
|
"comment": "인증 방식",
|
|
51
|
-
"type": [
|
|
52
|
-
"password",
|
|
53
|
-
"oauth",
|
|
54
|
-
"2fa_totp",
|
|
55
|
-
"2fa_recovery"
|
|
56
|
-
],
|
|
51
|
+
"type": ["password", "oauth", "2fa_totp", "2fa_recovery"],
|
|
57
52
|
"default": "password"
|
|
58
53
|
},
|
|
59
54
|
"location_info": {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "anon_device",
|
|
3
|
+
"description": "비회원 디바이스 식별 및 사용 제한 집계. device_id 쿠키 값 기반으로 추적하며 익명 사용자 전용으로 사용합니다. 사용자 환경에 맞게 fields를 자유롭게 확장할 수 있습니다.",
|
|
4
|
+
"license_scope": false,
|
|
5
|
+
"fields": {
|
|
6
|
+
"id": {
|
|
7
|
+
"index": true,
|
|
8
|
+
"required": true,
|
|
9
|
+
"unique": true,
|
|
10
|
+
"comment": "익명 디바이스 ID (cookie/device_id)"
|
|
11
|
+
},
|
|
12
|
+
"calc_count": {
|
|
13
|
+
"index": true,
|
|
14
|
+
"type": "uint",
|
|
15
|
+
"default": 0,
|
|
16
|
+
"comment": "거리 계산 사용 횟수"
|
|
17
|
+
},
|
|
18
|
+
"first_seen_time": {
|
|
19
|
+
"comment": "최초 식별 시각"
|
|
20
|
+
},
|
|
21
|
+
"last_seen_time": {
|
|
22
|
+
"index": true,
|
|
23
|
+
"comment": "마지막 식별 시각"
|
|
24
|
+
},
|
|
25
|
+
"last_calc_time": {
|
|
26
|
+
"index": true,
|
|
27
|
+
"comment": "마지막 거리 계산 시각"
|
|
28
|
+
},
|
|
29
|
+
"blocked_until_time": {
|
|
30
|
+
"index": true,
|
|
31
|
+
"comment": "차단 해제 시각"
|
|
32
|
+
},
|
|
33
|
+
"last_ip_addr": {
|
|
34
|
+
"comment": "마지막 IP주소"
|
|
35
|
+
},
|
|
36
|
+
"device_type": {
|
|
37
|
+
"comment": "기기유형",
|
|
38
|
+
"type": ["mobile", "tablet", "desktop", "watch"],
|
|
39
|
+
"default": "mobile"
|
|
40
|
+
},
|
|
41
|
+
"platform": {
|
|
42
|
+
"comment": "플랫폼",
|
|
43
|
+
"type": ["android", "ios", "web", "windows", "macos", "linux"]
|
|
44
|
+
},
|
|
45
|
+
"browser": {
|
|
46
|
+
"comment": "브라우저"
|
|
47
|
+
},
|
|
48
|
+
"browser_version": {
|
|
49
|
+
"comment": "브라우저버전"
|
|
50
|
+
},
|
|
51
|
+
"user_agent": {
|
|
52
|
+
"comment": "User Agent"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"history": false
|
|
56
|
+
}
|
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
7
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
8
8
|
BIN_PATH="$PROJECT_ROOT/bin/entity-cli"
|
|
9
|
+
if [ ! -f "$BIN_PATH" ] && [ -f "$PROJECT_ROOT/entity-cli" ]; then
|
|
10
|
+
BIN_PATH="$PROJECT_ROOT/entity-cli"
|
|
11
|
+
fi
|
|
9
12
|
|
|
10
13
|
cd "$PROJECT_ROOT"
|
|
11
14
|
|
|
@@ -100,9 +103,9 @@ fi
|
|
|
100
103
|
# CLI 바이너리 존재 확인
|
|
101
104
|
if [ ! -f "$BIN_PATH" ]; then
|
|
102
105
|
if [ "$LANGUAGE" = "en" ]; then
|
|
103
|
-
echo "❌ bin/entity-cli
|
|
106
|
+
echo "❌ entity-cli not found (bin/entity-cli or ./entity-cli). Run: ./scripts/build.sh"
|
|
104
107
|
else
|
|
105
|
-
echo "❌ bin/entity-cli
|
|
108
|
+
echo "❌ entity-cli 파일이 없습니다 (bin/entity-cli 또는 ./entity-cli). 먼저 ./scripts/build.sh 를 실행하세요."
|
|
106
109
|
fi
|
|
107
110
|
exit 1
|
|
108
111
|
fi
|
|
@@ -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)
|
|
@@ -41,14 +46,14 @@ if [ $# -eq 0 ]; then
|
|
|
41
46
|
fi
|
|
42
47
|
|
|
43
48
|
# Require prebuilt CLI binary
|
|
44
|
-
if [ ! -f "$
|
|
49
|
+
if [ ! -f "$ENTITY_CLI_BIN" ]; then
|
|
45
50
|
if [ "$LANGUAGE" = "en" ]; then
|
|
46
|
-
echo "❌ bin/entity-cli
|
|
51
|
+
echo "❌ entity-cli not found (bin/entity-cli or ./entity-cli)"
|
|
47
52
|
else
|
|
48
|
-
echo "❌ bin/entity-cli
|
|
53
|
+
echo "❌ entity-cli 파일이 없습니다 (bin/entity-cli 또는 ./entity-cli)"
|
|
49
54
|
fi
|
|
50
55
|
exit 1
|
|
51
56
|
fi
|
|
52
57
|
|
|
53
58
|
# Pass-through to CLI
|
|
54
|
-
"$
|
|
59
|
+
"$ENTITY_CLI_BIN" cleanup-history "$@"
|
package/template/scripts/cli.sh
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
6
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
7
7
|
BIN_PATH="$PROJECT_ROOT/bin/entity-cli"
|
|
8
|
+
if [ ! -f "$BIN_PATH" ] && [ -f "$PROJECT_ROOT/entity-cli" ]; then
|
|
9
|
+
BIN_PATH="$PROJECT_ROOT/entity-cli"
|
|
10
|
+
fi
|
|
8
11
|
|
|
9
12
|
# Load language from .env
|
|
10
13
|
if [ -f "$PROJECT_ROOT/.env" ]; then
|
|
@@ -15,9 +18,9 @@ LANGUAGE=${LANGUAGE:-ko}
|
|
|
15
18
|
# Require prebuilt CLI binary
|
|
16
19
|
if [ ! -f "$BIN_PATH" ]; then
|
|
17
20
|
if [ "$LANGUAGE" = "en" ]; then
|
|
18
|
-
echo "❌ bin/entity-cli
|
|
21
|
+
echo "❌ entity-cli not found (bin/entity-cli or ./entity-cli)"
|
|
19
22
|
else
|
|
20
|
-
echo "❌ bin/entity-cli
|
|
23
|
+
echo "❌ entity-cli 파일이 없습니다 (bin/entity-cli 또는 ./entity-cli)"
|
|
21
24
|
fi
|
|
22
25
|
exit 1
|
|
23
26
|
fi
|
|
@@ -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)
|
|
@@ -59,14 +64,14 @@ if [ $# -eq 0 ]; then
|
|
|
59
64
|
fi
|
|
60
65
|
|
|
61
66
|
# Require prebuilt CLI binary
|
|
62
|
-
if [ ! -f "$
|
|
67
|
+
if [ ! -f "$ENTITY_CLI_BIN" ]; then
|
|
63
68
|
if [ "$LANGUAGE" = "en" ]; then
|
|
64
|
-
echo "❌ bin/entity-cli
|
|
69
|
+
echo "❌ entity-cli not found (bin/entity-cli or ./entity-cli)"
|
|
65
70
|
else
|
|
66
|
-
echo "❌ bin/entity-cli
|
|
71
|
+
echo "❌ entity-cli 파일이 없습니다 (bin/entity-cli 또는 ./entity-cli)"
|
|
67
72
|
fi
|
|
68
73
|
exit 1
|
|
69
74
|
fi
|
|
70
75
|
|
|
71
76
|
# Pass-through to CLI
|
|
72
|
-
"$
|
|
77
|
+
"$ENTITY_CLI_BIN" init-entity "$@"
|
|
@@ -19,6 +19,10 @@ RUN_GROUP="$(id -gn "$RUN_USER" 2>/dev/null || true)"
|
|
|
19
19
|
START_NOW=true
|
|
20
20
|
INTERACTIVE=false
|
|
21
21
|
SERVER_CONFIG="$PROJECT_ROOT/configs/server.json"
|
|
22
|
+
SERVER_BIN="$PROJECT_ROOT/bin/entity-server"
|
|
23
|
+
if [ ! -f "$SERVER_BIN" ] && [ -f "$PROJECT_ROOT/entity-server" ]; then
|
|
24
|
+
SERVER_BIN="$PROJECT_ROOT/entity-server"
|
|
25
|
+
fi
|
|
22
26
|
|
|
23
27
|
load_namespace() {
|
|
24
28
|
local namespace=""
|
|
@@ -151,12 +155,12 @@ if [ ! -x "$PROJECT_ROOT/scripts/run.sh" ]; then
|
|
|
151
155
|
chmod +x "$PROJECT_ROOT/scripts/run.sh"
|
|
152
156
|
fi
|
|
153
157
|
|
|
154
|
-
if [ ! -f "$
|
|
158
|
+
if [ ! -f "$SERVER_BIN" ]; then
|
|
155
159
|
if [ "$LANGUAGE" = "en" ]; then
|
|
156
|
-
echo "❌ bin/entity-server
|
|
160
|
+
echo "❌ entity-server not found (bin/entity-server or ./entity-server)"
|
|
157
161
|
echo "Run ./scripts/build.sh first."
|
|
158
162
|
else
|
|
159
|
-
echo "❌ bin/entity-server
|
|
163
|
+
echo "❌ entity-server 파일이 없습니다 (bin/entity-server 또는 ./entity-server)"
|
|
160
164
|
echo "먼저 ./scripts/build.sh 를 실행하세요."
|
|
161
165
|
fi
|
|
162
166
|
exit 1
|
|
@@ -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)
|
|
@@ -92,11 +97,11 @@ if [ $# -eq 0 ]; then
|
|
|
92
97
|
fi
|
|
93
98
|
|
|
94
99
|
# Require prebuilt CLI binary
|
|
95
|
-
if [ ! -f "$
|
|
100
|
+
if [ ! -f "$ENTITY_CLI_BIN" ]; then
|
|
96
101
|
if [ "$LANGUAGE" = "en" ]; then
|
|
97
|
-
echo "❌ bin/entity-cli
|
|
102
|
+
echo "❌ entity-cli not found (bin/entity-cli or ./entity-cli). Run scripts/build.sh first."
|
|
98
103
|
else
|
|
99
|
-
echo "❌ bin/entity-cli
|
|
104
|
+
echo "❌ entity-cli 파일이 없습니다 (bin/entity-cli 또는 ./entity-cli). scripts/build.sh 를 먼저 실행하세요."
|
|
100
105
|
fi
|
|
101
106
|
exit 1
|
|
102
107
|
fi
|
|
@@ -125,7 +130,7 @@ for arg in "$@"; do
|
|
|
125
130
|
esac
|
|
126
131
|
done
|
|
127
132
|
|
|
128
|
-
CMD=("$
|
|
133
|
+
CMD=("$ENTITY_CLI_BIN" normalize-entities)
|
|
129
134
|
[ -n "$ENTITY_FLAG" ] && CMD+=("$ENTITY_FLAG")
|
|
130
135
|
[ -n "$APPLY_FLAG" ] && CMD+=("$APPLY_FLAG")
|
|
131
136
|
|
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
6
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
7
7
|
BIN_PATH="$PROJECT_ROOT/bin/entity-cli"
|
|
8
|
+
if [ ! -f "$BIN_PATH" ] && [ -f "$PROJECT_ROOT/entity-cli" ]; then
|
|
9
|
+
BIN_PATH="$PROJECT_ROOT/entity-cli"
|
|
10
|
+
fi
|
|
8
11
|
|
|
9
12
|
cd "$PROJECT_ROOT"
|
|
10
13
|
|
|
@@ -97,9 +100,9 @@ fi
|
|
|
97
100
|
# CLI 바이너리 존재 확인
|
|
98
101
|
if [ ! -f "$BIN_PATH" ]; then
|
|
99
102
|
if [ "$LANGUAGE" = "en" ]; then
|
|
100
|
-
echo "❌ bin/entity-cli
|
|
103
|
+
echo "❌ entity-cli not found (bin/entity-cli or ./entity-cli). Run: ./scripts/build.sh"
|
|
101
104
|
else
|
|
102
|
-
echo "❌ bin/entity-cli
|
|
105
|
+
echo "❌ entity-cli 파일이 없습니다 (bin/entity-cli 또는 ./entity-cli). 먼저 ./scripts/build.sh 를 실행하세요."
|
|
103
106
|
fi
|
|
104
107
|
exit 1
|
|
105
108
|
fi
|
|
@@ -19,12 +19,86 @@ trap cleanup EXIT
|
|
|
19
19
|
|
|
20
20
|
cd "$PROJECT_ROOT"
|
|
21
21
|
|
|
22
|
+
ENTITY_CLI_BIN="$PROJECT_ROOT/bin/entity-cli"
|
|
23
|
+
if [ ! -f "$ENTITY_CLI_BIN" ] && [ -f "$PROJECT_ROOT/entity-cli" ]; then
|
|
24
|
+
ENTITY_CLI_BIN="$PROJECT_ROOT/entity-cli"
|
|
25
|
+
fi
|
|
26
|
+
|
|
22
27
|
# Load language from .env
|
|
23
28
|
if [ -f .env ]; then
|
|
24
29
|
LANGUAGE=$(grep '^LANGUAGE=' .env | cut -d '=' -f2 || true)
|
|
25
30
|
fi
|
|
26
31
|
LANGUAGE=${LANGUAGE:-ko}
|
|
27
32
|
|
|
33
|
+
get_env_value() {
|
|
34
|
+
local key="$1"
|
|
35
|
+
local value="${!key}"
|
|
36
|
+
|
|
37
|
+
if [ -n "$value" ]; then
|
|
38
|
+
echo "$value"
|
|
39
|
+
return
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
if [ -f .env ]; then
|
|
43
|
+
value=$(grep -E "^${key}=" .env | tail -n 1 | cut -d '=' -f2-)
|
|
44
|
+
echo "$value"
|
|
45
|
+
fi
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
get_database_default_group() {
|
|
49
|
+
grep -E '"default"[[:space:]]*:' "$PROJECT_ROOT/configs/database.json" \
|
|
50
|
+
| head -n 1 \
|
|
51
|
+
| sed -E 's/.*:[[:space:]]*"([^"]+)".*/\1/'
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
get_database_group_field() {
|
|
55
|
+
local group="$1"
|
|
56
|
+
local field="$2"
|
|
57
|
+
|
|
58
|
+
awk -v group="$group" -v field="$field" '
|
|
59
|
+
$0 ~ "^[[:space:]]*\"" group "\"[[:space:]]*:[[:space:]]*\\{" { in_group=1; next }
|
|
60
|
+
in_group && $0 ~ "^[[:space:]]*}" { exit }
|
|
61
|
+
in_group && $0 ~ "^[[:space:]]*\"" field "\"[[:space:]]*:" {
|
|
62
|
+
match($0, /"[^"]+"[[:space:]]*:[[:space:]]*"([^"]+)"/, arr)
|
|
63
|
+
if (arr[1] != "") {
|
|
64
|
+
print arr[1]
|
|
65
|
+
}
|
|
66
|
+
exit
|
|
67
|
+
}
|
|
68
|
+
' "$PROJECT_ROOT/configs/database.json"
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
resolve_database_name() {
|
|
72
|
+
local group="$1"
|
|
73
|
+
local raw_value
|
|
74
|
+
raw_value=$(get_database_group_field "$group" "database")
|
|
75
|
+
|
|
76
|
+
if [[ "$raw_value" =~ ^\$\{([A-Z0-9_]+)\}$ ]]; then
|
|
77
|
+
get_env_value "${BASH_REMATCH[1]}"
|
|
78
|
+
return
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
echo "$raw_value"
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
print_target_database() {
|
|
85
|
+
local group
|
|
86
|
+
local database_name
|
|
87
|
+
|
|
88
|
+
group=$(get_database_default_group)
|
|
89
|
+
database_name=$(resolve_database_name "$group")
|
|
90
|
+
|
|
91
|
+
echo ""
|
|
92
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
93
|
+
echo "Target database group: ${group:-<unknown>}"
|
|
94
|
+
echo "Target database name : ${database_name:-<unknown>}"
|
|
95
|
+
else
|
|
96
|
+
echo "대상 DB 그룹 : ${group:-<unknown>}"
|
|
97
|
+
echo "대상 DB 이름 : ${database_name:-<unknown>}"
|
|
98
|
+
fi
|
|
99
|
+
echo ""
|
|
100
|
+
}
|
|
101
|
+
|
|
28
102
|
# Show usage if no arguments
|
|
29
103
|
if [ $# -eq 0 ]; then
|
|
30
104
|
if [ "$LANGUAGE" = "en" ]; then
|
|
@@ -66,11 +140,11 @@ if [ $# -eq 0 ]; then
|
|
|
66
140
|
fi
|
|
67
141
|
|
|
68
142
|
# Require prebuilt CLI binary
|
|
69
|
-
if [ ! -f "$
|
|
143
|
+
if [ ! -f "$ENTITY_CLI_BIN" ]; then
|
|
70
144
|
if [ "$LANGUAGE" = "en" ]; then
|
|
71
|
-
echo "❌ bin/entity-cli
|
|
145
|
+
echo "❌ entity-cli not found (bin/entity-cli or ./entity-cli)"
|
|
72
146
|
else
|
|
73
|
-
echo "❌ bin/entity-cli
|
|
147
|
+
echo "❌ entity-cli 파일이 없습니다 (bin/entity-cli 또는 ./entity-cli)"
|
|
74
148
|
fi
|
|
75
149
|
exit 1
|
|
76
150
|
fi
|
|
@@ -78,9 +152,11 @@ fi
|
|
|
78
152
|
# Execute based on flag
|
|
79
153
|
case "$1" in
|
|
80
154
|
--dry-run)
|
|
81
|
-
|
|
155
|
+
print_target_database
|
|
156
|
+
"$ENTITY_CLI_BIN" reset-all
|
|
82
157
|
;;
|
|
83
158
|
--force|--apply)
|
|
159
|
+
print_target_database
|
|
84
160
|
# 필수 엔티티 없으면 자동 생성 (api_keys, rbac_roles, account, user)
|
|
85
161
|
if [ "$LANGUAGE" = "en" ]; then
|
|
86
162
|
echo "⚙️ Checking required entities..."
|
|
@@ -88,15 +164,16 @@ case "$1" in
|
|
|
88
164
|
echo "⚙️ 필수 엔티티 확인 중..."
|
|
89
165
|
fi
|
|
90
166
|
LANGUAGE="$LANGUAGE" "$SCRIPT_DIR/normalize-entities.sh" --apply
|
|
167
|
+
|
|
91
168
|
RESET_LOG=$(mktemp)
|
|
92
169
|
if [ "$1" = "--force" ]; then
|
|
93
170
|
set +e
|
|
94
|
-
"$
|
|
171
|
+
"$ENTITY_CLI_BIN" reset-all --apply --force 2>&1 | tee "$RESET_LOG"
|
|
95
172
|
RESET_STATUS=${PIPESTATUS[0]}
|
|
96
173
|
set -e
|
|
97
174
|
else
|
|
98
175
|
set +e
|
|
99
|
-
"$
|
|
176
|
+
"$ENTITY_CLI_BIN" reset-all --apply 2>&1 | tee "$RESET_LOG"
|
|
100
177
|
RESET_STATUS=${PIPESTATUS[0]}
|
|
101
178
|
set -e
|
|
102
179
|
fi
|
|
@@ -110,8 +187,8 @@ case "$1" in
|
|
|
110
187
|
fi
|
|
111
188
|
|
|
112
189
|
# 새로 생성된 API 키 조회 후 .env 업데이트
|
|
113
|
-
NEW_API_KEY=$("$
|
|
114
|
-
NEW_HMAC=$("$
|
|
190
|
+
NEW_API_KEY=$("$ENTITY_CLI_BIN" api-key show --seq=1 --reveal-secret 2>/dev/null | grep -E '^key_value' | awk '{print $NF}')
|
|
191
|
+
NEW_HMAC=$("$ENTITY_CLI_BIN" api-key show --seq=1 --reveal-secret 2>/dev/null | grep -E '^hmac_secret' | awk '{print $NF}')
|
|
115
192
|
|
|
116
193
|
if [ -n "$NEW_API_KEY" ] && [ -n "$NEW_HMAC" ]; then
|
|
117
194
|
echo ""
|
|
@@ -123,15 +200,16 @@ case "$1" in
|
|
|
123
200
|
echo " ENTITY_API_KEY = $NEW_API_KEY"
|
|
124
201
|
echo " ENTITY_HMAC_SECRET = $NEW_HMAC"
|
|
125
202
|
|
|
126
|
-
# 게이트웨이 .env 자동 업데이트 (같은
|
|
127
|
-
|
|
128
|
-
|
|
203
|
+
# 게이트웨이 .env 자동 업데이트 (개발 환경: entity-app-server/ 폴더가 같은 레벨에 있을 때만)
|
|
204
|
+
GW_DIR="$(dirname "$PROJECT_ROOT")/entity-app-server"
|
|
205
|
+
GW_ENV="$GW_DIR/.env"
|
|
206
|
+
if [ -d "$GW_DIR" ] && [ -f "$GW_ENV" ]; then
|
|
129
207
|
sed -i "s|^ENTITY_API_KEY=.*|ENTITY_API_KEY=$NEW_API_KEY|" "$GW_ENV"
|
|
130
208
|
sed -i "s|^ENTITY_HMAC_SECRET=.*|ENTITY_HMAC_SECRET=$NEW_HMAC|" "$GW_ENV"
|
|
131
209
|
if [ "$LANGUAGE" = "en" ]; then
|
|
132
|
-
echo " ✓ Updated:
|
|
210
|
+
echo " ✓ Updated: entity-app-server/.env"
|
|
133
211
|
else
|
|
134
|
-
echo " ✓ 업데이트 완료:
|
|
212
|
+
echo " ✓ 업데이트 완료: entity-app-server/.env"
|
|
135
213
|
fi
|
|
136
214
|
fi
|
|
137
215
|
fi
|