create-entity-server 0.0.9
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 +280 -0
- package/package.json +42 -0
- package/template/.env.example +14 -0
- package/template/configs/cache.json +22 -0
- package/template/configs/cors.json +7 -0
- package/template/configs/database.json +23 -0
- package/template/configs/jwt.json +7 -0
- package/template/configs/logging.json +45 -0
- package/template/configs/security.json +21 -0
- package/template/configs/server.json +10 -0
- package/template/entities/Account/account_audit.json +17 -0
- package/template/entities/Auth/account.json +60 -0
- package/template/entities/Auth/api_keys.json +26 -0
- package/template/entities/Auth/license.json +36 -0
- package/template/entities/Auth/rbac_roles.json +76 -0
- package/template/entities/README.md +380 -0
- package/template/entities/System/system_audit_log.json +65 -0
- package/template/entities/company.json +22 -0
- package/template/entities/product.json +36 -0
- package/template/entities/todo.json +16 -0
- package/template/samples/README.md +65 -0
- package/template/samples/flutter/lib/entity_server_client.dart +218 -0
- package/template/samples/flutter/pubspec.yaml +14 -0
- package/template/samples/java/EntityServerClient.java +304 -0
- package/template/samples/java/EntityServerExample.java +49 -0
- package/template/samples/kotlin/EntityServerClient.kt +194 -0
- package/template/samples/node/package.json +16 -0
- package/template/samples/node/src/EntityServerClient.js +246 -0
- package/template/samples/node/src/example.js +39 -0
- package/template/samples/php/ci4/Controllers/ProductController.php +141 -0
- package/template/samples/php/ci4/Libraries/EntityServer.php +260 -0
- package/template/samples/php/laravel/Http/Controllers/ProductController.php +62 -0
- package/template/samples/php/laravel/Services/EntityServerService.php +210 -0
- package/template/samples/python/entity_server.py +225 -0
- package/template/samples/python/example.py +50 -0
- package/template/samples/react/src/api/entityServerClient.ts +290 -0
- package/template/samples/react/src/example.tsx +127 -0
- package/template/samples/react/src/hooks/useEntity.ts +105 -0
- package/template/samples/swift/EntityServerClient.swift +221 -0
- package/template/scripts/api-key.ps1 +123 -0
- package/template/scripts/api-key.sh +130 -0
- package/template/scripts/cleanup-history.ps1 +69 -0
- package/template/scripts/cleanup-history.sh +54 -0
- package/template/scripts/cli.ps1 +24 -0
- package/template/scripts/cli.sh +27 -0
- package/template/scripts/entity.ps1 +70 -0
- package/template/scripts/entity.sh +72 -0
- package/template/scripts/generate-env-keys.ps1 +125 -0
- package/template/scripts/generate-env-keys.sh +148 -0
- package/template/scripts/install-systemd.sh +222 -0
- package/template/scripts/normalize-entities.ps1 +87 -0
- package/template/scripts/normalize-entities.sh +132 -0
- package/template/scripts/rbac-role.ps1 +124 -0
- package/template/scripts/rbac-role.sh +127 -0
- package/template/scripts/remove-systemd.sh +158 -0
- package/template/scripts/reset-all.ps1 +83 -0
- package/template/scripts/reset-all.sh +95 -0
- package/template/scripts/run.ps1 +239 -0
- package/template/scripts/run.sh +315 -0
- package/template/scripts/sync.ps1 +145 -0
- package/template/scripts/sync.sh +178 -0
- package/template/scripts/update-server.ps1 +117 -0
- package/template/scripts/update-server.sh +165 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Register entity-server as a systemd service using the current project path.
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
+
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
9
|
+
|
|
10
|
+
# Load language from .env
|
|
11
|
+
if [ -f "$PROJECT_ROOT/.env" ]; then
|
|
12
|
+
LANGUAGE=$(grep '^LANGUAGE=' "$PROJECT_ROOT/.env" | cut -d '=' -f2)
|
|
13
|
+
fi
|
|
14
|
+
LANGUAGE=${LANGUAGE:-ko}
|
|
15
|
+
|
|
16
|
+
SERVICE_NAME="entity-server"
|
|
17
|
+
RUN_USER="${SUDO_USER:-$(stat -c '%U' "$PROJECT_ROOT")}"
|
|
18
|
+
RUN_GROUP="$(id -gn "$RUN_USER" 2>/dev/null || true)"
|
|
19
|
+
START_NOW=true
|
|
20
|
+
INTERACTIVE=false
|
|
21
|
+
SERVER_CONFIG="$PROJECT_ROOT/configs/server.json"
|
|
22
|
+
|
|
23
|
+
load_namespace() {
|
|
24
|
+
local namespace=""
|
|
25
|
+
if [ -f "$SERVER_CONFIG" ]; then
|
|
26
|
+
namespace=$(sed -n 's/.*"namespace"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$SERVER_CONFIG" | head -n 1)
|
|
27
|
+
fi
|
|
28
|
+
namespace=$(echo "$namespace" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9_-]/-/g')
|
|
29
|
+
if [ -z "$namespace" ]; then
|
|
30
|
+
namespace="default"
|
|
31
|
+
fi
|
|
32
|
+
SERVICE_NAME="${namespace}-entity-server"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
load_namespace
|
|
36
|
+
|
|
37
|
+
show_help() {
|
|
38
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
39
|
+
echo "Install systemd service for Entity Server"
|
|
40
|
+
echo "========================================"
|
|
41
|
+
echo ""
|
|
42
|
+
echo "Usage: $0 [options]"
|
|
43
|
+
echo ""
|
|
44
|
+
echo "Options:"
|
|
45
|
+
echo " --user=<user> Service run user (default: project owner)"
|
|
46
|
+
echo " --group=<group> Service run group (default: user's primary group)"
|
|
47
|
+
echo " --no-start Enable only, do not start immediately"
|
|
48
|
+
echo ""
|
|
49
|
+
echo "Service name is auto-generated as '<namespace>-entity-server'."
|
|
50
|
+
echo "Run without arguments to enter interactive mode."
|
|
51
|
+
else
|
|
52
|
+
echo "Entity Server systemd 서비스 등록"
|
|
53
|
+
echo "==============================="
|
|
54
|
+
echo ""
|
|
55
|
+
echo "사용법: $0 [옵션]"
|
|
56
|
+
echo ""
|
|
57
|
+
echo "옵션:"
|
|
58
|
+
echo " --user=<사용자> 실행 사용자 (기본값: 프로젝트 소유자)"
|
|
59
|
+
echo " --group=<그룹> 실행 그룹 (기본값: 사용자 기본 그룹)"
|
|
60
|
+
echo " --no-start enable만 수행, 즉시 start 하지 않음"
|
|
61
|
+
echo ""
|
|
62
|
+
echo "서비스명은 '<namespace>-entity-server' 형식으로 자동 생성됩니다."
|
|
63
|
+
echo "인수 없이 실행하면 인터랙티브 모드로 진입합니다."
|
|
64
|
+
fi
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if [ $# -eq 0 ]; then
|
|
68
|
+
INTERACTIVE=true
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
for arg in "$@"; do
|
|
72
|
+
case "$arg" in
|
|
73
|
+
--user=*)
|
|
74
|
+
RUN_USER="${arg#*=}"
|
|
75
|
+
;;
|
|
76
|
+
--group=*)
|
|
77
|
+
RUN_GROUP="${arg#*=}"
|
|
78
|
+
;;
|
|
79
|
+
--no-start)
|
|
80
|
+
START_NOW=false
|
|
81
|
+
;;
|
|
82
|
+
*)
|
|
83
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
84
|
+
echo "❌ Unknown option: $arg"
|
|
85
|
+
echo " Service name is fixed: $SERVICE_NAME"
|
|
86
|
+
else
|
|
87
|
+
echo "❌ 알 수 없는 옵션: $arg"
|
|
88
|
+
echo " 서비스명은 자동 고정값입니다: $SERVICE_NAME"
|
|
89
|
+
fi
|
|
90
|
+
exit 1
|
|
91
|
+
;;
|
|
92
|
+
esac
|
|
93
|
+
done
|
|
94
|
+
|
|
95
|
+
if [ "$INTERACTIVE" = true ]; then
|
|
96
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
97
|
+
echo "[interactive] systemd service setup"
|
|
98
|
+
echo "service name: $SERVICE_NAME"
|
|
99
|
+
else
|
|
100
|
+
echo "[interactive] systemd 서비스 설정"
|
|
101
|
+
echo "서비스명: $SERVICE_NAME"
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
read -r -p "Run user [$RUN_USER]: " input
|
|
105
|
+
if [ -n "$input" ]; then
|
|
106
|
+
RUN_USER="$input"
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
if [ -z "$RUN_GROUP" ]; then
|
|
110
|
+
RUN_GROUP="$(id -gn "$RUN_USER" 2>/dev/null || true)"
|
|
111
|
+
fi
|
|
112
|
+
read -r -p "Run group [$RUN_GROUP]: " input
|
|
113
|
+
if [ -n "$input" ]; then
|
|
114
|
+
RUN_GROUP="$input"
|
|
115
|
+
fi
|
|
116
|
+
|
|
117
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
118
|
+
read -r -p "Start service now? [Y/n]: " input
|
|
119
|
+
else
|
|
120
|
+
read -r -p "서비스를 즉시 시작할까요? [Y/n]: " input
|
|
121
|
+
fi
|
|
122
|
+
input=$(echo "$input" | tr '[:upper:]' '[:lower:]')
|
|
123
|
+
if [ "$input" = "n" ] || [ "$input" = "no" ]; then
|
|
124
|
+
START_NOW=false
|
|
125
|
+
fi
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
if [ "$RUN_GROUP" = "" ]; then
|
|
129
|
+
RUN_GROUP="$(id -gn "$RUN_USER")"
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
if ! id -u "$RUN_USER" >/dev/null 2>&1; then
|
|
133
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
134
|
+
echo "❌ User not found: $RUN_USER"
|
|
135
|
+
else
|
|
136
|
+
echo "❌ 사용자를 찾을 수 없습니다: $RUN_USER"
|
|
137
|
+
fi
|
|
138
|
+
exit 1
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
if ! getent group "$RUN_GROUP" >/dev/null 2>&1; then
|
|
142
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
143
|
+
echo "❌ Group not found: $RUN_GROUP"
|
|
144
|
+
else
|
|
145
|
+
echo "❌ 그룹을 찾을 수 없습니다: $RUN_GROUP"
|
|
146
|
+
fi
|
|
147
|
+
exit 1
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
if [ ! -x "$PROJECT_ROOT/scripts/run.sh" ]; then
|
|
151
|
+
chmod +x "$PROJECT_ROOT/scripts/run.sh"
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
if [ ! -f "$PROJECT_ROOT/bin/entity-server" ]; then
|
|
155
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
156
|
+
echo "❌ bin/entity-server not found"
|
|
157
|
+
echo "Run ./scripts/build.sh first."
|
|
158
|
+
else
|
|
159
|
+
echo "❌ bin/entity-server 파일이 없습니다"
|
|
160
|
+
echo "먼저 ./scripts/build.sh 를 실행하세요."
|
|
161
|
+
fi
|
|
162
|
+
exit 1
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
UNIT_PATH="/etc/systemd/system/${SERVICE_NAME}.service"
|
|
166
|
+
|
|
167
|
+
if [ "$EUID" -ne 0 ]; then
|
|
168
|
+
if command -v sudo >/dev/null 2>&1; then
|
|
169
|
+
SUDO_ARGS=("--user=$RUN_USER" "--group=$RUN_GROUP")
|
|
170
|
+
if [ "$START_NOW" = false ]; then
|
|
171
|
+
SUDO_ARGS+=("--no-start")
|
|
172
|
+
fi
|
|
173
|
+
exec sudo "$0" "${SUDO_ARGS[@]}"
|
|
174
|
+
fi
|
|
175
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
176
|
+
echo "❌ This script requires root privileges"
|
|
177
|
+
else
|
|
178
|
+
echo "❌ 이 스크립트는 root 권한이 필요합니다"
|
|
179
|
+
fi
|
|
180
|
+
exit 1
|
|
181
|
+
fi
|
|
182
|
+
|
|
183
|
+
cat > "$UNIT_PATH" <<EOF
|
|
184
|
+
[Unit]
|
|
185
|
+
Description=Entity Server
|
|
186
|
+
After=network.target
|
|
187
|
+
|
|
188
|
+
[Service]
|
|
189
|
+
Type=simple
|
|
190
|
+
User=$RUN_USER
|
|
191
|
+
Group=$RUN_GROUP
|
|
192
|
+
WorkingDirectory=$PROJECT_ROOT
|
|
193
|
+
EnvironmentFile=-$PROJECT_ROOT/.env
|
|
194
|
+
ExecStart=$PROJECT_ROOT/scripts/run.sh start
|
|
195
|
+
Restart=always
|
|
196
|
+
RestartSec=3
|
|
197
|
+
LimitNOFILE=65535
|
|
198
|
+
|
|
199
|
+
[Install]
|
|
200
|
+
WantedBy=multi-user.target
|
|
201
|
+
EOF
|
|
202
|
+
|
|
203
|
+
systemctl daemon-reload
|
|
204
|
+
systemctl enable "$SERVICE_NAME"
|
|
205
|
+
|
|
206
|
+
if [ "$START_NOW" = true ]; then
|
|
207
|
+
systemctl restart "$SERVICE_NAME"
|
|
208
|
+
fi
|
|
209
|
+
|
|
210
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
211
|
+
echo "✅ Service registered: $SERVICE_NAME"
|
|
212
|
+
echo " Unit: $UNIT_PATH"
|
|
213
|
+
echo " Start: sudo systemctl start $SERVICE_NAME"
|
|
214
|
+
echo " Stop: sudo systemctl stop $SERVICE_NAME"
|
|
215
|
+
echo " Status: sudo systemctl status $SERVICE_NAME"
|
|
216
|
+
else
|
|
217
|
+
echo "✅ 서비스 등록 완료: $SERVICE_NAME"
|
|
218
|
+
echo " Unit: $UNIT_PATH"
|
|
219
|
+
echo " 시작: sudo systemctl start $SERVICE_NAME"
|
|
220
|
+
echo " 중지: sudo systemctl stop $SERVICE_NAME"
|
|
221
|
+
echo " 상태: sudo systemctl status $SERVICE_NAME"
|
|
222
|
+
fi
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# normalize-entities.ps1 — 엔티티 JSON 정규화
|
|
2
|
+
#
|
|
3
|
+
# 사용법:
|
|
4
|
+
# .\scripts\normalize-entities.ps1 # 도움말
|
|
5
|
+
# .\scripts\normalize-entities.ps1 -Apply # 전체 정규화
|
|
6
|
+
# .\scripts\normalize-entities.ps1 -Entity account # account dry-run
|
|
7
|
+
# .\scripts\normalize-entities.ps1 -Entity account -Apply # account 정규화
|
|
8
|
+
|
|
9
|
+
param(
|
|
10
|
+
[string]$Entity = "",
|
|
11
|
+
[switch]$Apply
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
$ErrorActionPreference = "Stop"
|
|
15
|
+
|
|
16
|
+
$ProjectRoot = Split-Path -Parent $PSScriptRoot
|
|
17
|
+
Set-Location $ProjectRoot
|
|
18
|
+
|
|
19
|
+
# LANGUAGE 로드
|
|
20
|
+
$Lang = $env:LANGUAGE
|
|
21
|
+
if (-not $Lang) {
|
|
22
|
+
$EnvFile = Join-Path $ProjectRoot ".env"
|
|
23
|
+
if (Test-Path $EnvFile) {
|
|
24
|
+
$line = Get-Content $EnvFile | Where-Object { $_ -match '^LANGUAGE=' } | Select-Object -Last 1
|
|
25
|
+
if ($line) { $Lang = $line -replace '^LANGUAGE=', '' }
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (-not $Lang) { $Lang = "ko" }
|
|
29
|
+
|
|
30
|
+
function Show-Help {
|
|
31
|
+
if ($Lang -eq "en") {
|
|
32
|
+
Write-Host "Normalize Entity JSON"
|
|
33
|
+
Write-Host "====================="
|
|
34
|
+
Write-Host ""
|
|
35
|
+
Write-Host "Remove redundant default values and reorder keys in entity JSON files."
|
|
36
|
+
Write-Host "Also auto-creates missing required entities (api_keys, rbac_roles, and account/user when JWT is enabled)."
|
|
37
|
+
Write-Host ""
|
|
38
|
+
Write-Host "Usage: .\scripts\normalize-entities.ps1 [-Entity <name>] [-Apply]"
|
|
39
|
+
Write-Host ""
|
|
40
|
+
Write-Host "Options:"
|
|
41
|
+
Write-Host " -Apply Apply changes (default is dry-run)"
|
|
42
|
+
Write-Host " -Entity <name> Normalize a single entity only"
|
|
43
|
+
Write-Host ""
|
|
44
|
+
Write-Host "Examples:"
|
|
45
|
+
Write-Host " .\scripts\normalize-entities.ps1 # Dry-run all"
|
|
46
|
+
Write-Host " .\scripts\normalize-entities.ps1 -Apply # Normalize all"
|
|
47
|
+
Write-Host " .\scripts\normalize-entities.ps1 -Entity account # Dry-run account"
|
|
48
|
+
Write-Host " .\scripts\normalize-entities.ps1 -Entity account -Apply # Normalize account"
|
|
49
|
+
} else {
|
|
50
|
+
Write-Host "엔티티 JSON 정규화"
|
|
51
|
+
Write-Host "=================="
|
|
52
|
+
Write-Host ""
|
|
53
|
+
Write-Host "엔티티 JSON 파일에서 불필요한 기본값을 제거하고 키 순서를 정렬합니다."
|
|
54
|
+
Write-Host "전체 모드에서는 필수 엔티티(api_keys, rbac_roles, JWT 사용 시 account/user)가 없으면 자동 생성합니다."
|
|
55
|
+
Write-Host ""
|
|
56
|
+
Write-Host "사용법: .\scripts\normalize-entities.ps1 [-Entity <이름>] [-Apply]"
|
|
57
|
+
Write-Host ""
|
|
58
|
+
Write-Host "옵션:"
|
|
59
|
+
Write-Host " -Apply 실제 파일 수정 (기본은 dry-run)"
|
|
60
|
+
Write-Host " -Entity <이름> 단일 엔티티만 정규화"
|
|
61
|
+
Write-Host ""
|
|
62
|
+
Write-Host "예제:"
|
|
63
|
+
Write-Host " .\scripts\normalize-entities.ps1 # 전체 dry-run"
|
|
64
|
+
Write-Host " .\scripts\normalize-entities.ps1 -Apply # 전체 정규화"
|
|
65
|
+
Write-Host " .\scripts\normalize-entities.ps1 -Entity account # account dry-run"
|
|
66
|
+
Write-Host " .\scripts\normalize-entities.ps1 -Entity account -Apply # account 정규화"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
# 인자 없으면 도움말
|
|
71
|
+
if (-not $Apply -and -not $Entity) {
|
|
72
|
+
Show-Help
|
|
73
|
+
exit 0
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
$CliBin = Join-Path $ProjectRoot "entity-cli.exe"
|
|
77
|
+
if (-not (Test-Path $CliBin)) {
|
|
78
|
+
if ($Lang -eq "en") { Write-Error "❌ entity-cli.exe not found. Run scripts\build.sh first." }
|
|
79
|
+
else { Write-Error "❌ entity-cli.exe 파일이 없습니다. scripts\build.sh 를 먼저 실행하세요." }
|
|
80
|
+
exit 1
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
$Args = @("normalize-entities")
|
|
84
|
+
if ($Entity) { $Args += "--entity=$Entity" }
|
|
85
|
+
if ($Apply) { $Args += "--apply" }
|
|
86
|
+
|
|
87
|
+
& $CliBin @Args
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# 엔티티 JSON 파일 정규화 (기본값 제거, 키 순서 정렬)
|
|
4
|
+
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
7
|
+
|
|
8
|
+
cd "$PROJECT_ROOT"
|
|
9
|
+
|
|
10
|
+
# Load language from .env
|
|
11
|
+
if [ -f .env ]; then
|
|
12
|
+
LANGUAGE=$(grep '^LANGUAGE=' .env | cut -d '=' -f2)
|
|
13
|
+
fi
|
|
14
|
+
LANGUAGE=${LANGUAGE:-ko}
|
|
15
|
+
|
|
16
|
+
# 인자 없이 실행하면 도움말 표시
|
|
17
|
+
if [ $# -eq 0 ]; then
|
|
18
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
19
|
+
echo "Normalize Entity JSON"
|
|
20
|
+
echo "====================="
|
|
21
|
+
echo ""
|
|
22
|
+
echo "Remove redundant default values and reorder keys in entity JSON files."
|
|
23
|
+
echo "Also auto-creates missing required entities (api_keys, rbac_roles, and account/user when JWT is enabled)."
|
|
24
|
+
echo ""
|
|
25
|
+
echo "Usage: $0 [options]"
|
|
26
|
+
echo ""
|
|
27
|
+
echo "Options:"
|
|
28
|
+
echo " --apply Apply changes (default is dry-run)"
|
|
29
|
+
echo " --entity=<name> Normalize a single entity only"
|
|
30
|
+
echo ""
|
|
31
|
+
echo "Normalization rules:"
|
|
32
|
+
echo " - Remove enabled:true (default)"
|
|
33
|
+
echo " - Remove hard_delete:false (default)"
|
|
34
|
+
echo " - Remove optimistic_lock:false (default)"
|
|
35
|
+
echo " - Remove optimistic_lock:true when global_optimistic_lock=true"
|
|
36
|
+
echo " - Remove license_scope:true when global_license_scope=true"
|
|
37
|
+
echo " - Remove cache.enabled:true (default within cache block)"
|
|
38
|
+
echo " - Remove explicit fk entries auto-inferred from *_seq (e.g. user_seq: user.seq)"
|
|
39
|
+
echo " - Remove explicit types entries when equal to inferred field type"
|
|
40
|
+
echo " - Reorder index field keys to canonical order"
|
|
41
|
+
echo " - Reorder top-level keys to canonical order"
|
|
42
|
+
echo ""
|
|
43
|
+
echo "Required entities (auto-created if missing, full mode only):"
|
|
44
|
+
echo " - api_keys → entities/Auth/api_keys.json"
|
|
45
|
+
echo " - rbac_roles → entities/Auth/rbac_roles.json"
|
|
46
|
+
echo " - account → entities/Auth/account.json (JWT enabled only)"
|
|
47
|
+
echo " - user → entities/User/user.json (JWT enabled only)"
|
|
48
|
+
echo ""
|
|
49
|
+
echo "Examples:"
|
|
50
|
+
echo " $0 # Dry-run all entities"
|
|
51
|
+
echo " $0 --apply # Normalize all + create missing required entities"
|
|
52
|
+
echo " $0 --entity=account # Dry-run for account entity"
|
|
53
|
+
echo " $0 --entity=account --apply # Normalize account entity"
|
|
54
|
+
else
|
|
55
|
+
echo "엔티티 JSON 정규화"
|
|
56
|
+
echo "=================="
|
|
57
|
+
echo ""
|
|
58
|
+
echo "엔티티 JSON 파일에서 불필요한 기본값을 제거하고 키 순서를 정렬합니다."
|
|
59
|
+
echo "전체 모드에서는 필수 엔티티(api_keys, rbac_roles, JWT 사용 시 account/user)가 없으면 자동 생성합니다."
|
|
60
|
+
echo ""
|
|
61
|
+
echo "사용법: $0 [옵션]"
|
|
62
|
+
echo ""
|
|
63
|
+
echo "옵션:"
|
|
64
|
+
echo " --apply 실제 파일 수정 (기본은 dry-run)"
|
|
65
|
+
echo " --entity=<이름> 단일 엔티티만 정규화"
|
|
66
|
+
echo ""
|
|
67
|
+
echo "정규화 규칙:"
|
|
68
|
+
echo " - enabled:true 제거 (기본값)"
|
|
69
|
+
echo " - hard_delete:false 제거 (기본값)"
|
|
70
|
+
echo " - optimistic_lock:false 제거 (기본값)"
|
|
71
|
+
echo " - optimistic_lock:true 제거 (전역 설정과 동일할 경우)"
|
|
72
|
+
echo " - license_scope:true 제거 (전역 설정과 동일할 경우)"
|
|
73
|
+
echo " - cache.enabled:true 제거 (cache 블록 내 기본값)"
|
|
74
|
+
echo " - *_seq 자동추론과 동일한 명시 fk 제거 (예: user_seq: user.seq)"
|
|
75
|
+
echo " - 자동추론 타입과 동일한 types 명시 제거"
|
|
76
|
+
echo " - index 필드 키 순서 정규화"
|
|
77
|
+
echo " - 최상위 키 순서 정규화"
|
|
78
|
+
echo ""
|
|
79
|
+
echo "필수 엔티티 자동 생성 (전체 모드, 없을 경우):"
|
|
80
|
+
echo " - api_keys → entities/Auth/api_keys.json"
|
|
81
|
+
echo " - rbac_roles → entities/Auth/rbac_roles.json"
|
|
82
|
+
echo " - account → entities/Auth/account.json (JWT 활성 시)"
|
|
83
|
+
echo " - user → entities/User/user.json (JWT 활성 시)"
|
|
84
|
+
echo ""
|
|
85
|
+
echo "예제:"
|
|
86
|
+
echo " $0 # 전체 엔티티 dry-run 미리보기"
|
|
87
|
+
echo " $0 --apply # 전체 정규화 + 필수 엔티티 없으면 생성"
|
|
88
|
+
echo " $0 --entity=account # account 엔티티 dry-run"
|
|
89
|
+
echo " $0 --entity=account --apply # account 엔티티 정규화"
|
|
90
|
+
fi
|
|
91
|
+
exit 0
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
# Require prebuilt CLI binary
|
|
95
|
+
if [ ! -f "$PROJECT_ROOT/bin/entity-cli" ]; then
|
|
96
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
97
|
+
echo "❌ bin/entity-cli not found. Run scripts/build.sh first."
|
|
98
|
+
else
|
|
99
|
+
echo "❌ bin/entity-cli 파일이 없습니다. scripts/build.sh 를 먼저 실행하세요."
|
|
100
|
+
fi
|
|
101
|
+
exit 1
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
APPLY_FLAG=""
|
|
105
|
+
ENTITY_FLAG=""
|
|
106
|
+
|
|
107
|
+
for arg in "$@"; do
|
|
108
|
+
case "$arg" in
|
|
109
|
+
--apply)
|
|
110
|
+
APPLY_FLAG="--apply"
|
|
111
|
+
;;
|
|
112
|
+
--entity=*)
|
|
113
|
+
ENTITY_FLAG="$arg"
|
|
114
|
+
;;
|
|
115
|
+
*)
|
|
116
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
117
|
+
echo "❌ Unknown option: $arg"
|
|
118
|
+
echo "Run '$0' with no arguments for usage"
|
|
119
|
+
else
|
|
120
|
+
echo "❌ 알 수 없는 옵션: $arg"
|
|
121
|
+
echo "'$0' 를 인자 없이 실행하면 사용법을 확인할 수 있습니다"
|
|
122
|
+
fi
|
|
123
|
+
exit 1
|
|
124
|
+
;;
|
|
125
|
+
esac
|
|
126
|
+
done
|
|
127
|
+
|
|
128
|
+
CMD=("$PROJECT_ROOT/bin/entity-cli" normalize-entities)
|
|
129
|
+
[ -n "$ENTITY_FLAG" ] && CMD+=("$ENTITY_FLAG")
|
|
130
|
+
[ -n "$APPLY_FLAG" ] && CMD+=("$APPLY_FLAG")
|
|
131
|
+
|
|
132
|
+
exec "${CMD[@]}"
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# RBAC Role Management Script (CLI mode) - Windows PowerShell
|
|
2
|
+
# Can be used even when the server is stopped.
|
|
3
|
+
param(
|
|
4
|
+
[Parameter(Position=0)]
|
|
5
|
+
[string]$SubCommand = ""
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
9
|
+
$ProjectRoot = Split-Path -Parent $ScriptDir
|
|
10
|
+
$BinPath = Join-Path $ProjectRoot "bin\entity-cli.exe"
|
|
11
|
+
|
|
12
|
+
Set-Location $ProjectRoot
|
|
13
|
+
|
|
14
|
+
# Load language from .env
|
|
15
|
+
$Language = "ko"
|
|
16
|
+
$EnvFile = Join-Path $ProjectRoot ".env"
|
|
17
|
+
if (Test-Path $EnvFile) {
|
|
18
|
+
$LangLine = Get-Content $EnvFile | Where-Object { $_ -match '^LANGUAGE=' } | Select-Object -First 1
|
|
19
|
+
if ($LangLine) { $Language = $LangLine -replace '^LANGUAGE=', '' }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function Show-Help {
|
|
23
|
+
if ($Language -eq "en") {
|
|
24
|
+
Write-Host "RBAC Role Management (CLI mode)"
|
|
25
|
+
Write-Host "================================"
|
|
26
|
+
Write-Host ""
|
|
27
|
+
Write-Host "Manage rbac_roles entity directly via CLI binary."
|
|
28
|
+
Write-Host "Server does NOT need to be running."
|
|
29
|
+
Write-Host ""
|
|
30
|
+
Write-Host "Usage: .\rbac-role.ps1 <subcommand> [options]"
|
|
31
|
+
Write-Host ""
|
|
32
|
+
Write-Host "Subcommands:"
|
|
33
|
+
Write-Host " list List RBAC roles"
|
|
34
|
+
Write-Host " add Create a new role"
|
|
35
|
+
Write-Host " delete Delete a role by name or seq"
|
|
36
|
+
Write-Host " help Show this help"
|
|
37
|
+
Write-Host ""
|
|
38
|
+
Write-Host "list options:"
|
|
39
|
+
Write-Host " --limit=<n> Max rows to show (default: 50)"
|
|
40
|
+
Write-Host ""
|
|
41
|
+
Write-Host "add options:"
|
|
42
|
+
Write-Host " --name=<name> Role name (required, unique)"
|
|
43
|
+
Write-Host ' --permissions=<j> Permissions JSON array (default: ["entity:read","entity:list"])'
|
|
44
|
+
Write-Host " --description=<t> Description"
|
|
45
|
+
Write-Host " --apply Execute (default is dry-run)"
|
|
46
|
+
Write-Host ""
|
|
47
|
+
Write-Host "delete options:"
|
|
48
|
+
Write-Host " --name=<name> Role name to delete"
|
|
49
|
+
Write-Host " --seq=<n> Role seq to delete"
|
|
50
|
+
Write-Host " --apply Execute (default is dry-run)"
|
|
51
|
+
Write-Host ""
|
|
52
|
+
Write-Host "Examples:"
|
|
53
|
+
Write-Host " .\rbac-role.ps1 list"
|
|
54
|
+
Write-Host ' .\rbac-role.ps1 add --name=readonly --permissions=["entity:read","entity:list"] --apply'
|
|
55
|
+
Write-Host ' .\rbac-role.ps1 add --name=fullaccess --permissions=["*"] --description="Full access" --apply'
|
|
56
|
+
Write-Host " .\rbac-role.ps1 delete --name=readonly --apply"
|
|
57
|
+
Write-Host " .\rbac-role.ps1 delete --seq=5 --apply"
|
|
58
|
+
} else {
|
|
59
|
+
Write-Host "RBAC 역할 관리 (CLI 모드)"
|
|
60
|
+
Write-Host "======================"
|
|
61
|
+
Write-Host ""
|
|
62
|
+
Write-Host "CLI 바이너리로 rbac_roles 엔티티를 직접 조작합니다."
|
|
63
|
+
Write-Host "서버가 실행 중이지 않아도 사용 가능합니다."
|
|
64
|
+
Write-Host ""
|
|
65
|
+
Write-Host "사용법: .\rbac-role.ps1 <하위명령> [옵션]"
|
|
66
|
+
Write-Host ""
|
|
67
|
+
Write-Host "하위 명령:"
|
|
68
|
+
Write-Host " list RBAC 역할 목록 조회"
|
|
69
|
+
Write-Host " add 새 역할 추가"
|
|
70
|
+
Write-Host " delete 역할 삭제 (이름 또는 seq 지정)"
|
|
71
|
+
Write-Host " help 도움말 출력"
|
|
72
|
+
Write-Host ""
|
|
73
|
+
Write-Host "list 옵션:"
|
|
74
|
+
Write-Host " --limit=<n> 최대 출력 행 수 (기본: 50)"
|
|
75
|
+
Write-Host ""
|
|
76
|
+
Write-Host "add 옵션:"
|
|
77
|
+
Write-Host " --name=<이름> 역할 이름 (필수, unique)"
|
|
78
|
+
Write-Host ' --permissions=<j> 권한 JSON 배열 (기본: ["entity:read","entity:list"])'
|
|
79
|
+
Write-Host " --description=<t> 설명"
|
|
80
|
+
Write-Host " --apply 실제 실행 (기본: dry-run)"
|
|
81
|
+
Write-Host ""
|
|
82
|
+
Write-Host "delete 옵션:"
|
|
83
|
+
Write-Host " --name=<이름> 삭제할 역할 이름"
|
|
84
|
+
Write-Host " --seq=<n> 삭제할 역할 seq"
|
|
85
|
+
Write-Host " --apply 실제 실행 (기본: dry-run)"
|
|
86
|
+
Write-Host ""
|
|
87
|
+
Write-Host "예제:"
|
|
88
|
+
Write-Host " .\rbac-role.ps1 list"
|
|
89
|
+
Write-Host ' .\rbac-role.ps1 add --name=readonly --permissions=["entity:read","entity:list"] --apply'
|
|
90
|
+
Write-Host ' .\rbac-role.ps1 add --name=fullaccess --permissions=["*"] --description="전체 권한" --apply'
|
|
91
|
+
Write-Host " .\rbac-role.ps1 delete --name=readonly --apply"
|
|
92
|
+
Write-Host " .\rbac-role.ps1 delete --seq=5 --apply"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (-not $SubCommand) {
|
|
97
|
+
Show-Help
|
|
98
|
+
exit 0
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (-not (Test-Path $BinPath)) {
|
|
102
|
+
if ($Language -eq "en") { Write-Host "X bin/entity-cli.exe not found. Run: .\scripts\build.ps1" }
|
|
103
|
+
else { Write-Host "X bin/entity-cli.exe 파일이 없습니다. 먼저 .\scripts\build.ps1 를 실행하세요." }
|
|
104
|
+
exit 1
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
$remainingArgs = $args
|
|
108
|
+
|
|
109
|
+
switch ($SubCommand) {
|
|
110
|
+
{ $_ -in @("list", "show", "add", "delete") } {
|
|
111
|
+
$env:ENTITY_CLI_NAME = "rbac-role"
|
|
112
|
+
& $BinPath rbac-role $SubCommand @remainingArgs
|
|
113
|
+
}
|
|
114
|
+
{ $_ -in @("help", "-h", "--help") } {
|
|
115
|
+
Show-Help
|
|
116
|
+
}
|
|
117
|
+
default {
|
|
118
|
+
if ($Language -eq "en") { Write-Host "X Unknown subcommand: $SubCommand" }
|
|
119
|
+
else { Write-Host "X 알 수 없는 하위 명령: $SubCommand" }
|
|
120
|
+
Write-Host ""
|
|
121
|
+
Show-Help
|
|
122
|
+
exit 1
|
|
123
|
+
}
|
|
124
|
+
}
|