create-entity-server 0.0.27 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/package.json +1 -1
  2. package/template/configs/cache.json +2 -1
  3. package/template/configs/database.json +18 -7
  4. package/template/entities/README.md +3 -3
  5. package/template/entities/System/Address/addr_dong.json +10115 -0
  6. package/template/entities/System/Address/addr_sido.json +39 -0
  7. package/template/entities/System/Address/addr_sigungu.json +1398 -0
  8. package/template/entities/System/Auth/account.json +94 -18
  9. package/template/entities/System/Auth/account_audit.json +11 -3
  10. package/template/entities/System/Auth/account_device.json +13 -27
  11. package/template/entities/System/Auth/account_login_log.json +17 -7
  12. package/template/entities/System/Auth/anon_device.json +56 -0
  13. package/template/entities/System/Auth/api_keys.json +18 -9
  14. package/template/entities/System/Auth/license.json +41 -20
  15. package/template/entities/System/Auth/rbac_roles.json +10 -7
  16. package/template/entities/System/Backup/backup_log.json +11 -7
  17. package/template/entities/System/Email/smtp_log.json +9 -5
  18. package/template/entities/System/Email/smtp_msg.json +5 -5
  19. package/template/entities/System/Storage/file_backup_log.json +11 -6
  20. package/template/entities/System/Storage/file_download_log.json +7 -5
  21. package/template/entities/System/Storage/file_meta.json +20 -7
  22. package/template/entities/System/system_audit_log.json +38 -34
  23. package/template/entities/company.json +5 -2
  24. package/template/entities/goods.json +10 -3
  25. package/template/entities/todo.json +4 -2
  26. package/template/samples/entities/01_basic_fields.json +15 -2
  27. package/template/samples/entities/02_types_and_defaults.json +15 -5
  28. package/template/samples/entities/03_hash_and_unique.json +18 -3
  29. package/template/samples/entities/04_fk_and_composite_unique.json +18 -3
  30. package/template/samples/entities/05_cache.json +15 -9
  31. package/template/samples/entities/06_history_and_hard_delete.json +19 -6
  32. package/template/samples/entities/07_license_scope.json +18 -3
  33. package/template/samples/entities/08_hook_sql.json +24 -5
  34. package/template/samples/entities/09_hook_entity.json +12 -2
  35. package/template/samples/entities/10_hook_submit_delete.json +14 -5
  36. package/template/samples/entities/11_hook_webhook.json +20 -6
  37. package/template/samples/entities/12_hook_push.json +15 -2
  38. package/template/samples/entities/13_read_only.json +8 -4
  39. package/template/samples/entities/14_optimistic_lock.json +13 -2
  40. package/template/samples/entities/15_reset_defaults.json +7 -1
  41. package/template/samples/entities/16_isolated_license.json +19 -6
  42. package/template/scripts/reset-all.sh +130 -3
  43. package/template/scripts/run.sh +129 -33
  44. package/template/templates/ocr/business_reg.json +145 -0
  45. package/template/templates/ocr/career_cert.json +93 -0
  46. package/template/templates/ocr/driver_license.json +89 -0
  47. package/template/templates/ocr/facility_card.json +82 -0
  48. package/template/templates/ocr/id_card.json +55 -0
  49. package/template/templates/ocr/invoice.json +92 -0
  50. package/template/templates/ocr/namecard.json +116 -0
  51. package/template/templates/ocr/prompts/business_reg.json +14 -0
  52. package/template/templates/ocr/prompts/career_cert.json +16 -0
  53. package/template/templates/ocr/prompts/driver_license.json +14 -0
  54. package/template/templates/ocr/prompts/facility_card.json +15 -0
  55. package/template/templates/ocr/prompts/general.json +13 -0
  56. package/template/templates/ocr/prompts/id_card.json +11 -0
  57. package/template/templates/ocr/prompts/invoice.json +17 -0
  58. package/template/templates/ocr/prompts/namecard.json +15 -0
  59. package/template/templates/ocr/prompts/receipt.json +14 -0
  60. package/template/templates/ocr/receipt.json +79 -0
  61. package/template/configs/auth/identity.json +0 -27
  62. package/template/configs/auth/oauth.json +0 -40
  63. package/template/configs/auth/password.json +0 -33
  64. package/template/configs/auth/privacy_policy.json +0 -28
  65. package/template/configs/auth/two_factor.json +0 -12
  66. package/template/configs/extensions/pg.json +0 -37
  67. package/template/configs/extensions/tax-invoice.json +0 -59
  68. package/template/configs/keys/apns.p8.example +0 -7
  69. package/template/configs/keys/firebase.pem.example +0 -7
  70. package/template/configs/notification/alimtalk.json +0 -75
  71. package/template/configs/notification/push.json +0 -25
  72. package/template/configs/notification/sms.json +0 -54
  73. package/template/entities/System/Auth/account_oauth.json +0 -45
  74. package/template/entities/System/Auth/identity_verification.json +0 -95
  75. package/template/entities/System/Auth/password_history.json +0 -20
  76. package/template/entities/System/Notification/alimtalk_log.json +0 -45
  77. package/template/entities/System/Notification/alimtalk_msg.json +0 -39
  78. package/template/entities/System/Notification/friendtalk_log.json +0 -48
  79. package/template/entities/System/Notification/friendtalk_msg.json +0 -63
  80. package/template/entities/System/Notification/sms_log.json +0 -26
  81. package/template/entities/System/Notification/sms_msg.json +0 -52
  82. package/template/entities/System/Notification/sms_verification.json +0 -40
  83. package/template/entities/System/Payment/pg_cancel.json +0 -45
  84. package/template/entities/System/Payment/pg_order.json +0 -88
  85. package/template/entities/System/Payment/pg_webhook_log.json +0 -37
  86. package/template/entities/System/Push/push_log.json +0 -71
  87. package/template/entities/System/Push/push_msg.json +0 -55
  88. package/template/templates/email/account/dormancy_warning.html +0 -20
  89. package/template/templates/email/account/password_expiry_warning.html +0 -21
  90. package/template/templates/email/auth/2fa_disabled.html +0 -23
  91. package/template/templates/email/auth/2fa_recovery_regenerated.html +0 -31
  92. package/template/templates/email/auth/2fa_setup_complete.html +0 -43
  93. package/template/templates/email/auth/email_verification.html +0 -18
  94. package/template/templates/email/auth/force_reset.html +0 -18
  95. package/template/templates/email/auth/password_reset.html +0 -19
  96. package/template/templates/email/auth/verification.html +0 -15
  97. package/template/templates/email/auth/verification_link.html +0 -25
  98. package/template/templates/email/auth/welcome.html +0 -18
  99. package/template/templates/email/order/order_confirmation.html +0 -30
  100. /package/template/configs/{notification/smtp.json → smtp.json} +0 -0
@@ -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)
@@ -62,6 +126,9 @@ is_running() {
62
126
  if [ -n "$port_pid" ] && kill -0 "$port_pid" 2>/dev/null; then
63
127
  return 0
64
128
  fi
129
+ if is_port_in_use; then
130
+ return 0
131
+ fi
65
132
  return 1
66
133
  fi
67
134
  local pid
@@ -70,6 +137,9 @@ is_running() {
70
137
  if [ -n "$port_pid" ] && kill -0 "$port_pid" 2>/dev/null; then
71
138
  return 0
72
139
  fi
140
+ if is_port_in_use; then
141
+ return 0
142
+ fi
73
143
  return 1
74
144
  fi
75
145
  if kill -0 "$pid" 2>/dev/null; then
@@ -80,6 +150,10 @@ is_running() {
80
150
  return 0
81
151
  fi
82
152
 
153
+ if is_port_in_use; then
154
+ return 0
155
+ fi
156
+
83
157
  return 1
84
158
  }
85
159
 
@@ -89,6 +163,26 @@ find_pid_by_port() {
89
163
  ss -ltnp 2>/dev/null | grep ":$port " | sed -n 's/.*pid=\([0-9]\+\).*/\1/p' | head -n 1
90
164
  }
91
165
 
166
+ is_port_in_use() {
167
+ local port
168
+ port=$(get_server_value "port" "3400")
169
+ ss -ltn 2>/dev/null | grep -q ":$port "
170
+ }
171
+
172
+ show_port_in_use_message() {
173
+ local port
174
+ port=$(get_server_value "port" "3400")
175
+ if [ "$LANGUAGE" = "en" ]; then
176
+ echo "❌ Port $port is already in use, but the owning PID could not be identified."
177
+ echo "Check with: ss -ltnp | grep :$port"
178
+ echo "Or: lsof -iTCP:$port -sTCP:LISTEN -n -P"
179
+ else
180
+ echo "❌ 포트 $port 가 이미 사용 중이지만, 점유 PID를 식별할 수 없습니다."
181
+ echo "확인: ss -ltnp | grep :$port"
182
+ echo "또는: lsof -iTCP:$port -sTCP:LISTEN -n -P"
183
+ fi
184
+ }
185
+
92
186
  stop_pid_with_confirm() {
93
187
  local pid="$1"
94
188
  local reason="$2"
@@ -116,7 +210,7 @@ stop_pid_with_confirm() {
116
210
  read -r -p "이 프로세스를 중지할까요? [y/N]: " input
117
211
  fi
118
212
  input=$(echo "$input" | tr '[:upper:]' '[:lower:]')
119
- if [ "$input" != "y" ] && [ "$input" != "yes" ]; then
213
+ if [ "$input" != "y" ] && [ "$input" != "yes" ] && [ "$input" != "ㅛ" ]; then
120
214
  if [ "$LANGUAGE" = "en" ]; then
121
215
  echo "Canceled."
122
216
  else
@@ -157,6 +251,10 @@ stop_server() {
157
251
  stop_pid_with_confirm "$port_pid" "port fallback"
158
252
  return $?
159
253
  fi
254
+ if is_port_in_use; then
255
+ show_port_in_use_message
256
+ return 1
257
+ fi
160
258
  if [ "$LANGUAGE" = "en" ]; then
161
259
  echo "ℹ️ Server is not running (pid file not found)."
162
260
  else
@@ -191,6 +289,10 @@ stop_server() {
191
289
  stop_pid_with_confirm "$port_pid" "port fallback"
192
290
  return $?
193
291
  fi
292
+ if is_port_in_use; then
293
+ show_port_in_use_message
294
+ return 1
295
+ fi
194
296
  if [ "$LANGUAGE" = "en" ]; then
195
297
  echo "ℹ️ Stale pid file removed (process not found)."
196
298
  else
@@ -235,13 +337,13 @@ if [ $# -eq 0 ]; then
235
337
  echo "Entity Server - Run Script"
236
338
  echo "=========================="
237
339
  echo ""
238
- echo "Force configs/server.json environment and configs/database.json default group, then start compiled server binary."
340
+ echo "Adjust configs/server.json environment as needed, then start the compiled server binary."
239
341
  echo ""
240
342
  echo "Usage: $0 <mode>"
241
343
  echo ""
242
344
  echo "Modes:"
243
- echo " dev environment=development, database.default=development, then run binary"
244
- 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"
245
347
  echo " stop stop background server started by this script"
246
348
  echo " status show server status"
247
349
  echo ""
@@ -254,13 +356,13 @@ if [ $# -eq 0 ]; then
254
356
  echo "Entity Server - 실행 스크립트"
255
357
  echo "==========================="
256
358
  echo ""
257
- echo "configs/server.json의 environment configs/database.json의 default를 강제 설정하고 바이너리를 실행합니다."
359
+ echo "configs/server.json의 environment 기준으로 필요한 경우에만 database.default를 조정한 바이너리를 실행합니다."
258
360
  echo ""
259
361
  echo "사용법: $0 <모드>"
260
362
  echo ""
261
363
  echo "모드:"
262
- echo " dev environment=development, database.default=development 강제 바이너리 실행"
263
- echo " start environment=production, database.default=production 강제 백그라운드 실행"
364
+ echo " dev environment=development 설정하고 database.default 유지한 바이너리 실행"
365
+ echo " start environment=production으로 설정하고 production일 때만 database.default=production으로 맞춘 백그라운드 실행"
264
366
  echo " stop run.sh로 백그라운드 실행한 서버 중지"
265
367
  echo " status 서버 상태 조회"
266
368
  echo ""
@@ -305,49 +407,43 @@ fi
305
407
  case "$MODE" in
306
408
  dev|development)
307
409
  if is_running; then
308
- if [ "$LANGUAGE" = "en" ]; then
309
- echo "❌ Server already running (pid: $(cat "$PID_FILE")). Stop first: ./run.sh stop"
310
- else
311
- echo "❌ 이미 서버가 실행 중입니다 (pid: $(cat "$PID_FILE")). 먼저 중지하세요: ./run.sh stop"
312
- fi
313
- exit 1
314
- fi
315
-
316
- if ! grep -Eq '"development"[[:space:]]*:' "$DATABASE_CONFIG"; then
317
- if [ "$LANGUAGE" = "en" ]; then
318
- echo "❌ database group 'development' not found in configs/database.json"
410
+ local running_pid
411
+ running_pid=$(find_pid_by_port)
412
+ if [ -n "$running_pid" ]; then
413
+ if [ "$LANGUAGE" = "en" ]; then
414
+ echo "❌ Server already running (pid: $running_pid). Stop first: ./run.sh stop"
415
+ else
416
+ echo "❌ 이미 서버가 실행 중입니다 (pid: $running_pid). 먼저 중지하세요: ./run.sh stop"
417
+ fi
319
418
  else
320
- echo "❌ configs/database.json에 'development' 그룹이 없습니다"
419
+ show_port_in_use_message
321
420
  fi
322
421
  exit 1
323
422
  fi
324
423
 
325
424
  sed -E -i 's/("environment"[[:space:]]*:[[:space:]]*")[^"]+(")/\1development\2/' "$SERVER_CONFIG"
326
- sed -E -i 's/("default"[[:space:]]*:[[:space:]]*")[^"]+(")/\1development\2/' "$DATABASE_CONFIG"
425
+ sync_database_default_for_environment "$LINENO" || exit 1
327
426
  "$SERVER_BIN"
328
427
  ;;
329
428
 
330
429
  start)
331
430
  if is_running; then
332
- if [ "$LANGUAGE" = "en" ]; then
333
- echo "❌ Server already running (pid: $(cat "$PID_FILE")). Stop first: ./run.sh stop"
334
- else
335
- echo "❌ 이미 서버가 실행 중입니다 (pid: $(cat "$PID_FILE")). 먼저 중지하세요: ./run.sh stop"
336
- fi
337
- exit 1
338
- fi
339
-
340
- if ! grep -Eq '"production"[[:space:]]*:' "$DATABASE_CONFIG"; then
341
- if [ "$LANGUAGE" = "en" ]; then
342
- echo "❌ database group 'production' not found in configs/database.json"
431
+ local running_pid
432
+ running_pid=$(find_pid_by_port)
433
+ if [ -n "$running_pid" ]; then
434
+ if [ "$LANGUAGE" = "en" ]; then
435
+ echo "❌ Server already running (pid: $running_pid). Stop first: ./run.sh stop"
436
+ else
437
+ echo "❌ 이미 서버가 실행 중입니다 (pid: $running_pid). 먼저 중지하세요: ./run.sh stop"
438
+ fi
343
439
  else
344
- echo "❌ configs/database.json에 'production' 그룹이 없습니다"
440
+ show_port_in_use_message
345
441
  fi
346
442
  exit 1
347
443
  fi
348
444
 
349
445
  sed -E -i 's/("environment"[[:space:]]*:[[:space:]]*")[^"]+(")/\1production\2/' "$SERVER_CONFIG"
350
- sed -E -i 's/("default"[[:space:]]*:[[:space:]]*")[^"]+(")/\1production\2/' "$DATABASE_CONFIG"
446
+ sync_database_default_for_environment "$LINENO" || exit 1
351
447
 
352
448
  "$SERVER_BIN" banner
353
449
  nohup "$SERVER_BIN" >> "$STDOUT_LOG" 2>&1 &
@@ -0,0 +1,145 @@
1
+ {
2
+ "doc_type": "business_reg",
3
+ "label": "사업자등록증",
4
+ "preprocess": {
5
+ "max_slope": 0.03,
6
+ "y_tolerance": 5,
7
+ "x_tolerance": 10,
8
+ "remove_patterns": [
9
+ "NATIONAL TAX SERVICE REPUBLIC OF KOREA",
10
+ "나라사랑e",
11
+ "nts\\.go\\.kr"
12
+ ],
13
+ "remove_keywords": [
14
+ "KOREA",
15
+ "OF",
16
+ "NATIONAL",
17
+ "REPULIC",
18
+ "국세청",
19
+ "nts.go.kr",
20
+ "TAX",
21
+ "SERVICE"
22
+ ],
23
+ "merge_patterns": ["주식회사", "(주)"]
24
+ },
25
+ "keywords": {
26
+ "dummy": ["국세청", "법인사업자", "개인사업자", "사업자등록증"],
27
+ "corp_num": ["등록번호", "사업자등록번호"],
28
+ "corp_reg_num": ["법인등록번호"],
29
+ "corp_name": ["법인명", "단체명", "상호", "법인명(단체명)"],
30
+ "ceo_name": ["대표자", "성명"],
31
+ "birthday": ["생년월일"],
32
+ "open_date": ["개업연월일"],
33
+ "address": ["사업장소재지"],
34
+ "head_address": ["본점소재지"],
35
+ "biz_type": ["업태", "사업의종류"],
36
+ "biz_class": ["종목"],
37
+ "issue_reason": ["발급사유"],
38
+ "tax_unit": ["사업자단위과세적용사업자여부"],
39
+ "email": ["전자세금계산서전용전자우편주소"]
40
+ },
41
+ "fields": {
42
+ "corp_num": {
43
+ "mode": "regex_scan",
44
+ "pattern": "([0-9]{3}-[0-9]{2}-[0-9]{5})",
45
+ "refine": "biz_num"
46
+ },
47
+ "corp_reg_num": {
48
+ "mode": "anchor",
49
+ "required_keyword": "법인등록번호",
50
+ "criteria": [
51
+ { "keyword": "법인등록번호", "direction": "RIGHT" },
52
+ { "keyword": "대표자", "direction": "DOWN" },
53
+ { "keyword": "상호", "direction": "DOWN" },
54
+ { "keyword": "사업장소재지", "direction": "UP" }
55
+ ]
56
+ },
57
+ "corp_name": {
58
+ "mode": "anchor",
59
+ "criteria": [
60
+ { "keyword": "법인명(단체명)", "direction": "RIGHT" },
61
+ { "keyword": "상호", "direction": "RIGHT" },
62
+ { "keyword": "등록번호", "direction": "DOWN" },
63
+ { "keyword": "대표자", "direction": "UP" },
64
+ { "keyword": "성명", "direction": "UP" },
65
+ { "keyword": "생년월일", "direction": "LEFT" }
66
+ ]
67
+ },
68
+ "ceo_name": {
69
+ "mode": "anchor",
70
+ "criteria": [
71
+ { "keyword": "대표자", "direction": "RIGHT" },
72
+ { "keyword": "성명", "direction": "RIGHT" },
73
+ { "keyword": "생년월일", "direction": "LEFT" },
74
+ { "keyword": "법인명(단체명)", "direction": "DOWN" },
75
+ { "keyword": "상호", "direction": "DOWN" },
76
+ { "keyword": "개업연월일", "direction": "UP" }
77
+ ]
78
+ },
79
+ "open_date": {
80
+ "mode": "anchor",
81
+ "criteria": [
82
+ { "keyword": "개업연월일", "direction": "RIGHT" },
83
+ { "keyword": "법인등록번호", "direction": "LEFT" },
84
+ { "keyword": "사업장소재지", "direction": "UP" },
85
+ { "keyword": "대표자", "direction": "DOWN" },
86
+ { "keyword": "성명", "direction": "DOWN" }
87
+ ],
88
+ "refine": "date"
89
+ },
90
+ "address": {
91
+ "mode": "anchor",
92
+ "criteria": [
93
+ { "keyword": "사업장소재지", "direction": "RIGHT" },
94
+ { "keyword": "사업장소재지", "direction": "DOWN" },
95
+ { "keyword": "본점소재지", "direction": "UP" },
96
+ { "keyword": "사업의종류", "direction": "UP" },
97
+ { "keyword": "개업연월일", "direction": "DOWN" }
98
+ ]
99
+ },
100
+ "biz_type": {
101
+ "mode": "anchor",
102
+ "criteria": [
103
+ { "keyword": "업태", "direction": "RIGHT" },
104
+ { "keyword": "종목", "direction": "LEFT" },
105
+ { "keyword": "본점소재지", "direction": "DOWN" },
106
+ { "keyword": "사업장소재지", "direction": "DOWN" },
107
+ { "keyword": "발급사유", "direction": "UP" },
108
+ { "keyword": "사업자단위과세적용사업자여부", "direction": "UP" }
109
+ ]
110
+ },
111
+ "biz_class": {
112
+ "mode": "anchor",
113
+ "criteria": [
114
+ { "keyword": "종목", "direction": "RIGHT" },
115
+ { "keyword": "본점소재지", "direction": "DOWN" },
116
+ { "keyword": "사업장소재지", "direction": "DOWN" },
117
+ { "keyword": "발급사유", "direction": "UP" },
118
+ { "keyword": "사업자단위과세적용사업자여부", "direction": "UP" }
119
+ ]
120
+ },
121
+ "email": {
122
+ "mode": "anchor",
123
+ "criteria": [
124
+ {
125
+ "keyword": "전자세금계산서전용전자우편주소",
126
+ "direction": "RIGHT"
127
+ },
128
+ {
129
+ "keyword": "전자세금계산서전용전자우편주소",
130
+ "direction": "DOWN"
131
+ }
132
+ ]
133
+ }
134
+ },
135
+ "required_fields": ["corp_num", "corp_name"],
136
+ "confidence_weight": {
137
+ "corp_num": 0.35,
138
+ "corp_name": 0.3,
139
+ "ceo_name": 0.1,
140
+ "open_date": 0.1,
141
+ "address": 0.1,
142
+ "biz_type": 0.025,
143
+ "biz_class": 0.025
144
+ }
145
+ }
@@ -0,0 +1,93 @@
1
+ {
2
+ "doc_type": "career_cert",
3
+ "label": "경력증명서 (재직증명서)",
4
+ "preprocess": {
5
+ "max_slope": 0.03,
6
+ "y_tolerance": 5,
7
+ "x_tolerance": 10
8
+ },
9
+ "keywords": {
10
+ "name": ["성명", "이름", "위\\s*사람"],
11
+ "id_number": ["주민등록번호", "생년월일"],
12
+ "company": ["회사명", "법인명", "상호", "근무처"],
13
+ "department": ["부서", "소속"],
14
+ "position": ["직위", "직급", "직책"],
15
+ "join_date": ["입사일", "입사일자", "근무시작일"],
16
+ "leave_date": ["퇴사일", "퇴사일자", "근무종료일"],
17
+ "issue_date": ["발급일", "발행일", "증명서발급일"],
18
+ "issuer": ["대표이사", "대표자", "발급기관"]
19
+ },
20
+ "fields": {
21
+ "name": {
22
+ "mode": "anchor",
23
+ "criteria": [
24
+ { "keyword": "성명", "direction": "RIGHT" },
25
+ { "keyword": "이름", "direction": "RIGHT" }
26
+ ],
27
+ "refine": "trim"
28
+ },
29
+ "id_number": {
30
+ "mode": "regex_scan",
31
+ "pattern": "([0-9]{6}-[0-9*]{7})",
32
+ "refine": "id_num"
33
+ },
34
+ "company": {
35
+ "mode": "anchor",
36
+ "criteria": [
37
+ { "keyword": "회사명", "direction": "RIGHT" },
38
+ { "keyword": "법인명", "direction": "RIGHT" },
39
+ { "keyword": "상호", "direction": "RIGHT" }
40
+ ]
41
+ },
42
+ "department": {
43
+ "mode": "anchor",
44
+ "criteria": [
45
+ { "keyword": "부서", "direction": "RIGHT" },
46
+ { "keyword": "소속", "direction": "RIGHT" }
47
+ ]
48
+ },
49
+ "position": {
50
+ "mode": "anchor",
51
+ "criteria": [
52
+ { "keyword": "직위", "direction": "RIGHT" },
53
+ { "keyword": "직급", "direction": "RIGHT" },
54
+ { "keyword": "직책", "direction": "RIGHT" }
55
+ ]
56
+ },
57
+ "join_date": {
58
+ "mode": "anchor",
59
+ "criteria": [
60
+ { "keyword": "입사일", "direction": "RIGHT" },
61
+ { "keyword": "입사일자", "direction": "RIGHT" }
62
+ ],
63
+ "refine": "date"
64
+ },
65
+ "leave_date": {
66
+ "mode": "anchor",
67
+ "criteria": [
68
+ { "keyword": "퇴사일", "direction": "RIGHT" },
69
+ { "keyword": "퇴사일자", "direction": "RIGHT" }
70
+ ],
71
+ "refine": "date"
72
+ },
73
+ "issue_date": {
74
+ "mode": "regex_scan",
75
+ "pattern": "발급일[\\s:]*([0-9]{4}[.\\-/][0-9]{1,2}[.\\-/][0-9]{1,2})",
76
+ "refine": "date"
77
+ },
78
+ "issuer": {
79
+ "mode": "regex_scan",
80
+ "pattern": "대표(?:이사)?\\s*([가-힣]{2,5})(?:\\s*[\\(印\\)\\s]|$)"
81
+ }
82
+ },
83
+ "required_fields": ["name", "company"],
84
+ "confidence_weight": {
85
+ "name": 0.2,
86
+ "company": 0.2,
87
+ "join_date": 0.2,
88
+ "leave_date": 0.15,
89
+ "position": 0.1,
90
+ "issue_date": 0.1,
91
+ "issuer": 0.05
92
+ }
93
+ }
@@ -0,0 +1,89 @@
1
+ {
2
+ "doc_type": "driver_license",
3
+ "label": "운전면허증",
4
+
5
+ "preprocess": {
6
+ "max_slope": 0.03,
7
+ "y_tolerance": 4,
8
+ "x_tolerance": 8,
9
+ "remove_keywords": ["(Driver's License)", "Driver's", "License"],
10
+ "remove_patterns": ["^\\s*$", "^[가-힣]{2,4}\\s*도로교통공단$"]
11
+ },
12
+
13
+ "keywords": {
14
+ "keyword": ["자동차운전면허증", "적성검사", "기간"],
15
+ "license_type": [
16
+ "1종대형",
17
+ "1종보통",
18
+ "2종보통",
19
+ "2종소형",
20
+ "원동기",
21
+ "특수(대형견인,구난차)",
22
+ "특수(소형견인,구난차)",
23
+ "특수(건설기계)",
24
+ "특수(농기계)",
25
+ "특수(비상구난차)",
26
+ "특수(경찰용)",
27
+ "특수(소형이동기계)"
28
+ ]
29
+ },
30
+
31
+ "fields": {
32
+ "name": {
33
+ "mode": "anchor",
34
+ "criteria": [
35
+ {
36
+ "keyword": "(?:[가-힣]+\\s+)?\\d{2}-\\d{2}-\\d{6}-\\d{2}",
37
+ "direction": "DOWN_OVERLAP",
38
+ "is_regex": true
39
+ },
40
+ {
41
+ "keyword": "\\d{6}-?(\\d{7}|\\*{7})",
42
+ "direction": "UP_OVERLAP",
43
+ "is_regex": true
44
+ }
45
+ ]
46
+ },
47
+ "license_type": {
48
+ "mode": "keywords_scan",
49
+ "keywords_key": "license_type"
50
+ },
51
+ "license_num": {
52
+ "mode": "regex_scan",
53
+ "pattern": "(?:[가-힣]+\\s+)?(\\d{2}-\\d{2}-\\d{6}-\\d{2})",
54
+ "refine": "driver_license"
55
+ },
56
+ "id_number": {
57
+ "mode": "regex_scan",
58
+ "pattern": "(\\d{6}-?(\\d{7}|\\*{7}))",
59
+ "refine": "id_num"
60
+ },
61
+ "expiry_date": {
62
+ "mode": "regex_scan",
63
+ "pattern": "(\\d{4}[.\\-\\/]\\d{1,2}[.\\-\\/]\\d{1,2})\\s*~\\s*(\\d{4}[.\\-\\/]\\d{1,2}[.\\-\\/]\\d{1,2})",
64
+ "capture_group": 2,
65
+ "refine": "date"
66
+ },
67
+ "issue_date": {
68
+ "mode": "dates_scan",
69
+ "dates_index": 2,
70
+ "refine": "date"
71
+ },
72
+ "issuer": {
73
+ "mode": "regex_scan",
74
+ "pattern": "([가-힣]+지방경찰청|[가-힣]+경찰청)",
75
+ "capture_group": 1
76
+ }
77
+ },
78
+
79
+ "required_fields": ["name", "license_num"],
80
+
81
+ "confidence_weight": {
82
+ "name": 0.25,
83
+ "id_number": 0.2,
84
+ "license_num": 0.3,
85
+ "license_type": 0.1,
86
+ "issue_date": 0.1,
87
+ "expiry_date": 0.05
88
+ }
89
+ }
@@ -0,0 +1,82 @@
1
+ {
2
+ "doc_type": "facility_card",
3
+ "label": "건축물대장",
4
+ "preprocess": {
5
+ "max_slope": 0.03,
6
+ "y_tolerance": 5,
7
+ "x_tolerance": 12
8
+ },
9
+ "keywords": {
10
+ "building_name": ["건물명", "건축물명", "명칭"],
11
+ "address": ["소재지", "대지위치", "주소"],
12
+ "building_use": ["주용도", "용도"],
13
+ "structure": ["구조"],
14
+ "area": ["연면적", "건축면적", "면적"],
15
+ "floor_count": ["층수", "지상", "지하"],
16
+ "approval_date": ["사용승인일", "사용승인", "준공일"],
17
+ "owner": ["소유자", "건축주"]
18
+ },
19
+ "fields": {
20
+ "building_name": {
21
+ "mode": "anchor",
22
+ "criteria": [
23
+ { "keyword": "건물명", "direction": "RIGHT" },
24
+ { "keyword": "건축물명", "direction": "RIGHT" },
25
+ { "keyword": "명칭", "direction": "RIGHT" }
26
+ ]
27
+ },
28
+ "address": {
29
+ "mode": "anchor",
30
+ "criteria": [
31
+ { "keyword": "소재지", "direction": "RIGHT" },
32
+ { "keyword": "대지위치", "direction": "RIGHT" }
33
+ ]
34
+ },
35
+ "building_use": {
36
+ "mode": "anchor",
37
+ "criteria": [
38
+ { "keyword": "주용도", "direction": "RIGHT" },
39
+ { "keyword": "용도", "direction": "RIGHT" }
40
+ ]
41
+ },
42
+ "structure": {
43
+ "mode": "anchor",
44
+ "criteria": [{ "keyword": "구조", "direction": "RIGHT" }]
45
+ },
46
+ "area": {
47
+ "mode": "anchor",
48
+ "criteria": [
49
+ { "keyword": "연면적", "direction": "RIGHT" },
50
+ { "keyword": "건축면적", "direction": "RIGHT" }
51
+ ],
52
+ "refine": "number"
53
+ },
54
+ "floor_count": {
55
+ "mode": "regex_scan",
56
+ "pattern": "지상\\s*(\\d+)층"
57
+ },
58
+ "approval_date": {
59
+ "mode": "anchor",
60
+ "criteria": [
61
+ { "keyword": "사용승인일", "direction": "RIGHT" },
62
+ { "keyword": "사용승인", "direction": "RIGHT" }
63
+ ],
64
+ "refine": "date"
65
+ },
66
+ "owner": {
67
+ "mode": "anchor",
68
+ "criteria": [
69
+ { "keyword": "소유자", "direction": "RIGHT" },
70
+ { "keyword": "건축주", "direction": "RIGHT" }
71
+ ]
72
+ }
73
+ },
74
+ "required_fields": ["address"],
75
+ "confidence_weight": {
76
+ "address": 0.3,
77
+ "building_use": 0.2,
78
+ "area": 0.2,
79
+ "approval_date": 0.15,
80
+ "owner": 0.15
81
+ }
82
+ }