@sun-asterisk/sunlint 1.3.39 → 1.3.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/rules/rules-registry-generated.json +134 -108
- package/core/rule-selection-service.js +11 -0
- package/docs/GENERATED_FILES_QUICK_REFERENCE.md +96 -0
- package/docs/GENERATED_FILE_HANDLING_SUMMARY.md +152 -0
- package/docs/skills/CREATE_NEW_DART_RULE.md +161 -14
- package/origin-rules/dart-en.md +151 -163
- package/package.json +2 -1
- package/rules/dart/D002_dispose_resources/config.json +25 -0
- package/rules/dart/D003_prefer_widgets_over_methods/config.json +14 -0
- package/rules/dart/D004_avoid_shrinkwrap_listview/config.json +13 -0
- package/rules/dart/D005_limit_widget_nesting/config.json +13 -0
- package/rules/dart/D006_prefer_extracting_large_callbacks/config.json +25 -0
- package/rules/dart/D007_prefer_init_first_dispose_last/config.json +10 -0
- package/rules/dart/D008_avoid_long_functions/config.json +12 -0
- package/rules/dart/D009_limit_function_parameters/config.json +13 -0
- package/rules/dart/D010_limit_cyclomatic_complexity/config.json +12 -0
- package/rules/dart/D011_prefer_named_parameters/config.json +12 -0
- package/rules/dart/D012_prefer_named_boolean_parameters/config.json +9 -0
- package/rules/dart/D013_single_public_class/config.json +10 -0
- package/rules/dart/D014_unsafe_collection_access/config.json +10 -0
- package/rules/dart/D015_copywith_all_parameters/config.json +9 -0
- package/rules/dart/D016_project_should_have_tests/config.json +24 -0
- package/rules/dart/D017_pubspec_dependencies_review/config.json +23 -0
- package/rules/dart/D018_remove_commented_code/config.json +13 -0
- package/rules/dart/D019_avoid_single_child_multi_child_widget/config.json +21 -0
- package/rules/dart/D020_limit_if_else_branches/config.json +12 -0
- package/rules/dart/D021_avoid_negated_boolean_checks/config.json +14 -0
- package/rules/dart/D022_use_setstate_correctly/config.json +14 -0
- package/rules/dart/D023_avoid_unnecessary_method_overrides/config.json +13 -0
- package/rules/dart/D024_avoid_unnecessary_stateful_widget/config.json +9 -0
- package/rules/dart/D025_avoid_nested_conditional_expressions/config.json +9 -0
- package/skill-assets/sunlint-code-quality/AGENTS.md +80 -0
- package/skill-assets/sunlint-code-quality/SKILL.md +176 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C006-verb-noun-functions.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C013-no-dead-code.md +38 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C014-dependency-injection.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C017-no-constructor-logic.md +46 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C018-generic-errors.md +38 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C019-error-log-level.md +29 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C020-no-unused-imports.md +30 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C022-no-unused-variables.md +33 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C023-no-duplicate-names.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C024-centralize-constants.md +33 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C029-catch-log-root-cause.md +40 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C030-custom-error-classes.md +38 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C033-separate-data-access.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C035-error-context-logging.md +31 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C041-no-hardcoded-secrets.md +25 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C042-boolean-naming.md +27 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C052-controller-parsing.md +41 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C060-superclass-logic.md +33 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C067-no-hardcoded-config.md +24 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S003-open-redirect.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S004-no-log-credentials.md +28 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S005-server-authorization.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S006-default-credentials.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S007-output-encoding.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S009-approved-crypto.md +37 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S010-csprng.md +32 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S011-encrypted-client-hello.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S012-secrets-management.md +35 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S013-tls-connections.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S016-no-sensitive-query-string.md +39 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S017-parameterized-queries.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S019-email-input-sanitization.md +35 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S020-eval-code-execution.md +56 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S022-context-escaping.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S023-dynamic-js-encoding.md +34 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S025-server-validation.md +56 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S026-tls-encryption.md +28 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S027-mtls-validation.md +40 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S028-upload-limits.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S029-csrf-protection.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S030-directory-browsing.md +26 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S031-secure-cookie-flag.md +35 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S032-httponly-cookie.md +31 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S033-samesite-cookie.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S034-host-prefix-cookie.md +31 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S035-app-hostnames.md +26 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S036-internal-file-paths.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S037-anti-cache-headers.md +33 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S039-tls-certificate-validation.md +41 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S041-logout-invalidation.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S042-long-lived-sessions.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S044-critical-changes-reauth.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S045-brute-force-protection.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S047-oauth-csrf-protection.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S048-oauth-redirect-validation.md +37 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S049-auth-code-expiry.md +33 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S050-token-entropy.md +33 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S051-password-length.md +35 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S052-otp-entropy.md +26 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S053-generic-error-messages.md +32 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S054-no-default-admin.md +31 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S055-content-type-validation.md +44 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S056-log-injection.md +33 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S057-synchronized-time.md +27 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S058-ssrf-protection.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/go/C006-verb-noun-functions.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/go/C013-no-dead-code.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/go/C014-dependency-injection.md +85 -0
- package/skill-assets/sunlint-code-quality/rules/go/C017-no-constructor-logic.md +67 -0
- package/skill-assets/sunlint-code-quality/rules/go/C018-generic-errors.md +63 -0
- package/skill-assets/sunlint-code-quality/rules/go/C019-error-log-level.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/go/C020-no-unused-imports.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/go/C022-no-unused-variables.md +34 -0
- package/skill-assets/sunlint-code-quality/rules/go/C023-no-duplicate-names.md +41 -0
- package/skill-assets/sunlint-code-quality/rules/go/C024-centralize-constants.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/go/C029-catch-log-root-cause.md +56 -0
- package/skill-assets/sunlint-code-quality/rules/go/C030-custom-error-classes.md +69 -0
- package/skill-assets/sunlint-code-quality/rules/go/C033-separate-data-access.md +68 -0
- package/skill-assets/sunlint-code-quality/rules/go/C035-error-context-logging.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/go/C041-no-hardcoded-secrets.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/go/C042-boolean-naming.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/go/C052-controller-parsing.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/go/C060-superclass-logic.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/go/C067-no-hardcoded-config.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/go/S003-open-redirect.md +80 -0
- package/skill-assets/sunlint-code-quality/rules/go/S004-no-log-credentials.md +66 -0
- package/skill-assets/sunlint-code-quality/rules/go/S005-server-authorization.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/go/S006-default-credentials.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/go/S007-output-encoding.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/go/S009-approved-crypto.md +63 -0
- package/skill-assets/sunlint-code-quality/rules/go/S010-csprng.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/go/S011-encrypted-client-hello.md +34 -0
- package/skill-assets/sunlint-code-quality/rules/go/S012-secrets-management.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/go/S013-tls-connections.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/go/S016-no-sensitive-query-string.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/go/S017-parameterized-queries.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/go/S019-email-input-sanitization.md +44 -0
- package/skill-assets/sunlint-code-quality/rules/go/S020-eval-code-execution.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/go/S022-context-escaping.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/go/S023-dynamic-js-encoding.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/go/S025-server-validation.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/go/S026-tls-encryption.md +46 -0
- package/skill-assets/sunlint-code-quality/rules/go/S027-mtls-validation.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/go/S028-upload-limits.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/go/S029-csrf-protection.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/go/S030-directory-browsing.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/go/S031-secure-cookie-flag.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/go/S032-httponly-cookie.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/go/S033-samesite-cookie.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/go/S034-host-prefix-cookie.md +44 -0
- package/skill-assets/sunlint-code-quality/rules/go/S035-app-hostnames.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/go/S036-internal-file-paths.md +56 -0
- package/skill-assets/sunlint-code-quality/rules/go/S037-anti-cache-headers.md +43 -0
- package/skill-assets/sunlint-code-quality/rules/go/S039-tls-certificate-validation.md +41 -0
- package/skill-assets/sunlint-code-quality/rules/go/S041-logout-invalidation.md +46 -0
- package/skill-assets/sunlint-code-quality/rules/go/S042-long-lived-sessions.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/go/S044-critical-changes-reauth.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/go/S045-brute-force-protection.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/go/S047-oauth-csrf-protection.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/go/S048-oauth-redirect-validation.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/go/S049-auth-code-expiry.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/go/S050-token-entropy.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/go/S051-password-length.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/go/S052-otp-entropy.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/go/S053-generic-error-messages.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/go/S054-no-default-admin.md +43 -0
- package/skill-assets/sunlint-code-quality/rules/go/S055-content-type-validation.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/go/S056-log-injection.md +40 -0
- package/skill-assets/sunlint-code-quality/rules/go/S057-synchronized-time.md +40 -0
- package/skill-assets/sunlint-code-quality/rules/go/S058-ssrf-protection.md +70 -0
- package/skill-assets/sunlint-code-quality/rules/java/C006-verb-noun-functions.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/java/C013-no-dead-code.md +175 -0
- package/skill-assets/sunlint-code-quality/rules/java/C014-dependency-injection.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/java/C017-no-constructor-logic.md +39 -0
- package/skill-assets/sunlint-code-quality/rules/java/C018-generic-errors.md +28 -0
- package/skill-assets/sunlint-code-quality/rules/java/C019-error-log-level.md +34 -0
- package/skill-assets/sunlint-code-quality/rules/java/C020-no-unused-imports.md +34 -0
- package/skill-assets/sunlint-code-quality/rules/java/C022-no-unused-variables.md +31 -0
- package/skill-assets/sunlint-code-quality/rules/java/C023-no-duplicate-names.md +37 -0
- package/skill-assets/sunlint-code-quality/rules/java/C024-centralize-constants.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/java/C029-catch-log-root-cause.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/java/C030-custom-error-classes.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/java/C033-separate-data-access.md +46 -0
- package/skill-assets/sunlint-code-quality/rules/java/C035-error-context-logging.md +38 -0
- package/skill-assets/sunlint-code-quality/rules/java/C041-no-hardcoded-secrets.md +34 -0
- package/skill-assets/sunlint-code-quality/rules/java/C042-boolean-naming.md +27 -0
- package/skill-assets/sunlint-code-quality/rules/java/C052-controller-parsing.md +39 -0
- package/skill-assets/sunlint-code-quality/rules/java/C060-superclass-logic.md +32 -0
- package/skill-assets/sunlint-code-quality/rules/java/C067-no-hardcoded-config.md +31 -0
- package/skill-assets/sunlint-code-quality/rules/java/S003-open-redirect.md +38 -0
- package/skill-assets/sunlint-code-quality/rules/java/S004-no-log-credentials.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/java/S005-server-authorization.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/java/S006-default-credentials.md +39 -0
- package/skill-assets/sunlint-code-quality/rules/java/S007-output-encoding.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/java/S009-approved-crypto.md +40 -0
- package/skill-assets/sunlint-code-quality/rules/java/S010-csprng.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/java/S011-encrypted-client-hello.md +27 -0
- package/skill-assets/sunlint-code-quality/rules/java/S012-secrets-management.md +34 -0
- package/skill-assets/sunlint-code-quality/rules/java/S013-tls-connections.md +40 -0
- package/skill-assets/sunlint-code-quality/rules/java/S016-no-sensitive-query-string.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/java/S017-parameterized-queries.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/java/S019-email-input-sanitization.md +32 -0
- package/skill-assets/sunlint-code-quality/rules/java/S020-eval-code-execution.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/java/S022-context-escaping.md +28 -0
- package/skill-assets/sunlint-code-quality/rules/java/S023-dynamic-js-encoding.md +28 -0
- package/skill-assets/sunlint-code-quality/rules/java/S025-server-validation.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/java/S026-tls-encryption.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/java/S027-mtls-validation.md +26 -0
- package/skill-assets/sunlint-code-quality/rules/java/S028-upload-limits.md +35 -0
- package/skill-assets/sunlint-code-quality/rules/java/S029-csrf-protection.md +35 -0
- package/skill-assets/sunlint-code-quality/rules/java/S030-directory-browsing.md +38 -0
- package/skill-assets/sunlint-code-quality/rules/java/S031-secure-cookie-flag.md +38 -0
- package/skill-assets/sunlint-code-quality/rules/java/S032-httponly-cookie.md +31 -0
- package/skill-assets/sunlint-code-quality/rules/java/S033-samesite-cookie.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/java/S034-host-prefix-cookie.md +35 -0
- package/skill-assets/sunlint-code-quality/rules/java/S035-app-hostnames.md +23 -0
- package/skill-assets/sunlint-code-quality/rules/java/S036-internal-file-paths.md +39 -0
- package/skill-assets/sunlint-code-quality/rules/java/S037-anti-cache-headers.md +37 -0
- package/skill-assets/sunlint-code-quality/rules/java/S039-tls-certificate-validation.md +43 -0
- package/skill-assets/sunlint-code-quality/rules/java/S041-logout-invalidation.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/java/S042-long-lived-sessions.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/java/S044-critical-changes-reauth.md +28 -0
- package/skill-assets/sunlint-code-quality/rules/java/S045-brute-force-protection.md +38 -0
- package/skill-assets/sunlint-code-quality/rules/java/S047-oauth-csrf-protection.md +33 -0
- package/skill-assets/sunlint-code-quality/rules/java/S048-oauth-redirect-validation.md +25 -0
- package/skill-assets/sunlint-code-quality/rules/java/S049-auth-code-expiry.md +23 -0
- package/skill-assets/sunlint-code-quality/rules/java/S050-token-entropy.md +20 -0
- package/skill-assets/sunlint-code-quality/rules/java/S051-password-length.md +20 -0
- package/skill-assets/sunlint-code-quality/rules/java/S052-otp-entropy.md +23 -0
- package/skill-assets/sunlint-code-quality/rules/java/S053-generic-error-messages.md +21 -0
- package/skill-assets/sunlint-code-quality/rules/java/S054-no-default-admin.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/java/S055-content-type-validation.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/java/S056-log-injection.md +38 -0
- package/skill-assets/sunlint-code-quality/rules/java/S057-synchronized-time.md +35 -0
- package/skill-assets/sunlint-code-quality/rules/java/S058-ssrf-protection.md +56 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C006-verb-noun-functions.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C013-no-dead-code.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C014-dependency-injection.md +64 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C017-no-constructor-logic.md +68 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C018-generic-errors.md +46 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C019-error-log-level.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C020-no-unused-imports.md +44 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C022-no-unused-variables.md +39 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C023-no-duplicate-names.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C024-centralize-constants.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C029-catch-log-root-cause.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C030-custom-error-classes.md +72 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C033-separate-data-access.md +69 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C035-error-context-logging.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C041-no-hardcoded-secrets.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C042-boolean-naming.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C052-controller-parsing.md +71 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C060-superclass-logic.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C067-no-hardcoded-config.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S003-open-redirect.md +66 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S004-no-log-credentials.md +59 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S005-server-authorization.md +75 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S006-default-credentials.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S007-output-encoding.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S009-approved-crypto.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S010-csprng.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S011-encrypted-client-hello.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S012-secrets-management.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S013-tls-connections.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S016-no-sensitive-query-string.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S017-parameterized-queries.md +41 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S019-email-input-sanitization.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S020-eval-code-execution.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S022-context-escaping.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S023-dynamic-js-encoding.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S025-server-validation.md +59 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S026-tls-encryption.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S027-mtls-validation.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S028-upload-limits.md +67 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S029-csrf-protection.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S030-directory-browsing.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S031-secure-cookie-flag.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S032-httponly-cookie.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S033-samesite-cookie.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S034-host-prefix-cookie.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S035-app-hostnames.md +59 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S036-internal-file-paths.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S037-anti-cache-headers.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S039-tls-certificate-validation.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S041-logout-invalidation.md +71 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S042-long-lived-sessions.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S044-critical-changes-reauth.md +64 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S045-brute-force-protection.md +64 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S047-oauth-csrf-protection.md +74 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S048-oauth-redirect-validation.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S049-auth-code-expiry.md +70 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S050-token-entropy.md +65 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S051-password-length.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S052-otp-entropy.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S053-generic-error-messages.md +66 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S054-no-default-admin.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S055-content-type-validation.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S056-log-injection.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S057-synchronized-time.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S058-ssrf-protection.md +69 -0
- package/skill-assets/sunlint-code-quality/rules/php/C006-verb-noun-functions.md +46 -0
- package/skill-assets/sunlint-code-quality/rules/php/C013-no-dead-code.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/php/C014-dependency-injection.md +71 -0
- package/skill-assets/sunlint-code-quality/rules/php/C017-no-constructor-logic.md +68 -0
- package/skill-assets/sunlint-code-quality/rules/php/C018-generic-errors.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/php/C019-error-log-level.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/php/C020-no-unused-imports.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/php/C022-no-unused-variables.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/php/C023-no-duplicate-names.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/php/C024-centralize-constants.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/php/C029-catch-log-root-cause.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/php/C030-custom-error-classes.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/php/C033-separate-data-access.md +79 -0
- package/skill-assets/sunlint-code-quality/rules/php/C035-error-context-logging.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/php/C041-no-hardcoded-secrets.md +59 -0
- package/skill-assets/sunlint-code-quality/rules/php/C042-boolean-naming.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/php/C052-controller-parsing.md +66 -0
- package/skill-assets/sunlint-code-quality/rules/php/C060-superclass-logic.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/php/C067-no-hardcoded-config.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/php/S003-open-redirect.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/php/S004-no-log-credentials.md +67 -0
- package/skill-assets/sunlint-code-quality/rules/php/S005-server-authorization.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/php/S006-default-credentials.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/php/S007-output-encoding.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/php/S009-approved-crypto.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/php/S010-csprng.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/php/S011-encrypted-client-hello.md +41 -0
- package/skill-assets/sunlint-code-quality/rules/php/S012-secrets-management.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/php/S013-tls-connections.md +67 -0
- package/skill-assets/sunlint-code-quality/rules/php/S016-no-sensitive-query-string.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/php/S017-parameterized-queries.md +44 -0
- package/skill-assets/sunlint-code-quality/rules/php/S019-email-input-sanitization.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/php/S020-eval-code-execution.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/php/S022-context-escaping.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/php/S023-dynamic-js-encoding.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/php/S025-server-validation.md +63 -0
- package/skill-assets/sunlint-code-quality/rules/php/S026-tls-encryption.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/php/S027-mtls-validation.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/php/S028-upload-limits.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/php/S029-csrf-protection.md +65 -0
- package/skill-assets/sunlint-code-quality/rules/php/S030-directory-browsing.md +40 -0
- package/skill-assets/sunlint-code-quality/rules/php/S031-secure-cookie-flag.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/php/S032-httponly-cookie.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/php/S033-samesite-cookie.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/php/S034-host-prefix-cookie.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/php/S035-app-hostnames.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/php/S036-internal-file-paths.md +56 -0
- package/skill-assets/sunlint-code-quality/rules/php/S037-anti-cache-headers.md +56 -0
- package/skill-assets/sunlint-code-quality/rules/php/S039-tls-certificate-validation.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/php/S041-logout-invalidation.md +63 -0
- package/skill-assets/sunlint-code-quality/rules/php/S042-long-lived-sessions.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/php/S044-critical-changes-reauth.md +71 -0
- package/skill-assets/sunlint-code-quality/rules/php/S045-brute-force-protection.md +67 -0
- package/skill-assets/sunlint-code-quality/rules/php/S047-oauth-csrf-protection.md +72 -0
- package/skill-assets/sunlint-code-quality/rules/php/S048-oauth-redirect-validation.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/php/S049-auth-code-expiry.md +71 -0
- package/skill-assets/sunlint-code-quality/rules/php/S050-token-entropy.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/php/S051-password-length.md +59 -0
- package/skill-assets/sunlint-code-quality/rules/php/S052-otp-entropy.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/php/S053-generic-error-messages.md +59 -0
- package/skill-assets/sunlint-code-quality/rules/php/S054-no-default-admin.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/php/S055-content-type-validation.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/php/S056-log-injection.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/php/S057-synchronized-time.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/php/S058-ssrf-protection.md +65 -0
- package/skill-assets/sunlint-code-quality/rules/python/C006-verb-noun-functions.md +30 -0
- package/skill-assets/sunlint-code-quality/rules/python/C013-no-dead-code.md +24 -0
- package/skill-assets/sunlint-code-quality/rules/python/C014-dependency-injection.md +68 -0
- package/skill-assets/sunlint-code-quality/rules/python/C017-no-constructor-logic.md +30 -0
- package/skill-assets/sunlint-code-quality/rules/python/C018-generic-errors.md +25 -0
- package/skill-assets/sunlint-code-quality/rules/python/C019-error-log-level.md +26 -0
- package/skill-assets/sunlint-code-quality/rules/python/C020-no-unused-imports.md +28 -0
- package/skill-assets/sunlint-code-quality/rules/python/C022-no-unused-variables.md +24 -0
- package/skill-assets/sunlint-code-quality/rules/python/C023-no-duplicate-names.md +27 -0
- package/skill-assets/sunlint-code-quality/rules/python/C024-centralize-constants.md +27 -0
- package/skill-assets/sunlint-code-quality/rules/python/C029-catch-log-root-cause.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/python/C030-custom-error-classes.md +28 -0
- package/skill-assets/sunlint-code-quality/rules/python/C033-separate-data-access.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/python/C035-error-context-logging.md +26 -0
- package/skill-assets/sunlint-code-quality/rules/python/C041-no-hardcoded-secrets.md +23 -0
- package/skill-assets/sunlint-code-quality/rules/python/C042-boolean-naming.md +24 -0
- package/skill-assets/sunlint-code-quality/rules/python/C052-controller-parsing.md +34 -0
- package/skill-assets/sunlint-code-quality/rules/python/C060-superclass-logic.md +26 -0
- package/skill-assets/sunlint-code-quality/rules/python/C067-no-hardcoded-config.md +22 -0
- package/skill-assets/sunlint-code-quality/rules/python/S003-open-redirect.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S004-no-log-credentials.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S005-server-authorization.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S006-default-credentials.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S007-output-encoding.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S009-approved-crypto.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S010-csprng.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S011-encrypted-client-hello.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S012-secrets-management.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S013-tls-connections.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S016-no-sensitive-query-string.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S017-parameterized-queries.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/python/S019-email-input-sanitization.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S020-eval-code-execution.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/python/S022-context-escaping.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S023-dynamic-js-encoding.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S025-server-validation.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S026-tls-encryption.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S027-mtls-validation.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S028-upload-limits.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S029-csrf-protection.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S030-directory-browsing.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S031-secure-cookie-flag.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S032-httponly-cookie.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S033-samesite-cookie.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S034-host-prefix-cookie.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S035-app-hostnames.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S036-internal-file-paths.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/python/S037-anti-cache-headers.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S039-tls-certificate-validation.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S041-logout-invalidation.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S042-long-lived-sessions.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S044-critical-changes-reauth.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S045-brute-force-protection.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S047-oauth-csrf-protection.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S048-oauth-redirect-validation.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S049-auth-code-expiry.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S050-token-entropy.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S051-password-length.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S052-otp-entropy.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S053-generic-error-messages.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S054-no-default-admin.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S055-content-type-validation.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S056-log-injection.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S057-synchronized-time.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S058-ssrf-protection.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C006-verb-noun-functions.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C013-no-dead-code.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C014-dependency-injection.md +69 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C017-no-constructor-logic.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C018-generic-errors.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C019-error-log-level.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C020-no-unused-imports.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C022-no-unused-variables.md +59 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C023-no-duplicate-names.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C024-centralize-constants.md +56 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C029-catch-log-root-cause.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C030-custom-error-classes.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C033-separate-data-access.md +69 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C035-error-context-logging.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C041-no-hardcoded-secrets.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C042-boolean-naming.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C052-controller-parsing.md +64 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C060-superclass-logic.md +67 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C067-no-hardcoded-config.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S003-open-redirect.md +76 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S004-no-log-credentials.md +71 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S005-server-authorization.md +68 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S006-default-credentials.md +69 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S007-output-encoding.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S009-approved-crypto.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S010-csprng.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S011-encrypted-client-hello.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S012-secrets-management.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S013-tls-connections.md +70 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S016-no-sensitive-query-string.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S017-parameterized-queries.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S019-email-input-sanitization.md +56 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S020-eval-code-execution.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S022-context-escaping.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S023-dynamic-js-encoding.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S025-server-validation.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S026-tls-encryption.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S027-mtls-validation.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S028-upload-limits.md +65 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S029-csrf-protection.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S030-directory-browsing.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S031-secure-cookie-flag.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S032-httponly-cookie.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S033-samesite-cookie.md +46 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S034-host-prefix-cookie.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S035-app-hostnames.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S036-internal-file-paths.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S037-anti-cache-headers.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S039-tls-certificate-validation.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S041-logout-invalidation.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S042-long-lived-sessions.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S044-critical-changes-reauth.md +69 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S045-brute-force-protection.md +59 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S047-oauth-csrf-protection.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S048-oauth-redirect-validation.md +59 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S049-auth-code-expiry.md +73 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S050-token-entropy.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S051-password-length.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S052-otp-entropy.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S053-generic-error-messages.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S054-no-default-admin.md +64 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S055-content-type-validation.md +64 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S056-log-injection.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S057-synchronized-time.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S058-ssrf-protection.md +63 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Function Names Verb-Noun
|
|
3
|
+
impact: LOW
|
|
4
|
+
impactDescription: makes code self-documenting
|
|
5
|
+
tags: naming, functions, readability, conventions, quality, php
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Function Names Verb-Noun
|
|
9
|
+
|
|
10
|
+
Functions represent actions. Using "Verb-Noun" pattern makes the purpose of the function clear and the code self-documenting.
|
|
11
|
+
|
|
12
|
+
**Incorrect (vague names):**
|
|
13
|
+
|
|
14
|
+
```php
|
|
15
|
+
function user() { } // Noun only
|
|
16
|
+
function userData() { } // Noun only
|
|
17
|
+
function process() { } // Vague
|
|
18
|
+
function handle() { } // Vague
|
|
19
|
+
function stuff() { } // Noun only
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Correct (action verbs):**
|
|
23
|
+
|
|
24
|
+
```php
|
|
25
|
+
function getUser() { }
|
|
26
|
+
function createUserAccount() { }
|
|
27
|
+
function validateEmailFormat() { }
|
|
28
|
+
function calculateTotalPrice() { }
|
|
29
|
+
function sendConfirmationEmail() { }
|
|
30
|
+
function convertCurrencyToUSD() { }
|
|
31
|
+
function hasActiveSubscription(): bool { }
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Verb categories:**
|
|
35
|
+
|
|
36
|
+
| Category | Verbs |
|
|
37
|
+
|----------|-------|
|
|
38
|
+
| Retrieval | `get`, `fetch`, `find`, `load`, `query` |
|
|
39
|
+
| Creation | `create`, `build`, `make`, `generate` |
|
|
40
|
+
| Modification | `set`, `update`, `modify`, `change`, `save` |
|
|
41
|
+
| Deletion | `delete`, `remove`, `destroy`, `clear` |
|
|
42
|
+
| Validation | `validate`, `verify`, `check`, `ensure` |
|
|
43
|
+
| Computation | `calculate`, `compute`, `parse`, `format` |
|
|
44
|
+
| Boolean | `is`, `has`, `can`, `should`, `will` |
|
|
45
|
+
|
|
46
|
+
**Tools:** PR review, PHPStan, Psalm
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Do Not Use Dead Code
|
|
3
|
+
impact: LOW
|
|
4
|
+
impactDescription: reduces codebase noise and improves maintainability
|
|
5
|
+
tags: dead-code, cleanup, maintenance, quality, php
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Do Not Use Dead Code
|
|
9
|
+
|
|
10
|
+
Dead code (commented-out blocks, unused functions, unreachable logic) confuses developers and increases codebase noise. Git history already preserves deleted code, so there is no need to keep it in the active codebase.
|
|
11
|
+
|
|
12
|
+
**Incorrect (keeping dead code):**
|
|
13
|
+
|
|
14
|
+
```php
|
|
15
|
+
function processOrder($order) {
|
|
16
|
+
// Old implementation - keeping for reference
|
|
17
|
+
/*
|
|
18
|
+
$total = 0;
|
|
19
|
+
foreach ($order->items as $item) {
|
|
20
|
+
$total += $item->price * $item->quantity;
|
|
21
|
+
}
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
$total = $this->calculator->calculate($order);
|
|
25
|
+
return $total;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Unused function - "someone might need it later"
|
|
29
|
+
function legacyCalculation() {
|
|
30
|
+
// ...
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Correct (clean code):**
|
|
35
|
+
|
|
36
|
+
```php
|
|
37
|
+
function processOrder($order) {
|
|
38
|
+
return $this->calculator->calculate($order);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Delete unused functions - rely on Git history if needed later.
|
|
42
|
+
// Delete commented-out code blocks.
|
|
43
|
+
// Remove unused 'use' statements.
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Types of dead code:**
|
|
47
|
+
- Commented-out code blocks.
|
|
48
|
+
- Unused functions, methods, or classes.
|
|
49
|
+
- Unused `use` (import) statements.
|
|
50
|
+
- Unreachable code (logic after a `return` or `throw`).
|
|
51
|
+
- Unused private properties or local variables.
|
|
52
|
+
|
|
53
|
+
**Tools:** PHPStan, Psalm, PHP_CodeSniffer, PR review
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Use Dependency Injection
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: enables testability and loose coupling
|
|
5
|
+
tags: dependency-injection, testing, coupling, architecture, quality, php
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Use Dependency Injection
|
|
9
|
+
|
|
10
|
+
Direct instantiation creates tight coupling, making testing difficult and changes risky. Dependency Injection (DI) allows for mockability, replaceability, and better overall architecture.
|
|
11
|
+
|
|
12
|
+
**Incorrect (hardcoded dependencies):**
|
|
13
|
+
|
|
14
|
+
```php
|
|
15
|
+
class OrderService {
|
|
16
|
+
private Database $db;
|
|
17
|
+
private Mailer $mailer;
|
|
18
|
+
|
|
19
|
+
public function __construct() {
|
|
20
|
+
// Hardcoded dependencies - impossible to mock in unit tests
|
|
21
|
+
$this->db = new MySqlDatabase();
|
|
22
|
+
$this->mailer = new SmtpMailer();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public function createOrder($data) {
|
|
26
|
+
$this->db->save($data);
|
|
27
|
+
$this->mailer->send($data['email'], 'Order created');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Correct (injected dependencies via constructor):**
|
|
33
|
+
|
|
34
|
+
```php
|
|
35
|
+
interface DatabaseInterface {
|
|
36
|
+
public function save(array $data);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface MailerInterface {
|
|
40
|
+
public function send(string $to, string $msg);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
class OrderService {
|
|
44
|
+
// PHP 8+ Constructor Property Promotion
|
|
45
|
+
public function __construct(
|
|
46
|
+
private DatabaseInterface $db,
|
|
47
|
+
private MailerInterface $mailer
|
|
48
|
+
) {}
|
|
49
|
+
|
|
50
|
+
public function createOrder(array $data) {
|
|
51
|
+
$this->db->save($data);
|
|
52
|
+
$this->mailer->send($data['email'], 'Order created');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// In production (using a DI Container like Laravel Service Container or Symfony)
|
|
57
|
+
$service = $container->get(OrderService::class);
|
|
58
|
+
|
|
59
|
+
// In Unit Tests
|
|
60
|
+
$mockDb = $this->createMock(DatabaseInterface::class);
|
|
61
|
+
$mockMailer = $this->createMock(MailerInterface::class);
|
|
62
|
+
$testService = new OrderService($mockDb, $mockMailer);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Benefits:**
|
|
66
|
+
- **Testability**: Easily swap real services for mocks or stubs.
|
|
67
|
+
- **Maintainability**: Centralized control over dependency lifetimes and configurations.
|
|
68
|
+
- **Flexibility**: Change implementations (e.g., switch from SMTP to SendGrid) without modifying business logic.
|
|
69
|
+
- **CLarity**: Class dependencies are explicitly declared in the constructor.
|
|
70
|
+
|
|
71
|
+
**Tools:** PHPUnit, Mockery, Laravel/Symfony Containers, PHPStan
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: No Business Logic In Constructors
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: ensures predictable object initialization
|
|
5
|
+
tags: constructor, initialization, side-effects, patterns, quality, php
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## No Business Logic In Constructors
|
|
9
|
+
|
|
10
|
+
Constructors should be used exclusively for assigning dependencies and initializing basic object state. Including complex business logic, file I/O, or API calls in constructors makes code unpredictable, harder to test, and can lead to unexpected side effects during object instantiation.
|
|
11
|
+
|
|
12
|
+
**Incorrect (heavy logic in constructor):**
|
|
13
|
+
|
|
14
|
+
```php
|
|
15
|
+
class UserService {
|
|
16
|
+
private array $config;
|
|
17
|
+
|
|
18
|
+
public function __construct(string $configPath) {
|
|
19
|
+
// BAD: File I/O in constructor
|
|
20
|
+
if (!file_exists($configPath)) {
|
|
21
|
+
throw new Exception("Config not found");
|
|
22
|
+
}
|
|
23
|
+
$this->config = json_decode(file_get_contents($configPath), true);
|
|
24
|
+
|
|
25
|
+
// BAD: Establishing connections or complex logic
|
|
26
|
+
$this->db = new PDO($this->config['dsn']);
|
|
27
|
+
|
|
28
|
+
// BAD: Side effects
|
|
29
|
+
Log::info("UserService started");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Correct (assignments only or Factory pattern):**
|
|
35
|
+
|
|
36
|
+
```php
|
|
37
|
+
class UserService {
|
|
38
|
+
public function __construct(
|
|
39
|
+
private array $config,
|
|
40
|
+
private PDO $db
|
|
41
|
+
) {
|
|
42
|
+
// Assignments only - no side effects
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Factory method for controlled initialization
|
|
47
|
+
*/
|
|
48
|
+
public static function create(string $configPath): self {
|
|
49
|
+
$config = json_decode(file_get_contents($configPath), true);
|
|
50
|
+
$db = new PDO($config['dsn']);
|
|
51
|
+
|
|
52
|
+
Log::info("UserService initialized via factory");
|
|
53
|
+
|
|
54
|
+
return new self($config, $db);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Usage
|
|
59
|
+
$service = UserService::create('/path/to/config.json');
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Why avoid logic in constructors?**
|
|
63
|
+
- **Testability**: You cannot easily mock the behavior of a constructor.
|
|
64
|
+
- **Predictability**: `new MyClass()` should be fast and side-effect free.
|
|
65
|
+
- **Error Handling**: Exceptions in constructors can leave objects in an inconsistent state or be difficult to handle during DI container resolution.
|
|
66
|
+
- **Coupling**: It often forces the class to know how to create its own dependencies.
|
|
67
|
+
|
|
68
|
+
**Tools:** PHPStan, Psalm, PR review
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Do Not Throw Generic Errors
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: enables proper error handling and monitoring
|
|
5
|
+
tags: error-handling, exceptions, custom-errors, debugging, quality, php
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Do Not Throw Generic Errors
|
|
9
|
+
|
|
10
|
+
Throwing generic exceptions like `\Exception`, `\Error`, or `\RuntimeException` with vague messages makes it impossible to distinguish between different types of failure. Proper error handling requires specific exception types that convey meaning and context.
|
|
11
|
+
|
|
12
|
+
**Incorrect (generic errors):**
|
|
13
|
+
|
|
14
|
+
```php
|
|
15
|
+
if (!$user) {
|
|
16
|
+
throw new \Exception("error"); // Vague message, generic type
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if ($amount < 0) {
|
|
20
|
+
throw new \RuntimeException("Invalid"); // Generic type
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// In Laravel - avoid generic aborts without explanation
|
|
24
|
+
abort(500);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Correct (specific exceptions with context):**
|
|
28
|
+
|
|
29
|
+
```php
|
|
30
|
+
if (!$user) {
|
|
31
|
+
throw new UserNotFoundException("User with ID {$userId} not found in database.");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if ($amount < 0) {
|
|
35
|
+
throw new InvalidTransactionAmountException("Transaction amount '{$amount}' cannot be negative.");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Custom error with structured context (if supported by your base exception)
|
|
39
|
+
throw new ValidationException([
|
|
40
|
+
'email' => 'The provided email is already in use.',
|
|
41
|
+
'code' => 'EMAIL_TAKEN'
|
|
42
|
+
]);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Custom errors should include:**
|
|
46
|
+
- A descriptive message that explains **what** failed and **why**.
|
|
47
|
+
- Relevant identifiers (IDs, keys) for easier debugging.
|
|
48
|
+
- Specific exception types that allow for targeted `catch` blocks.
|
|
49
|
+
|
|
50
|
+
**Tools:** PHPStan, Psalm, PR review
|
|
@@ -0,0 +1,54 @@
|
|
|
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, php
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Do Not Use Error Log For Non-critical
|
|
9
|
+
|
|
10
|
+
Using the `error` log level for non-critical or expected business events (like wrong passwords or validation failures) creates noise and causes alert fatigue. When too many non-critical events are logged as errors, real system failures may be overlooked.
|
|
11
|
+
|
|
12
|
+
**Incorrect (overusing ERROR level):**
|
|
13
|
+
|
|
14
|
+
```php
|
|
15
|
+
// NOT an error - expected business behavior
|
|
16
|
+
Log::error('User entered wrong password', ['user_id' => $id]);
|
|
17
|
+
|
|
18
|
+
// NOT an error - validation failure
|
|
19
|
+
Log::error('Validation failed for email format', ['email' => $email]);
|
|
20
|
+
|
|
21
|
+
// NOT an error - temporary network retry
|
|
22
|
+
Log::error('Retrying external API call... attempt 2');
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Correct (appropriate PSR-3 log levels):**
|
|
26
|
+
|
|
27
|
+
```php
|
|
28
|
+
// WARNING - Pathological but recoverable scenarios
|
|
29
|
+
Log::warning('API timeout, retrying...', ['attempt' => 2, 'service' => 'payment-gateway']);
|
|
30
|
+
|
|
31
|
+
// INFO - Significant business events
|
|
32
|
+
Log::info('Login failed: invalid credentials', ['username' => $username, 'attempts' => 3]);
|
|
33
|
+
|
|
34
|
+
// DEBUG - Information helpful for developers during troubleshooting
|
|
35
|
+
Log::debug('Form validation failed', ['field' => 'email', 'error' => 'invalid_format']);
|
|
36
|
+
|
|
37
|
+
// ERROR - Actual system failures that require attention
|
|
38
|
+
Log::error('Database connection lost', ['host' => $host, 'exception' => $e->getMessage()]);
|
|
39
|
+
|
|
40
|
+
// CRITICAL/EMERGENCY - System unusable or widespread failure
|
|
41
|
+
Log::emergency('Server out of disk space!');
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Log Level Guide (PSR-3):**
|
|
45
|
+
|
|
46
|
+
| Level | Use For | Action Required? |
|
|
47
|
+
|-------|---------|------------------|
|
|
48
|
+
| **EMERGENCY/CRITICAL** | System is unusable, widespread failure | Immediate wake-up call |
|
|
49
|
+
| **ERROR** | Runtime errors that do not require immediate action but should be logged | Investigation within regular hours |
|
|
50
|
+
| **WARNING** | Exceptional occurrences that are not errors (deprecations, retries) | Periodic review |
|
|
51
|
+
| **INFO** | Interesting events (Logins, SQL logs in dev) | None (monitoring only) |
|
|
52
|
+
| **DEBUG** | Detailed debug information | Temporary use |
|
|
53
|
+
|
|
54
|
+
**Tools:** Monolog, Laravel/Symfony Logging, Sentry, New Relic
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Do Not Use Unused Classes or Namespaces
|
|
3
|
+
impact: LOW
|
|
4
|
+
impactDescription: reduces codebase noise and improves clarity
|
|
5
|
+
tags: imports, use-statements, cleanup, quality, php
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Do Not Use Unused Classes or Namespaces
|
|
9
|
+
|
|
10
|
+
Unused `use` statements (imports) add unnecessary noise to the code, making it harder for developers to see which dependencies are actually required.
|
|
11
|
+
|
|
12
|
+
**Incorrect (unused imports):**
|
|
13
|
+
|
|
14
|
+
```php
|
|
15
|
+
namespace App\Services;
|
|
16
|
+
|
|
17
|
+
use App\Models\User;
|
|
18
|
+
use App\Models\Order;
|
|
19
|
+
use App\Models\Product;
|
|
20
|
+
use App\Models\Category;
|
|
21
|
+
use Illuminate\Support\Str;
|
|
22
|
+
use Carbon\Carbon;
|
|
23
|
+
|
|
24
|
+
class UserService
|
|
25
|
+
{
|
|
26
|
+
// Only User is actually used in this class
|
|
27
|
+
public function findUser($id)
|
|
28
|
+
{
|
|
29
|
+
return User::find($id);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Correct (only needed imports):**
|
|
35
|
+
|
|
36
|
+
```php
|
|
37
|
+
namespace App\Services;
|
|
38
|
+
|
|
39
|
+
use App\Models\User;
|
|
40
|
+
|
|
41
|
+
class UserService
|
|
42
|
+
{
|
|
43
|
+
public function findUser($id)
|
|
44
|
+
{
|
|
45
|
+
return User::find($id);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Why remove unused imports?**
|
|
51
|
+
- **Readability**: Quickly understand a file's dependencies.
|
|
52
|
+
- **Maintenance**: Avoid confusion when refactoring or deleting classes.
|
|
53
|
+
- **IDE Performance**: Slightly faster indexing and better suggestions.
|
|
54
|
+
|
|
55
|
+
**Tools:** PHPStorm (Optimize Imports), PHP_CodeSniffer (`SlevomatCodingStandard.Namespaces.UnusedUses`), PHPStan, Psalm
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Do Not Leave Unused Variables
|
|
3
|
+
impact: LOW
|
|
4
|
+
impactDescription: reduces code noise and prevents potential bugs
|
|
5
|
+
tags: variables, cleanup, quality, php
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Do Not Leave Unused Variables
|
|
9
|
+
|
|
10
|
+
Unused variables make the code harder to read and often indicate incomplete refactoring or accidental logic errors.
|
|
11
|
+
|
|
12
|
+
**Incorrect (unused variables):**
|
|
13
|
+
|
|
14
|
+
```php
|
|
15
|
+
function processOrder($order) {
|
|
16
|
+
$user = $order->user; // Declared but never used
|
|
17
|
+
$timestamp = time(); // Never used
|
|
18
|
+
$items = $order->items;
|
|
19
|
+
|
|
20
|
+
return array_map(fn($item) => $item->name, $items);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Unused method parameters
|
|
24
|
+
function deleteUser($id, $force = false) {
|
|
25
|
+
// $force is never used in the logic
|
|
26
|
+
return User::destroy($id);
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Correct (clean logic):**
|
|
31
|
+
|
|
32
|
+
```php
|
|
33
|
+
function processOrder($order) {
|
|
34
|
+
return array_map(fn($item) => $item->name, $order->items);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Remove unused parameters if they aren't part of an interface
|
|
38
|
+
function deleteUser($id) {
|
|
39
|
+
return User::destroy($id);
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Common Scenarios:**
|
|
44
|
+
- Variables assigned but never read.
|
|
45
|
+
- Function parameters that are not used in the body.
|
|
46
|
+
- Loop variables (like `$key => $value`) where the key is never used.
|
|
47
|
+
|
|
48
|
+
**Exceptions:**
|
|
49
|
+
- Implementing an interface where a method signature is fixed, but you don't need all parameters. In some tools, prefixing with an underscore (e.g., `$_param`) can signal intentional non-use.
|
|
50
|
+
|
|
51
|
+
**Tools:** PHPStan, Psalm, PHP_CodeSniffer (`SlevomatCodingStandard.Variables.UnusedVariable`)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: No Duplicate Variable Names In Scope
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: prevents variable shadowing bugs and improves code clarity
|
|
5
|
+
tags: variables, shadowing, scope, quality, php
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## No Duplicate Variable Names In Scope
|
|
9
|
+
|
|
10
|
+
Variable shadowing occurs when a variable declared within a certain scope (like a function or a closure) has the same name as a variable in an outer scope. This can lead to subtle bugs and makes the code difficult to follow.
|
|
11
|
+
|
|
12
|
+
**Incorrect (shadowed variables):**
|
|
13
|
+
|
|
14
|
+
```php
|
|
15
|
+
$user = Auth::user();
|
|
16
|
+
|
|
17
|
+
function updateProfile($request) {
|
|
18
|
+
// Shadows the potentially global or outer $user
|
|
19
|
+
$user = $request->input('user_data');
|
|
20
|
+
|
|
21
|
+
// Which $user is this?
|
|
22
|
+
$user->save();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Shadowing in loops
|
|
26
|
+
foreach ($orders as $order) {
|
|
27
|
+
$order = $this->repository->enhance($order); // Shadowing the loop variable
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Correct (unique names):**
|
|
32
|
+
|
|
33
|
+
```php
|
|
34
|
+
$currentUser = Auth::user();
|
|
35
|
+
|
|
36
|
+
function updateProfile($request) {
|
|
37
|
+
$profileData = $request->input('user_data');
|
|
38
|
+
|
|
39
|
+
$profileData->save();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
foreach ($orders as $order) {
|
|
43
|
+
$enhancedOrder = $this->repository->enhance($order);
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Shadowing in Closures (PHP):**
|
|
48
|
+
Be careful when using `use` in anonymous functions:
|
|
49
|
+
```php
|
|
50
|
+
$message = "Hello";
|
|
51
|
+
|
|
52
|
+
$callback = function($input) use ($message) {
|
|
53
|
+
$message = $input; // Shadows the captured $message (only locally)
|
|
54
|
+
};
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Why avoid shadowing?**
|
|
58
|
+
- **Clarity**: Developers don't have to keep track of multiple meanings for the same variable name.
|
|
59
|
+
- **Bug Prevention**: Avoids accidentally overwriting or reading the wrong value when scopes are nested or side effects occur.
|
|
60
|
+
|
|
61
|
+
**Tools:** PHPStan, Psalm, PHP_CodeSniffer
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Centralize Constants
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: makes values easy to find, update, and manage
|
|
5
|
+
tags: constants, magic-numbers, configuration, quality, php
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Centralize Constants
|
|
9
|
+
|
|
10
|
+
Magic numbers or strings scattered throughout the codebase are difficult to maintain and understand. Centralizing constants in classes or using Enums makes the code self-documenting and provides a single source of truth.
|
|
11
|
+
|
|
12
|
+
**Incorrect (magic values):**
|
|
13
|
+
|
|
14
|
+
```php
|
|
15
|
+
if (strlen($password) < 8) { ... }
|
|
16
|
+
if ($retryCount > 3) { ... }
|
|
17
|
+
if ($order->status === 1) { ... }
|
|
18
|
+
sleep(300); // 5 minutes?
|
|
19
|
+
if ($user->role === 'admin') { ... }
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Correct (centralized constants and Enums):**
|
|
23
|
+
|
|
24
|
+
```php
|
|
25
|
+
/**
|
|
26
|
+
* Using Class Constants
|
|
27
|
+
*/
|
|
28
|
+
class AuthConfig {
|
|
29
|
+
public const PASSWORD_MIN_LENGTH = 8;
|
|
30
|
+
public const MAX_RETRY_ATTEMPTS = 3;
|
|
31
|
+
public const SESSION_TIMEOUT_SECONDS = 300;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Using PHP 8.1+ Enums (Recommended for categories)
|
|
36
|
+
*/
|
|
37
|
+
enum OrderStatus: int {
|
|
38
|
+
case PENDING = 1;
|
|
39
|
+
case APPROVED = 2;
|
|
40
|
+
case SHIPPED = 3;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
enum UserRole: string {
|
|
44
|
+
case ADMIN = 'admin';
|
|
45
|
+
case USER = 'user';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Usage
|
|
49
|
+
if (strlen($password) < AuthConfig::PASSWORD_MIN_LENGTH) { ... }
|
|
50
|
+
if ($order->status === OrderStatus::PENDING->value) { ... }
|
|
51
|
+
if ($user->role === UserRole::ADMIN->value) { ... }
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Benefits:**
|
|
55
|
+
- **Searchability**: Find all usages of a constant instantly.
|
|
56
|
+
- **Self-Documentation**: `MAX_RETRY_ATTEMPTS` is clearer than `3`.
|
|
57
|
+
- **Consistency**: Prevents typos (e.g., `'admn'` vs `'admin'`).
|
|
58
|
+
- **Refactoring**: Change a value in one place to update the entire application.
|
|
59
|
+
|
|
60
|
+
**Tools:** PHPStan (disallow magic numbers), Psalm, PR review
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: All Catch Blocks Must Log Root Cause
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: enables debugging and incident response
|
|
5
|
+
tags: error-handling, logging, debugging, observability, quality, php
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## All Catch Blocks Must Log Root Cause
|
|
9
|
+
|
|
10
|
+
Silent failures make debugging impossible. Without proper logging of the root cause and relevant context, you cannot trace issues in production or understand why a process failed.
|
|
11
|
+
|
|
12
|
+
**Incorrect (silent or minimal logging):**
|
|
13
|
+
|
|
14
|
+
```php
|
|
15
|
+
try {
|
|
16
|
+
$this->paymentService->process($order);
|
|
17
|
+
} catch (\Exception $e) {
|
|
18
|
+
// Empty catch - silent failure!
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
$this->userRepository->save($user);
|
|
23
|
+
} catch (\Exception $e) {
|
|
24
|
+
return false; // No logging, no context provided for the failure
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Correct (comprehensive error logging):**
|
|
29
|
+
|
|
30
|
+
```php
|
|
31
|
+
try {
|
|
32
|
+
$this->paymentService->process($order);
|
|
33
|
+
} catch (\Throwable $error) {
|
|
34
|
+
// Use a logger (e.g., Monolog, Laravel Log)
|
|
35
|
+
Log::error('Payment processing failed', [
|
|
36
|
+
'order_id' => $order->id,
|
|
37
|
+
'user_id' => $order->user_id,
|
|
38
|
+
'amount' => $order->amount,
|
|
39
|
+
'message' => $error->getMessage(),
|
|
40
|
+
'file' => $error->getFile(),
|
|
41
|
+
'line' => $error->getLine(),
|
|
42
|
+
'trace' => $error->getTraceAsString()
|
|
43
|
+
]);
|
|
44
|
+
|
|
45
|
+
// Rethrow or wrap in a custom exception with the original as the cause
|
|
46
|
+
throw new PaymentFailedException('Payment could not be processed', 0, $error);
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Log context should include:**
|
|
51
|
+
- Error message and stack trace (`$e->getMessage()`, `$e->getTraceAsString()`).
|
|
52
|
+
- File and line number where the error occurred.
|
|
53
|
+
- Relevant entity IDs (order, user, etc.).
|
|
54
|
+
- Request/correlation ID (if available).
|
|
55
|
+
- Input data that caused the error (careful with sensitive data).
|
|
56
|
+
|
|
57
|
+
**Tools:** PHPStan, Psalm, SonarQube, PR review
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Use Custom Error Classes
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: enables proper error categorization and handling
|
|
5
|
+
tags: error-handling, custom-errors, exceptions, patterns, quality, php
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Use Custom Error Classes
|
|
9
|
+
|
|
10
|
+
Defining your own exception classes allows you to categorize errors, attach relevant metadata, and implement specific handling strategies for different parts of your application. It provides a clear contract for the callers of your methods.
|
|
11
|
+
|
|
12
|
+
**Incorrect (generic exceptions):**
|
|
13
|
+
|
|
14
|
+
```php
|
|
15
|
+
throw new \Exception("User not found");
|
|
16
|
+
throw new \InvalidArgumentException("Invalid input data");
|
|
17
|
+
throw new \RuntimeException("Database connection failed");
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**Correct (custom exception hierarchy):**
|
|
21
|
+
|
|
22
|
+
```php
|
|
23
|
+
// Base application exception
|
|
24
|
+
abstract class AppServiceException extends \Exception {
|
|
25
|
+
protected int $statusCode = 500;
|
|
26
|
+
protected string $errorCode = 'INTERNAL_ERROR';
|
|
27
|
+
protected array $context = [];
|
|
28
|
+
|
|
29
|
+
public function __construct(string $message, array $context = [], ?\Throwable $previous = null) {
|
|
30
|
+
parent::__construct($message, 0, $previous);
|
|
31
|
+
$this->context = $context;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public function getStatusCode(): int { return $this->statusCode; }
|
|
35
|
+
public function getErrorCode(): string { return $this->errorCode; }
|
|
36
|
+
public function getContext(): array { return $this->context; }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Specific domain exceptions
|
|
40
|
+
class UserNotFoundException extends AppServiceException {
|
|
41
|
+
protected int $statusCode = 404;
|
|
42
|
+
protected string $errorCode = 'USER_NOT_FOUND';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
class InsufficientBalanceException extends AppServiceException {
|
|
46
|
+
protected int $statusCode = 422;
|
|
47
|
+
protected string $errorCode = 'INSUFFICIENT_BALANCE';
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Usage
|
|
51
|
+
if (!$user) {
|
|
52
|
+
throw new UserNotFoundException("User {$userId} does not exist", ['id' => $userId]);
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Benefits:**
|
|
57
|
+
- **Granular Catching**: You can catch specific domain errors (e.g., `catch (UserNotFoundException $e)`) while letting others bubble up.
|
|
58
|
+
- **Structured Metadata**: Attach request IDs, user IDs, or input data directly to the exception.
|
|
59
|
+
- **HTTP Mapping**: Easily map exceptions to HTTP status codes in a global error handler (e.g., in Laravel `Handler.php` or Symfony `ExceptionSubscriber`).
|
|
60
|
+
- **Observability**: Search logs for specific exception class names.
|
|
61
|
+
|
|
62
|
+
**Tools:** PHPUnit (expectException), PHPStan, Psalm
|