create-entity-server 0.0.23 → 0.0.26
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/package.json +1 -1
- package/template/.env.example +12 -0
- package/template/configs/backup.json +46 -0
- package/template/configs/database.json +0 -159
- package/template/configs/database.json.example +186 -0
- package/template/configs/push.json +1 -2
- package/template/configs/server.json +1 -0
- package/template/configs/smtp.json +43 -0
- package/template/configs/storage.json +148 -0
- package/template/entities/README.md +7 -7
- package/template/samples/entities/README.md +2 -2
- package/template/scripts/generate-env-keys.sh +16 -0
package/package.json
CHANGED
package/template/.env.example
CHANGED
|
@@ -11,6 +11,10 @@ ENCRYPTION_KEY=your-32-char-hex-encryption-key-here
|
|
|
11
11
|
# 운영에서는 충분히 긴 랜덤 시크릿을 사용하세요.
|
|
12
12
|
JWT_SECRET=your-jwt-secret-here
|
|
13
13
|
|
|
14
|
+
# 백업 암호화 키 (backup.json의 ${BACKUP_ENCRYPT_KEY}와 매핑)
|
|
15
|
+
# 비워두면 암호화 비활성화. 설정 시 충분한 길이의 랜덤 문자열 권장.
|
|
16
|
+
# BACKUP_ENCRYPT_KEY=your-backup-encryption-key-here
|
|
17
|
+
|
|
14
18
|
# 서버 포트 (configs/server.json의 port를 오버라이드)
|
|
15
19
|
SERVER_PORT=47200
|
|
16
20
|
|
|
@@ -27,5 +31,13 @@ DB_NAME_PRODUCTION=your-production-db-name
|
|
|
27
31
|
DB_USER_PRODUCTION=your-production-db-user
|
|
28
32
|
DB_PASSWORD_PRODUCTION=your-production-db-password
|
|
29
33
|
|
|
34
|
+
# SMTP 이메일 (smtp.json에서 ${SMTP_USERNAME} 등으로 참조)
|
|
35
|
+
# SMTP_USERNAME=user@gmail.com
|
|
36
|
+
# SMTP_PASSWORD=your-app-specific-password
|
|
37
|
+
# SENDGRID_API_KEY=SG.xxxx...
|
|
38
|
+
# SES_SMTP_USERNAME=your-ses-smtp-username
|
|
39
|
+
# SES_SMTP_PASSWORD=your-ses-smtp-password
|
|
40
|
+
# MAILGUN_SMTP_PASSWORD=your-mailgun-smtp-password
|
|
41
|
+
|
|
30
42
|
# 푸시 알림 (push.json에서 ${FCM_PROJECT_ID} 등으로 참조 가능)
|
|
31
43
|
# FCM_PROJECT_ID=your-firebase-project-id
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"enabled": false,
|
|
3
|
+
|
|
4
|
+
"data": {
|
|
5
|
+
"enabled": true,
|
|
6
|
+
"schedule": "0 2 * * *",
|
|
7
|
+
"db_groups": ["default"],
|
|
8
|
+
"entities": {
|
|
9
|
+
"include": [],
|
|
10
|
+
"exclude": [],
|
|
11
|
+
"exclude_patterns": ["*_log"]
|
|
12
|
+
},
|
|
13
|
+
"include_history": false,
|
|
14
|
+
"format": "jsonl",
|
|
15
|
+
"compress": true,
|
|
16
|
+
"encrypt_passphrase": "${BACKUP_ENCRYPT_KEY}",
|
|
17
|
+
"batch_size": 500,
|
|
18
|
+
"max_concurrent_entities": 3,
|
|
19
|
+
"retention": {
|
|
20
|
+
"keep_count": 7,
|
|
21
|
+
"keep_days": 30
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
"files": {
|
|
26
|
+
"enabled": true,
|
|
27
|
+
"mode": "realtime",
|
|
28
|
+
"max_retries": 3,
|
|
29
|
+
"retry_interval_sec": 60
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
"schema": {
|
|
33
|
+
"enabled": true
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
"target": {
|
|
37
|
+
"storage_key": "s3-backup",
|
|
38
|
+
"prefix": "backups"
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
"notification": {
|
|
42
|
+
"on_success": false,
|
|
43
|
+
"on_failure": true,
|
|
44
|
+
"channels": ["log", "smtp"]
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -1,17 +1,6 @@
|
|
|
1
|
-
// ──────────────────────────────────────────────────────────────────────────
|
|
2
|
-
// database.json 설정 예시 (주석 포함 예시 전용 파일 — 실제 파일은 순수 JSON)
|
|
3
|
-
//
|
|
4
|
-
// "default" : 사용할 그룹 이름 (groups 키 중 하나)
|
|
5
|
-
// "groups" : 드라이버별 연결 설정 모음
|
|
6
|
-
// driver : "mysql" | "postgres" | "mongodb" | "dynamodb" |
|
|
7
|
-
// "firestore" | "scylladb" | "couchdb"
|
|
8
|
-
//
|
|
9
|
-
// 환경 변수 참조: "${ENV_VAR_NAME}" 형식으로 값을 주입합니다.
|
|
10
|
-
// ──────────────────────────────────────────────────────────────────────────
|
|
11
1
|
{
|
|
12
2
|
"default": "development",
|
|
13
3
|
"groups": {
|
|
14
|
-
// ── MySQL (SQL) ─────────────────────────────────────────────────
|
|
15
4
|
"development": {
|
|
16
5
|
"driver": "mysql",
|
|
17
6
|
"host": "${DB_HOST_DEVELOPMENT}",
|
|
@@ -33,154 +22,6 @@
|
|
|
33
22
|
"maxOpenConns": 50,
|
|
34
23
|
"maxIdleConns": 25,
|
|
35
24
|
"connMaxLifetimeSec": 3600
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
// ── MongoDB ─────────────────────────────────────────────────────
|
|
39
|
-
// URI 우선 사용. uri 가 없으면 host/port/database/username/password 조합.
|
|
40
|
-
"mongodb_dev": {
|
|
41
|
-
"driver": "mongodb",
|
|
42
|
-
"uri": "mongodb://localhost:27017/entity_dev",
|
|
43
|
-
"database": "entity_dev"
|
|
44
|
-
},
|
|
45
|
-
"mongodb_prod": {
|
|
46
|
-
"driver": "mongodb",
|
|
47
|
-
"host": "${MONGO_HOST}",
|
|
48
|
-
"port": 27017,
|
|
49
|
-
"database": "${MONGO_DB}",
|
|
50
|
-
"username": "${MONGO_USER}",
|
|
51
|
-
"password": "${MONGO_PASSWORD}",
|
|
52
|
-
"uri": ""
|
|
53
|
-
},
|
|
54
|
-
"mongodb_replica": {
|
|
55
|
-
"driver": "mongodb",
|
|
56
|
-
"uri": "mongodb://${MONGO_USER}:${MONGO_PASS}@mongo1:27017,mongo2:27017,mongo3:27017/${MONGO_DB}?replicaSet=rs0&authSource=admin",
|
|
57
|
-
"database": "${MONGO_DB}"
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
// ── Amazon DynamoDB ─────────────────────────────────────────────
|
|
61
|
-
// region 과 IAM 인증이 필요합니다.
|
|
62
|
-
// 로컬 테스트: endpoint 에 "http://localhost:8000" 지정.
|
|
63
|
-
"dynamodb_dev": {
|
|
64
|
-
"driver": "dynamodb",
|
|
65
|
-
"region": "ap-northeast-2",
|
|
66
|
-
"endpoint": "http://localhost:8000",
|
|
67
|
-
"access_key_id": "${AWS_ACCESS_KEY_ID}",
|
|
68
|
-
"secret_access_key": "${AWS_SECRET_ACCESS_KEY}"
|
|
69
|
-
},
|
|
70
|
-
"dynamodb_prod": {
|
|
71
|
-
"driver": "dynamodb",
|
|
72
|
-
"region": "${AWS_REGION}",
|
|
73
|
-
"access_key_id": "${AWS_ACCESS_KEY_ID}",
|
|
74
|
-
"secret_access_key": "${AWS_SECRET_ACCESS_KEY}"
|
|
75
|
-
},
|
|
76
|
-
|
|
77
|
-
// ── Google Cloud Firestore ──────────────────────────────────────
|
|
78
|
-
// GCP 프로젝트 ID 와 서비스 계정 JSON 파일(또는 ADC)이 필요합니다.
|
|
79
|
-
// credentials_file : 서비스 계정 키 파일 경로 (선택)
|
|
80
|
-
// ADC 자동 사용 시 credentials_file 생략 가능.
|
|
81
|
-
"firestore_dev": {
|
|
82
|
-
"driver": "firestore",
|
|
83
|
-
"project_id": "${GCP_PROJECT_ID}",
|
|
84
|
-
"credentials_file": "${GOOGLE_APPLICATION_CREDENTIALS}"
|
|
85
|
-
},
|
|
86
|
-
"firestore_prod": {
|
|
87
|
-
"driver": "firestore",
|
|
88
|
-
"project_id": "${GCP_PROJECT_ID}"
|
|
89
|
-
},
|
|
90
|
-
|
|
91
|
-
// ── ScyllaDB / Apache Cassandra ────────────────────────────────
|
|
92
|
-
// hosts 는 쉼표 구분 문자열 또는 배열 모두 허용합니다.
|
|
93
|
-
// keyspace 가 없으면 자동 생성됩니다.
|
|
94
|
-
"scylladb_dev": {
|
|
95
|
-
"driver": "scylladb",
|
|
96
|
-
"hosts": "localhost:9042",
|
|
97
|
-
"keyspace": "entity_dev",
|
|
98
|
-
"username": "",
|
|
99
|
-
"password": ""
|
|
100
|
-
},
|
|
101
|
-
"scylladb_prod": {
|
|
102
|
-
"driver": "scylladb",
|
|
103
|
-
"hosts": "${SCYLLA_HOSTS}",
|
|
104
|
-
"keyspace": "${SCYLLA_KEYSPACE}",
|
|
105
|
-
"username": "${SCYLLA_USER}",
|
|
106
|
-
"password": "${SCYLLA_PASSWORD}",
|
|
107
|
-
"consistency": "quorum",
|
|
108
|
-
"timeout": "10s"
|
|
109
|
-
},
|
|
110
|
-
|
|
111
|
-
// ── Apache CouchDB ──────────────────────────────────────────────
|
|
112
|
-
// URI 우선 사용. uri 가 없으면 host/port/username/password 조합.
|
|
113
|
-
// 포트 기본값: 5984
|
|
114
|
-
"couchdb_dev": {
|
|
115
|
-
"driver": "couchdb",
|
|
116
|
-
"host": "localhost",
|
|
117
|
-
"port": 5984,
|
|
118
|
-
"username": "admin",
|
|
119
|
-
"password": "password"
|
|
120
|
-
},
|
|
121
|
-
"couchdb_uri": {
|
|
122
|
-
"driver": "couchdb",
|
|
123
|
-
"uri": "http://admin:password@localhost:5984/"
|
|
124
|
-
},
|
|
125
|
-
"couchdb_prod": {
|
|
126
|
-
"driver": "couchdb",
|
|
127
|
-
"uri": "http://${COUCH_USER}:${COUCH_PASS}@${COUCH_HOST}:${COUCH_PORT}/"
|
|
128
25
|
}
|
|
129
26
|
}
|
|
130
27
|
}
|
|
131
|
-
|
|
132
|
-
// ──────────────────────────────────────────────────────────────────────────
|
|
133
|
-
// DataStore 단독 사용 — flat 형식 (groups 없이 최상위에 driver 직접 지정)
|
|
134
|
-
//
|
|
135
|
-
// SQL 없이 NoSQL DataStore만 단독으로 사용할 때는 groups 없이
|
|
136
|
-
// database.json 최상위에 driver 를 직접 지정합니다.
|
|
137
|
-
// store_loader.go 가 groups 키가 없고 NoSQL driver 인 경우에만 DataStore로 인식합니다.
|
|
138
|
-
// ──────────────────────────────────────────────────────────────────────────
|
|
139
|
-
|
|
140
|
-
// MongoDB flat 형식
|
|
141
|
-
{
|
|
142
|
-
"driver": "mongodb",
|
|
143
|
-
"uri": "mongodb://localhost:27017",
|
|
144
|
-
"database": "entity_server"
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// MongoDB — 환경변수 방식
|
|
148
|
-
{
|
|
149
|
-
"driver": "mongodb",
|
|
150
|
-
"host": "${MONGO_HOST}",
|
|
151
|
-
"port": "${MONGO_PORT}",
|
|
152
|
-
"username": "${MONGO_USER}",
|
|
153
|
-
"password": "${MONGO_PASSWORD}",
|
|
154
|
-
"database": "${MONGO_DATABASE}"
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// DynamoDB flat 형식
|
|
158
|
-
{
|
|
159
|
-
"driver": "dynamodb",
|
|
160
|
-
"region": "${AWS_REGION}",
|
|
161
|
-
"access_key_id": "${AWS_ACCESS_KEY_ID}",
|
|
162
|
-
"secret_access_key": "${AWS_SECRET_ACCESS_KEY}"
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Firestore flat 형식
|
|
166
|
-
{
|
|
167
|
-
"driver": "firestore",
|
|
168
|
-
"project_id": "${GCP_PROJECT_ID}",
|
|
169
|
-
"credentials_file": "${GOOGLE_APPLICATION_CREDENTIALS}"
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// ScyllaDB flat 형식
|
|
173
|
-
{
|
|
174
|
-
"driver": "scylladb",
|
|
175
|
-
"host": "${SCYLLA_HOST}",
|
|
176
|
-
"port": 9042,
|
|
177
|
-
"database": "${SCYLLA_KEYSPACE}",
|
|
178
|
-
"username": "${SCYLLA_USER}",
|
|
179
|
-
"password": "${SCYLLA_PASSWORD}"
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// CouchDB flat 형식
|
|
183
|
-
{
|
|
184
|
-
"driver": "couchdb",
|
|
185
|
-
"uri": "http://${COUCH_USER}:${COUCH_PASS}@${COUCH_HOST}:5984/"
|
|
186
|
-
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
2
|
+
// database.json 설정 예시 (주석 포함 예시 전용 파일 — 실제 파일은 순수 JSON)
|
|
3
|
+
//
|
|
4
|
+
// "default" : 사용할 그룹 이름 (groups 키 중 하나)
|
|
5
|
+
// "groups" : 드라이버별 연결 설정 모음
|
|
6
|
+
// driver : "mysql" | "postgres" | "mongodb" | "dynamodb" |
|
|
7
|
+
// "firestore" | "scylladb" | "couchdb"
|
|
8
|
+
//
|
|
9
|
+
// 환경 변수 참조: "${ENV_VAR_NAME}" 형식으로 값을 주입합니다.
|
|
10
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
11
|
+
{
|
|
12
|
+
"default": "development",
|
|
13
|
+
"groups": {
|
|
14
|
+
// ── MySQL (SQL) ─────────────────────────────────────────────────
|
|
15
|
+
"development": {
|
|
16
|
+
"driver": "mysql",
|
|
17
|
+
"host": "${DB_HOST_DEVELOPMENT}",
|
|
18
|
+
"port": "${DB_PORT_DEVELOPMENT}",
|
|
19
|
+
"database": "${DB_NAME_DEVELOPMENT}",
|
|
20
|
+
"user": "${DB_USER_DEVELOPMENT}",
|
|
21
|
+
"password": "${DB_PASSWORD_DEVELOPMENT}",
|
|
22
|
+
"maxOpenConns": 20,
|
|
23
|
+
"maxIdleConns": 10,
|
|
24
|
+
"connMaxLifetimeSec": 3600
|
|
25
|
+
},
|
|
26
|
+
"production": {
|
|
27
|
+
"driver": "mysql",
|
|
28
|
+
"host": "${DB_HOST_PRODUCTION}",
|
|
29
|
+
"port": "${DB_PORT_PRODUCTION}",
|
|
30
|
+
"database": "${DB_NAME_PRODUCTION}",
|
|
31
|
+
"user": "${DB_USER_PRODUCTION}",
|
|
32
|
+
"password": "${DB_PASSWORD_PRODUCTION}",
|
|
33
|
+
"maxOpenConns": 50,
|
|
34
|
+
"maxIdleConns": 25,
|
|
35
|
+
"connMaxLifetimeSec": 3600
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
// ── MongoDB ─────────────────────────────────────────────────────
|
|
39
|
+
// URI 우선 사용. uri 가 없으면 host/port/database/username/password 조합.
|
|
40
|
+
"mongodb_dev": {
|
|
41
|
+
"driver": "mongodb",
|
|
42
|
+
"uri": "mongodb://localhost:27017/entity_dev",
|
|
43
|
+
"database": "entity_dev"
|
|
44
|
+
},
|
|
45
|
+
"mongodb_prod": {
|
|
46
|
+
"driver": "mongodb",
|
|
47
|
+
"host": "${MONGO_HOST}",
|
|
48
|
+
"port": 27017,
|
|
49
|
+
"database": "${MONGO_DB}",
|
|
50
|
+
"username": "${MONGO_USER}",
|
|
51
|
+
"password": "${MONGO_PASSWORD}",
|
|
52
|
+
"uri": ""
|
|
53
|
+
},
|
|
54
|
+
"mongodb_replica": {
|
|
55
|
+
"driver": "mongodb",
|
|
56
|
+
"uri": "mongodb://${MONGO_USER}:${MONGO_PASS}@mongo1:27017,mongo2:27017,mongo3:27017/${MONGO_DB}?replicaSet=rs0&authSource=admin",
|
|
57
|
+
"database": "${MONGO_DB}"
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
// ── Amazon DynamoDB ─────────────────────────────────────────────
|
|
61
|
+
// region 과 IAM 인증이 필요합니다.
|
|
62
|
+
// 로컬 테스트: endpoint 에 "http://localhost:8000" 지정.
|
|
63
|
+
"dynamodb_dev": {
|
|
64
|
+
"driver": "dynamodb",
|
|
65
|
+
"region": "ap-northeast-2",
|
|
66
|
+
"endpoint": "http://localhost:8000",
|
|
67
|
+
"access_key_id": "${AWS_ACCESS_KEY_ID}",
|
|
68
|
+
"secret_access_key": "${AWS_SECRET_ACCESS_KEY}"
|
|
69
|
+
},
|
|
70
|
+
"dynamodb_prod": {
|
|
71
|
+
"driver": "dynamodb",
|
|
72
|
+
"region": "${AWS_REGION}",
|
|
73
|
+
"access_key_id": "${AWS_ACCESS_KEY_ID}",
|
|
74
|
+
"secret_access_key": "${AWS_SECRET_ACCESS_KEY}"
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
// ── Google Cloud Firestore ──────────────────────────────────────
|
|
78
|
+
// GCP 프로젝트 ID 와 서비스 계정 JSON 파일(또는 ADC)이 필요합니다.
|
|
79
|
+
// credentials_file : 서비스 계정 키 파일 경로 (선택)
|
|
80
|
+
// ADC 자동 사용 시 credentials_file 생략 가능.
|
|
81
|
+
"firestore_dev": {
|
|
82
|
+
"driver": "firestore",
|
|
83
|
+
"project_id": "${GCP_PROJECT_ID}",
|
|
84
|
+
"credentials_file": "${GOOGLE_APPLICATION_CREDENTIALS}"
|
|
85
|
+
},
|
|
86
|
+
"firestore_prod": {
|
|
87
|
+
"driver": "firestore",
|
|
88
|
+
"project_id": "${GCP_PROJECT_ID}"
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
// ── ScyllaDB / Apache Cassandra ────────────────────────────────
|
|
92
|
+
// hosts 는 쉼표 구분 문자열 또는 배열 모두 허용합니다.
|
|
93
|
+
// keyspace 가 없으면 자동 생성됩니다.
|
|
94
|
+
"scylladb_dev": {
|
|
95
|
+
"driver": "scylladb",
|
|
96
|
+
"hosts": "localhost:9042",
|
|
97
|
+
"keyspace": "entity_dev",
|
|
98
|
+
"username": "",
|
|
99
|
+
"password": ""
|
|
100
|
+
},
|
|
101
|
+
"scylladb_prod": {
|
|
102
|
+
"driver": "scylladb",
|
|
103
|
+
"hosts": "${SCYLLA_HOSTS}",
|
|
104
|
+
"keyspace": "${SCYLLA_KEYSPACE}",
|
|
105
|
+
"username": "${SCYLLA_USER}",
|
|
106
|
+
"password": "${SCYLLA_PASSWORD}",
|
|
107
|
+
"consistency": "quorum",
|
|
108
|
+
"timeout": "10s"
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
// ── Apache CouchDB ──────────────────────────────────────────────
|
|
112
|
+
// URI 우선 사용. uri 가 없으면 host/port/username/password 조합.
|
|
113
|
+
// 포트 기본값: 5984
|
|
114
|
+
"couchdb_dev": {
|
|
115
|
+
"driver": "couchdb",
|
|
116
|
+
"host": "localhost",
|
|
117
|
+
"port": 5984,
|
|
118
|
+
"username": "admin",
|
|
119
|
+
"password": "password"
|
|
120
|
+
},
|
|
121
|
+
"couchdb_uri": {
|
|
122
|
+
"driver": "couchdb",
|
|
123
|
+
"uri": "http://admin:password@localhost:5984/"
|
|
124
|
+
},
|
|
125
|
+
"couchdb_prod": {
|
|
126
|
+
"driver": "couchdb",
|
|
127
|
+
"uri": "http://${COUCH_USER}:${COUCH_PASS}@${COUCH_HOST}:${COUCH_PORT}/"
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
133
|
+
// DataStore 단독 사용 — flat 형식 (groups 없이 최상위에 driver 직접 지정)
|
|
134
|
+
//
|
|
135
|
+
// SQL 없이 NoSQL DataStore만 단독으로 사용할 때는 groups 없이
|
|
136
|
+
// database.json 최상위에 driver 를 직접 지정합니다.
|
|
137
|
+
// store_loader.go 가 groups 키가 없고 NoSQL driver 인 경우에만 DataStore로 인식합니다.
|
|
138
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
139
|
+
|
|
140
|
+
// MongoDB flat 형식
|
|
141
|
+
{
|
|
142
|
+
"driver": "mongodb",
|
|
143
|
+
"uri": "mongodb://localhost:27017",
|
|
144
|
+
"database": "entity_server"
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// MongoDB — 환경변수 방식
|
|
148
|
+
{
|
|
149
|
+
"driver": "mongodb",
|
|
150
|
+
"host": "${MONGO_HOST}",
|
|
151
|
+
"port": "${MONGO_PORT}",
|
|
152
|
+
"username": "${MONGO_USER}",
|
|
153
|
+
"password": "${MONGO_PASSWORD}",
|
|
154
|
+
"database": "${MONGO_DATABASE}"
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// DynamoDB flat 형식
|
|
158
|
+
{
|
|
159
|
+
"driver": "dynamodb",
|
|
160
|
+
"region": "${AWS_REGION}",
|
|
161
|
+
"access_key_id": "${AWS_ACCESS_KEY_ID}",
|
|
162
|
+
"secret_access_key": "${AWS_SECRET_ACCESS_KEY}"
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Firestore flat 형식
|
|
166
|
+
{
|
|
167
|
+
"driver": "firestore",
|
|
168
|
+
"project_id": "${GCP_PROJECT_ID}",
|
|
169
|
+
"credentials_file": "${GOOGLE_APPLICATION_CREDENTIALS}"
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// ScyllaDB flat 형식
|
|
173
|
+
{
|
|
174
|
+
"driver": "scylladb",
|
|
175
|
+
"host": "${SCYLLA_HOST}",
|
|
176
|
+
"port": 9042,
|
|
177
|
+
"database": "${SCYLLA_KEYSPACE}",
|
|
178
|
+
"username": "${SCYLLA_USER}",
|
|
179
|
+
"password": "${SCYLLA_PASSWORD}"
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// CouchDB flat 형식
|
|
183
|
+
{
|
|
184
|
+
"driver": "couchdb",
|
|
185
|
+
"uri": "http://${COUCH_USER}:${COUCH_PASS}@${COUCH_HOST}:5984/"
|
|
186
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"workers": 2,
|
|
3
3
|
"queue_size": 500,
|
|
4
4
|
"fcm": {
|
|
5
|
-
"enabled":
|
|
5
|
+
"enabled": false,
|
|
6
6
|
"type": "service_account",
|
|
7
7
|
"project_id": "your-firebase-project-id",
|
|
8
8
|
"private_key_id": "abc123def456...",
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
},
|
|
17
17
|
"apns": {
|
|
18
18
|
"enabled": false,
|
|
19
|
-
"_comment": "APNs 직접 전송 (미구현 - 예약)",
|
|
20
19
|
"key_file": "./configs/keys/apns.p8",
|
|
21
20
|
"key_id": "ABCDE12345",
|
|
22
21
|
"team_id": "FGHIJ67890",
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"enabled": false,
|
|
3
|
+
"default": "main",
|
|
4
|
+
"workers": 2,
|
|
5
|
+
"queue_size": 200,
|
|
6
|
+
"dispatch_interval_sec": 5,
|
|
7
|
+
"max_retries": 3,
|
|
8
|
+
|
|
9
|
+
"providers": {
|
|
10
|
+
"main": {
|
|
11
|
+
"host": "smtp.gmail.com",
|
|
12
|
+
"port": 587,
|
|
13
|
+
"username": "${SMTP_USERNAME}",
|
|
14
|
+
"password": "${SMTP_PASSWORD}",
|
|
15
|
+
"from": "noreply@example.com",
|
|
16
|
+
"from_name": "My Service",
|
|
17
|
+
"encryption": "starttls",
|
|
18
|
+
"auth": "plain",
|
|
19
|
+
"timeout_sec": 30,
|
|
20
|
+
"max_connections": 5
|
|
21
|
+
},
|
|
22
|
+
"transactional": {
|
|
23
|
+
"host": "smtp.sendgrid.net",
|
|
24
|
+
"port": 465,
|
|
25
|
+
"username": "apikey",
|
|
26
|
+
"password": "${SENDGRID_API_KEY}",
|
|
27
|
+
"from": "alerts@example.com",
|
|
28
|
+
"from_name": "My Service Alerts",
|
|
29
|
+
"encryption": "ssl",
|
|
30
|
+
"auth": "plain"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
"templates": {
|
|
35
|
+
"dir": "./configs/templates/email",
|
|
36
|
+
"default_layout": "layout.html"
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
"rate_limit": {
|
|
40
|
+
"per_minute": 0,
|
|
41
|
+
"per_hour": 0
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
{
|
|
2
|
+
"enabled": true,
|
|
3
|
+
"default": "local-main",
|
|
4
|
+
"max_file_size_mb": 20,
|
|
5
|
+
"storages": {
|
|
6
|
+
"local-main": {
|
|
7
|
+
"driver": "local",
|
|
8
|
+
"root": "./uploads"
|
|
9
|
+
},
|
|
10
|
+
|
|
11
|
+
"s3-aws": {
|
|
12
|
+
"driver": "s3",
|
|
13
|
+
"bucket": "my-entity-files",
|
|
14
|
+
"region": "ap-northeast-2",
|
|
15
|
+
"access_key": "${AWS_ACCESS_KEY_ID}",
|
|
16
|
+
"secret_key": "${AWS_SECRET_ACCESS_KEY}",
|
|
17
|
+
"prefix": "entity-files"
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
"s3-r2": {
|
|
21
|
+
"driver": "s3",
|
|
22
|
+
"bucket": "my-files",
|
|
23
|
+
"region": "auto",
|
|
24
|
+
"endpoint": "https://${CF_ACCOUNT_ID}.r2.cloudflarestorage.com",
|
|
25
|
+
"access_key": "${R2_ACCESS_KEY}",
|
|
26
|
+
"secret_key": "${R2_SECRET_KEY}",
|
|
27
|
+
"prefix": "",
|
|
28
|
+
"_comment": "Cloudflare R2 (S3 호환) — 이그레스 무료"
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
"s3-b2": {
|
|
32
|
+
"driver": "s3",
|
|
33
|
+
"bucket": "my-files",
|
|
34
|
+
"region": "us-west-004",
|
|
35
|
+
"endpoint": "https://s3.us-west-004.backblazeb2.com",
|
|
36
|
+
"access_key": "${B2_KEY_ID}",
|
|
37
|
+
"secret_key": "${B2_APP_KEY}",
|
|
38
|
+
"_comment": "Backblaze B2 (S3 호환) — S3 대비 1/4 가격"
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
"s3-wasabi": {
|
|
42
|
+
"driver": "s3",
|
|
43
|
+
"bucket": "my-files",
|
|
44
|
+
"region": "ap-northeast-2",
|
|
45
|
+
"endpoint": "https://s3.ap-northeast-2.wasabisys.com",
|
|
46
|
+
"access_key": "${WASABI_ACCESS_KEY}",
|
|
47
|
+
"secret_key": "${WASABI_SECRET_KEY}",
|
|
48
|
+
"_comment": "Wasabi (S3 호환) — 저가 hot storage"
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
"s3-do-spaces": {
|
|
52
|
+
"driver": "s3",
|
|
53
|
+
"bucket": "my-files",
|
|
54
|
+
"region": "sgp1",
|
|
55
|
+
"endpoint": "https://sgp1.digitaloceanspaces.com",
|
|
56
|
+
"access_key": "${DO_SPACES_KEY}",
|
|
57
|
+
"secret_key": "${DO_SPACES_SECRET}",
|
|
58
|
+
"_comment": "DigitalOcean Spaces (S3 호환)"
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
"s3-minio": {
|
|
62
|
+
"driver": "s3",
|
|
63
|
+
"bucket": "entity-files",
|
|
64
|
+
"region": "us-east-1",
|
|
65
|
+
"endpoint": "http://minio.internal:9000",
|
|
66
|
+
"access_key": "minioadmin",
|
|
67
|
+
"secret_key": "minioadmin",
|
|
68
|
+
"_comment": "MinIO (S3 호환) — 자체 호스팅"
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
"s3-ncloud": {
|
|
72
|
+
"driver": "s3",
|
|
73
|
+
"bucket": "my-files",
|
|
74
|
+
"region": "kr-standard",
|
|
75
|
+
"endpoint": "https://kr.object.ncloudstorage.com",
|
|
76
|
+
"access_key": "${NCLOUD_ACCESS_KEY}",
|
|
77
|
+
"secret_key": "${NCLOUD_SECRET_KEY}",
|
|
78
|
+
"_comment": "Naver Cloud Object Storage (S3 호환)"
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
"azure-example": {
|
|
82
|
+
"driver": "azure",
|
|
83
|
+
"container": "files",
|
|
84
|
+
"account_name": "${AZURE_STORAGE_ACCOUNT}",
|
|
85
|
+
"account_key": "${AZURE_STORAGE_KEY}",
|
|
86
|
+
"prefix": "entity-files"
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
"gcs-example": {
|
|
90
|
+
"driver": "gcs",
|
|
91
|
+
"bucket": "my-entity-files",
|
|
92
|
+
"credentials_file": "./configs/keys/gcp-sa.json",
|
|
93
|
+
"prefix": "entity-files",
|
|
94
|
+
"_comment": "GKE/Cloud Run에서는 credentials_file 불필요 (Workload Identity)"
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
"sftp-example": {
|
|
98
|
+
"driver": "sftp",
|
|
99
|
+
"host": "nas.company.com",
|
|
100
|
+
"port": 22,
|
|
101
|
+
"user": "backup",
|
|
102
|
+
"private_key_file": "./configs/keys/backup_rsa",
|
|
103
|
+
"root": "/volume1/entity-files",
|
|
104
|
+
"_comment": "NAS/온프레미스 서버 연동"
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
"swift-kt": {
|
|
108
|
+
"driver": "swift",
|
|
109
|
+
"auth_url": "https://ssproxy.ucloudbiz.olleh.com/identity/v3",
|
|
110
|
+
"container": "my-files",
|
|
111
|
+
"user": "${KT_USER}",
|
|
112
|
+
"password": "${KT_PASSWORD}",
|
|
113
|
+
"tenant_name": "${KT_TENANT}",
|
|
114
|
+
"domain_name": "Default",
|
|
115
|
+
"region": "kr1",
|
|
116
|
+
"_comment": "KT Cloud Storage (OpenStack Swift)"
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
"thumbnail": {
|
|
120
|
+
"enabled": true,
|
|
121
|
+
"auto_orient": true,
|
|
122
|
+
"sizes": {
|
|
123
|
+
"sm": {
|
|
124
|
+
"width": 160,
|
|
125
|
+
"height": 160
|
|
126
|
+
},
|
|
127
|
+
"md": {
|
|
128
|
+
"width": 480,
|
|
129
|
+
"height": 480
|
|
130
|
+
},
|
|
131
|
+
"lg": {
|
|
132
|
+
"width": 1024,
|
|
133
|
+
"height": 1024
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
"quality": 85
|
|
137
|
+
},
|
|
138
|
+
"quota": {
|
|
139
|
+
"default_limit_gb": 0,
|
|
140
|
+
"threshold_percent": 80,
|
|
141
|
+
"notify": ["log", "smtp"]
|
|
142
|
+
},
|
|
143
|
+
"gc": {
|
|
144
|
+
"enabled": true,
|
|
145
|
+
"orphan_threshold_hours": 24,
|
|
146
|
+
"cron": "0 3 * * *"
|
|
147
|
+
}
|
|
148
|
+
}
|
|
@@ -17,13 +17,13 @@
|
|
|
17
17
|
|
|
18
18
|
## 문서 바로가기
|
|
19
19
|
|
|
20
|
-
| 섹션
|
|
21
|
-
|
|
|
22
|
-
| [포함된 예제](#포함된-예제)
|
|
23
|
-
| [엔티티 설정 규칙](#엔티티-설정-규칙)
|
|
24
|
-
| [훅 (Hooks)](#훅-hooks)
|
|
25
|
-
| [라이선스 스코프](#라이선스-스코프란)
|
|
26
|
-
| [Entity Config Guide](../../docs/
|
|
20
|
+
| 섹션 | 내용 |
|
|
21
|
+
| -------------------------------------------------------------------- | ----------------------------------------- |
|
|
22
|
+
| [포함된 예제](#포함된-예제) | 각 예제 파일 상세 설명 |
|
|
23
|
+
| [엔티티 설정 규칙](#엔티티-설정-규칙) | 자동 추론 필드, Types, index 형식, 복합키 |
|
|
24
|
+
| [훅 (Hooks)](#훅-hooks) | SQL 훅, Entity 훅, 실행 시점, 템플릿 변수 |
|
|
25
|
+
| [라이선스 스코프](#라이선스-스코프란) | 멀티테넌트 / 단일 시스템 모드 |
|
|
26
|
+
| [Entity Config Guide](../../docs/guides/data/entity-config-guide.md) | 전체 엔티티 설정 레퍼런스 |
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
`entities/` 디렉토리에 배치하는 `.json` 설정 파일 예제 모음입니다.
|
|
4
4
|
엔티티 서버의 **모든 주요 기능을 하나씩** 알아볼 수 있도록 주제별로 구성하였습니다.
|
|
5
5
|
|
|
6
|
-
> **전체 레퍼런스**: [docs/
|
|
7
|
-
> **훅 가이드**: [docs/
|
|
6
|
+
> **전체 레퍼런스**: [docs/guides/data/entity-config-guide.md](../../docs/guides/data/entity-config-guide.md)
|
|
7
|
+
> **훅 가이드**: [docs/guides/extensions/hooks.md](../../docs/guides/extensions/hooks.md)
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -31,6 +31,11 @@ Options:
|
|
|
31
31
|
--export Print shell export format
|
|
32
32
|
--apply Apply values directly to project .env
|
|
33
33
|
|
|
34
|
+
Generated keys:
|
|
35
|
+
ENCRYPTION_KEY Master encryption key (32-byte hex)
|
|
36
|
+
JWT_SECRET JWT signing key (64-byte hex)
|
|
37
|
+
BACKUP_ENCRYPT_KEY Backup file encryption key (32-byte hex)
|
|
38
|
+
|
|
34
39
|
Examples:
|
|
35
40
|
./scripts/generate-env-keys.sh --create
|
|
36
41
|
./scripts/generate-env-keys.sh --export
|
|
@@ -53,6 +58,11 @@ ENCRYPTION_KEY, JWT_SECRET 랜덤 값을 생성합니다.
|
|
|
53
58
|
--export export 형식으로 출력
|
|
54
59
|
--apply 프로젝트 루트 .env 파일에 즉시 반영
|
|
55
60
|
|
|
61
|
+
생성 키:
|
|
62
|
+
ENCRYPTION_KEY 마스터 암호화 키 (32바이트 hex)
|
|
63
|
+
JWT_SECRET JWT 서명 키 (64바이트 hex)
|
|
64
|
+
BACKUP_ENCRYPT_KEY 백업 파일 암호화 키 (32바이트 hex)
|
|
65
|
+
|
|
56
66
|
예제:
|
|
57
67
|
./scripts/generate-env-keys.sh --create
|
|
58
68
|
./scripts/generate-env-keys.sh --export
|
|
@@ -106,17 +116,20 @@ gen_hex() {
|
|
|
106
116
|
|
|
107
117
|
ENCRYPTION_KEY="$(gen_hex 16)"
|
|
108
118
|
JWT_SECRET="$(gen_hex 32)"
|
|
119
|
+
BACKUP_ENCRYPT_KEY="$(gen_hex 16)"
|
|
109
120
|
|
|
110
121
|
if [[ "$OUTPUT_MODE" == "export" ]]; then
|
|
111
122
|
cat <<EOF
|
|
112
123
|
export ENCRYPTION_KEY=$ENCRYPTION_KEY
|
|
113
124
|
export JWT_SECRET=$JWT_SECRET
|
|
125
|
+
export BACKUP_ENCRYPT_KEY=$BACKUP_ENCRYPT_KEY
|
|
114
126
|
EOF
|
|
115
127
|
elif [[ "$OUTPUT_MODE" == "dotenv" ]]; then
|
|
116
128
|
cat <<EOF
|
|
117
129
|
# $( [ "$LANGUAGE" = "en" ] && echo "Copy & paste to .env" || echo ".env에 복사해서 붙여넣기" )
|
|
118
130
|
ENCRYPTION_KEY=$ENCRYPTION_KEY
|
|
119
131
|
JWT_SECRET=$JWT_SECRET
|
|
132
|
+
BACKUP_ENCRYPT_KEY=$BACKUP_ENCRYPT_KEY
|
|
120
133
|
EOF
|
|
121
134
|
else
|
|
122
135
|
# --apply
|
|
@@ -135,14 +148,17 @@ else
|
|
|
135
148
|
|
|
136
149
|
upsert_env_key "ENCRYPTION_KEY" "$ENCRYPTION_KEY"
|
|
137
150
|
upsert_env_key "JWT_SECRET" "$JWT_SECRET"
|
|
151
|
+
upsert_env_key "BACKUP_ENCRYPT_KEY" "$BACKUP_ENCRYPT_KEY"
|
|
138
152
|
|
|
139
153
|
if [ "$LANGUAGE" = "en" ]; then
|
|
140
154
|
echo "✓ Updated: $ENV_FILE"
|
|
141
155
|
echo " - ENCRYPTION_KEY"
|
|
142
156
|
echo " - JWT_SECRET"
|
|
157
|
+
echo " - BACKUP_ENCRYPT_KEY"
|
|
143
158
|
else
|
|
144
159
|
echo "✓ 업데이트 완료: $ENV_FILE"
|
|
145
160
|
echo " - ENCRYPTION_KEY"
|
|
146
161
|
echo " - JWT_SECRET"
|
|
162
|
+
echo " - BACKUP_ENCRYPT_KEY"
|
|
147
163
|
fi
|
|
148
164
|
fi
|