activo 0.4.4 → 0.5.0

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 (161) hide show
  1. package/README.md +203 -1
  2. package/data/2026-03-04_20-54.json +181 -0
  3. package/data/2026-03-04_20-56.json +181 -0
  4. package/data/apex-rulesets/egov.yaml +469 -0
  5. package/data/apex-rulesets/modernize.yaml +687 -0
  6. package/data/apex-rulesets/quality.yaml +1677 -0
  7. package/data/apex-rulesets/rule-schema.yaml +587 -0
  8. package/data/apex-rulesets/secure.yaml +1688 -0
  9. package/data/apex-rulesets/spring.yaml +455 -0
  10. package/data/apex-rulesets/sql-format.yaml +99 -0
  11. package/data/apex-rulesets/sql-oracle.yaml +281 -0
  12. package/data/apex-rulesets/sql.yaml +1660 -0
  13. package/dist/cli/headless.d.ts.map +1 -1
  14. package/dist/cli/headless.js +32 -10
  15. package/dist/cli/headless.js.map +1 -1
  16. package/dist/cli/index.js +31 -3
  17. package/dist/cli/index.js.map +1 -1
  18. package/dist/core/agent.d.ts +3 -3
  19. package/dist/core/agent.d.ts.map +1 -1
  20. package/dist/core/agent.js +203 -384
  21. package/dist/core/agent.js.map +1 -1
  22. package/dist/core/commands.d.ts +2 -1
  23. package/dist/core/commands.d.ts.map +1 -1
  24. package/dist/core/commands.js +61 -9
  25. package/dist/core/commands.js.map +1 -1
  26. package/dist/core/config.d.ts +14 -0
  27. package/dist/core/config.d.ts.map +1 -1
  28. package/dist/core/config.js +41 -4
  29. package/dist/core/config.js.map +1 -1
  30. package/dist/core/conversation.d.ts +2 -2
  31. package/dist/core/conversation.d.ts.map +1 -1
  32. package/dist/core/conversation.js.map +1 -1
  33. package/dist/core/intentRouter.d.ts +43 -0
  34. package/dist/core/intentRouter.d.ts.map +1 -0
  35. package/dist/core/intentRouter.js +804 -0
  36. package/dist/core/intentRouter.js.map +1 -0
  37. package/dist/core/llm/anthropic.d.ts +24 -0
  38. package/dist/core/llm/anthropic.d.ts.map +1 -0
  39. package/dist/core/llm/anthropic.js +226 -0
  40. package/dist/core/llm/anthropic.js.map +1 -0
  41. package/dist/core/llm/ollama.d.ts +5 -14
  42. package/dist/core/llm/ollama.d.ts.map +1 -1
  43. package/dist/core/llm/ollama.js +3 -0
  44. package/dist/core/llm/ollama.js.map +1 -1
  45. package/dist/core/llm/types.d.ts +22 -0
  46. package/dist/core/llm/types.d.ts.map +1 -0
  47. package/dist/core/llm/types.js +2 -0
  48. package/dist/core/llm/types.js.map +1 -0
  49. package/dist/core/mcp/client.d.ts +6 -0
  50. package/dist/core/mcp/client.d.ts.map +1 -1
  51. package/dist/core/mcp/client.js +16 -0
  52. package/dist/core/mcp/client.js.map +1 -1
  53. package/dist/core/mcp/init.d.ts +12 -0
  54. package/dist/core/mcp/init.d.ts.map +1 -0
  55. package/dist/core/mcp/init.js +55 -0
  56. package/dist/core/mcp/init.js.map +1 -0
  57. package/dist/core/mcp/logger.d.ts +14 -0
  58. package/dist/core/mcp/logger.d.ts.map +1 -0
  59. package/dist/core/mcp/logger.js +50 -0
  60. package/dist/core/mcp/logger.js.map +1 -0
  61. package/dist/core/tools/analyzePatterns.d.ts +3 -0
  62. package/dist/core/tools/analyzePatterns.d.ts.map +1 -0
  63. package/dist/core/tools/analyzePatterns.js +293 -0
  64. package/dist/core/tools/analyzePatterns.js.map +1 -0
  65. package/dist/core/tools/apexPaths.d.ts +14 -0
  66. package/dist/core/tools/apexPaths.d.ts.map +1 -0
  67. package/dist/core/tools/apexPaths.js +54 -0
  68. package/dist/core/tools/apexPaths.js.map +1 -0
  69. package/dist/core/tools/apexUtils.d.ts +36 -0
  70. package/dist/core/tools/apexUtils.d.ts.map +1 -0
  71. package/dist/core/tools/apexUtils.js +83 -0
  72. package/dist/core/tools/apexUtils.js.map +1 -0
  73. package/dist/core/tools/explainIssue.d.ts +3 -0
  74. package/dist/core/tools/explainIssue.d.ts.map +1 -0
  75. package/dist/core/tools/explainIssue.js +181 -0
  76. package/dist/core/tools/explainIssue.js.map +1 -0
  77. package/dist/core/tools/fixGen.d.ts +3 -0
  78. package/dist/core/tools/fixGen.d.ts.map +1 -0
  79. package/dist/core/tools/fixGen.js +338 -0
  80. package/dist/core/tools/fixGen.js.map +1 -0
  81. package/dist/core/tools/generateImprovements.d.ts +21 -0
  82. package/dist/core/tools/generateImprovements.d.ts.map +1 -0
  83. package/dist/core/tools/generateImprovements.js +602 -0
  84. package/dist/core/tools/generateImprovements.js.map +1 -0
  85. package/dist/core/tools/generateReport.d.ts +3 -0
  86. package/dist/core/tools/generateReport.d.ts.map +1 -0
  87. package/dist/core/tools/generateReport.js +315 -0
  88. package/dist/core/tools/generateReport.js.map +1 -0
  89. package/dist/core/tools/index.d.ts +7 -0
  90. package/dist/core/tools/index.d.ts.map +1 -1
  91. package/dist/core/tools/index.js +62 -23
  92. package/dist/core/tools/index.js.map +1 -1
  93. package/dist/core/tools/recommendProfile.d.ts +3 -0
  94. package/dist/core/tools/recommendProfile.d.ts.map +1 -0
  95. package/dist/core/tools/recommendProfile.js +334 -0
  96. package/dist/core/tools/recommendProfile.js.map +1 -0
  97. package/dist/core/tools/ruleGen.d.ts +3 -0
  98. package/dist/core/tools/ruleGen.d.ts.map +1 -0
  99. package/dist/core/tools/ruleGen.js +1103 -0
  100. package/dist/core/tools/ruleGen.js.map +1 -0
  101. package/dist/core/tools/standards.d.ts.map +1 -1
  102. package/dist/core/tools/standards.js +7 -3
  103. package/dist/core/tools/standards.js.map +1 -1
  104. package/dist/ui/App.d.ts.map +1 -1
  105. package/dist/ui/App.js +86 -35
  106. package/dist/ui/App.js.map +1 -1
  107. package/dist/ui/components/InputBox.d.ts +1 -3
  108. package/dist/ui/components/InputBox.d.ts.map +1 -1
  109. package/dist/ui/components/InputBox.js +146 -5
  110. package/dist/ui/components/InputBox.js.map +1 -1
  111. package/dist/ui/components/MessageList.d.ts +3 -1
  112. package/dist/ui/components/MessageList.d.ts.map +1 -1
  113. package/dist/ui/components/MessageList.js +13 -7
  114. package/dist/ui/components/MessageList.js.map +1 -1
  115. package/dist/ui/components/StatusBar.d.ts +1 -1
  116. package/dist/ui/components/StatusBar.d.ts.map +1 -1
  117. package/dist/ui/components/StatusBar.js +3 -2
  118. package/dist/ui/components/StatusBar.js.map +1 -1
  119. package/dist/ui/components/ToolStatus.d.ts +3 -1
  120. package/dist/ui/components/ToolStatus.d.ts.map +1 -1
  121. package/dist/ui/components/ToolStatus.js +19 -4
  122. package/dist/ui/components/ToolStatus.js.map +1 -1
  123. package/package.json +7 -1
  124. package/demo.gif +0 -0
  125. package/demo.tape +0 -53
  126. package/screenshot.png +0 -0
  127. package/src/cli/banner.ts +0 -38
  128. package/src/cli/headless.ts +0 -63
  129. package/src/cli/index.ts +0 -57
  130. package/src/core/agent.ts +0 -711
  131. package/src/core/commands.ts +0 -118
  132. package/src/core/config.ts +0 -98
  133. package/src/core/conversation.ts +0 -235
  134. package/src/core/llm/ollama.ts +0 -351
  135. package/src/core/mcp/client.ts +0 -143
  136. package/src/core/tools/analyzeAll.ts +0 -482
  137. package/src/core/tools/ast.ts +0 -826
  138. package/src/core/tools/builtIn.ts +0 -221
  139. package/src/core/tools/cache.ts +0 -570
  140. package/src/core/tools/cssAnalysis.ts +0 -324
  141. package/src/core/tools/dependencyAnalysis.ts +0 -363
  142. package/src/core/tools/embeddings.ts +0 -746
  143. package/src/core/tools/frontendAst.ts +0 -802
  144. package/src/core/tools/htmlAnalysis.ts +0 -466
  145. package/src/core/tools/index.ts +0 -160
  146. package/src/core/tools/javaAst.ts +0 -1030
  147. package/src/core/tools/javaQuality.integration.test.ts +0 -537
  148. package/src/core/tools/memory.ts +0 -655
  149. package/src/core/tools/mybatisAnalysis.ts +0 -322
  150. package/src/core/tools/openapiAnalysis.ts +0 -431
  151. package/src/core/tools/pythonAnalysis.ts +0 -477
  152. package/src/core/tools/sqlAnalysis.ts +0 -298
  153. package/src/core/tools/standards.test.ts +0 -186
  154. package/src/core/tools/standards.ts +0 -889
  155. package/src/core/tools/types.ts +0 -38
  156. package/src/ui/App.tsx +0 -334
  157. package/src/ui/components/InputBox.tsx +0 -37
  158. package/src/ui/components/MessageList.tsx +0 -80
  159. package/src/ui/components/StatusBar.tsx +0 -36
  160. package/src/ui/components/ToolStatus.tsx +0 -38
  161. package/tsconfig.json +0 -21
@@ -0,0 +1,587 @@
1
+ # APEX YAML Rule Schema — LLM Rule Generation Reference
2
+ # Version: 1.0
3
+ # Purpose: LLM이 이 스키마를 읽고 유효한 커스텀 규칙 YAML을 생성할 수 있도록 하는 참조 문서
4
+ #
5
+ # Usage:
6
+ # 1. activo의 generate_apex_rules 도구가 이 파일을 읽음
7
+ # 2. 개발표준 항목 + 이 스키마 → LLM에게 규칙 생성 요청
8
+ # 3. 생성된 규칙은 configs/rulesets/ 에 배치하여 apex가 실행
9
+
10
+ version: "1.0"
11
+ description: "APEX YAML 규칙 스키마 — LLM 규칙 생성용"
12
+
13
+ # ─────────────────────────────────────────────
14
+ # 규칙 기본 형식
15
+ # ─────────────────────────────────────────────
16
+ rule_format:
17
+ required_fields:
18
+ - id # string: 규칙 고유 ID
19
+ - name # string: 규칙 이름 (한글 가능)
20
+ - severity # enum: low | medium | high | critical
21
+ - category # string: 분류 (naming, security, exception, performance, design 등)
22
+ - description # string: 위반 시 설명
23
+ - enabled # boolean: 활성화 여부
24
+ - pattern # object: 패턴 정의 (아래 pattern_types 참조)
25
+
26
+ optional_fields:
27
+ - exclude # string[]: 제외할 파일 패턴 (glob)
28
+ - file_extensions # string[]: 대상 파일 확장자 (기본: 언어에 따라 자동)
29
+ - custom # map: 추가 메타데이터 (rule_id, fix, cwe, example 등)
30
+
31
+ severity_values: ["low", "medium", "high", "critical"]
32
+
33
+ id_convention: "custom-{category}-{number}"
34
+ # 예: custom-naming-001, custom-security-001, custom-perf-001
35
+
36
+ ruleset_format: |
37
+ # 규칙셋 파일 형식 (configs/rulesets/*.yaml)
38
+ version: "1.0"
39
+ profile: "custom"
40
+ languages:
41
+ - language: java
42
+ rules:
43
+ - id: "custom-xxx-001"
44
+ ...
45
+ - language: sql
46
+ rules:
47
+ - id: "custom-sql-001"
48
+ ...
49
+
50
+ # ─────────────────────────────────────────────
51
+ # 패턴 타입 정의 (20개)
52
+ # ─────────────────────────────────────────────
53
+ pattern_types:
54
+
55
+ # ========== 1. regex ==========
56
+ - type: "regex"
57
+ description: "소스 라인별 정규식 매칭. 주석/문자열 내부도 매칭됨."
58
+ languages: [java, javascript, html, css, sql, xml, python]
59
+ params:
60
+ required: [regex]
61
+ optional: [flags]
62
+ notes: |
63
+ - flags: "i" (대소문자 무시)
64
+ - 주석 내부도 매칭되므로, 주석 제외가 필요하면 ast-filtered-regex 사용
65
+ example:
66
+ - id: "custom-logging-001"
67
+ name: "System.out 사용 금지"
68
+ severity: "medium"
69
+ category: "logging"
70
+ description: "운영 코드에서 System.out 사용 금지. Logger를 사용하세요."
71
+ enabled: true
72
+ pattern:
73
+ type: "regex"
74
+ regex: "System\\.(out|err)\\.(print|println)"
75
+
76
+ # ========== 2. regex-multiline ==========
77
+ - type: "regex-multiline"
78
+ description: "여러 줄에 걸친 정규식 매칭. [\\s\\S]로 줄바꿈 포함 매칭 가능."
79
+ languages: [java, javascript, html, css, sql, xml, python]
80
+ params:
81
+ required: [regex]
82
+ optional: [flags]
83
+ notes: |
84
+ - 파일 전체 텍스트에서 매칭 (줄 단위가 아님)
85
+ - flags: "i" (대소문자 무시)
86
+ - SQL 패턴이나 어노테이션+메서드 조합 검출에 유용
87
+ example:
88
+ - id: "custom-sql-smell-001"
89
+ name: "SELECT DISTINCT + GROUP BY 동시 사용"
90
+ severity: "high"
91
+ category: "performance"
92
+ description: "SELECT DISTINCT와 GROUP BY를 동시에 사용하면 불필요한 중복 정렬이 발생합니다."
93
+ enabled: true
94
+ pattern:
95
+ type: "regex-multiline"
96
+ regex: "\\bSELECT\\s+DISTINCT\\b[\\s\\S]*?\\bGROUP\\s+BY\\b"
97
+ flags: "i"
98
+
99
+ # ========== 3. ast-filtered-regex ==========
100
+ - type: "ast-filtered-regex"
101
+ description: "Java AST 분석으로 주석/문자열 내부를 제외한 후 정규식 매칭."
102
+ languages: [java]
103
+ params:
104
+ required: [regex]
105
+ optional: [flags]
106
+ notes: |
107
+ - regex와 동일하지만, 주석(// /* */)과 문자열 리터럴 내부를 제외
108
+ - SQL 문자열 연결 등 정확한 코드 영역만 검출할 때 사용
109
+ example:
110
+ - id: "custom-security-001"
111
+ name: "문자열 연결 쿼리 금지"
112
+ severity: "critical"
113
+ category: "sql-injection"
114
+ description: "SQL 문자열 연결은 SQL Injection에 취약합니다."
115
+ enabled: true
116
+ pattern:
117
+ type: "ast-filtered-regex"
118
+ regex: "\"SELECT[^\"]*\"\\s*\\+|\"INSERT[^\"]*\"\\s*\\+|\"UPDATE[^\"]*\"\\s*\\+|\"DELETE[^\"]*\"\\s*\\+"
119
+
120
+ # ========== 4. annotation-missing-attr ==========
121
+ - type: "annotation-missing-attr"
122
+ description: "Java 어노테이션에서 필수 속성이 누락된 경우 검출."
123
+ languages: [java]
124
+ params:
125
+ required: [annotation, required_attr]
126
+ optional: []
127
+ notes: |
128
+ - annotation: 어노테이션 이름 (@ 제외)
129
+ - required_attr: 반드시 있어야 하는 속성명
130
+ example:
131
+ - id: "custom-api-001"
132
+ name: "@DzParam key 속성 누락"
133
+ severity: "high"
134
+ category: "api"
135
+ description: "@DzParam 어노테이션에 key 속성이 필요합니다."
136
+ enabled: true
137
+ pattern:
138
+ type: "annotation-missing-attr"
139
+ annotation: "DzParam"
140
+ required_attr: "key"
141
+
142
+ # ========== 5. line-length ==========
143
+ - type: "line-length"
144
+ description: "라인 길이가 max_length를 초과하는 경우 검출."
145
+ languages: [java, sql, javascript, python]
146
+ params:
147
+ required: [max_length]
148
+ optional: [line_pattern]
149
+ notes: |
150
+ - max_length: 최대 허용 문자 수
151
+ - line_pattern: 특정 패턴의 라인만 검사 (정규식, 선택사항)
152
+ example:
153
+ - id: "custom-format-001"
154
+ name: "SQL 라인 80자 초과"
155
+ severity: "low"
156
+ category: "format"
157
+ description: "한 라인 80자 초과는 가독성을 저해합니다."
158
+ enabled: true
159
+ pattern:
160
+ type: "line-length"
161
+ max_length: 80
162
+
163
+ # ========== 6. ast-method-call ==========
164
+ - type: "ast-method-call"
165
+ description: "Java 메서드 호출 탐지. 메서드명, 호출 객체, 컨텍스트 조건 지정 가능."
166
+ languages: [java]
167
+ params:
168
+ required: []
169
+ optional: [method, qualifier, context]
170
+ notes: |
171
+ - method: 메서드명 정규식 (예: "^executeQuery$")
172
+ - qualifier: 호출 객체 정규식 (예: "(?i)engine")
173
+ - context: 호출 위치 조건
174
+ - "inside-loop": 루프 내부
175
+ - "inside-catch": catch 블록 내부
176
+ - "not-inside-catch": catch 블록 외부
177
+ - "method-name:<regex>": 특정 메서드 내
178
+ - "has-method-annotation:<regex>": 메서드에 특정 어노테이션이 있을 때
179
+ custom_fields: [args_min, args_max, fix]
180
+ example:
181
+ - id: "custom-perf-001"
182
+ name: "루프 내 DB 호출"
183
+ severity: "high"
184
+ category: "performance"
185
+ description: "루프 내에서 DB 쿼리를 호출하면 N+1 문제가 발생합니다."
186
+ enabled: true
187
+ pattern:
188
+ type: "ast-method-call"
189
+ method: "^(executeQuery|executeUpdate)$"
190
+ context: "inside-loop"
191
+
192
+ # ========== 7. ast-annotation ==========
193
+ - type: "ast-annotation"
194
+ description: "Java 어노테이션 존재/속성 검사."
195
+ languages: [java]
196
+ params:
197
+ required: [annotation]
198
+ optional: [missing_attr_name, attr_value, context]
199
+ notes: |
200
+ - annotation: 어노테이션명 정규식 (@ 제외, 예: "^Autowired$")
201
+ - missing_attr_name: 이 속성이 없으면 위반 (예: "method")
202
+ - attr_value: 속성값 정규식
203
+ - context: "method-name:<regex>" 등
204
+ example:
205
+ - id: "custom-design-001"
206
+ name: "@RequestMapping method 속성 누락"
207
+ severity: "medium"
208
+ category: "design"
209
+ description: "@RequestMapping에 method 속성이 없으면 모든 HTTP 메서드를 허용합니다."
210
+ enabled: true
211
+ pattern:
212
+ type: "ast-annotation"
213
+ annotation: "^RequestMapping$"
214
+ missing_attr_name: "method"
215
+ context: "method-name:.*"
216
+
217
+ # ========== 8. ast-import ==========
218
+ - type: "ast-import"
219
+ description: "Java import 문 검사. deprecated/금지 패키지 검출."
220
+ languages: [java]
221
+ params:
222
+ required: [import]
223
+ optional: [class_annotation]
224
+ notes: |
225
+ - import: import 경로 정규식 (예: "^java\\.util\\.Date$")
226
+ - class_annotation: 클래스에 특정 어노테이션이 있을 때만 검사
227
+ example:
228
+ - id: "custom-deprecated-001"
229
+ name: "java.util.Date import 금지"
230
+ severity: "medium"
231
+ category: "deprecated"
232
+ description: "java.util.Date는 thread-unsafe합니다. java.time API를 사용하세요."
233
+ enabled: true
234
+ pattern:
235
+ type: "ast-import"
236
+ import: "^java\\.util\\.Date$"
237
+
238
+ # ========== 9. ast-variable ==========
239
+ - type: "ast-variable"
240
+ description: "Java 변수 선언 검사. 타입, 이름 패턴으로 네이밍 규칙 위반 검출."
241
+ languages: [java]
242
+ params:
243
+ required: []
244
+ optional: [name_pattern, type_pattern]
245
+ notes: |
246
+ - name_pattern: 변수명 정규식 (위반 시 매칭)
247
+ - type_pattern: 변수 타입 정규식
248
+ - 둘 다 지정 시 AND 조건
249
+ example:
250
+ - id: "custom-naming-001"
251
+ name: "String 변수 헝가리안 표기법 금지"
252
+ severity: "low"
253
+ category: "naming"
254
+ description: "strXxx 형태의 헝가리안 표기법은 사용하지 마세요."
255
+ enabled: true
256
+ pattern:
257
+ type: "ast-variable"
258
+ type_pattern: "String"
259
+ name_pattern: "^str[A-Z]"
260
+
261
+ # ========== 10. ast-try-catch ==========
262
+ - type: "ast-try-catch"
263
+ description: "Java 예외 처리 패턴 검사. 빈 catch, 특정 예외 타입 처리 등."
264
+ languages: [java]
265
+ params:
266
+ required: []
267
+ optional: [exception_type]
268
+ notes: |
269
+ - exception_type: catch하는 예외 타입 정규식 (예: "IOException|SQLException")
270
+ - custom.catch_is_empty: true → 빈 catch 블록 검출
271
+ - custom.has_resources: false → try-with-resources 미사용
272
+ - custom.has_finally: false → finally 블록 없음
273
+ example:
274
+ - id: "custom-exception-001"
275
+ name: "빈 catch 블록"
276
+ severity: "critical"
277
+ category: "exception"
278
+ description: "catch 블록이 비어있으면 예외가 무시됩니다."
279
+ enabled: true
280
+ pattern:
281
+ type: "ast-try-catch"
282
+ custom:
283
+ catch_is_empty: true
284
+ fix: "catch 블록에 logger.error(\"message\", e)를 추가하세요"
285
+
286
+ # ========== 11. ast-class ==========
287
+ - type: "ast-class"
288
+ description: "Java 클래스 레벨 검사. 클래스명, 메서드 수, 필수 어노테이션 등."
289
+ languages: [java]
290
+ params:
291
+ required: []
292
+ optional: [name_pattern, has_annotation, missing_annotation]
293
+ notes: |
294
+ - name_pattern: 클래스명 정규식 (예: ".*ServiceImpl$")
295
+ - has_annotation: 클래스에 이 어노테이션이 있을 때 검사
296
+ - missing_annotation: 클래스에 이 어노테이션이 없으면 위반
297
+ - custom.max_methods: 메서드 수 초과 시 위반
298
+ example:
299
+ - id: "custom-design-002"
300
+ name: "ServiceImpl 과대 클래스"
301
+ severity: "medium"
302
+ category: "design"
303
+ description: "ServiceImpl 클래스의 메서드가 너무 많습니다. 책임을 분리하세요."
304
+ enabled: true
305
+ pattern:
306
+ type: "ast-class"
307
+ name_pattern: ".*ServiceImpl$"
308
+ custom:
309
+ max_methods: 20
310
+ fix: "도메인별로 Service 클래스를 분리하세요"
311
+
312
+ # ========== 12. ast-method ==========
313
+ - type: "ast-method"
314
+ description: "Java 메서드 선언 검사. 메서드명, 파라미터 수, 라인 수 등."
315
+ languages: [java]
316
+ params:
317
+ required: []
318
+ optional: [name_pattern, context]
319
+ notes: |
320
+ - name_pattern: 메서드명 정규식
321
+ - context: "has-method-annotation:<regex>" 등
322
+ - custom.max_lines: 메서드 라인 수 초과 시 위반
323
+ - custom.max_params: 파라미터 수 초과 시 위반
324
+ example:
325
+ - id: "custom-design-003"
326
+ name: "메서드 라인 수 초과"
327
+ severity: "medium"
328
+ category: "design"
329
+ description: "메서드가 너무 깁니다. 50줄 이내로 분리하세요."
330
+ enabled: true
331
+ pattern:
332
+ type: "ast-method"
333
+ custom:
334
+ max_lines: 50
335
+ fix: "메서드를 더 작은 단위로 분리하세요"
336
+
337
+ # ========== 13. ast-multi-cud ==========
338
+ - type: "ast-multi-cud"
339
+ description: "Java 메서드 내 복수 CUD(Create/Update/Delete) 호출 검사. @Transactional 누락 검출."
340
+ languages: [java]
341
+ params:
342
+ required: []
343
+ optional: [method, qualifier]
344
+ notes: |
345
+ - method: CUD 메서드명 정규식 (예: "insert|update|delete|save|remove")
346
+ - qualifier: 호출 대상 객체 정규식 (예: ".*Dao|.*Repository|.*Mapper")
347
+ - custom.min_cud_calls: N개 이상 CUD 호출 시 위반 (기본: 2)
348
+ example:
349
+ - id: "custom-tx-001"
350
+ name: "복수 CUD 작업에 @Transactional 누락"
351
+ severity: "high"
352
+ category: "transaction"
353
+ description: "2개 이상의 CUD 작업 호출 시 @Transactional이 필요합니다."
354
+ enabled: true
355
+ pattern:
356
+ type: "ast-multi-cud"
357
+ method: "insert|update|delete|save|remove|create|modify"
358
+ qualifier: ".*Dao|.*Repository|.*Mapper|.*Service"
359
+ custom:
360
+ min_cud_calls: 2
361
+ fix: "@Transactional을 추가하세요"
362
+
363
+ # ========== 14. ast-dead-code ==========
364
+ - type: "ast-dead-code"
365
+ description: "Java 미사용 코드 검출. private 메서드/필드 중 호출되지 않는 것 검출."
366
+ languages: [java]
367
+ params:
368
+ required: []
369
+ optional: []
370
+ notes: |
371
+ - 파일 내에서 선언되었으나 사용되지 않는 private 메서드/필드 검출
372
+ - 리플렉션이나 외부 참조는 탐지 불가 (오탐 가능)
373
+ example:
374
+ - id: "custom-clean-001"
375
+ name: "미사용 private 메서드"
376
+ severity: "low"
377
+ category: "dead-code"
378
+ description: "사용되지 않는 private 메서드는 제거하세요."
379
+ enabled: true
380
+ pattern:
381
+ type: "ast-dead-code"
382
+
383
+ # ========== 15. ast-sql-table ==========
384
+ - type: "ast-sql-table"
385
+ description: "SQL AST 분석 — 테이블 참조 검사. 과다 테이블 조인 등."
386
+ languages: [sql]
387
+ params:
388
+ required: [conditions]
389
+ optional: []
390
+ notes: |
391
+ conditions 값:
392
+ - "table-count-excessive": JOIN 테이블 수 초과 (custom.max_tables로 임계값)
393
+ - "missing-alias": 테이블 별칭 누락
394
+ example:
395
+ - id: "custom-sql-table-001"
396
+ name: "JOIN 테이블 7개 초과"
397
+ severity: "high"
398
+ category: "maintainability"
399
+ description: "JOIN 테이블이 7개를 초과합니다. 쿼리를 분리하세요."
400
+ enabled: true
401
+ pattern:
402
+ type: "ast-sql-table"
403
+ conditions:
404
+ - "table-count-excessive"
405
+ custom:
406
+ max_tables: 7
407
+
408
+ # ========== 16. ast-sql-join ==========
409
+ - type: "ast-sql-join"
410
+ description: "SQL AST 분석 — JOIN 패턴 검사."
411
+ languages: [sql]
412
+ params:
413
+ required: [conditions]
414
+ optional: []
415
+ notes: |
416
+ conditions 값:
417
+ - "left-join-excessive": LEFT JOIN 과다 (custom.max_left_joins)
418
+ - "cartesian-product": 카르테시안 곱 (FROM a, b without JOIN condition)
419
+ - "left-join-where-filter": LEFT JOIN 후 WHERE에서 필터 (실질 INNER JOIN)
420
+ - "inner-after-left": LEFT JOIN 체인에서 INNER JOIN 사용
421
+ example:
422
+ - id: "custom-sql-join-001"
423
+ name: "LEFT JOIN 과다"
424
+ severity: "high"
425
+ category: "maintainability"
426
+ description: "LEFT JOIN이 5개를 초과합니다."
427
+ enabled: true
428
+ pattern:
429
+ type: "ast-sql-join"
430
+ conditions:
431
+ - "left-join-excessive"
432
+ custom:
433
+ max_left_joins: 5
434
+
435
+ # ========== 17. ast-sql-select ==========
436
+ - type: "ast-sql-select"
437
+ description: "SQL AST 분석 — SELECT 절 검사."
438
+ languages: [sql]
439
+ params:
440
+ required: [conditions]
441
+ optional: []
442
+ notes: |
443
+ conditions 값:
444
+ - "select-star": SELECT * 사용
445
+ - "column-count-excessive": 컬럼 수 초과 (custom.max_columns)
446
+ example:
447
+ - id: "custom-sql-select-001"
448
+ name: "SELECT * 사용 금지"
449
+ severity: "medium"
450
+ category: "performance"
451
+ description: "SELECT *는 불필요한 컬럼까지 조회합니다."
452
+ enabled: true
453
+ pattern:
454
+ type: "ast-sql-select"
455
+ conditions:
456
+ - "select-star"
457
+
458
+ # ========== 18. ast-sql-where ==========
459
+ - type: "ast-sql-where"
460
+ description: "SQL AST 분석 — WHERE 절 검사."
461
+ languages: [sql]
462
+ params:
463
+ required: [conditions]
464
+ optional: []
465
+ notes: |
466
+ conditions 값:
467
+ - "function-on-column": 컬럼에 함수 적용 (인덱스 무효화)
468
+ - "implicit-type-cast": 암시적 타입 변환
469
+ - "having-non-aggregate": HAVING절에 비집계 조건
470
+ example:
471
+ - id: "custom-sql-where-001"
472
+ name: "WHERE 절 컬럼 함수 적용"
473
+ severity: "high"
474
+ category: "performance"
475
+ description: "WHERE절에서 컬럼에 함수를 적용하면 인덱스를 사용할 수 없습니다."
476
+ enabled: true
477
+ pattern:
478
+ type: "ast-sql-where"
479
+ conditions:
480
+ - "function-on-column"
481
+
482
+ # ========== 19. ast-sql-subquery ==========
483
+ - type: "ast-sql-subquery"
484
+ description: "SQL AST 분석 — 서브쿼리 검사."
485
+ languages: [sql]
486
+ params:
487
+ required: [conditions]
488
+ optional: []
489
+ notes: |
490
+ conditions 값:
491
+ - "scalar-subquery-excessive": SELECT절 스칼라 서브쿼리 과다 (custom.max_scalar_subqueries)
492
+ - "correlated-in-where": WHERE절 상관 서브쿼리
493
+ - "nested-depth-excessive": 서브쿼리 중첩 깊이 과다
494
+ example:
495
+ - id: "custom-sql-subquery-001"
496
+ name: "스칼라 서브쿼리 과다"
497
+ severity: "high"
498
+ category: "performance"
499
+ description: "SELECT 절에 스칼라 서브쿼리가 2개를 초과합니다."
500
+ enabled: true
501
+ pattern:
502
+ type: "ast-sql-subquery"
503
+ conditions:
504
+ - "scalar-subquery-excessive"
505
+ custom:
506
+ max_scalar_subqueries: 2
507
+
508
+ # ========== 20. ast-sql-hint ==========
509
+ - type: "ast-sql-hint"
510
+ description: "SQL AST 분석 — Oracle 힌트 검사."
511
+ languages: [sql]
512
+ params:
513
+ required: [conditions]
514
+ optional: []
515
+ notes: |
516
+ conditions 값:
517
+ - "hint-exists": 힌트 사용 감지
518
+ - "non-leading-hint": LEADING 외 힌트 사용
519
+ example:
520
+ - id: "custom-sql-hint-001"
521
+ name: "힌트 사용 감지"
522
+ severity: "high"
523
+ category: "hint"
524
+ description: "힌트 사용은 DBA 협의가 필요합니다."
525
+ enabled: true
526
+ pattern:
527
+ type: "ast-sql-hint"
528
+ conditions:
529
+ - "hint-exists"
530
+
531
+ # ─────────────────────────────────────────────
532
+ # 추가 SQL AST 타입 (참고)
533
+ # ─────────────────────────────────────────────
534
+ additional_sql_types:
535
+ - type: "ast-sql-setop"
536
+ description: "UNION/EXCEPT/INTERSECT 연산 검사"
537
+ conditions: ["union-without-all", "setop-column-mismatch"]
538
+
539
+ - type: "ast-sql-orderby"
540
+ description: "ORDER BY 절 검사"
541
+ conditions: ["orderby-number", "orderby-with-union"]
542
+
543
+ # ─────────────────────────────────────────────
544
+ # YAML로 생성 불가능한 타입 (Go 코드 수정 필요)
545
+ # ─────────────────────────────────────────────
546
+ code_only_types:
547
+ - type: "method-analysis"
548
+ description: "Go로 구현된 커스텀 분석 로직. MyBatis XML 내 SQL 추출, 복합 분석 등."
549
+ note: "YAML로 생성 불가. Go 소스 수정 필요."
550
+ existing_rules:
551
+ - "sql-fmt-*" # SQL 포맷 규칙 (method-analysis 기반)
552
+ - "sql-mybatis-*" # MyBatis SQL 추출 기반 규칙
553
+
554
+ - type: "cross-file"
555
+ description: "여러 파일에 걸친 분석. 인터페이스-구현체 불일치 등."
556
+ note: "YAML로 생성 불가. Go 소스 수정 필요."
557
+
558
+ - type: "private-field"
559
+ description: "private 필드 접근 패턴 분석."
560
+ note: "Go 엔진 내장 규칙."
561
+
562
+ - type: "private-method"
563
+ description: "private 메서드 호출 패턴 분석."
564
+ note: "Go 엔진 내장 규칙."
565
+
566
+ # ─────────────────────────────────────────────
567
+ # 유효한 카테고리 예시
568
+ # ─────────────────────────────────────────────
569
+ category_examples:
570
+ - naming # 명명규칙
571
+ - security # 보안
572
+ - sql-injection # SQL 인젝션
573
+ - exception # 예외 처리
574
+ - performance # 성능
575
+ - design # 설계
576
+ - transaction # 트랜잭션
577
+ - logging # 로깅
578
+ - deprecated # 비추천 API
579
+ - format # 포맷/스타일
580
+ - documentation # 문서화
581
+ - dead-code # 미사용 코드
582
+ - maintainability # 유지보수성
583
+ - correctness # 정확성
584
+ - architecture # 아키텍처
585
+ - resource # 리소스 관리
586
+ - api # API 규약
587
+ - hint # SQL 힌트