Introduce Entity framework for data processing in Treaty#43
Draft
Introduce Entity framework for data processing in Treaty#43
Conversation
- Added `Configuration` class to manage default options for entity processing. - Introduced `Errors` class to handle structured validation errors. - Implemented `Processor` for orchestrating data through validation pipelines. - Added `Result` class to encapsulate processing outcomes, including data and errors. - Expanded `Entity` with core methods: `.call`, `.call!`, `.valid?`, and `.from_block`. - Extended validation orchestrator to integrate with the Entity framework. - Introduced comprehensive test suite for validating and transforming data.
- Removed all existing DTO classes (`Deserialization` and `Serialization`). - Replaced `ImageDto`, `UserDto`, `OrderDto`, and others with corresponding Entity classes. - Updated test suite to align with the new `Entity` framework. - Introduced `Gate::API::Posts::CreateRequestEntity` and `Gate::API::Posts::CreateResponseEntity`. - Refactored attribute validation rules, adding transformations and casts where needed. - Enhanced test coverage for both request and response Entities.
Add support for passing configuration to validation methods to allow runtime override of default required behavior. This enables entities to accept partial data when initialized with `required: false` option. Changes: - Add required_explicit tracking to Attribute to distinguish between explicitly set and default-applied required options - Add skip_default_required? method to Configuration to check if required: false was explicitly set - Pass configuration to validate_value! and validate_required! methods in AttributeValidator to enable conditional validation skipping - Update validation orchestrator to pass configuration when calling validator methods - Implement should_skip_required_validation? and validate_non_required_options! methods to handle selective validation based on configuration - Unpend tests for required: false option behavior This allows partial entity validation where missing fields are treated as optional when created with required: false, while explicitly required fields remain enforced.
- Change Result#data from attr_reader to attr_accessor, removing redundant private setter method - Simplify conditional assignments in Configuration using single-line syntax - Use Ruby's implicit keyword argument syntax (configuration:) in method calls - Add rubocop comments to methods with high complexity - Simplify early return conditions in attribute validation This improves code consistency and readability without changing functionality.
There was a problem hiding this comment.
RuboCop found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
Rename Configuration to Context to better reflect its purpose of holding validation context rather than entity configuration. This improves code semantics and clarity. Changes: - Replace Treaty::Entity::Configuration with Treaty::Entity::Context - Update all references from 'configuration' parameter to 'context' - Pass context to OptionOrchestrator for computing effective options - OptionOrchestrator now merges attribute options with context defaults - Update processor to accept optional context parameter - Remove configuration_spec.rb in favor of context_spec.rb - Update processor tests to use Context instead of Configuration - Simplify validation orchestrator by delegating option merging to OptionOrchestrator This change clarifies that Context represents the validation environment rather than entity-wide configuration, making the API more intuitive.
Rename the concept from "Context" to "Preset" to better communicate its purpose: representing a preset configuration for entity validation. This terminology is more intuitive for users configuring validation options. Changes: - Rename Treaty::Entity::Context to Treaty::Entity::Preset - Update .options() method to .preset() on Entity classes - Replace all 'configuration' parameter names with 'preset' for consistency - Update documentation and comments to use Preset terminology - Update all related specs - OptionOrchestrator and validators now accept preset parameter This change improves API clarity by using terminology that better reflects the purpose of temporary validation configuration.
Remove Processor class and move its logic into Entity as private methods. Preset now acts as a lightweight options wrapper that delegates to Entity's private _process and _process! methods via send. Changes: - Remove Treaty::Entity::Processor class (moved to Entity) - Create Entity.send(:_process) and Entity.send(:_process!) private methods - Simplify Preset to only store options and delegate via send - Preset.call/call!/valid? now use entity_class.send(:_process, ...) - Remove processor_spec.rb as logic moves to Entity - Create Context and Processing modules for organizing private methods This eliminates duplicate processing logic and makes Preset a simple, lightweight wrapper. The send pattern avoids conflicts if Entity has an attribute named 'preset'.
Reorganize code structure by moving Preset class into a dedicated Context namespace. This creates a clearer organizational hierarchy while maintaining all existing functionality. Changes: - Move Treaty::Entity::Preset to Treaty::Entity::Context::Preset - Update all references to use new namespace path - Move preset_spec.rb to context/preset_spec.rb - Update documentation references to use new namespace - Create Context module to organize context-related classes This refactoring improves code organization without changing behavior, making the codebase more maintainable by grouping context-related functionality together.
Move all attribute-related code from top-level lib/treaty/attribute into lib/treaty/entity/attribute namespace. This consolidates Entity-specific attribute handling and improves code organization. Changes: - Move Attribute module and submodules to Treaty::Entity::Attribute - Move all option validators, modifiers, and conditionals - Move validation orchestrators and validators - Consolidate Request and Response attribute code (removed duplicates) - Update all imports and references to new namespaces - Move corresponding spec files to match new structure This refactoring eliminates duplicate attribute code across Request, Response, and Entity modules by consolidating everything under Entity, making the codebase cleaner and easier to maintain.
Update Response attribute definitions to use required: true by default instead of required: false. This makes Response entities more strict about requiring all defined fields to be present in API responses. Changes: - Modify ResponseFactory to apply required: true as default - Update ResponseFactory.default_options - Add Default builder for Response with appropriate defaults - Update Attribute and Attribute::Base to support entity-type-specific defaults This change ensures that Response definitions enforce stricter validation, making it easier to catch missing fields in API responses. Request definitions continue to use their own defaults.
Use preset_options from Response factories to apply defaults during info generation. This ensures that the generated API documentation reflects the actual validation behavior used at runtime. Changes: - Add preset_options method to ResponseFactory - Update REST builder to create and apply presets during info generation - Pass preset through build_attributes_hash and build_nested_attributes - Add compute_effective_options to merge attribute options with preset - Response attributes now show required: false in generated info This ensures the generated API documentation accurately represents the validation defaults applied during processing.
Move preset_options configuration to Request::Validator and Response::Validator as the single source of truth. Factories and info generation now delegate to these validators. Changes: - Add preset_options class method to Request::Validator and Response::Validator - Request uses empty preset (Entity defaults) - Response uses required: false by default - Add info method to Request::Factory and Response::Factory - Update REST builder to call factory.info() instead of building attributes - Move preset application logic to Entity::Info::Builder - Add compute_effective_options and deep_dup helpers to Builder - Update Entity.info to accept preset parameter - Simplify REST builder by removing duplicate attribute building logic - Fix Entity module include to use fully qualified name This centralizes validation defaults in one place, making it easier to maintain consistency across request/response validation and info generation.
Resolved conflicts: - Removed old lib/treaty/attribute/builder/base.rb (moved to entity) - Removed old lib/treaty/attribute/entity/builder.rb (moved to entity) - Updated Request/Response builders to extend Treaty::Entity::Attribute::Builder::Base - Added deep_copy_attribute to Entity::Attribute::Builder::Default - Integrated use_entity functionality from main into new structure - Renamed DTOs to Entities (AuthorDto → AuthorEntity, SocialDto → SocialEntity) - Moved entities from dtos/shared/ to entities/shared/ - Entities now extend ApplicationEntity
Remove explicit require statements for builder classes that are automatically loaded by Ruby's require mechanism. Changes: - Remove require_relative for builder/base - Remove require_relative for builder/default These files are loaded through the normal module/class loading process and don't need explicit requires.
Update the default builder to copy only explicitly set options when creating Entity attributes from source. This allows each context (Entity, Request, Response) to apply its own defaults via the Preset system. Changes: - Filter attribute options to include only explicitly set ones - Skip options that came from apply_defaults! - Pass filtered options to new attribute creation - Allows target context to apply its own defaults via preset This ensures that implicit defaults from one context don't override the defaults of another context, making attribute copying more flexible.
Delete duplicate builder implementations for Request and Response as they are now consolidated into the Entity attribute builder system. Changes: - Delete lib/treaty/request/attribute/builder.rb - Delete lib/treaty/response/attribute/builder.rb The unified builder in lib/treaty/entity/attribute/builder handles attribute definition for all contexts, eliminating code duplication.
Consolidate duplicated code patterns from Request and Response factories and validation components into reusable shared modules. Changes: - Create FactoryBase to consolidate Request/Response factory patterns - Create ConditionalSupport module for if/unless conditional handling - Create ValidatorCache for caching validator instances - Update Request::Factory to use FactoryBase - Update Response::Factory to use FactoryBase - Extract conditional logic from validators into ConditionalSupport - Add validator caching for performance - Update Attribute::Base to support conditional helpers This reduces code duplication and makes the validation system more maintainable by centralizing common patterns in dedicated modules.
Introduce a cached_positions method in the Registry to precompute and store option positions for O(1) lookups during execution. This optimization improves performance and ensures consistent behavior. Changes: - Add cached_positions method to compute and cache option positions. - Update position_for to use cached_positions with a default of 0. - Reset cached_positions when the registry is reset. - Include thread-safety details for cache initialization in comments. - Refactor transform method for cleaner variable reuse. These changes enhance the Registry's efficiency and maintainability by reducing redundant calculations and improving clarity.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.