clean_architecture_linter 1.2.0 copy "clean_architecture_linter: ^1.2.0" to clipboard
clean_architecture_linter: ^1.2.0 copied to clipboard

A comprehensive custom lint package that automatically enforces Clean Architecture principles in Flutter projects with Riverpod state management.

Changelog #

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

1.2.0 - 2026-01-19 #

โœจ Added (2 new rules) #

  • ref_mounted_usage - Detects ref.mounted usage in Riverpod providers

    • Using ref.mounted to guard async operations masks design problems
    • Encourages proper patterns: AsyncValue, ref.listen, or completing async work before navigation
    • Only checks in /presentation/ and /providers/ directories
    • Severity: WARNING
  • riverpod_keep_alive - Warns against unnecessary @Riverpod(keepAlive: true)

    • keepAlive: true should only be used for truly global state (auth, settings, cache)
    • Warns when used on feature-specific providers (e.g., TodoListNotifier)
    • Skips infrastructure providers (DataSource, Repository, UseCase, Service, Client, API)
    • Valid patterns: auth, user, session, settings, preferences, config, theme, locale, cache, analytics, notification, connectivity, permission
    • Severity: WARNING

๐Ÿ“Š Statistics #

  • Total rules: 33 (was 31 in v1.1.0)
    • Presentation layer rules: 13 (was 11)

1.1.0 - 2026-01-09 #

๐Ÿš€ Breaking Changes #

  • Pass-through Repository Pattern - Result ํŒจํ„ด ์ œ๊ฑฐ, pass-through ํŒจํ„ด์œผ๋กœ ์ „ํ™˜
    • Repository๋Š” ์ด์ œ Future<Entity>๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ (๊ถŒ์žฅ)
    • Future<Result<Entity, Failure>> ์‚ฌ์šฉ ์‹œ ๊ฒฝ๊ณ  ํ‘œ์‹œ
    • ์—๋Ÿฌ๋Š” DataSource์—์„œ ๋ฐœ์ƒํ•˜์—ฌ Presentation๊นŒ์ง€ pass-through
    • AsyncValue.guard()๋กœ ์—๋Ÿฌ ์ž๋™ ์บ์น˜

โœจ Added #

  • AppException ํƒ€์ž… ์ธ์‹ - exception_validation_mixin์— AppException ํƒ€์ž… ์„ธํŠธ ์ถ”๊ฐ€

    • ํ‘œ์ค€ AppException ํƒ€์ž…: AppException, NetworkException, TimeoutException, ServerException, UnauthorizedException, ForbiddenException, NotFoundException, InvalidInputException, ConflictException, CacheException, UnknownException
    • isAppExceptionType() ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€
    • isAllowedWithoutPrefix()๊ฐ€ AppException ํƒ€์ž… ์ธ์‹
  • Loading ํ•„๋“œ ๊ฐ์ง€ - presentation_use_async_value ๊ทœ์น™ ๊ฐ•ํ™”

    • isLoading, loading, isSubmitting, submitting, isFetching, fetching, isProcessing, processing ํ•„๋“œ ๊ฐ์ง€
    • Freezed State์—์„œ ์ˆ˜๋™ ๋กœ๋”ฉ ์ƒํƒœ ๊ด€๋ฆฌ ๊ธˆ์ง€ (AsyncValue๊ฐ€ ์ž๋™ ๊ด€๋ฆฌ)

๐Ÿ”„ Changed #

  • repository_must_return_result - Result ํŒจํ„ด ์‚ฌ์šฉ ์‹œ ๊ฒฝ๊ณ 

    • ์ด์ „: Future<Entity> ๋˜๋Š” Future<Result<Entity, Failure>> ๋ชจ๋‘ ํ—ˆ์šฉ
    • ์ดํ›„: Future<Entity> ๊ถŒ์žฅ, Result ์‚ฌ์šฉ ์‹œ WARNING
  • repository_must_return_result โ†’ repository_pass_through (์ด๋ฆ„ ๋ณ€๊ฒฝ)

    • ๊ทœ์น™ ์ด๋ฆ„์ด pass-through ํŒจํ„ด์„ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ๋ฐ˜์˜
  • repository_no_throw - ๋ฌธ์„œ ์—…๋ฐ์ดํŠธ

    • Pass-through ํŒจํ„ด ์ค‘์‹ฌ์œผ๋กœ ๋ฌธ์„œ ์žฌ์ž‘์„ฑ
    • AppException ํƒ€์ž… throw ํ—ˆ์šฉ
    • ๋น„ํ‘œ์ค€ ์˜ˆ์™ธ throw ์‹œ INFO ๋ ˆ๋ฒจ ๊ฒฝ๊ณ 
  • datasource_exception_types - AppException ํƒ€์ž… ์ฒดํฌ ์ถ”๊ฐ€

    • isAppExceptionType() ์ฒดํฌ ์ถ”๊ฐ€
    • DataSource์—์„œ AppException ํƒ€์ž…๋งŒ throw ํ—ˆ์šฉ

โš ๏ธ Deprecated #

  • usecase_must_convert_failure - Pass-through ํŒจํ„ด์œผ๋กœ ์ธํ•ด ๋” ์ด์ƒ ํ•„์š” ์—†์Œ

    • UseCase์—์„œ Failureโ†’Exception ๋ณ€ํ™˜ ๋ถˆํ•„์š”
    • ์—๋Ÿฌ๊ฐ€ DataSource์—์„œ Presentation๊นŒ์ง€ ์ง์ ‘ ์ „๋‹ฌ๋จ
    • ๊ทœ์น™์€ ์œ ์ง€๋˜์ง€๋งŒ no-op (์•„๋ฌด ๋™์ž‘ ์•ˆํ•จ)
  • failure_naming_convention - Failure ํด๋ž˜์Šค ์‚ฌ์šฉ ์ž์ฒด๋ฅผ ๊ฒฝ๊ณ 

    • Result ํŒจํ„ด ์ œ๊ฑฐ๋กœ Failure ํด๋ž˜์Šค ๋ถˆํ•„์š”
    • ๊ทœ์น™์ด Failure ํด๋ž˜์Šค ์ •์˜ ์‹œ ๊ฒฝ๊ณ  ํ‘œ์‹œ
    • AppException ์‚ฌ์šฉ ๊ถŒ์žฅ

๐Ÿ“ Documentation #

  • CLAUDE.md - Pass-through ํŒจํ„ด ์ค‘์‹ฌ์œผ๋กœ ์—…๋ฐ์ดํŠธ

    • Result ํŒจํ„ด ์˜ˆ์ œ ์ œ๊ฑฐ
    • STATE_MANAGEMENT_GUIDE.md ์ฐธ์กฐ ์ถ”๊ฐ€
  • doc/UNIFIED_ERROR_GUIDE.md - ํ†ตํ•ฉ ์—๋Ÿฌ ํ•ธ๋“ค๋ง ๊ฐ€์ด๋“œ ์ถ”๊ฐ€

  • doc/STATE_MANAGEMENT_GUIDE.md - ์ƒํƒœ ๊ด€๋ฆฌ ๊ฐ€์ด๋“œ ์ถ”๊ฐ€

๐Ÿงช Tests #

  • ๋ชจ๋“  ํ…Œ์ŠคํŠธ ์—…๋ฐ์ดํŠธ (568๊ฐœ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ)
    • exception_validation_mixin_test.dart - AppException ํƒ€์ž… ํ…Œ์ŠคํŠธ ์ถ”๊ฐ€
    • repository_no_throw_rule_test.dart - Pass-through ํŒจํ„ด ํ…Œ์ŠคํŠธ๋กœ ๋ณ€๊ฒฝ
    • exception_handling_integration_test.dart - ์ „์ฒด ๋ฆฌํŒฉํ† ๋ง

1.0.11 - 2025-12-31 #

๐Ÿ”ง Fixed #

  • layer_dependency_rule - DI Provider ํŒŒ์ผ์—์„œ Data Models import ๊ธˆ์ง€ ์ถ”๊ฐ€
    • DI/Provider ํŒŒ์ผ(*_providers.dart, providers.dart)์—์„œ DataSource/Repository ๊ตฌํ˜„์ฒด import๋Š” ํ—ˆ์šฉ
    • ํ•˜์ง€๋งŒ Data Models(/data/models/) import๋Š” DI ํŒŒ์ผ์—์„œ๋„ ๊ธˆ์ง€
    • Data Models๋Š” Data ๋ ˆ์ด์–ด ๋‚ด๋ถ€์šฉ์ด๋ฉฐ, Presentation ๋ ˆ์ด์–ด(DI ํฌํ•จ)์—์„œ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ๋จ
    • ์ƒˆ๋กœ์šด _isDataModelImport() ํ—ฌํผ ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€

1.0.10 - 2025-12-10 #

โœจ Added #

  • allowed_instance_variables_rule - Extended infrastructure SDK type support
    • Google Mobile Ads SDK: BannerAd, InterstitialAd, RewardedAd, NativeAd, AppOpenAd, AdWidget
    • In-App Purchase SDK: InAppPurchase, ProductDetails, PurchaseDetails
    • Subscription type (StreamSubscription, etc.)
    • These SDK types require mutable state for lifecycle management

๐ŸŽจ Improved #

  • Correction messages - Made all rule correction messages more concise for better VS Code PROBLEMS panel display
    • Removed verbose examples from correction messages
    • Focused on brief, actionable fix instructions
    • Affected rules: failure_naming_convention, model_naming_convention, exception_message_localization, presentation_no_data_exceptions, presentation_use_async_value, riverpod_provider_naming, riverpod_ref_usage, widget_no_usecase_call, widget_ref_read_then_when

1.0.9 - 2025-11-12 #

โœจ Added (1 new rule) #

  • allowed_instance_variables_rule - Enforce stateless architecture in UseCase, Repository, and DataSource classes
    • UseCase: Only final/const Repository and Service dependencies allowed
    • Repository: Only final/const DataSource and infrastructure dependencies (primitives, Stream, HTTP, Firebase, Database) allowed
    • DataSource: Only final/const primitives and infrastructure dependencies allowed
    • Mock/Fake classes can have mutable state for testing purposes
    • Prevents hidden state bugs and enables testability
    • Comprehensive validation with clear error messages
    • Total rules: 34 (was 33)
    • Cross-layer rules: 3 (was 2)

๐Ÿ”ง Fixed #

  • Domain Layer dart:io Support - Fixed false positive for dart:io imports in domain layer

    • domain_purity_rule: Now allows dart:io imports for type references (File, Directory) in domain layer method signatures
    • Actual I/O operations should still be implemented in data layer
    • Addresses legitimate use cases where domain repositories need File type parameters
  • Database Library Support - Added proper exceptions for database libraries (ObjectBox, Realm, Isar, Drift)

    • layer_dependency_rule: Data layer can now import package:objectbox/, package:realm/, package:isar/, package:drift/
    • datasource_abstraction_rule:
      • Private methods/getters (starting with _) are now skipped from validation
      • Database entity types (Box<*Entity>, *ObjectBoxEntity, *RealmEntity, etc.) are allowed in return types
    • model_structure_rule: Models with database annotations (@Entity, @RealmModel, @collection, etc.) are exempt from @freezed requirement
    • These libraries require mutable classes with their own code generation, incompatible with Freezed

๐Ÿ“ Documentation #

  • CLAUDE.md

    • Added "Instance Variables & Stateless Architecture" section with comprehensive examples
    • Added "Domain Layer with dart:io Types" example showing allowed usage of File type in repository signatures
    • Updated Layer Dependencies section to clarify dart:io is allowed for type references
    • Documented allowed infrastructure types for each layer
    • Explained Mock/Fake exception for testing
    • Added "Database Library Exceptions" section with comprehensive examples
    • Explained why database Models don't use @freezed (mutability requirement)
    • Listed all allowed database imports and annotations
  • README.md

    • Updated rule count from 33 to 34
    • Added allowed_instance_variables_rule to Core Clean Architecture Principles section
    • Added ObjectBox example in "Good Examples" section
    • Documented database library exceptions with clear note
  • README_KO.md

    • Updated rule count from 29 to 34
    • Synchronized with English README structure

๐ŸŽจ Improved #

  • exception_naming_convention_rule - More concise error messages for better VS Code PROBLEMS panel display

1.0.8 - 2025-10-30 #

๐Ÿ”ง Changed #

  • Minimum Dart SDK updated to 3.7.0
    • Updated from ^3.6.0 to ^3.7.0 for better compatibility
    • Downgraded lints from ^6.0.0 to ^5.1.1 for Dart 3.7.0 compatibility
    • All existing features and tests remain compatible
    • No breaking changes to API or functionality

1.0.6 - 2025-10-28 #

๐Ÿ”ง Fixed #

  • Fixed package dependencies structure
    • Moved analyzer, custom_lint_builder, and path back to dependencies
    • These packages are used in lib/ code and must be runtime dependencies
    • custom_lint, lints, and test remain in dev_dependencies
    • Note: End users still add this package to dev_dependencies in their projects

๐Ÿ“ฆ Dependencies #

  • Runtime dependencies (used in lib/): analyzer, custom_lint_builder, path
  • Dev dependencies (development only): custom_lint, lints, test

1.0.5 - 2025-10-28 #

๐Ÿ”ง Changed #

  • Upgraded custom_lint_builder from 0.7.6 to 0.8.0
    • Ensures compatibility with riverpod_generator 3.0.0
    • Upgraded custom_lint dev dependency to 0.8.0
    • All 527 tests pass successfully
    • No breaking API changes required
    • Maintains backward compatibility

๐Ÿ“ฆ Dependencies #

  • custom_lint_builder: ^0.7.6 โ†’ ^0.8.0
  • custom_lint: ^0.7.6 โ†’ ^0.8.0 (dev dependency)

1.0.4 - 2025-10-22 #

โœจ Added (2 new rules) #

  • widget_no_usecase_call rule - Enforce proper Riverpod architecture: Widget โ†’ Provider โ†’ UseCase

    • Prevents widgets from directly importing or calling UseCases
    • Enforces proper separation: Widgets should only interact with Providers
    • Detects UseCase imports in widget/page files
    • Detects direct UseCase provider calls via ref.read() or ref.watch()
    • Provides comprehensive correction messages with proper Riverpod patterns
    • Severity: WARNING
  • widget_ref_read_then_when rule - Prevent anti-pattern of using .when() after ref.read()

    • Detects ref.read() followed by .when() in the same function
    • Enforces proper patterns: ref.watch() + .when() for UI, ref.listen() for side effects
    • Prevents misuse of AsyncValue state management
    • Explains why this pattern is incorrect (state is already settled after operation)
    • Provides three correct alternatives based on use case
    • Severity: WARNING

๐Ÿ”„ Changed #

  • presentation_no_throw rule - Enhanced detection capabilities

    • Now checks /providers/ directory in addition to /states/ and /state/
    • Improved State/Notifier class detection with three methods:
      1. Detects @riverpod annotation (Riverpod Generator pattern)
      2. Detects extends AsyncNotifier/Notifier/StateNotifier/ChangeNotifier
      3. Detects generated classes with _$ prefix
    • More robust validation of Riverpod-based state management classes
    • Better coverage of modern Riverpod code generation patterns
  • Total rules: 31 (was 29 in v1.0.3)

    • Added: 2 new presentation layer rules
    • Modified: 1 rule (presentation_no_throw)

๐Ÿ“ Documentation #

  • Enhanced CLAUDE.md with comprehensive Riverpod state management patterns
    • Added 3-tier provider architecture documentation
    • Documented Entity Providers (AsyncNotifier), UI State Providers (Notifier), and Computed Logic Providers
    • Added detailed examples of AsyncValue.when() pattern usage
    • Included common violations and their solutions
    • Comprehensive Widget usage examples with proper error handling

๐Ÿ“Š Statistics #

  • Files changed: 5 files
    • 2 new rule implementations
    • 1 rule enhancement
    • 1 test file
    • 1 main registration file
  • Lines added: ~600+ lines
    • widget_no_usecase_call_rule.dart: 265 lines
    • widget_ref_read_then_when_rule.dart: 301 lines
    • Enhanced presentation_no_throw_rule.dart
  • Test coverage: Comprehensive unit tests for widget_no_usecase_call rule

1.0.3 - 2025-10-17 #

โœจ Added (3 new rules) #

  • model_entity_direct_access rule - Enforce .toEntity() method usage instead of direct .entity property access in Data layer

    • Prevents direct .entity access in Repository and DataSource implementations
    • Allows direct access inside extension methods (where conversion logic is implemented)
    • Allows direct access in test files
    • Provides clear architectural boundaries for Model โ†’ Entity conversion
  • model_naming_convention rule - Enforce naming conventions for Models in Data layer

    • Models must end with Model suffix
    • Validates proper naming in data/models/ directories
    • Helps maintain consistent codebase structure
  • presentation_no_throw rule - Enforce no exception throwing in Presentation layer

    • Presentation layer should use AsyncValue for error handling
    • No direct exception throws in widgets, states, or notifiers
    • Aligns with Riverpod best practices

๐Ÿ”„ Changed #

  • model_conversion_methods rule - Updated to align with Dart/Freezed best practices

    • Now only requires toEntity() method in extensions (mandatory)
    • fromEntity() implementation is optional and should use factory constructors in the Model class
    • Removed extension static method pattern (not idiomatic in Dart)
    • Updated error messages to guide users toward factory constructor pattern
  • Total rules: 29 (was 26 in v1.0.2)

    • Added: 3 new rules
    • Modified: 1 rule (model_conversion_methods)

๐Ÿ› Bug Fixes #

  • Fixed exception_naming_convention rule to skip core/ directory (framework-level exceptions)
  • Fixed failure_naming_convention rule to skip core/ directory
  • Fixed data file detection to correctly exclude domain/repositories/ from data layer
  • Fixed model_conversion_methods rule incorrectly requiring extension static methods
  • Improved error severity levels across multiple rules

๐Ÿ“ Documentation #

  • Updated CLAUDE.md with comprehensive .entity access control guidelines
  • Updated Data Layer rules README with all 3 new rules documentation
  • Enhanced Model conversion pattern examples with factory constructor approach
  • Added 48 new lines of documentation in CLAUDE.md
  • Added 55 new lines in Data Layer README
  • Updated README.md with accurate rule count

๐Ÿ“Š Statistics #

  • Files changed: 23 files
  • Lines added: ~1,237 lines
  • New test coverage: 398+ lines of new tests for new rules
  • Documentation improvements: 100+ lines across multiple files

1.0.2 - 2025-10-09 #

๐Ÿ—‘๏ธ Removed #

  • entity_business_logic rule - Removed overly strict rule requiring all entities to have business logic methods
    • Not all entities need business logic (e.g., events, DTOs, value objects)
    • Users reported this as too restrictive for practical use cases
    • Total rules: 27 โ†’ 26

๐Ÿ“ Documentation #

  • Fixed incomplete code snippet in README.md examples section
  • Synchronized README_KO.md structure with README.md (removed inconsistent sections)
  • Updated rule count from 27 to 26 in both English and Korean READMEs

1.0.1 - 2025-10-09 #

๐Ÿ“ Documentation #

  • Updated README.md with accurate rule count (27 rules instead of 16+)
  • Updated README_KO.md with accurate rule count and simplified structure
  • Simplified configuration section, removed non-existent Core/Strict modes
  • Reorganized rules documentation with clear categorization
  • Removed unnecessary documentation files (VALIDATION_REPORT.md, ERROR_HANDLING_RULES_TODO.md)

๐Ÿ”ง CI/CD #

  • Improved publish workflow to use official OIDC-based authentication
  • Added quality checks (tests, analyzer, format) before publishing
  • Aligned publish workflow with CI workflow for consistency

1.0.0 - 2025-10-09 #

๐ŸŽ‰ Initial Release #

A comprehensive custom lint package that automatically enforces Clean Architecture principles in Flutter/Dart projects.

โœจ Added #

New Utility Infrastructure

  • CleanArchitectureUtils - Centralized utility class for common Clean Architecture validations
    • File path detection (isDomainFile, isDataFile, isPresentationFile)
    • Component detection (isUseCaseFile, isDataSourceFile, isRepositoryFile)
    • Class name validation (isUseCaseClass, isDataSourceClass, isRepositoryClass)
    • Type checking (isVoidType, isResultType)
    • Exception pattern recognition (isDataException, isDomainException)
    • AST utilities (findParentClass, isPrivateMethod, isRethrow)
    • Feature extraction (extractFeatureName)

New Mixin System

  • ExceptionValidationMixin - Exception naming and validation logic
  • ReturnTypeValidationMixin - Return type validation for methods
  • RepositoryRuleVisitor - Repository-specific validation

๐Ÿ”„ Changed #

Code Organization

  • 170 lines removed (13.6% code reduction) through deduplication
  • Consolidated 13 rules to use shared mixins and utilities
  • Improved consistency across all validation logic
  • Enhanced test coverage with 76 comprehensive tests

Refactored All 24 Rules

All lint rules were refactored to leverage the new utility and mixin infrastructure:

Cross-Layer Rules (4)

  • LayerDependencyRule
  • CircularDependencyRule
  • BoundaryCrossingRule
  • TestCoverageRule

Domain Layer Rules (4)

  • DomainPurityRule
  • DependencyInversionRule
  • RepositoryInterfaceRule
  • UseCaseNoResultReturnRule
  • UseCaseMustConvertFailureRule
  • ExceptionNamingConventionRule
  • ExceptionMessageLocalizationRule

Data Layer Rules (7)

  • ModelStructureRule
  • DataSourceAbstractionRule
  • DataSourceNoResultReturnRule
  • RepositoryMustReturnResultRule
  • RepositoryNoThrowRule
  • DataSourceExceptionTypesRule
  • FailureNamingConventionRule

Presentation Layer Rules (6)

  • NoPresentationModelsRule
  • ExtensionLocationRule
  • FreezedUsageRule
  • RiverpodGeneratorRule
  • PresentationNoDataExceptionsRule
  • PresentationUseAsyncValueRule

๐Ÿ“ˆ Improved #

Documentation

  • Added comprehensive ARCHITECTURE.md with system overview
  • Created CONTRIBUTING.md with development guidelines
  • Added RULE_DEVELOPMENT_GUIDE.md for contributors
  • Enhanced inline documentation across all files

Testing

  • 76 comprehensive tests covering all utilities and mixins
  • 100% coverage of utility methods
  • Extensive mixin behavior validation

Code Quality

  • Eliminated 170 lines of duplicate code
  • Consistent validation patterns across all rules
  • Improved error messages with better context
  • Enhanced maintainability through shared components

๐Ÿ”ง Technical Details #

Dependencies

  • Dart SDK: ^3.6.0
  • analyzer: ^7.6.0
  • custom_lint_builder: ^0.7.6
  • path: ^1.9.1
2
likes
130
points
218
downloads

Documentation

Documentation
API reference

Publisher

verified publisherittae.com

Weekly Downloads

A comprehensive custom lint package that automatically enforces Clean Architecture principles in Flutter projects with Riverpod state management.

Repository (GitHub)
View/report issues
Contributing

Topics

#clean-architecture #lint #custom-lint #linter #static-analysis

License

MIT (license)

Dependencies

analyzer, custom_lint_builder, path

More

Packages that depend on clean_architecture_linter