@hatem427/code-guard-ci 3.0.0 → 3.1.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 (102) hide show
  1. package/config/fastify.config.ts +326 -0
  2. package/config/hono.config.ts +331 -0
  3. package/config/nestjs.config.ts +500 -0
  4. package/config/node.config.ts +425 -0
  5. package/config/python.config.ts +512 -0
  6. package/dist/config/fastify.config.d.ts +17 -0
  7. package/dist/config/fastify.config.d.ts.map +1 -0
  8. package/dist/config/fastify.config.js +279 -0
  9. package/dist/config/fastify.config.js.map +1 -0
  10. package/dist/config/hono.config.d.ts +17 -0
  11. package/dist/config/hono.config.d.ts.map +1 -0
  12. package/dist/config/hono.config.js +287 -0
  13. package/dist/config/hono.config.js.map +1 -0
  14. package/dist/config/nestjs.config.d.ts +17 -0
  15. package/dist/config/nestjs.config.d.ts.map +1 -0
  16. package/dist/config/nestjs.config.js +440 -0
  17. package/dist/config/nestjs.config.js.map +1 -0
  18. package/dist/config/node.config.d.ts +17 -0
  19. package/dist/config/node.config.d.ts.map +1 -0
  20. package/dist/config/node.config.js +363 -0
  21. package/dist/config/node.config.js.map +1 -0
  22. package/dist/config/python.config.d.ts +15 -0
  23. package/dist/config/python.config.d.ts.map +1 -0
  24. package/dist/config/python.config.js +475 -0
  25. package/dist/config/python.config.js.map +1 -0
  26. package/dist/scripts/auto-fix.d.ts +5 -0
  27. package/dist/scripts/auto-fix.d.ts.map +1 -1
  28. package/dist/scripts/auto-fix.js +5 -0
  29. package/dist/scripts/auto-fix.js.map +1 -1
  30. package/dist/scripts/cli.js +2 -2
  31. package/dist/scripts/cli.js.map +1 -1
  32. package/dist/scripts/config-generators/ai-config-generator.d.ts.map +1 -1
  33. package/dist/scripts/config-generators/ai-config-generator.js +6 -0
  34. package/dist/scripts/config-generators/ai-config-generator.js.map +1 -1
  35. package/dist/scripts/config-generators/eslint-generator.d.ts.map +1 -1
  36. package/dist/scripts/config-generators/eslint-generator.js +108 -0
  37. package/dist/scripts/config-generators/eslint-generator.js.map +1 -1
  38. package/dist/scripts/config-generators/frameworks/fastify.d.ts +6 -0
  39. package/dist/scripts/config-generators/frameworks/fastify.d.ts.map +1 -0
  40. package/dist/scripts/config-generators/frameworks/fastify.js +68 -0
  41. package/dist/scripts/config-generators/frameworks/fastify.js.map +1 -0
  42. package/dist/scripts/config-generators/frameworks/hono.d.ts +6 -0
  43. package/dist/scripts/config-generators/frameworks/hono.d.ts.map +1 -0
  44. package/dist/scripts/config-generators/frameworks/hono.js +63 -0
  45. package/dist/scripts/config-generators/frameworks/hono.js.map +1 -0
  46. package/dist/scripts/config-generators/frameworks/index.d.ts +3 -0
  47. package/dist/scripts/config-generators/frameworks/index.d.ts.map +1 -1
  48. package/dist/scripts/config-generators/frameworks/index.js +7 -1
  49. package/dist/scripts/config-generators/frameworks/index.js.map +1 -1
  50. package/dist/scripts/config-generators/frameworks/nestjs.d.ts +6 -0
  51. package/dist/scripts/config-generators/frameworks/nestjs.d.ts.map +1 -0
  52. package/dist/scripts/config-generators/frameworks/nestjs.js +83 -0
  53. package/dist/scripts/config-generators/frameworks/nestjs.js.map +1 -0
  54. package/dist/scripts/config-generators/frameworks/node.d.ts +2 -2
  55. package/dist/scripts/config-generators/frameworks/node.d.ts.map +1 -1
  56. package/dist/scripts/config-generators/frameworks/node.js +56 -11
  57. package/dist/scripts/config-generators/frameworks/node.js.map +1 -1
  58. package/dist/scripts/config-generators/typescript-generator.d.ts.map +1 -1
  59. package/dist/scripts/config-generators/typescript-generator.js +33 -0
  60. package/dist/scripts/config-generators/typescript-generator.js.map +1 -1
  61. package/dist/scripts/config-generators/vscode-generator.d.ts.map +1 -1
  62. package/dist/scripts/config-generators/vscode-generator.js +73 -0
  63. package/dist/scripts/config-generators/vscode-generator.js.map +1 -1
  64. package/dist/scripts/generate-pr-checklist.d.ts +5 -0
  65. package/dist/scripts/generate-pr-checklist.d.ts.map +1 -1
  66. package/dist/scripts/generate-pr-checklist.js +6 -1
  67. package/dist/scripts/generate-pr-checklist.js.map +1 -1
  68. package/dist/scripts/postinstall.js +38 -0
  69. package/dist/scripts/postinstall.js.map +1 -1
  70. package/dist/scripts/precommit-check.d.ts +13 -0
  71. package/dist/scripts/precommit-check.d.ts.map +1 -1
  72. package/dist/scripts/precommit-check.js +288 -5
  73. package/dist/scripts/precommit-check.js.map +1 -1
  74. package/dist/scripts/utils/naming-validator.d.ts.map +1 -1
  75. package/dist/scripts/utils/naming-validator.js +96 -2
  76. package/dist/scripts/utils/naming-validator.js.map +1 -1
  77. package/dist/scripts/utils/project-detector.d.ts +12 -9
  78. package/dist/scripts/utils/project-detector.d.ts.map +1 -1
  79. package/dist/scripts/utils/project-detector.js +63 -11
  80. package/dist/scripts/utils/project-detector.js.map +1 -1
  81. package/dist/scripts/utils/structure-validator.d.ts.map +1 -1
  82. package/dist/scripts/utils/structure-validator.js +50 -0
  83. package/dist/scripts/utils/structure-validator.js.map +1 -1
  84. package/package.json +10 -3
  85. package/scripts/auto-fix.ts +5 -0
  86. package/scripts/cli.ts +2 -2
  87. package/scripts/config-generators/ai-config-generator.ts +9 -0
  88. package/scripts/config-generators/eslint-generator.ts +110 -0
  89. package/scripts/config-generators/frameworks/fastify.ts +65 -0
  90. package/scripts/config-generators/frameworks/hono.ts +60 -0
  91. package/scripts/config-generators/frameworks/index.ts +3 -0
  92. package/scripts/config-generators/frameworks/nestjs.ts +80 -0
  93. package/scripts/config-generators/frameworks/node.ts +57 -11
  94. package/scripts/config-generators/typescript-generator.ts +36 -0
  95. package/scripts/config-generators/vscode-generator.ts +84 -0
  96. package/scripts/generate-pr-checklist.ts +6 -1
  97. package/scripts/postinstall.ts +38 -0
  98. package/scripts/precommit-check.ts +334 -6
  99. package/scripts/utils/naming-validator.ts +104 -2
  100. package/scripts/utils/project-detector.ts +78 -11
  101. package/scripts/utils/structure-validator.ts +54 -0
  102. package/templates/feature-doc-backend.md +114 -0
@@ -0,0 +1,475 @@
1
+ "use strict";
2
+ /**
3
+ * ============================================================================
4
+ * python.config.ts — Python-specific coding rules
5
+ * ============================================================================
6
+ *
7
+ * Registers rules that apply to Python projects (Django, FastAPI, Flask,
8
+ * and generic Python). Rules are applied based on the `applicableTo` field:
9
+ * - ['python'] → all Python projects
10
+ * - ['django'] → Django only
11
+ * - ['fastapi'] → FastAPI only
12
+ * - ['flask'] → Flask only
13
+ * - ['django', 'fastapi'] → multi-framework
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ const guidelines_config_1 = require("./guidelines.config");
17
+ const pythonRules = [
18
+ // ── Generic Python ────────────────────────────────────────────────────────
19
+ // ─────────────────────────────────────────
20
+ // RULE: python-no-bare-except
21
+ // ROLE: Enforce specific exception handling
22
+ // PURPOSE: `except:` (bare) silently swallows every exception including
23
+ // KeyboardInterrupt and SystemExit, making debugging impossible
24
+ // and preventing graceful shutdown.
25
+ // EXAMPLE:
26
+ // WRONG:
27
+ // try:
28
+ // result = db.query(...)
29
+ // except:
30
+ // pass
31
+ // RIGHT:
32
+ // try:
33
+ // result = db.query(...)
34
+ // except Exception as e:
35
+ // logger.error("Query failed: %s", e)
36
+ // raise
37
+ // ─────────────────────────────────────────
38
+ {
39
+ id: 'python-no-bare-except',
40
+ label: 'No bare except clauses',
41
+ description: 'Always catch a specific exception type (e.g. `except ValueError`) or at minimum `except Exception`. Bare `except:` swallows every error including KeyboardInterrupt.',
42
+ severity: 'error',
43
+ fileExtensions: ['py'],
44
+ pattern: /^\s*except\s*:/,
45
+ applicableTo: ['python', 'django', 'fastapi', 'flask'],
46
+ category: 'Error Handling',
47
+ },
48
+ // ─────────────────────────────────────────
49
+ // RULE: python-no-print-statements
50
+ // ROLE: Enforce structured logging
51
+ // PURPOSE: print() in production code bypasses log aggregation systems
52
+ // (CloudWatch, Datadog, etc.) and cannot be toggled by log level.
53
+ // Use the standard `logging` module or a structured logger instead.
54
+ // EXAMPLE:
55
+ // WRONG: print(f"User {user_id} created")
56
+ // RIGHT: logger.info("User %s created", user_id)
57
+ // ─────────────────────────────────────────
58
+ {
59
+ id: 'python-no-print-statements',
60
+ label: 'No print() in production code — use logging',
61
+ description: 'Replace print() calls with proper logging (logging.info / logger.info). print() bypasses log levels, log aggregation, and structured logging pipelines.',
62
+ severity: 'warning',
63
+ fileExtensions: ['py'],
64
+ pattern: /(?<![#\w])print\s*\(/,
65
+ applicableTo: ['python', 'django', 'fastapi', 'flask'],
66
+ category: 'Observability',
67
+ },
68
+ // ─────────────────────────────────────────
69
+ // RULE: python-no-hardcoded-secrets
70
+ // ROLE: Prevent credential leaks in source code
71
+ // PURPOSE: Hardcoded passwords, API keys, and secret tokens get committed
72
+ // to version control and are trivially discoverable.
73
+ // EXAMPLE:
74
+ // WRONG: SECRET_KEY = "mysupersecret123"
75
+ // RIGHT: SECRET_KEY = os.environ["SECRET_KEY"]
76
+ // ─────────────────────────────────────────
77
+ {
78
+ id: 'python-no-hardcoded-secrets',
79
+ label: 'No hardcoded secrets or API keys',
80
+ description: 'Do not hardcode passwords, API keys, or secret tokens. Load sensitive values from environment variables or a secrets manager.',
81
+ severity: 'error',
82
+ fileExtensions: ['py'],
83
+ pattern: /(?:password|secret|api_key|apikey|token|auth_key)\s*=\s*['"][^'"]{6,}['"]/i,
84
+ applicableTo: ['python', 'django', 'fastapi', 'flask'],
85
+ category: 'Security',
86
+ },
87
+ // ─────────────────────────────────────────
88
+ // RULE: python-no-eval
89
+ // ROLE: Prevent arbitrary code execution
90
+ // PURPOSE: eval() and exec() execute arbitrary strings as code, opening
91
+ // a direct remote-code-execution vector if user input reaches them.
92
+ // EXAMPLE:
93
+ // WRONG: result = eval(user_input)
94
+ // RIGHT: use ast.literal_eval() for safe literal parsing
95
+ // ─────────────────────────────────────────
96
+ {
97
+ id: 'python-no-eval',
98
+ label: 'No eval() or exec() with dynamic input',
99
+ description: 'eval() and exec() are remote code execution vulnerabilities when fed user-controlled data. Use ast.literal_eval() for data parsing or redesign the logic.',
100
+ severity: 'error',
101
+ fileExtensions: ['py'],
102
+ pattern: /\beval\s*\(|\bexec\s*\(/,
103
+ applicableTo: ['python', 'django', 'fastapi', 'flask'],
104
+ category: 'Security',
105
+ },
106
+ // ─────────────────────────────────────────
107
+ // RULE: python-type-hints-required
108
+ // ROLE: Enforce type annotations on function signatures
109
+ // PURPOSE: Type hints enable static analysis (mypy, pyright), improve IDE
110
+ // autocompletion, and make APIs self-documenting.
111
+ // EXAMPLE:
112
+ // WRONG:
113
+ // def create_user(name, email):
114
+ // ...
115
+ // RIGHT:
116
+ // def create_user(name: str, email: str) -> User:
117
+ // ...
118
+ // ─────────────────────────────────────────
119
+ {
120
+ id: 'python-type-hints-required',
121
+ label: 'Add type hints to function parameters and return types',
122
+ description: 'Public functions and methods should have type annotations on all parameters and the return type. Enables mypy/pyright static analysis.',
123
+ severity: 'warning',
124
+ fileExtensions: ['py'],
125
+ pattern: /^def\s+[a-z_]\w*\s*\([^)]*\)\s*:/,
126
+ customCheck: (file) => {
127
+ const violations = [];
128
+ for (let i = 0; i < file.lines.length; i++) {
129
+ const line = file.lines[i];
130
+ // Match function definitions without return type annotation (no ->)
131
+ if (/^\s*def\s+[a-z_]\w*\s*\([^)]*\)\s*:/.test(line) && !line.includes('->')) {
132
+ // Skip dunder methods like __init__, __str__
133
+ if (!/__\w+__/.test(line)) {
134
+ violations.push({
135
+ line: i + 1,
136
+ message: 'Function is missing a return type annotation. Add `-> ReturnType:` after the parameter list.',
137
+ });
138
+ }
139
+ }
140
+ }
141
+ return violations;
142
+ },
143
+ applicableTo: ['python', 'django', 'fastapi', 'flask'],
144
+ category: 'Code Quality',
145
+ },
146
+ // ── Django ────────────────────────────────────────────────────────────────
147
+ // ─────────────────────────────────────────
148
+ // RULE: django-no-raw-sql
149
+ // ROLE: Prevent SQL injection via raw queries
150
+ // PURPOSE: cursor.execute() and raw() with string formatting bypass the ORM
151
+ // parameterization, enabling SQL injection if user input is present.
152
+ // EXAMPLE:
153
+ // WRONG:
154
+ // cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
155
+ // RIGHT:
156
+ // cursor.execute("SELECT * FROM users WHERE id = %s", [user_id])
157
+ // OR: User.objects.filter(id=user_id)
158
+ // ─────────────────────────────────────────
159
+ {
160
+ id: 'django-no-raw-sql',
161
+ label: 'No string-formatted raw SQL queries',
162
+ description: 'cursor.execute() and .raw() with f-strings or % formatting are SQL injection risks. Use parameterized queries or the Django ORM.',
163
+ severity: 'error',
164
+ fileExtensions: ['py'],
165
+ pattern: /cursor\.execute\s*\(\s*f['"]|cursor\.execute\s*\(\s*['"][^'"]*%\s*(?!s\b|\()/,
166
+ applicableTo: ['django'],
167
+ category: 'Security',
168
+ },
169
+ // ─────────────────────────────────────────
170
+ // RULE: django-no-logic-in-view
171
+ // ROLE: Enforce thin views (controller pattern)
172
+ // PURPOSE: Business logic in Django views cannot be unit-tested without
173
+ // the full HTTP request/response cycle. Logic belongs in service
174
+ // modules or model methods.
175
+ // EXAMPLE:
176
+ // WRONG:
177
+ // class UserCreateView(APIView):
178
+ // def post(self, request):
179
+ // salt = bcrypt.gensalt()
180
+ // hashed = bcrypt.hashpw(request.data['password'].encode(), salt)
181
+ // User.objects.create(password=hashed, ...)
182
+ // RIGHT:
183
+ // class UserCreateView(APIView):
184
+ // def post(self, request):
185
+ // serializer = UserSerializer(data=request.data)
186
+ // serializer.is_valid(raise_exception=True)
187
+ // return UserService.create(serializer.validated_data)
188
+ // ─────────────────────────────────────────
189
+ {
190
+ id: 'django-no-logic-in-view',
191
+ label: 'No business logic in Django views',
192
+ description: 'Django views should only validate input (via serializers/forms) and delegate to service modules. Move hashing, computation, and ORM writes to a service layer.',
193
+ severity: 'warning',
194
+ fileExtensions: ['py'],
195
+ pattern: null,
196
+ customCheck: (file) => {
197
+ const violations = [];
198
+ if (!file.relativePath.includes('/views/') &&
199
+ !file.relativePath.endsWith('views.py') &&
200
+ !file.relativePath.endsWith('viewsets.py')) {
201
+ return [];
202
+ }
203
+ const businessPatterns = [
204
+ { regex: /bcrypt\.(hashpw|checkpw|gensalt)/g, label: 'bcrypt hashing' },
205
+ { regex: /\.objects\.create\s*\(/g, label: 'direct ORM create()' },
206
+ { regex: /send_mail\s*\(|send_message\s*\(/g, label: 'direct email/message send' },
207
+ ];
208
+ for (let i = 0; i < file.lines.length; i++) {
209
+ for (const { regex, label } of businessPatterns) {
210
+ regex.lastIndex = 0;
211
+ if (regex.test(file.lines[i])) {
212
+ violations.push({
213
+ line: i + 1,
214
+ message: `Business logic (${label}) in view. Move to a service module.`,
215
+ });
216
+ }
217
+ }
218
+ }
219
+ return violations;
220
+ },
221
+ applicableTo: ['django'],
222
+ category: 'Architecture',
223
+ },
224
+ // ─────────────────────────────────────────
225
+ // RULE: django-use-serializer-validation
226
+ // ROLE: Enforce validation via DRF serializers
227
+ // PURPOSE: Accessing request.data directly without calling is_valid() skips
228
+ // all field-level validation and can allow malformed or malicious
229
+ // data into the system.
230
+ // EXAMPLE:
231
+ // WRONG:
232
+ // def post(self, request):
233
+ // User.objects.create(**request.data)
234
+ // RIGHT:
235
+ // def post(self, request):
236
+ // serializer = UserSerializer(data=request.data)
237
+ // serializer.is_valid(raise_exception=True)
238
+ // serializer.save()
239
+ // ─────────────────────────────────────────
240
+ {
241
+ id: 'django-use-serializer-validation',
242
+ label: 'Validate request data through a serializer before use',
243
+ description: 'Do not pass request.data directly to model constructors or ORM calls. Always use a DRF Serializer with is_valid(raise_exception=True) first.',
244
+ severity: 'error',
245
+ fileExtensions: ['py'],
246
+ pattern: /\.objects\.create\s*\(\s*\*\*request\.data/,
247
+ applicableTo: ['django'],
248
+ category: 'Validation',
249
+ },
250
+ // ── FastAPI ───────────────────────────────────────────────────────────────
251
+ // ─────────────────────────────────────────
252
+ // RULE: fastapi-use-pydantic-models
253
+ // ROLE: Enforce schema-based request validation
254
+ // PURPOSE: FastAPI route functions that accept `request: Request` and then
255
+ // call await request.json() bypass Pydantic validation entirely.
256
+ // Pydantic models provide automatic type coercion, validation, and
257
+ // OpenAPI schema generation.
258
+ // EXAMPLE:
259
+ // WRONG:
260
+ // @router.post("/users")
261
+ // async def create_user(request: Request):
262
+ // body = await request.json()
263
+ // RIGHT:
264
+ // @router.post("/users")
265
+ // async def create_user(body: CreateUserRequest):
266
+ // ...
267
+ // ─────────────────────────────────────────
268
+ {
269
+ id: 'fastapi-use-pydantic-models',
270
+ label: 'Use Pydantic models for request bodies — not raw Request',
271
+ description: 'Route handlers should declare their request body as a typed Pydantic model. Using `await request.json()` bypasses validation and OpenAPI schema generation.',
272
+ severity: 'error',
273
+ fileExtensions: ['py'],
274
+ pattern: /await\s+request\.json\s*\(\)/,
275
+ applicableTo: ['fastapi'],
276
+ category: 'Validation',
277
+ },
278
+ // ─────────────────────────────────────────
279
+ // RULE: fastapi-async-route-handler
280
+ // ROLE: Enforce async route handlers
281
+ // PURPOSE: Synchronous route handlers block the FastAPI event loop, which
282
+ // defeats the purpose of the async framework and causes latency
283
+ // spikes under concurrent load.
284
+ // EXAMPLE:
285
+ // WRONG:
286
+ // @router.get("/users/{id}")
287
+ // def get_user(id: int, db: Session = Depends(get_db)):
288
+ // return db.query(User).filter(User.id == id).first()
289
+ // RIGHT:
290
+ // @router.get("/users/{id}")
291
+ // async def get_user(id: int, db: AsyncSession = Depends(get_db)):
292
+ // return await db.get(User, id)
293
+ // ─────────────────────────────────────────
294
+ {
295
+ id: 'fastapi-async-route-handler',
296
+ label: 'Route handlers should be async',
297
+ description: 'Synchronous route handlers block the FastAPI event loop. Use `async def` with async DB drivers (e.g. SQLAlchemy async, databases, asyncpg).',
298
+ severity: 'warning',
299
+ fileExtensions: ['py'],
300
+ pattern: null,
301
+ customCheck: (file) => {
302
+ const violations = [];
303
+ for (let i = 0; i < file.lines.length; i++) {
304
+ const line = file.lines[i];
305
+ // Detect @router.get/post/put/patch/delete followed by a sync def on the next line
306
+ if (/@(?:router|app)\s*\.\s*(?:get|post|put|patch|delete)\s*\(/.test(line)) {
307
+ const nextLine = file.lines[i + 1] || '';
308
+ if (/^\s*def\s+/.test(nextLine) && !/^\s*async\s+def\s+/.test(nextLine)) {
309
+ violations.push({
310
+ line: i + 2,
311
+ message: 'Route handler is synchronous. Use `async def` to avoid blocking the FastAPI event loop.',
312
+ });
313
+ }
314
+ }
315
+ }
316
+ return violations;
317
+ },
318
+ applicableTo: ['fastapi'],
319
+ category: 'Performance',
320
+ },
321
+ // ─────────────────────────────────────────
322
+ // RULE: fastapi-response-model-required
323
+ // ROLE: Enforce response type declarations
324
+ // PURPOSE: Without a response_model, FastAPI will serialize the entire
325
+ // returned object, potentially leaking internal fields (passwords,
326
+ // tokens, internal IDs). response_model also generates the OpenAPI
327
+ // response schema.
328
+ // EXAMPLE:
329
+ // WRONG:
330
+ // @router.post("/users")
331
+ // async def create_user(body: CreateUserRequest, db: AsyncSession = Depends(get_db)):
332
+ // return await user_service.create(db, body)
333
+ // RIGHT:
334
+ // @router.post("/users", response_model=UserResponse, status_code=201)
335
+ // async def create_user(body: CreateUserRequest, db: AsyncSession = Depends(get_db)):
336
+ // return await user_service.create(db, body)
337
+ // ─────────────────────────────────────────
338
+ {
339
+ id: 'fastapi-response-model-required',
340
+ label: 'Declare response_model on all mutating routes',
341
+ description: 'POST/PUT/PATCH/DELETE routes should declare a response_model to prevent data leaks and generate OpenAPI response schemas.',
342
+ severity: 'warning',
343
+ fileExtensions: ['py'],
344
+ pattern: null,
345
+ customCheck: (file) => {
346
+ const violations = [];
347
+ for (let i = 0; i < file.lines.length; i++) {
348
+ const line = file.lines[i];
349
+ if (/@(?:router|app)\s*\.\s*(?:post|put|patch|delete)\s*\(/.test(line)) {
350
+ // Collect the decorator (may span multiple lines)
351
+ const decoratorBlock = file.lines.slice(i, i + 5).join(' ');
352
+ if (!decoratorBlock.includes('response_model')) {
353
+ violations.push({
354
+ line: i + 1,
355
+ message: 'Mutating route is missing response_model. Add response_model=YourSchema to prevent data leaks.',
356
+ });
357
+ }
358
+ }
359
+ }
360
+ return violations;
361
+ },
362
+ applicableTo: ['fastapi'],
363
+ category: 'Security',
364
+ },
365
+ // ── Flask ─────────────────────────────────────────────────────────────────
366
+ // ─────────────────────────────────────────
367
+ // RULE: flask-use-blueprint-structure
368
+ // ROLE: Enforce Flask Blueprint organisation
369
+ // PURPOSE: Defining all routes directly on the `app` object in a single
370
+ // file does not scale. Blueprints allow grouping related routes
371
+ // into separate modules with their own URL prefixes.
372
+ // EXAMPLE:
373
+ // WRONG:
374
+ // @app.route('/users', methods=['POST'])
375
+ // def create_user(): ...
376
+ // RIGHT:
377
+ // users_bp = Blueprint('users', __name__, url_prefix='/users')
378
+ // @users_bp.route('/', methods=['POST'])
379
+ // def create_user(): ...
380
+ // ─────────────────────────────────────────
381
+ {
382
+ id: 'flask-use-blueprint-structure',
383
+ label: 'Define routes on Blueprints, not directly on app',
384
+ description: 'Register routes on Blueprint instances instead of the global `app` object. Blueprints enable modular structure and independent URL prefixes.',
385
+ severity: 'warning',
386
+ fileExtensions: ['py'],
387
+ pattern: /@app\.route\s*\(/,
388
+ customCheck: (file) => {
389
+ const violations = [];
390
+ // Only flag if the file does not define a Blueprint itself
391
+ const definesBp = file.content.includes('Blueprint(');
392
+ if (definesBp)
393
+ return [];
394
+ for (let i = 0; i < file.lines.length; i++) {
395
+ if (/@app\.route\s*\(/.test(file.lines[i])) {
396
+ violations.push({
397
+ line: i + 1,
398
+ message: 'Route registered directly on `app`. Move to a Blueprint for modular structure.',
399
+ });
400
+ }
401
+ }
402
+ return violations;
403
+ },
404
+ applicableTo: ['flask'],
405
+ category: 'Architecture',
406
+ },
407
+ // ─────────────────────────────────────────
408
+ // RULE: flask-validate-request-data
409
+ // ROLE: Enforce input validation before use
410
+ // PURPOSE: request.json and request.form return raw dicts with no type
411
+ // coercion or validation. A missing or malformed field will cause
412
+ // an unhandled KeyError or TypeError at runtime.
413
+ // Use Flask-Marshmallow, Pydantic, or wtforms validation.
414
+ // EXAMPLE:
415
+ // WRONG:
416
+ // data = request.json
417
+ // user = User(name=data['name'], email=data['email'])
418
+ // RIGHT:
419
+ // schema = CreateUserSchema()
420
+ // data = schema.load(request.json) # raises ValidationError on bad input
421
+ // user = User(**data)
422
+ // ─────────────────────────────────────────
423
+ {
424
+ id: 'flask-validate-request-data',
425
+ label: 'Validate request.json / request.form before use',
426
+ description: 'Do not use request.json or request.form directly. Validate with a schema library (Marshmallow, Pydantic) to catch malformed input before it reaches business logic.',
427
+ severity: 'error',
428
+ fileExtensions: ['py'],
429
+ pattern: null,
430
+ customCheck: (file) => {
431
+ const violations = [];
432
+ for (let i = 0; i < file.lines.length; i++) {
433
+ const line = file.lines[i];
434
+ if (/request\s*\.\s*(?:json|form)\b/.test(line)) {
435
+ // Check surrounding lines for a schema.load / validate call
436
+ const context = file.lines.slice(Math.max(0, i - 5), i + 5).join('\n');
437
+ if (!context.includes('.load(') && !context.includes('.validate(') && !context.includes('schema')) {
438
+ violations.push({
439
+ line: i + 1,
440
+ message: 'request.json/form used without schema validation. Run input through a Marshmallow schema or Pydantic model before use.',
441
+ });
442
+ }
443
+ }
444
+ }
445
+ return violations;
446
+ },
447
+ applicableTo: ['flask'],
448
+ category: 'Validation',
449
+ },
450
+ // ─────────────────────────────────────────
451
+ // RULE: flask-no-debug-in-production
452
+ // ROLE: Prevent debug mode in production
453
+ // PURPOSE: app.run(debug=True) exposes the Werkzeug interactive debugger,
454
+ // which allows arbitrary Python code execution in the browser.
455
+ // It must never run in production.
456
+ // EXAMPLE:
457
+ // WRONG: app.run(debug=True)
458
+ // RIGHT: app.run(debug=os.getenv("FLASK_DEBUG", "false").lower() == "true")
459
+ // ─────────────────────────────────────────
460
+ {
461
+ id: 'flask-no-debug-in-production',
462
+ label: 'Do not hardcode debug=True in app.run()',
463
+ description: 'app.run(debug=True) exposes the Werkzeug interactive debugger — a remote code execution vulnerability. Read the debug flag from an environment variable.',
464
+ severity: 'error',
465
+ fileExtensions: ['py'],
466
+ pattern: /app\.run\s*\([^)]*debug\s*=\s*True/,
467
+ applicableTo: ['flask'],
468
+ category: 'Security',
469
+ },
470
+ ];
471
+ (0, guidelines_config_1.registerRules)('python', pythonRules.filter(r => r.applicableTo?.includes('python')));
472
+ (0, guidelines_config_1.registerRules)('django', pythonRules.filter(r => r.applicableTo?.includes('django')));
473
+ (0, guidelines_config_1.registerRules)('fastapi', pythonRules.filter(r => r.applicableTo?.includes('fastapi')));
474
+ (0, guidelines_config_1.registerRules)('flask', pythonRules.filter(r => r.applicableTo?.includes('flask')));
475
+ //# sourceMappingURL=python.config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"python.config.js","sourceRoot":"","sources":["../../config/python.config.ts"],"names":[],"mappings":"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"}
@@ -13,4 +13,9 @@
13
13
  import '../config/angular.config';
14
14
  import '../config/react.config';
15
15
  import '../config/nextjs.config';
16
+ import '../config/nestjs.config';
17
+ import '../config/node.config';
18
+ import '../config/fastify.config';
19
+ import '../config/hono.config';
20
+ import '../config/python.config';
16
21
  //# sourceMappingURL=auto-fix.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auto-fix.d.ts","sourceRoot":"","sources":["../../scripts/auto-fix.ts"],"names":[],"mappings":";AACA;;;;;;;;;;GAUG;AAWH,OAAO,0BAA0B,CAAC;AAClC,OAAO,wBAAwB,CAAC;AAChC,OAAO,yBAAyB,CAAC"}
1
+ {"version":3,"file":"auto-fix.d.ts","sourceRoot":"","sources":["../../scripts/auto-fix.ts"],"names":[],"mappings":";AACA;;;;;;;;;;GAUG;AAWH,OAAO,0BAA0B,CAAC;AAClC,OAAO,wBAAwB,CAAC;AAChC,OAAO,yBAAyB,CAAC;AACjC,OAAO,yBAAyB,CAAC;AACjC,OAAO,uBAAuB,CAAC;AAC/B,OAAO,0BAA0B,CAAC;AAClC,OAAO,uBAAuB,CAAC;AAC/B,OAAO,yBAAyB,CAAC"}
@@ -56,6 +56,11 @@ const logger = __importStar(require("./utils/logger"));
56
56
  require("../config/angular.config");
57
57
  require("../config/react.config");
58
58
  require("../config/nextjs.config");
59
+ require("../config/nestjs.config");
60
+ require("../config/node.config");
61
+ require("../config/fastify.config");
62
+ require("../config/hono.config");
63
+ require("../config/python.config");
59
64
  const CHECKABLE_EXTENSIONS = ['ts', 'tsx', 'js', 'jsx', 'html', 'css', 'scss', 'sass', 'less'];
60
65
  function parseArgs() {
61
66
  const args = process.argv.slice(2);
@@ -1 +1 @@
1
- {"version":3,"file":"auto-fix.js","sourceRoot":"","sources":["../../scripts/auto-fix.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auto-fix.js","sourceRoot":"","sources":["../../scripts/auto-fix.ts"],"names":[],"mappings":"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"}
@@ -583,7 +583,7 @@ function copyCodeGuardianFiles(cwd) {
583
583
  if (!fs.existsSync(configDir)) {
584
584
  fs.mkdirSync(configDir, { recursive: true });
585
585
  }
586
- const configFiles = ['guidelines.config.ts', 'angular.config.ts', 'react.config.ts', 'nextjs.config.ts'];
586
+ const configFiles = ['guidelines.config.ts', 'angular.config.ts', 'react.config.ts', 'nextjs.config.ts', 'nestjs.config.ts', 'node.config.ts', 'fastify.config.ts', 'hono.config.ts', 'python.config.ts'];
587
587
  const sourceConfigDirs = [path.join(distDir, 'config'), path.join(pkgRootDir, 'config')];
588
588
  for (const file of configFiles) {
589
589
  let src = null;
@@ -605,7 +605,7 @@ function copyCodeGuardianFiles(cwd) {
605
605
  if (!fs.existsSync(templatesDir)) {
606
606
  fs.mkdirSync(templatesDir, { recursive: true });
607
607
  }
608
- const templateFiles = ['feature-doc-ui.md', 'feature-doc-api.md', 'feature-doc-service.md'];
608
+ const templateFiles = ['feature-doc-ui.md', 'feature-doc-api.md', 'feature-doc-service.md', 'feature-doc-backend.md'];
609
609
  const sourceTemplateDirs = [path.join(distDir, 'templates'), path.join(pkgRootDir, 'templates')];
610
610
  for (const file of templateFiles) {
611
611
  let src = null;