@sun-asterisk/sunlint 1.3.40 → 1.3.42

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 (172) hide show
  1. package/core/rule-selection-service.js +11 -0
  2. package/package.json +1 -1
  3. package/skill-assets/sunlint-code-quality/rules/dart/D001-recommended-lints.md +36 -0
  4. package/skill-assets/sunlint-code-quality/rules/dart/D002-dispose-resources.md +44 -0
  5. package/skill-assets/sunlint-code-quality/rules/dart/D003-prefer-widget-classes.md +53 -0
  6. package/skill-assets/sunlint-code-quality/rules/dart/D004-avoid-shrinkwrap.md +31 -0
  7. package/skill-assets/sunlint-code-quality/rules/dart/D005-widget-nesting.md +62 -0
  8. package/skill-assets/sunlint-code-quality/rules/dart/D006-large-callbacks.md +54 -0
  9. package/skill-assets/sunlint-code-quality/rules/dart/D007-lifecycle-order.md +44 -0
  10. package/skill-assets/sunlint-code-quality/rules/dart/D008-long-functions.md +37 -0
  11. package/skill-assets/sunlint-code-quality/rules/dart/D009-function-parameters.md +38 -0
  12. package/skill-assets/sunlint-code-quality/rules/dart/D010-cyclomatic-complexity.md +46 -0
  13. package/skill-assets/sunlint-code-quality/rules/dart/D011-named-parameters.md +31 -0
  14. package/skill-assets/sunlint-code-quality/rules/dart/D012-named-booleans.md +28 -0
  15. package/skill-assets/sunlint-code-quality/rules/dart/D013-single-public-class.md +34 -0
  16. package/skill-assets/sunlint-code-quality/rules/dart/D014-safe-collection-access.md +30 -0
  17. package/skill-assets/sunlint-code-quality/rules/dart/D015-copywith-consistency.md +52 -0
  18. package/skill-assets/sunlint-code-quality/rules/dart/D016-project-tests.md +32 -0
  19. package/skill-assets/sunlint-code-quality/rules/dart/D017-review-dependencies.md +24 -0
  20. package/skill-assets/sunlint-code-quality/rules/dart/D018-no-commented-code.md +34 -0
  21. package/skill-assets/sunlint-code-quality/rules/dart/D019-single-child-wrappers.md +31 -0
  22. package/skill-assets/sunlint-code-quality/rules/dart/D020-if-else-limit.md +41 -0
  23. package/skill-assets/sunlint-code-quality/rules/dart/D021-negated-booleans.md +26 -0
  24. package/skill-assets/sunlint-code-quality/rules/dart/D022-setstate-usage.md +35 -0
  25. package/skill-assets/sunlint-code-quality/rules/dart/D023-unnecessary-overrides.md +32 -0
  26. package/skill-assets/sunlint-code-quality/rules/dart/D024-avoid-unnecessary-statefulwidget.md +45 -0
  27. package/skill-assets/sunlint-code-quality/rules/dart/D025-nested-ternaries.md +35 -0
  28. package/skill-assets/sunlint-code-quality/rules/go/C006-verb-noun-functions.md +45 -0
  29. package/skill-assets/sunlint-code-quality/rules/go/C013-no-dead-code.md +48 -0
  30. package/skill-assets/sunlint-code-quality/rules/go/C014-dependency-injection.md +85 -0
  31. package/skill-assets/sunlint-code-quality/rules/go/C017-no-constructor-logic.md +67 -0
  32. package/skill-assets/sunlint-code-quality/rules/go/C018-generic-errors.md +63 -0
  33. package/skill-assets/sunlint-code-quality/rules/go/C019-error-log-level.md +50 -0
  34. package/skill-assets/sunlint-code-quality/rules/go/C020-no-unused-imports.md +45 -0
  35. package/skill-assets/sunlint-code-quality/rules/go/C022-no-unused-variables.md +34 -0
  36. package/skill-assets/sunlint-code-quality/rules/go/C023-no-duplicate-names.md +41 -0
  37. package/skill-assets/sunlint-code-quality/rules/go/C024-centralize-constants.md +55 -0
  38. package/skill-assets/sunlint-code-quality/rules/go/C029-catch-log-root-cause.md +56 -0
  39. package/skill-assets/sunlint-code-quality/rules/go/C030-custom-error-classes.md +69 -0
  40. package/skill-assets/sunlint-code-quality/rules/go/C033-separate-data-access.md +68 -0
  41. package/skill-assets/sunlint-code-quality/rules/go/C035-error-context-logging.md +48 -0
  42. package/skill-assets/sunlint-code-quality/rules/go/C041-no-hardcoded-secrets.md +45 -0
  43. package/skill-assets/sunlint-code-quality/rules/go/C042-boolean-naming.md +42 -0
  44. package/skill-assets/sunlint-code-quality/rules/go/C052-controller-parsing.md +62 -0
  45. package/skill-assets/sunlint-code-quality/rules/go/C060-superclass-logic.md +60 -0
  46. package/skill-assets/sunlint-code-quality/rules/go/C067-no-hardcoded-config.md +51 -0
  47. package/skill-assets/sunlint-code-quality/rules/go/S003-open-redirect.md +80 -0
  48. package/skill-assets/sunlint-code-quality/rules/go/S004-no-log-credentials.md +66 -0
  49. package/skill-assets/sunlint-code-quality/rules/go/S005-server-authorization.md +55 -0
  50. package/skill-assets/sunlint-code-quality/rules/go/S006-default-credentials.md +47 -0
  51. package/skill-assets/sunlint-code-quality/rules/go/S007-output-encoding.md +50 -0
  52. package/skill-assets/sunlint-code-quality/rules/go/S009-approved-crypto.md +63 -0
  53. package/skill-assets/sunlint-code-quality/rules/go/S010-csprng.md +53 -0
  54. package/skill-assets/sunlint-code-quality/rules/go/S011-encrypted-client-hello.md +34 -0
  55. package/skill-assets/sunlint-code-quality/rules/go/S012-secrets-management.md +49 -0
  56. package/skill-assets/sunlint-code-quality/rules/go/S013-tls-connections.md +61 -0
  57. package/skill-assets/sunlint-code-quality/rules/go/S016-no-sensitive-query-string.md +42 -0
  58. package/skill-assets/sunlint-code-quality/rules/go/S017-parameterized-queries.md +36 -0
  59. package/skill-assets/sunlint-code-quality/rules/go/S019-email-input-sanitization.md +44 -0
  60. package/skill-assets/sunlint-code-quality/rules/go/S020-eval-code-execution.md +47 -0
  61. package/skill-assets/sunlint-code-quality/rules/go/S022-context-escaping.md +49 -0
  62. package/skill-assets/sunlint-code-quality/rules/go/S023-dynamic-js-encoding.md +51 -0
  63. package/skill-assets/sunlint-code-quality/rules/go/S025-server-validation.md +57 -0
  64. package/skill-assets/sunlint-code-quality/rules/go/S026-tls-encryption.md +46 -0
  65. package/skill-assets/sunlint-code-quality/rules/go/S027-mtls-validation.md +52 -0
  66. package/skill-assets/sunlint-code-quality/rules/go/S028-upload-limits.md +58 -0
  67. package/skill-assets/sunlint-code-quality/rules/go/S029-csrf-protection.md +53 -0
  68. package/skill-assets/sunlint-code-quality/rules/go/S030-directory-browsing.md +53 -0
  69. package/skill-assets/sunlint-code-quality/rules/go/S031-secure-cookie-flag.md +48 -0
  70. package/skill-assets/sunlint-code-quality/rules/go/S032-httponly-cookie.md +42 -0
  71. package/skill-assets/sunlint-code-quality/rules/go/S033-samesite-cookie.md +49 -0
  72. package/skill-assets/sunlint-code-quality/rules/go/S034-host-prefix-cookie.md +44 -0
  73. package/skill-assets/sunlint-code-quality/rules/go/S035-app-hostnames.md +50 -0
  74. package/skill-assets/sunlint-code-quality/rules/go/S036-internal-file-paths.md +56 -0
  75. package/skill-assets/sunlint-code-quality/rules/go/S037-anti-cache-headers.md +43 -0
  76. package/skill-assets/sunlint-code-quality/rules/go/S039-tls-certificate-validation.md +41 -0
  77. package/skill-assets/sunlint-code-quality/rules/go/S041-logout-invalidation.md +46 -0
  78. package/skill-assets/sunlint-code-quality/rules/go/S042-long-lived-sessions.md +58 -0
  79. package/skill-assets/sunlint-code-quality/rules/go/S044-critical-changes-reauth.md +53 -0
  80. package/skill-assets/sunlint-code-quality/rules/go/S045-brute-force-protection.md +55 -0
  81. package/skill-assets/sunlint-code-quality/rules/go/S047-oauth-csrf-protection.md +51 -0
  82. package/skill-assets/sunlint-code-quality/rules/go/S048-oauth-redirect-validation.md +58 -0
  83. package/skill-assets/sunlint-code-quality/rules/go/S049-auth-code-expiry.md +52 -0
  84. package/skill-assets/sunlint-code-quality/rules/go/S050-token-entropy.md +53 -0
  85. package/skill-assets/sunlint-code-quality/rules/go/S051-password-length.md +49 -0
  86. package/skill-assets/sunlint-code-quality/rules/go/S052-otp-entropy.md +48 -0
  87. package/skill-assets/sunlint-code-quality/rules/go/S053-generic-error-messages.md +51 -0
  88. package/skill-assets/sunlint-code-quality/rules/go/S054-no-default-admin.md +43 -0
  89. package/skill-assets/sunlint-code-quality/rules/go/S055-content-type-validation.md +52 -0
  90. package/skill-assets/sunlint-code-quality/rules/go/S056-log-injection.md +40 -0
  91. package/skill-assets/sunlint-code-quality/rules/go/S057-synchronized-time.md +40 -0
  92. package/skill-assets/sunlint-code-quality/rules/go/S058-ssrf-protection.md +70 -0
  93. package/skill-assets/sunlint-code-quality/rules/ruby/RB001-use-snake-case.md +30 -0
  94. package/skill-assets/sunlint-code-quality/rules/ruby/RB002-use-camel-case.md +38 -0
  95. package/skill-assets/sunlint-code-quality/rules/ruby/RB003-use-screaming-snake-case.md +26 -0
  96. package/skill-assets/sunlint-code-quality/rules/ruby/RB004-predicate-methods.md +36 -0
  97. package/skill-assets/sunlint-code-quality/rules/ruby/RB005-dangerous-methods.md +36 -0
  98. package/skill-assets/sunlint-code-quality/rules/ruby/RB006-indentation.md +32 -0
  99. package/skill-assets/sunlint-code-quality/rules/ruby/RB007-line-length.md +25 -0
  100. package/skill-assets/sunlint-code-quality/rules/ruby/RB008-rescue-exception.md +36 -0
  101. package/skill-assets/sunlint-code-quality/rules/ruby/RB009-save-bang.md +41 -0
  102. package/skill-assets/sunlint-code-quality/rules/ruby/RB010-avoid-n-plus-one.md +32 -0
  103. package/skill-assets/sunlint-code-quality/rules/ruby/RB011-use-find-each.md +30 -0
  104. package/skill-assets/sunlint-code-quality/rules/ruby/RB012-sql-injection.md +29 -0
  105. package/skill-assets/sunlint-code-quality/rules/ruby/RB013-prefer-has-many-through.md +35 -0
  106. package/skill-assets/sunlint-code-quality/rules/ruby/RB014-dependent-associations.md +28 -0
  107. package/skill-assets/sunlint-code-quality/rules/ruby/RB015-modern-validations.md +29 -0
  108. package/skill-assets/sunlint-code-quality/rules/ruby/RB016-thin-controllers.md +45 -0
  109. package/skill-assets/sunlint-code-quality/rules/ruby/RB017-avoid-fat-models.md +41 -0
  110. package/skill-assets/sunlint-code-quality/rules/ruby/RB018-service-objects.md +36 -0
  111. package/skill-assets/sunlint-code-quality/rules/ruby/RB019-avoid-metaprogramming.md +40 -0
  112. package/skill-assets/sunlint-code-quality/rules/ruby/RB020-use-pluck.md +29 -0
  113. package/skill-assets/sunlint-code-quality/rules/ruby/RB021-use-size.md +27 -0
  114. package/skill-assets/sunlint-code-quality/rules/ruby/RB022-order-by-timestamps.md +24 -0
  115. package/skill-assets/sunlint-code-quality/rules/ruby/RB023-where-missing.md +24 -0
  116. package/skill-assets/sunlint-code-quality/rules/ruby/RB024-method-length.md +41 -0
  117. package/skill-assets/sunlint-code-quality/rules/ruby/RB025-parameter-limits.md +28 -0
  118. package/skill-assets/sunlint-code-quality/rules/ruby/RB026-avoid-deep-nesting.md +38 -0
  119. package/skill-assets/sunlint-code-quality/rules/ruby/RB027-guard-clauses.md +37 -0
  120. package/skill-assets/sunlint-code-quality/rules/ruby/RB028-class-length.md +32 -0
  121. package/skill-assets/sunlint-code-quality/rules/ruby/RB029-meaningful-names.md +30 -0
  122. package/skill-assets/sunlint-code-quality/rules/ruby/RB030-dry-principle.md +37 -0
  123. package/skill-assets/sunlint-code-quality/rules/ruby/RB031-mvc-architecture.md +37 -0
  124. package/skill-assets/sunlint-code-quality/rules/ruby/RB032-use-concerns.md +31 -0
  125. package/skill-assets/sunlint-code-quality/rules/ruby/RB033-moderate-callbacks.md +31 -0
  126. package/skill-assets/sunlint-code-quality/rules/ruby/RB034-use-decorators.md +33 -0
  127. package/skill-assets/sunlint-code-quality/rules/ruby/RB035-comprehensive-tests.md +32 -0
  128. package/skill-assets/sunlint-code-quality/rules/ruby/RB036-frozen-string-literal.md +29 -0
  129. package/skill-assets/sunlint-code-quality/rules/ruby/RB037-it-parameter.md +25 -0
  130. package/skill-assets/sunlint-code-quality/rules/ruby/RB038-modern-enum-syntax.md +28 -0
  131. package/skill-assets/sunlint-code-quality/rules/ruby/RB039-solid-adapters.md +29 -0
  132. package/skill-assets/sunlint-code-quality/rules/ruby/RB040-rails-authentication.md +26 -0
  133. package/skill-assets/sunlint-code-quality/rules/ruby/RB041-async-query-loading.md +29 -0
  134. package/skill-assets/sunlint-code-quality/rules/ruby/RB042-hotwire-turbo.md +30 -0
  135. package/skill-assets/sunlint-code-quality/rules/ruby/RB043-use-propshaft.md +27 -0
  136. package/skill-assets/sunlint-code-quality/rules/ruby/RB044-structured-logging.md +35 -0
  137. package/skill-assets/sunlint-code-quality/rules/ruby/RB045-prism-parser.md +29 -0
  138. package/skill-assets/sunlint-code-quality/rules/swift/SW001-block-based-kvo.md +40 -0
  139. package/skill-assets/sunlint-code-quality/rules/swift/SW002-class-delegate-protocol.md +36 -0
  140. package/skill-assets/sunlint-code-quality/rules/swift/SW003-compiler-protocol-init.md +28 -0
  141. package/skill-assets/sunlint-code-quality/rules/swift/SW004-contains-over-filter-count.md +28 -0
  142. package/skill-assets/sunlint-code-quality/rules/swift/SW005-convenience-type.md +34 -0
  143. package/skill-assets/sunlint-code-quality/rules/swift/SW006-discarded-notification-center-observer.md +41 -0
  144. package/skill-assets/sunlint-code-quality/rules/swift/SW007-discouraged-direct-init.md +28 -0
  145. package/skill-assets/sunlint-code-quality/rules/swift/SW008-discouraged-optional-boolean.md +32 -0
  146. package/skill-assets/sunlint-code-quality/rules/swift/SW009-empty-count.md +30 -0
  147. package/skill-assets/sunlint-code-quality/rules/swift/SW010-empty-string.md +30 -0
  148. package/skill-assets/sunlint-code-quality/rules/swift/SW011-explicit-init.md +26 -0
  149. package/skill-assets/sunlint-code-quality/rules/swift/SW012-fatal-error-message.md +28 -0
  150. package/skill-assets/sunlint-code-quality/rules/swift/SW013-for-where.md +30 -0
  151. package/skill-assets/sunlint-code-quality/rules/swift/SW014-force-cast.md +26 -0
  152. package/skill-assets/sunlint-code-quality/rules/swift/SW015-force-try.md +30 -0
  153. package/skill-assets/sunlint-code-quality/rules/swift/SW016-force-unwrapping.md +32 -0
  154. package/skill-assets/sunlint-code-quality/rules/swift/SW017-function-parameter-count.md +37 -0
  155. package/skill-assets/sunlint-code-quality/rules/swift/SW018-large-tuple.md +41 -0
  156. package/skill-assets/sunlint-code-quality/rules/swift/SW019-legacy-constructor.md +28 -0
  157. package/skill-assets/sunlint-code-quality/rules/swift/SW020-nesting.md +38 -0
  158. package/skill-assets/sunlint-code-quality/rules/swift/SW021-no-extension-access-modifier.md +28 -0
  159. package/skill-assets/sunlint-code-quality/rules/swift/SW022-overridden-super-call.md +30 -0
  160. package/skill-assets/sunlint-code-quality/rules/swift/SW023-override-in-extension.md +32 -0
  161. package/skill-assets/sunlint-code-quality/rules/swift/SW024-private-over-fileprivate.md +28 -0
  162. package/skill-assets/sunlint-code-quality/rules/swift/SW025-private-unit-test.md +32 -0
  163. package/skill-assets/sunlint-code-quality/rules/swift/SW026-prohibited-super-call.md +29 -0
  164. package/skill-assets/sunlint-code-quality/rules/swift/SW027-sorted-first-last.md +28 -0
  165. package/skill-assets/sunlint-code-quality/rules/swift/SW028-syntactic-sugar.md +28 -0
  166. package/skill-assets/sunlint-code-quality/rules/swift/SW029-unused-closure-parameter.md +28 -0
  167. package/skill-assets/sunlint-code-quality/rules/swift/SW030-unused-enumerated.md +28 -0
  168. package/skill-assets/sunlint-code-quality/rules/swift/SW031-unused-optional-binding.md +26 -0
  169. package/skill-assets/sunlint-code-quality/rules/swift/SW032-valid-ibinspectable.md +26 -0
  170. package/skill-assets/sunlint-code-quality/rules/swift/SW033-vertical-parameter-alignment.md +36 -0
  171. package/skill-assets/sunlint-code-quality/rules/swift/SW034-void-return.md +28 -0
  172. package/skill-assets/sunlint-code-quality/rules/swift/SW035-weak-delegate.md +28 -0
@@ -0,0 +1,24 @@
1
+ ---
2
+ title: Pubspec dependencies should be reviewed regularly
3
+ impact: MEDIUM
4
+ impactDescription: Ensure dependencies are kept up-to-date for security and stability
5
+ tags: maintenance, security, dependencies
6
+ ---
7
+
8
+ ## Pubspec dependencies should be reviewed regularly
9
+
10
+ Dependencies in `pubspec.yaml` should be reviewed and updated regularly (at least every 4 months). Outdated dependencies may contain security vulnerabilities or miss critical performance improvements.
11
+
12
+ **Incorrect (old lock file):**
13
+
14
+ ```text
15
+ # pubspec.lock last modified: 6 months ago
16
+ ```
17
+
18
+ **Correct (regularly updated):**
19
+
20
+ ```text
21
+ # run 'flutter pub upgrade' and review dependencies regularly
22
+ ```
23
+
24
+ **Tools:** Custom analyzer (D017)
@@ -0,0 +1,34 @@
1
+ ---
2
+ title: Remove Commented-Out Code
3
+ impact: LOW
4
+ impactDescription: Keep codebase clean by removing commented-out code
5
+ tags: cleanliness, readability, maintenance
6
+ ---
7
+
8
+ ## Remove Commented-Out Code
9
+
10
+ Commented-out code should be removed instead of being left in the source files. Dead code comments create clutter and confusion. If you need to reference old code, rely on version control (Git).
11
+
12
+ **Incorrect (abandoned code):**
13
+
14
+ ```dart
15
+ void calculate() {
16
+ final result = 10 + 5;
17
+ // print("Debug result: $result");
18
+ // if (result > 10) {
19
+ // doSomething();
20
+ // }
21
+ return result;
22
+ }
23
+ ```
24
+
25
+ **Correct (clean file):**
26
+
27
+ ```dart
28
+ void calculate() {
29
+ final result = 10 + 5;
30
+ return result;
31
+ }
32
+ ```
33
+
34
+ **Tools:** Custom analyzer (D018)
@@ -0,0 +1,31 @@
1
+ ---
2
+ title: Avoid Single Child in Multi-Child Widget
3
+ impact: LOW
4
+ impactDescription: Use appropriate widget types for the number of children
5
+ tags: performance, efficiency, best-practices
6
+ ---
7
+
8
+ ## Avoid Single Child in Multi-Child Widget
9
+
10
+ Multi-child widgets like `Column`, `Row`, `Stack`, `ListView`, or `GridView` are inefficient when used with only a single child. Use single-child optimized widgets like `SizedBox`, `Padding`, `Center`, or `Container` instead.
11
+
12
+ **Incorrect (inefficient Column):**
13
+
14
+ ```dart
15
+ Column(
16
+ children: [
17
+ Text("Only one child here"),
18
+ ],
19
+ )
20
+ ```
21
+
22
+ **Correct (efficient wrapper):**
23
+
24
+ ```dart
25
+ Padding(
26
+ padding: const EdgeInsets.all(8.0),
27
+ child: Text("Only one child here"),
28
+ )
29
+ ```
30
+
31
+ **Tools:** Custom analyzer (D019)
@@ -0,0 +1,41 @@
1
+ ---
2
+ title: Limit If/Else Branches
3
+ impact: LOW
4
+ impactDescription: Reduce complexity by limiting the number of if/else branches
5
+ tags: readability, complexity, clean-code
6
+ ---
7
+
8
+ ## Limit If/Else Branches
9
+
10
+ Complex if/else chains with more than 3 branches reduce code readability and increase cyclomatic complexity. When facing multiple branches, consider using `switch` statements, lookup tables (Maps), or the Strategy pattern.
11
+
12
+ **Incorrect (long if/else chain):**
13
+
14
+ ```dart
15
+ if (type == 'A') {
16
+ doA();
17
+ } else if (type == 'B') {
18
+ doB();
19
+ } else if (type == 'C') {
20
+ doC();
21
+ } else if (type == 'D') {
22
+ doD();
23
+ } else {
24
+ doDefault();
25
+ }
26
+ ```
27
+
28
+ **Correct (using switch or Map):**
29
+
30
+ ```dart
31
+ // Option 1: Switch (better readability)
32
+ switch (type) {
33
+ case 'A': doA(); break;
34
+ case 'B': doB(); break;
35
+ case 'C': doC(); break;
36
+ case 'D': doD(); break;
37
+ default: doDefault();
38
+ }
39
+ ```
40
+
41
+ **Tools:** Custom analyzer (D020)
@@ -0,0 +1,26 @@
1
+ ---
2
+ title: Avoid Negated Boolean Checks
3
+ impact: LOW
4
+ impactDescription: Improve code readability by avoiding inverted or negated boolean conditions
5
+ tags: readability, logic, clean-code
6
+ ---
7
+
8
+ ## Avoid Negated Boolean Checks
9
+
10
+ Negated boolean checks (using `!`) make code harder to read and understand. Replace negative conditions with positive ones wherever possible, and avoid double negations like `!!`.
11
+
12
+ **Incorrect (fragmented logic):**
13
+
14
+ ```dart
15
+ if (!isNotAuthorized) { ... }
16
+ if (!(a == b)) { ... }
17
+ ```
18
+
19
+ **Correct (clear logic):**
20
+
21
+ ```dart
22
+ if (isAuthorized) { ... }
23
+ if (a != b) { ... }
24
+ ```
25
+
26
+ **Tools:** Custom analyzer (D021)
@@ -0,0 +1,35 @@
1
+ ---
2
+ title: Use setState Correctly
3
+ impact: HIGH
4
+ impactDescription: Ensure setState is used correctly in StatefulWidget to avoid performance issues and bugs
5
+ tags: performance, best-practices, lifecycle, state-management
6
+ ---
7
+
8
+ ## Use setState Correctly
9
+
10
+ Common `setState` anti-patterns include: calling `setState` inside `build()`, nesting `setState` calls, making multiple `setState` calls in the same method, or using async callbacks inside `setState`. These lead to performance issues, unnecessary rebuilds, or hard-to-track UI bugs.
11
+
12
+ **Incorrect (async inside setState):**
13
+
14
+ ```dart
15
+ setState(() async {
16
+ await fetchData(); // WRONG: setState should be synchronous
17
+ _data = "new data";
18
+ });
19
+ ```
20
+
21
+ **Correct (sync update after async):**
22
+
23
+ ```dart
24
+ // Fetch data first
25
+ final newData = await fetchData();
26
+
27
+ // Update state synchronously
28
+ if (mounted) {
29
+ setState(() {
30
+ _data = newData;
31
+ });
32
+ }
33
+ ```
34
+
35
+ **Tools:** Custom analyzer (D022)
@@ -0,0 +1,32 @@
1
+ ---
2
+ title: Avoid Unnecessary Method Overrides
3
+ impact: LOW
4
+ impactDescription: Remove methods that only call super with the same parameters as they add no value
5
+ tags: readability, clean-code, refactoring
6
+ ---
7
+
8
+ ## Avoid Unnecessary Method Overrides
9
+
10
+ Methods that override a parent method but only call `super.methodName()` with the same parameters are unnecessary and should be removed. These empty overrides add no functionality and create unnecessary code clutter. Common examples include lifecycle methods like `initState()`, `dispose()`, or `didUpdateWidget()` that only call their super implementation.
11
+
12
+ **Incorrect (super call only):**
13
+
14
+ ```dart
15
+ @override
16
+ void initState() {
17
+ super.initState();
18
+ }
19
+
20
+ @override
21
+ void dispose() {
22
+ super.dispose();
23
+ }
24
+ ```
25
+
26
+ **Correct (remove if no logic):**
27
+
28
+ ```dart
29
+ // Just remove the method override entirely if it only calls super
30
+ ```
31
+
32
+ **Tools:** Custom analyzer (D023)
@@ -0,0 +1,45 @@
1
+ ---
2
+ title: Avoid Unnecessary StatefulWidget
3
+ impact: LOW
4
+ impactDescription: Use StatelessWidget when no state management is needed to improve performance
5
+ tags: performance, flutter, widgets, best-practices
6
+ ---
7
+
8
+ ## Avoid Unnecessary StatefulWidget
9
+
10
+ StatefulWidget should only be used when the widget needs to maintain mutable state that changes over time. If a widget extends StatefulWidget but its State class has no mutable fields, never calls setState(), and doesn't use lifecycle methods beyond build(), it should be converted to StatelessWidget. StatelessWidget is more efficient as it doesn't maintain state and has less overhead.
11
+
12
+ **Incorrect (StatefulWidget with no state):**
13
+
14
+ ```dart
15
+ class MyTitle extends StatefulWidget {
16
+ final String text;
17
+ const MyTitle({super.key, required this.text});
18
+
19
+ @override
20
+ State<MyTitle> createState() => _MyTitleState();
21
+ }
22
+
23
+ class _MyTitleState extends State<MyTitle> {
24
+ @override
25
+ Widget build(BuildContext context) {
26
+ return Text(widget.text);
27
+ }
28
+ }
29
+ ```
30
+
31
+ **Correct (StatelessWidget):**
32
+
33
+ ```dart
34
+ class MyTitle extends StatelessWidget {
35
+ final String text;
36
+ const MyTitle({super.key, required this.text});
37
+
38
+ @override
39
+ Widget build(BuildContext context) {
40
+ return Text(text);
41
+ }
42
+ }
43
+ ```
44
+
45
+ **Tools:** Custom analyzer (D024)
@@ -0,0 +1,35 @@
1
+ ---
2
+ title: Avoid Nested Conditional Expressions
3
+ impact: LOW
4
+ impactDescription: Improve code readability by avoiding nested ternary operators
5
+ tags: readability, maintainability, clean-code
6
+ ---
7
+
8
+ ## Avoid Nested Conditional Expressions
9
+
10
+ Nested conditional expressions (ternary operators like `a ? b : c ? d : e`) reduce code readability significantly. When logic is complex, use if-else statements or extract the logic into a well-named variable or function.
11
+
12
+ **Incorrect (hard to follow):**
13
+
14
+ ```dart
15
+ final color = isAdmin ? Colors.red : isLogged ? Colors.green : Colors.grey;
16
+ ```
17
+
18
+ **Correct (descriptive logic):**
19
+
20
+ ```dart
21
+ // Option 1: if-else
22
+ Color userColor;
23
+ if (isAdmin) {
24
+ userColor = Colors.red;
25
+ } else if (isLogged) {
26
+ userColor = Colors.green;
27
+ } else {
28
+ userColor = Colors.grey;
29
+ }
30
+
31
+ // Option 2: Extracted getter
32
+ Color get userColor => _calculateUserColor();
33
+ ```
34
+
35
+ **Tools:** Custom analyzer (D025)
@@ -0,0 +1,45 @@
1
+ ---
2
+ title: Function Names Verb-Noun
3
+ impact: LOW
4
+ impactDescription: makes code self-documenting
5
+ tags: naming, functions, readability, conventions, quality
6
+ ---
7
+
8
+ ## Function Names Verb-Noun
9
+
10
+ Functions do things. Action verbs make purpose clear.
11
+
12
+ **Incorrect (vague names):**
13
+
14
+ ```go
15
+ func user() { } // Noun only
16
+ func userData() { } // Noun only
17
+ func doSomething() { } // Vague
18
+ func handleStuff() { } // Vague
19
+ func manager() { } // Noun only
20
+ ```
21
+
22
+ **Correct (action verbs):**
23
+
24
+ ```go
25
+ func GetUser() { }
26
+ func CreateUserAccount() { }
27
+ func ValidateEmailFormat() { }
28
+ func CalculateTotalPrice() { }
29
+ func SendConfirmationEmail() { }
30
+ func ConvertCurrencyToUSD() { }
31
+ ```
32
+
33
+ **Verb categories:**
34
+
35
+ | Category | Verbs |
36
+ |----------|-------|
37
+ | Retrieval | `Get`, `Fetch`, `Find`, `Load`, `Query` |
38
+ | Creation | `Create`, `Build`, `Make`, `Generate` |
39
+ | Modification | `Set`, `Update`, `Modify`, `Change` |
40
+ | Deletion | `Delete`, `Remove`, `Destroy`, `Clear` |
41
+ | Validation | `Validate`, `Verify`, `Check`, `Ensure` |
42
+ | Computation | `Calculate`, `Compute`, `Parse`, `Format` |
43
+ | Boolean | `Is`, `Has`, `Can`, `Should`, `Will` |
44
+
45
+ **Tools:** PR review, GolangCI-Lint
@@ -0,0 +1,48 @@
1
+ ---
2
+ title: Do Not Use Dead Code
3
+ impact: LOW
4
+ impactDescription: reduces codebase noise and maintenance burden
5
+ tags: dead-code, cleanup, maintenance, quality
6
+ ---
7
+
8
+ ## Do Not Use Dead Code
9
+
10
+ Dead code confuses readers and increases cognitive load. Git history preserves deleted code.
11
+
12
+ **Incorrect (keeping dead code):**
13
+
14
+ ```go
15
+ func ProcessOrder(order *Order) float64 {
16
+ // Old implementation - keeping for reference
17
+ // total := 0.0
18
+ // for _, item := range order.Items {
19
+ // total += item.Price * float64(item.Quantity)
20
+ // }
21
+ // return total
22
+
23
+ total := calculateTotal(order)
24
+ return total
25
+ }
26
+
27
+ // Unused function - someone might need it later
28
+ func legacyCalculation() { }
29
+ ```
30
+
31
+ **Correct (clean code):**
32
+
33
+ ```go
34
+ func ProcessOrder(order *Order) float64 {
35
+ return calculateTotal(order)
36
+ }
37
+
38
+ // Delete unused functions - git history preserves them
39
+ // Delete commented code - git history preserves it
40
+ ```
41
+
42
+ **Types of dead code:**
43
+ - Commented-out code
44
+ - Unused functions/structs/methods
45
+ - Unreachable code
46
+ - Unused variables (Go compiler will error on these locally, but they may exist in long-lived branches)
47
+
48
+ **Tools:** gofmt, govet, staticcheck, GolangCI-Lint
@@ -0,0 +1,85 @@
1
+ ---
2
+ title: Use Dependency Injection
3
+ impact: HIGH
4
+ impactDescription: enables testability and loose coupling
5
+ tags: dependency-injection, testing, coupling, architecture, quality
6
+ ---
7
+
8
+ ## Use Dependency Injection
9
+
10
+ Direct instantiation creates tight coupling, making testing difficult and changes risky. DI enables mockability, replaceability, and testability.
11
+
12
+ **Incorrect (hardcoded dependencies):**
13
+
14
+ ```go
15
+ type OrderService struct {
16
+ db *PostgresDatabase
17
+ mailer *SendGridMailer
18
+ }
19
+
20
+ func NewOrderService() *OrderService {
21
+ return &OrderService{
22
+ db: NewPostgresDatabase(), // Hardcoded dependency
23
+ mailer: NewSendGridMailer(), // Hardcoded dependency
24
+ }
25
+ }
26
+
27
+ func (s *OrderService) CreateOrder(data OrderData) error {
28
+ order, err := s.db.Insert("orders", data)
29
+ if err != nil {
30
+ return err
31
+ }
32
+ return s.mailer.Send(data.Email, "Order created")
33
+ }
34
+ ```
35
+
36
+ **Correct (injected dependencies via interfaces):**
37
+
38
+ ```go
39
+ type Database interface {
40
+ Insert(table string, data any) (any, error)
41
+ }
42
+
43
+ type Mailer interface {
44
+ Send(to string, message string) error
45
+ }
46
+
47
+ type OrderService struct {
48
+ db Database
49
+ mailer Mailer
50
+ }
51
+
52
+ func NewOrderService(db Database, mailer Mailer) *OrderService {
53
+ return &OrderService{
54
+ db: db,
55
+ mailer: mailer,
56
+ }
57
+ }
58
+
59
+ func (s *OrderService) CreateOrder(data OrderData) error {
60
+ order, err := s.db.Insert("orders", data)
61
+ if err != nil {
62
+ return err
63
+ }
64
+ return s.mailer.Send(data.Email, "Order created")
65
+ }
66
+
67
+ // Usage
68
+ service := NewOrderService(
69
+ NewPostgresDatabase(connString),
70
+ NewSendGridMailer(apiKey),
71
+ )
72
+
73
+ // Testing
74
+ mockDb := new(MockDatabase)
75
+ mockMailer := new(MockMailer)
76
+ testService := NewOrderService(mockDb, mockMailer)
77
+ ```
78
+
79
+ **Benefits:**
80
+ - Easy mocking for unit tests
81
+ - Swappable implementations
82
+ - Clear dependencies visible in constructor/factory
83
+ - Supports interface-based design (accept interfaces, return structs)
84
+
85
+ **Tools:** GolangCI-Lint, Manual review
@@ -0,0 +1,67 @@
1
+ ---
2
+ title: No Business Logic In Factory Functions
3
+ impact: HIGH
4
+ impactDescription: ensures predictable object initialization
5
+ tags: factory, initialization, side-effects, patterns, quality
6
+ ---
7
+
8
+ ## No Business Logic In Factory Functions
9
+
10
+ Factory functions (e.g., `NewService`) should only initialize state. Side effects in factory functions are unexpected and make testing difficult.
11
+
12
+ **Incorrect (logic in factory function):**
13
+
14
+ ```go
15
+ type UserService struct {
16
+ config Config
17
+ }
18
+
19
+ func NewUserService(configPath string) (*UserService, error) {
20
+ // BAD: Reading files in factory function
21
+ rawConfig, err := os.ReadFile(configPath)
22
+ if err != nil {
23
+ return nil, err
24
+ }
25
+ var config Config
26
+ json.Unmarshal(rawConfig, &config)
27
+
28
+ // BAD: Network calls/API initialization here
29
+ resp, _ := http.Get("https://api.example.com/init")
30
+
31
+ // BAD: Logging/side effects
32
+ log.Println("UserService initialized")
33
+
34
+ return &UserService{config: config}, nil
35
+ }
36
+ ```
37
+
38
+ **Correct (clear separation):**
39
+
40
+ ```go
41
+ type UserService struct {
42
+ config Config
43
+ httpClient *http.Client
44
+ }
45
+
46
+ func NewUserService(config Config, httpClient *http.Client) *UserService {
47
+ // Only assignment - no side effects
48
+ return &UserService{
49
+ config: config,
50
+ httpClient: httpClient,
51
+ }
52
+ }
53
+
54
+ // Service initialization in main or a dedicated bootstrapper
55
+ func InitializeApp() {
56
+ rawConfig, _ := os.ReadFile("./config.json")
57
+ var config Config
58
+ json.Unmarshal(rawConfig, &config)
59
+
60
+ httpClient := &http.Client{Timeout: 10 * time.Second}
61
+
62
+ service := NewUserService(config, httpClient)
63
+ log.Println("UserService ready")
64
+ }
65
+ ```
66
+
67
+ **Tools:** PR review, Manual review
@@ -0,0 +1,63 @@
1
+ ---
2
+ title: Do Not Return Generic Errors
3
+ impact: HIGH
4
+ impactDescription: enables proper error handling and monitoring
5
+ tags: error-handling, custom-errors, debugging, quality
6
+ ---
7
+
8
+ ## Do Not Return Generic Errors
9
+
10
+ Generic errors (like `errors.New("error")`) lack context needed for debugging. They make it impossible to distinguish between error types for proper handling.
11
+
12
+ **Incorrect (generic errors):**
13
+
14
+ ```go
15
+ if user == nil {
16
+ return errors.New("error")
17
+ }
18
+
19
+ if !isValid {
20
+ return fmt.Errorf("invalid")
21
+ }
22
+ ```
23
+
24
+ **Correct (specific custom errors or sentinel errors):**
25
+
26
+ ```go
27
+ // Sentinel errors for simple checks
28
+ var ErrUserNotFound = errors.New("user not found")
29
+
30
+ func (s *Service) GetUser(id string) (*User, error) {
31
+ if user == nil {
32
+ return nil, fmt.Errorf("%w: user with ID %s not found", ErrUserNotFound, id)
33
+ }
34
+ return user, nil
35
+ }
36
+
37
+ // Custom error types for complex context
38
+ type ValidationError struct {
39
+ Field string
40
+ Message string
41
+ Value any
42
+ }
43
+
44
+ func (e *ValidationError) Error() string {
45
+ return fmt.Sprintf("validation failed on %s: %s", e.Field, e.Message)
46
+ }
47
+
48
+ if !isValid {
49
+ return &ValidationError{
50
+ Field: "email",
51
+ Message: "invalid format",
52
+ Value: email,
53
+ }
54
+ }
55
+ ```
56
+
57
+ Custom errors should include:
58
+ - Descriptive message with context (use `%w` for wrapping)
59
+ - Error codes or types for programmatic handling (using `errors.Is` or `errors.As`)
60
+ - Relevant data for debugging
61
+ - Appropriate mapping to status codes in the transport layer (e.g., HTTP 404)
62
+
63
+ **Tools:** GolangCI-Lint (errname, goerr113), Manual review
@@ -0,0 +1,50 @@
1
+ ---
2
+ title: Do Not Use Error Log For Non-critical
3
+ impact: HIGH
4
+ impactDescription: prevents alert fatigue and log noise
5
+ tags: logging, log-levels, error, observability, quality
6
+ ---
7
+
8
+ ## Do Not Use Error Log For Non-critical
9
+
10
+ Incorrect log levels cause alert fatigue and hide real issues. When everything is an "error", nothing is.
11
+
12
+ **Incorrect (overusing error level):**
13
+
14
+ ```go
15
+ // NOT an error - expected business case
16
+ slog.Error("User entered wrong password")
17
+
18
+ // NOT an error - validation failure
19
+ slog.Error("Email format invalid")
20
+
21
+ // NOT an error - temporary network issue
22
+ slog.Error("Retry attempt 2 of 5")
23
+ ```
24
+
25
+ **Correct (appropriate log levels using slog):**
26
+
27
+ ```go
28
+ // WARN - recoverable, may need attention
29
+ slog.Warn("Payment retry attempt", "attempt", 2, "max_attempts", 5)
30
+
31
+ // INFO - normal business events
32
+ slog.Info("Login failed - invalid password", "user_id", userID, "attempts", 3)
33
+
34
+ // DEBUG - detailed troubleshooting
35
+ slog.Debug("Validation failed", "field", "email", "value", maskedEmail)
36
+
37
+ // ERROR - only for actual system failures
38
+ slog.Error("Database connection lost", "host", dbHost, "error", err)
39
+ ```
40
+
41
+ **Log Level Guide:**
42
+
43
+ | Level | Use For |
44
+ |-------|---------|
45
+ | ERROR | System failures, crashes, unrecoverable |
46
+ | WARN | Potential issues, degraded performance |
47
+ | INFO | Business events, state changes |
48
+ | DEBUG | Detailed troubleshooting |
49
+
50
+ **Tools:** Log linter, Custom rule, `slog` (standard library)