diff --git a/docs/featury/getting-started.md b/docs/featury/getting-started.md index d3a55de..0c73947 100644 --- a/docs/featury/getting-started.md +++ b/docs/featury/getting-started.md @@ -1,18 +1,28 @@ --- -title: Getting started with Featury -description: Requirements, conventions, installation and example of basic preparation +title: Getting Started with Featury +description: Guide to installing and configuring Featury prev: false next: false --- -# Getting started with Featury +# Getting Started with Featury -## Conventions +## What is Featury? -- All feature classes are subclasses of `Featury::Base` and are located in the `app/features` directory. It is common practice to create and inherit from `FeatureService::Base` class, which is a subclass of `Featury::Base`. -- Name features based on the process they relate to. Use nouns in names and try to equate them with model names whenever possible. For example, name the feature class `User::OnboardingFeature` instead of `User::OnboardFeature`. +Featury is a library for managing feature flags in Ruby/Rails applications. It provides a convenient API for working with feature flags and their groups. -## Version support +## Development Conventions + +Featury follows certain conventions to ensure code consistency: + +- All feature classes must inherit from `Featury::Base` and be placed in the `app/features` directory +- It is recommended to create a base class `ApplicationFeature::Base` that inherits from `Featury::Base` +- Feature names should reflect their belonging to the process +- Use nouns in feature names (e.g., `User::OnboardingFeature` instead of `User::OnboardFeature`) + +## Version Support + +Featury supports the following Ruby and Rails versions: | Ruby/Rails | 8.0 | 7.2 | 7.1 | 7.0 | 6.1 | 6.0 | 5.2 | 5.1 | 5.0 | |-------------|---|---|---|---|---|---|---|---|---| @@ -24,33 +34,40 @@ next: false ## Installation -Add this to `Gemfile`: +### Adding the Gem + +Add Featury to your `Gemfile`: ```ruby gem "featury" ``` -And execute: +### Installing Dependencies + +Run the command to install the gem: ```shell bundle install ``` -## Preparation +## Environment Setup -As a first step, it is recommended to prepare the base class for further inheritance. -This base class should contain actions within itself with the integration of the tool for features in the project. +### Creating a Base Class + +To start, it is recommended to prepare a base class for further inheritance. +This base class should contain actions with integration of the feature tool in the project. For example, it could be an ActiveRecord model, Flipper, or something else. -### ActiveRecord model +### Example with ActiveRecord -The `FeatureFlag` model will be used as an example. +The `FeatureFlag` model will be used as an example: ::: code-group ```ruby [app/features/application_feature/base.rb] module ApplicationFeature class Base < Featury::Base + # Check if feature is enabled action :enabled? do |features:, **options| features.all? do |feature| FeatureFlag @@ -59,6 +76,7 @@ module ApplicationFeature end end + # Check if feature is disabled action :disabled? do |features:, **options| features.any? do |feature| !FeatureFlag @@ -67,6 +85,7 @@ module ApplicationFeature end end + # Enable feature action :enable do |features:, **options| features.all? do |feature| FeatureFlag @@ -75,6 +94,7 @@ module ApplicationFeature end end + # Disable feature action :disable do |features:, **options| features.all? do |feature| FeatureFlag @@ -83,10 +103,12 @@ module ApplicationFeature end end + # Hook before executing any action before do |action:, features:| Slack::API::Notify.call!(action:, features:) end + # Hook after executing enabled? and disabled? actions after :enabled?, :disabled? do |action:, features:| Slack::API::Notify.call!(action:, features:) end @@ -95,3 +117,43 @@ end ``` ::: + +## Creating the First Feature + +### Feature Example + +```ruby +class User::OnboardingFeature < ApplicationFeature::Base + # Prefix for feature flags + prefix :onboarding + + # User resource + resource :user, type: User + + # Condition for working with the feature + condition ->(resources:) { resources.user.onboarding_awaiting? } + + # Set of feature flags + features :passage, :integration + + # Groups of feature flags + groups BillingFeature, + PaymentSystemFeature +end +``` + +### Usage + +```ruby +# Check if feature is enabled +User::OnboardingFeature.enabled?(user: current_user) + +# Enable feature +User::OnboardingFeature.enable(user: current_user) + +# Check if feature is disabled +User::OnboardingFeature.disabled?(user: current_user) + +# Disable feature +User::OnboardingFeature.disable(user: current_user) +``` diff --git a/docs/featury/guide/actions.md b/docs/featury/guide/actions.md index f299624..b5c6dee 100644 --- a/docs/featury/guide/actions.md +++ b/docs/featury/guide/actions.md @@ -5,17 +5,17 @@ prev: false next: false --- -# Actions of Featury +# Featury Actions -To work with feature flags via Featury, need to create actions. -Each action involves implementing logic over the names of the received feature flags and additional options. +To work with feature flags via Featury, you need to create actions. +Each action involves implementing logic for the names of the received feature flags and additional options. ## Example -As an example, let's imagine that we have an ActiveRecord model that is responsible for all the project's feature flags. -It's called `FeatureFlag`. +As an example, let's imagine we have an ActiveRecord model responsible for all feature flags in the project. +It is called `FeatureFlag`. -Let's also imagine that working with feature flags in a project requires 4 actions: +Also, let's assume that the project requires 4 actions to work with feature flags: - `enabled?` - `disabled?` diff --git a/docs/featury/guide/callbacks.md b/docs/featury/guide/callbacks.md index 26d3186..95e337f 100644 --- a/docs/featury/guide/callbacks.md +++ b/docs/featury/guide/callbacks.md @@ -1,6 +1,6 @@ --- -title: Callbacks of the Featury object -description: Description and examples of using callbacks of the Featury object +title: Featury Object Callbacks +description: Description and examples of using Featury object callbacks prev: false next: false --- diff --git a/docs/featury/guide/features.md b/docs/featury/guide/features.md index 4ad37ec..7de09d1 100644 --- a/docs/featury/guide/features.md +++ b/docs/featury/guide/features.md @@ -96,7 +96,6 @@ class User::OnboardingFeature < ApplicationFeature features :passage # [!code focus] end - ``` ```ruby [Several] @@ -143,3 +142,4 @@ class User::OnboardingFeature < ApplicationFeature groups BillingFeature, # [!code focus] PaymentSystemFeature # [!code focus] end +``` \ No newline at end of file diff --git a/docs/featury/guide/info.md b/docs/featury/guide/info.md index 594b096..4c970b5 100644 --- a/docs/featury/guide/info.md +++ b/docs/featury/guide/info.md @@ -1,15 +1,17 @@ --- -title: Information about Featury object -description: Description and examples of using the method to obtain information about a Featury object +title: Featury Object Information +description: Description and examples of getting information about features in Featury prev: false next: false --- -# Information about Featury object +# Featury Object Information -Information can be obtained about each Featury object. +Featury provides methods for getting information about features and their structure. This can be useful for debugging, documentation, and validation. -## Method `info` +## `info` method + +The `info` method returns detailed information about a feature, including all feature flags and groups. ```ruby [Example] info = User::OnboardingFeature.info @@ -18,5 +20,5 @@ info = User::OnboardingFeature.info ```ruby info.features # Feature flags of the current class. info.groups # Feature flag groups of the current class. -info.tree # Tree of feature flags from the current class. +info.tree # Feature flag tree from the current class. ``` diff --git a/docs/guide/actions/grouping.md b/docs/guide/actions/grouping.md index 98a480a..c2e420f 100644 --- a/docs/guide/actions/grouping.md +++ b/docs/guide/actions/grouping.md @@ -1,17 +1,17 @@ --- -title: Grouping actions in service -description: Description and examples of grouping actions (methods) in service -prev: Options for actions in service -next: Early successful termination +title: Grouping Actions in a Service +description: Description and examples of grouping actions (methods) in a service +prev: Options for Actions in a Service +next: Early Successful Completion --- -# Grouping actions +# Grouping Actions -You can use the `stage` method to group multiple methods into one execution group. +You can group the execution of several methods using the `stage` method. -:::info +::: info -Usage of the `position` option for `make` will sort only in `stage`. +Using the `position` option for `make` will only sort within `stage`. ::: @@ -39,6 +39,8 @@ end ### Option `only_unless` +The opposite of the `only_if` option. + ```ruby {2} stage do only_unless ->(context:) { Settings.features.preview.disabled } @@ -49,11 +51,9 @@ stage do end ``` -The opposite of the `only_if` option. - ### Option `wrap_in` -Group of methods in `stage` can be wrapped in something. +The group of methods in `stage` can be wrapped in something. For example, it could be `ActiveRecord::Base.transaction` from Rails. ```ruby {2} @@ -68,7 +68,7 @@ end ### Option `rollback` -If an exception occurs in one of the methods in the group or in `wrap_in`, this can be handled using the `rollback` method. +If an exception occurs in one of the methods in the group or in `wrap_in`, it can be handled using the `rollback` method. ```ruby {3,12} stage do diff --git a/docs/guide/actions/usage.md b/docs/guide/actions/usage.md index 11435b0..2411a0d 100644 --- a/docs/guide/actions/usage.md +++ b/docs/guide/actions/usage.md @@ -1,21 +1,21 @@ --- -title: Using actions in service -description: Description and examples of using actions (methods) in the service -prev: Dynamic options -next: Options for actions in service +title: Using Actions in a Service +description: Description and examples of using actions (methods) in a service +prev: Dynamic Options +next: Options for Actions in a Service --- -# Using actions +# Using Actions -Actions in the service are sequential calls to methods. +Actions in a service are sequential method calls. Service methods are called using the `make` method. ## Examples ### Minimal -In its minimal form, calling methods via `make` is optional. -The `call` method can be used instead. +In its minimal form, calling methods through `make` is optional. +Instead, you can use the `call` method. ```ruby class PostsService::Create < ApplicationService::Base @@ -25,7 +25,7 @@ class PostsService::Create < ApplicationService::Base end ``` -### Several methods +### Multiple Methods ```ruby{4-6,8,12,16} class PostsService::Create < ApplicationService::Base @@ -51,15 +51,15 @@ end ## Options -You can find out more about options in the [options](../actions/options) section. +For more information about options, see the [options](../actions/options) section. -## Group of multiple actions +## Group of Multiple Actions -You can find out more about a group of multiple actions (methods) in the [grouping](../actions/grouping) section. +For more information about a group of multiple actions (methods), see the [grouping](../actions/grouping) section. ## Aliases for `make` -Through the `action_aliases` configuration it is possible to add alternatives to the `make` method. +You can add alternative options for the `make` method through the `action_aliases` configuration. ```ruby {2,5} configuration do @@ -75,10 +75,10 @@ end ## Customization for `make` -Add frequently used words that are used as prefixes in method names through the `action_shortcuts` configuration. -It won't make the names of methods shorter, but that will shorten the lines using the `make` method and improve the readability of the service code, making it more expressive. +Through the `action_shortcuts` configuration, you can add frequently used words that are used as prefixes in method names. +The method names themselves won't become shorter, but this will allow you to shorten the lines with the `make` method and improve the readability of the service code, making it more expressive. -### Simple mode +### Simple Mode In simple mode, values are passed as an array of symbols. @@ -110,18 +110,18 @@ class CMSService::API::Posts::Create < CMSService::API::Base end ``` -### Advanced mode +### Extended Mode -In advanced mode, values are passed as a hash. +In extended mode, values are passed as a hash. ```ruby configuration do action_shortcuts( %i[assign], { - restrict: { # replacement for make - prefix: :create, # method name prefix - suffix: :restriction # method name suffix + restrict: { # replacement for make + prefix: :create, # method name prefix + suffix: :restriction # method name suffix } } ) diff --git a/docs/guide/configuration.md b/docs/guide/configuration.md index 204121f..21c4241 100644 --- a/docs/guide/configuration.md +++ b/docs/guide/configuration.md @@ -1,17 +1,17 @@ --- title: Configuration description: Description and examples of service configuration -prev: Service failures and error handling +prev: Failures and Error Handling next: RSpec --- # Configuration -Services are configured through the `configuration` method, which can be placed, for example, in the base class. +Services are configured through the `configuration` method, which can be located, for example, in the base class. -## Configuration examples +## Configuration Examples -### For exceptions +### For Exceptions ::: code-group @@ -43,7 +43,7 @@ end ::: -### For result +### For Result ::: code-group @@ -67,7 +67,7 @@ end ::: -### Collection mode +### Collection Mode ::: code-group @@ -83,7 +83,7 @@ end ::: -### Hash mode +### Hash Mode ::: code-group @@ -101,7 +101,7 @@ end ### Helpers for `input` -Custom helpers for `input` can be based on the `must` and `prepare` options. +Custom helpers for `input` can be based on `must` and `prepare` options. #### Example with `must` @@ -162,7 +162,7 @@ end ### Helpers for `internal` -Custom helpers for `output` can be based on the `must` option. +Custom helpers for `internal` can be based on the `must` option. #### Example with `must` @@ -234,7 +234,7 @@ end ### Aliases for `make` -The `action_aliases` configuration allows you to add alternatives to `make`. +The `action_aliases` configuration allows adding alternative options for `make`. ::: code-group diff --git a/docs/guide/exceptions/failure.md b/docs/guide/exceptions/failure.md index 3c1df6e..30ab4e1 100644 --- a/docs/guide/exceptions/failure.md +++ b/docs/guide/exceptions/failure.md @@ -1,15 +1,15 @@ --- -title: Service failures and error handling -description: Description and examples of use of service failures -prev: Early successful termination +title: Failure and Error Handling +description: Description and examples of using service failures and errors +prev: Early Successful Completion next: Configuration --- -# Failure and error handling +# Failure and Error Handling -## Description of methods and exceptions +## Description of Methods and Exceptions -The service can be terminated prematurely by calling one of these methods: +The service execution can be terminated prematurely by calling one of these methods: - `fail_input!`; - `fail_internal!`; @@ -17,38 +17,38 @@ The service can be terminated prematurely by calling one of these methods: - `fail!`; - `fail_result!`. -These methods will in turn throw an exception. +These methods will in turn raise an exception. -From the list above, only the following methods can be processed after being called via `call`: +From the list above, only the following methods can be handled after calling via `call`: - `fail!`; - `fail_result!`. -The remaining methods will always throw an exception. +The other methods will always raise an exception. -In addition, there are automatic checks for input, internal and output attributes. -In case of, for example, validation problems with these attributes, the corresponding exception will also be raised. -This behavior will be identical to what happens when these methods are called: +In addition, there are automatic checks for input, internal, and output attributes. +In case of validation issues with these attributes, the corresponding exception will also be raised. +This behavior will be identical to what happens when calling these methods: - `fail_input!`; - `fail_internal!`; - `fail_output!`. -There may be logic inside the service that will throw its own exceptions. -For example, this could be `ActiveRecord::RecordInvalid`. +The service may contain logic that will raise its own exceptions. +For example, it could be `ActiveRecord::RecordInvalid`. For such cases, the `fail_on!` method was developed at the class level. ## Methods ### Method `fail_input!` -Designed to throw an exception on behalf of the input attribute. +Designed to raise an exception on behalf of an input attribute. -The `fail_input!` method allows you to pass the error text, +The `fail_input!` method allows you to pass an error message, additional information through the `meta` attribute, -and also requires you to specify the name of the input attribute. +and requires specifying the name of the input attribute. -Any call to the service will throw an exception with the class `ApplicationService::Exceptions::Input`. +When calling the service, an exception with the class `ApplicationService::Exceptions::Input` will be raised. ```ruby{6} make :check! @@ -66,7 +66,7 @@ def check! end ``` -Example of information that the exception `ApplicationService::Exceptions::Input` might provide: +Example of information that can be provided by the `ApplicationService::Exceptions::Input` exception: ```ruby exception.service # => @@ -78,13 +78,13 @@ exception.meta # => {:received_invoice_number=>"BB-7650AE"} ### Method `fail_internal!` -Designed to throw an exception on behalf of the internal attribute. +Designed to raise an exception on behalf of an internal attribute. -The `fail_internal!` method allows you to pass the error text, +The `fail_internal!` method allows you to pass an error message, additional information through the `meta` attribute, -and also requires you to specify the name of the internal attribute. +and requires specifying the name of the internal attribute. -Any call to the service will throw an exception with the class `ApplicationService::Exceptions::Internal`. +When calling the service, an exception with the class `ApplicationService::Exceptions::Internal` will be raised. ```ruby{6} make :check! @@ -102,7 +102,7 @@ def check! end ``` -Example of information that the exception `ApplicationService::Exceptions::Internal` might provide: +Example of information that can be provided by the `ApplicationService::Exceptions::Internal` exception: ```ruby exception.service # => @@ -114,13 +114,13 @@ exception.meta # => {:received_invoice_number=>"BB-7650AE"} ### Method `fail_output!` -Designed to throw an exception on behalf of the output attribute. +Designed to raise an exception on behalf of an output attribute. -The `fail_output!` method allows you to pass the error text, +The `fail_output!` method allows you to pass an error message, additional information through the `meta` attribute, -and also requires you to specify the name of the output attribute. +and requires specifying the name of the output attribute. -Any call to the service will throw an exception with the class `ApplicationService::Exceptions::Output`. +When calling the service, an exception with the class `ApplicationService::Exceptions::Output` will be raised. ```ruby{6} make :check! @@ -138,7 +138,7 @@ def check! end ``` -Example of information that the exception `ApplicationService::Exceptions::Output` might provide: +Example of information that can be provided by the `ApplicationService::Exceptions::Output` exception: ```ruby exception.service # => @@ -152,14 +152,14 @@ exception.meta # => {:received_invoice_number=>"BB-7650AE"} Designed to describe custom errors. -The `fail!` method allows you to pass the error text, +The `fail!` method allows you to pass an error message, additional information through the `meta` attribute, -and also allows you to specify `type`. +and allows you to specify `type`. -By default, `type` is `base`, but you can pass any value for further processing. +By default, `type` has the value `base`, but you can pass any value for further processing. -When calling a service through the `call!` method, an exception with the class `Servactory::Exceptions::Failure` will be thrown. -When calling a method via the `call` method, the error will be logged and available in the `Result`. +When calling the service via the `call!` method, an exception with the class `Servactory::Exceptions::Failure` will be raised. +When calling the method via the `call` method, the error will be recorded and available in `Result`. ```ruby{6} make :check! @@ -194,7 +194,7 @@ exception.meta # => {:invoice_number=>"BB-7650AE"} Requires `Result` and internally calls the `fail!` method. -Designed for shorthand writing of code for passing an error from one service to the current one. +Designed for concise code writing to pass an error from one service to the current one. For example, from an API service to an application service. ```ruby @@ -213,13 +213,13 @@ fail!( ### Method `fail_on!` -Intended to catch specified exceptions. +Designed to catch specified exceptions. -The `fail_on!` method allows you to pass the class of the exception or exceptions, -and also allows you to customize the text of the message. +The `fail_on!` method allows you to pass an exception class or classes, +and also allows you to customize the message text. -Instead of the specified exceptions, the `fail!` method call will be used. -Information about the original exception will be passed to the `fail!` method via `meta`. +Instead of the specified exceptions, the `fail!` method will be used. +Information about the original exception will be passed to the `fail!` method through `meta`. #### Usage @@ -234,7 +234,7 @@ module ApplicationService end ``` -If you need to customize the text of the message, you can do it as follows: +If you need to customize the message text, you can do it like this: ```ruby fail_on! ActiveRecord::RecordNotFound, diff --git a/docs/guide/exceptions/success.md b/docs/guide/exceptions/success.md index 8af4f8b..99a0ece 100644 --- a/docs/guide/exceptions/success.md +++ b/docs/guide/exceptions/success.md @@ -1,19 +1,19 @@ --- -title: Early successful termination -description: Description and examples of using early manual successful termination of the service -prev: Grouping actions in service -next: Service failures and error handling +title: Early Successful Completion +description: Description and examples of using early manual successful completion of a service +prev: Grouping Actions in a Service +next: Failure and Error Handling --- -# Early successful termination +# Early Successful Completion -The service can be terminated prematurely and successfully by calling the `success!` method. +The service execution can be terminated prematurely and successfully by calling the `success!` method. -For Servactory this is also an exception, but a successful one. +For Servactory, this is also an exception, but a successful one. ## Usage -As an example, consider a notification service that should work depending on the environment where it is called. +As an example, let's consider a notification service that should work depending on the environment where it is called. ```ruby class NotificatorService::Slack::Error::Send < ApplicationService::Base @@ -37,5 +37,5 @@ class NotificatorService::Slack::Error::Send < ApplicationService::Base end ``` -Calling this service will immediately succeed in non-production environments. -This can be especially useful in more complex implementations where there are more conditions to work with. +Calling this service will immediately complete successfully in environments other than production. +This can be especially useful in more complex implementations where there are more conditions for operation. diff --git a/docs/guide/extensions.md b/docs/guide/extensions.md index 5f607e0..7ff6384 100644 --- a/docs/guide/extensions.md +++ b/docs/guide/extensions.md @@ -1,20 +1,20 @@ --- title: Extensions -description: Description and examples of implementation of custom extensions +description: Description and examples of implementing custom extensions prev: RSpec next: Internationalization (I18n) --- # Extensions -You can expand the basic functionality by adding your own extensions. +You can extend the base functionality by adding your own extensions. It is recommended to create extensions in the `app/services/application_service/extensions` directory. Also, as a recommendation, create extensions in their own directory. -## Example of implementation +## Implementation Example -### Connecting +### Connection You can add extensions using the `with_extensions` method. @@ -34,7 +34,7 @@ end ::: -### Extension code +### Extension Code ::: code-group diff --git a/docs/guide/i18n.md b/docs/guide/i18n.md index 0176c18..93e1539 100644 --- a/docs/guide/i18n.md +++ b/docs/guide/i18n.md @@ -2,11 +2,11 @@ title: Internationalization (I18n) description: Information about internationalization (Ruby I18n) prev: Extensions -next: Testing services +next: Service Testing --- # Internationalization (I18n) -All texts are stored in a localization file. These texts may be changed or supplemented with new locales. +All texts are stored in the localization file. These texts can be modified or supplemented with new locales. -[See en.yml file](https://github.com/servactory/servactory/tree/main/config/locales/en.yml) +[View en.yml file](https://github.com/servactory/servactory/tree/main/config/locales/en.yml) diff --git a/docs/guide/options/advanced.md b/docs/guide/options/advanced.md index 8a64f67..9470abc 100644 --- a/docs/guide/options/advanced.md +++ b/docs/guide/options/advanced.md @@ -1,13 +1,13 @@ --- -title: Advanced operating mode for attribute options -description: Description and examples of using advanced operating modes of options for all service attributes -prev: Options for service attributes -next: Dynamic options +title: Advanced Mode for Attribute Options +description: Description and examples of using advanced modes for options of all service attributes +prev: Options for Service Attributes +next: Dynamic Options --- -# Advanced mode +# Advanced Mode -Advanced mode involves more detailed work with the attribute option. +Advanced mode implies more detailed work with an attribute option. ## Option `required` @@ -27,7 +27,7 @@ input :first_name, ::: info Before version `2.6.0`, `service_class_name:` was used instead of `service:`. -In the `2.6.0` release, this attribute was replaced by `service:`, +In release `2.6.0`, this attribute was replaced with `service:`, which is an object with prepared data. ::: @@ -50,7 +50,7 @@ input :first_name, ::: info -Since version `2.12.0` this option is [dynamic](../options/dynamic#option-inclusion). +Since version `2.12.0`, this option is [dynamic](../options/dynamic#option-inclusion). ::: @@ -85,7 +85,7 @@ output :event_name, ::: info Before version `2.6.0`, `service_class_name:` was used instead of `service:`. -In the `2.6.0` release, this attribute was replaced by `service:`, +In release `2.6.0`, this attribute was replaced with `service:`, which is an object with prepared data. ::: @@ -131,7 +131,7 @@ output :event_name, ::: info -Since version `2.6.0` this option is [dynamic](../options/dynamic#option-consists-of). +Since version `2.6.0`, this option is [dynamic](../options/dynamic#option-consists-of). ::: @@ -171,7 +171,7 @@ output :ids, ```ruby [input] input :ids, type: Array, - # The default array element type is String + # Array element type is String by default consists_of: { message: "ID can only be of String type" } @@ -180,7 +180,7 @@ input :ids, ```ruby [internal] internal :ids, type: Array, - # The default array element type is String + # Array element type is String by default consists_of: { message: "ID can only be of String type" } @@ -189,7 +189,7 @@ internal :ids, ```ruby [output] output :ids, type: Array, - # The default array element type is String + # Array element type is String by default consists_of: { message: "ID can only be of String type" } @@ -201,7 +201,7 @@ output :ids, ::: info -Since version `2.12.0` this option is [dynamic](../options/dynamic#option-schema). +Since version `2.12.0`, this option is [dynamic](../options/dynamic#option-schema). ::: @@ -298,7 +298,7 @@ output :payload, ::: info -The `must` option can work only in advanced mode. +The `must` option can only work in advanced mode. ::: @@ -342,7 +342,7 @@ output :invoice_numbers, ::: info Before version `2.6.0`, `service_class_name:` was used instead of `service:`. -In the `2.6.0` release, this attribute was replaced by `service:`, +In release `2.6.0`, this attribute was replaced with `service:`, which is an object with prepared data. ::: diff --git a/docs/guide/options/dynamic.md b/docs/guide/options/dynamic.md index 6829f79..b599c7b 100644 --- a/docs/guide/options/dynamic.md +++ b/docs/guide/options/dynamic.md @@ -1,17 +1,18 @@ --- -title: Dynamic options for attributes +title: Dynamic Options for Attributes description: Description and examples of using dynamic options for all service attributes -prev: Advanced options mode -next: Using actions in service +prev: Advanced Options Mode +next: Using Actions in a Service --- -# Dynamic options +# Dynamic Options -Dynamic options are additional `must`-based options that can take values as arguments. +Dynamic options are additional options based on `must` +that can accept values as arguments. Dynamic options are similar to [custom helpers](../attributes/input#custom), -but what sets them apart is their ability to work with arguments. +but what distinguishes them is the ability to work with arguments. -Servactory out of the box provides the following set of dynamic options: +Servactory provides the following set of dynamic options out of the box: - `consists_of`; - `format`; @@ -22,26 +23,26 @@ Servactory out of the box provides the following set of dynamic options: - `schema`. By default, the following options are enabled: `consists_of`, `inclusion`, and `schema`. -For the rest to work, you need to use ready-made sets in the configuration -of option helpers for each of the existing attributes. +To use the others, you need to apply ready-made sets in the option helpers configuration +for each of the existing attributes. -## Ready-made options +## Ready-made Options ### Option `consists_of` -- Kit: `Servactory::ToolKit::DynamicOptions::ConsistsOf` +- Set: `Servactory::ToolKit::DynamicOptions::ConsistsOf` - Based on: `must` - Enabled by default: Yes - [Source code](https://github.com/servactory/servactory/blob/main/lib/servactory/tool_kit/dynamic_options/consists_of.rb) ### Option `format` -- Kit: `Servactory::ToolKit::DynamicOptions::Format` +- Set: `Servactory::ToolKit::DynamicOptions::Format` - Based on: `must` - Enabled by default: No - [Source code](https://github.com/servactory/servactory/blob/main/lib/servactory/tool_kit/dynamic_options/format.rb) -#### Supported formats +#### Supported Formats - `uuid`; - `email`; @@ -54,7 +55,7 @@ of option helpers for each of the existing attributes. #### Customization -You can overwrite existing formats and add your own. +You can override existing formats and add your own. To do this, use the `formats` attribute in the `use` method: ```ruby @@ -63,12 +64,16 @@ Servactory::ToolKit::DynamicOptions::Format.use( email: { pattern: /@/, validator: ->(value:) { value.present? } + }, + invoice: { + pattern: /^([A]{2})-([0-9A-Z]{6})$/, + validator: ->(value:) { value.present? } } } ) ``` -#### Installation and usage +#### Installation and Usage ::: code-group @@ -109,19 +114,19 @@ output :data, ### Option `inclusion` -- Kit: `Servactory::ToolKit::DynamicOptions::Inclusion` +- Set: `Servactory::ToolKit::DynamicOptions::Inclusion` - Based on: `must` - Enabled by default: Yes - [Source code](https://github.com/servactory/servactory/blob/main/lib/servactory/tool_kit/dynamic_options/inclusion.rb) ### Option `max` -- Kit: `Servactory::ToolKit::DynamicOptions::Max` +- Set: `Servactory::ToolKit::DynamicOptions::Max` - Based on: `must` - Enabled by default: No - [Source code](https://github.com/servactory/servactory/blob/main/lib/servactory/tool_kit/dynamic_options/max.rb) -#### Installation and usage +#### Installation and Usage ::: code-group @@ -163,12 +168,12 @@ output :data, ### Option `min` -- Kit: `Servactory::ToolKit::DynamicOptions::Min` +- Set: `Servactory::ToolKit::DynamicOptions::Min` - Based on: `must` - Enabled by default: No - [Source code](https://github.com/servactory/servactory/blob/main/lib/servactory/tool_kit/dynamic_options/min.rb) -#### Installation and usage +#### Installation and Usage ::: code-group @@ -210,18 +215,18 @@ output :data, ### Option `multiple_of` -- Kit: `Servactory::ToolKit::DynamicOptions::MultipleOf` +- Set: `Servactory::ToolKit::DynamicOptions::MultipleOf` - Based on: `must` - Enabled by default: No - [Source code](https://github.com/servactory/servactory/blob/main/lib/servactory/tool_kit/dynamic_options/multiple_of.rb) -#### Installation and usage +#### Installation and Usage ::: code-group ```ruby [Installation] input_option_helpers([ - Servactory::ToolKit::DynamicOptions::MultipleOf.use + Servactory::ToolKit::DynamicOptions::MultipleOf.use ]) internal_option_helpers([ @@ -257,16 +262,17 @@ output :data, ### Option `schema` -- Kit: `Servactory::ToolKit::DynamicOptions::Schema` +- Set: `Servactory::ToolKit::DynamicOptions::Schema` - Based on: `must` - Enabled by default: Yes - [Source code](https://github.com/servactory/servactory/blob/main/lib/servactory/tool_kit/dynamic_options/schema.rb) -## Custom options +## Custom Options You can create your own dynamic options. -Use the prepared template provided below to implement your own dynamic option. +Use the prepared template provided below to implement +your own dynamic option. It is recommended to place the class file in the `app/services/application_service/dynamic_options` directory of your project. @@ -284,27 +290,27 @@ module ApplicationService end def condition_for_input_with(input:, value:, option:) - # There should be conditions here that are intended for the input attribute + # Here should be conditions intended for the input attribute end def condition_for_internal_with(internal:, value:, option:) - # There should be conditions here that are intended for the internal attribute + # Here should be conditions intended for the internal attribute end def condition_for_output_with(output:, value:, option:) - # There should be conditions here that are intended for the output attribute + # Here should be conditions intended for the output attribute end def message_for_input_with(service:, input:, value:, option_value:, **) - # There should be a message text here in case the condition is not met + # Here should be the message text in case the condition is not met end def message_for_internal_with(service:, internal:, value:, option_value:, **) - # There should be a message text here in case the condition is not met + # Here should be the message text in case the condition is not met end def message_for_output_with(service:, output:, value:, option_value:, **) - # There should be a message text here in case the condition is not met + # Here should be the message text in case the condition is not met end end end diff --git a/docs/guide/options/usage.md b/docs/guide/options/usage.md index 2dc9d43..897f589 100644 --- a/docs/guide/options/usage.md +++ b/docs/guide/options/usage.md @@ -1,19 +1,19 @@ --- -title: Using options in attributes +title: Using Options in Attributes description: Description and examples of using options for all service attributes -prev: Service output attributes -next: Advanced options mode +prev: Output Attributes +next: Advanced Options Mode --- -# Using options in attributes +# Using Options in Attributes ## Option `type` -This option is validation. -It will check that the passed value corresponds to the specified type (class). -The `is_a?` method is used. +This option is for validation. +It will check that the passed value matches the specified type (class). +Uses the `is_a?` method. -Always required to specify. May contain one or more classes. +Always required. Must contain one or more classes. ::: code-group @@ -50,9 +50,9 @@ end ## Option `required` -This option is validation. +This option is for validation. It will check that the passed value is not empty. -The `present?` method is used. +Uses the `present?` method. By default, `required` is set to `true`. @@ -78,8 +78,8 @@ end ## Option `default` -This option is not validation. -It will assign a value to the attribute if one was not passed to the service. +This option is not for validation. +It will assign a value to the attribute if it was not passed to the service. ::: code-group @@ -100,9 +100,9 @@ end ## Option `as` -This option is not validation. -It will indicate the new name of the attribute to work within the service. -The original name inside the service will no longer be available. +This option is not for validation. +It will specify a new name for the attribute to be used inside the service. +The original name will become unavailable inside the service. ::: code-group @@ -127,14 +127,14 @@ end ::: info -Since version `2.12.0` this option is [dynamic](../options/dynamic#option-inclusion). +Starting from version `2.12.0`, this option is [dynamic](../options/dynamic#inclusion-option). ::: -This option is validation. +This option is for validation. This option is dynamic. -It will check that the passed value is in the specified array. -The `include?` method is used. +It will check that the passed value is included in the specified array. +Uses the `include?` method. ::: code-group @@ -178,21 +178,21 @@ end ::: info -Since version `2.6.0` this option is [dynamic](../options/dynamic#option-consists-of). +Starting from version `2.6.0`, this option is [dynamic](../options/dynamic#consists-of-option). ::: -This option is validation. +This option is for validation. This option is dynamic. It will check that each value in the collection matches the specified type (class). Checks nested values. -The `is_a?` method is used. +Uses the `is_a?` method. Works only with `Array` and `Set` types. -You can add a custom type through the [`collection_mode_class_names`](../configuration#collection-mode) configuration. +You can add your own type through the [`collection_mode_class_names`](../configuration#collection-mode) configuration. -Explicit use of this option is optional. -The default value is `String`. +Explicit use of this option is not required. +By default, it is set to `String`. ::: code-group @@ -220,19 +220,19 @@ output :ids, ::: info -Since version `2.12.0` this option is [dynamic](../options/dynamic#option-schema). +Starting from version `2.12.0`, this option is [dynamic](../options/dynamic#schema-option). ::: -This option is validation. +This option is for validation. This option is dynamic. -Requires a hash value that must describe the value structure of the output attribute. +Requires a hash value that should describe the structure of the attribute value. -Only works with the `Hash` type. -You can add a custom type through the [`hash_mode_class_names`](../configuration#hash-mode) configuration. +Works only with the `Hash` type. +You can add your own type through the [`hash_mode_class_names`](../configuration#hash-mode) configuration. -Explicit use of this option is optional. -If the schema value is not specified, the validation will be skipped. +Explicit use of this option is not required. +If the schema value is not specified, validation will be skipped. By default, no value is specified. ::: code-group @@ -302,7 +302,7 @@ output :payload, ::: -Each expected hash key must be described in the following format: +Each expected hash key should be described in this format: ```ruby { @@ -310,14 +310,14 @@ Each expected hash key must be described in the following format: } ``` -The following options are allowed: mandatory `type`, `required` and optional `default`, `prepare`. +The following options are allowed: required `type`, `required` and optional `default`, `prepare`. -If the `type` value is `Hash`, then nesting can be described in the same format. +If `Hash` is specified as the `type` value, then you can describe nesting in the same format. ## Option `must` -This option is validation. -Allows you to create your own validations. +This option is for validation. +Allows you to create custom validations. ::: code-group @@ -374,35 +374,37 @@ end ## Option `format` -This option is validation. -This option is dynamic and is not part of the main options. +This option is for validation. +This option is dynamic and is not part of the core options set. -[More information](./dynamic#option-format) +[Learn more](./dynamic#format-option) ## Option `max` -This option is validation. -This option is dynamic and is not part of the main options. +This option is for validation. +This option is dynamic and is not part of the core options set. -[More information](./dynamic#option-max) +[Learn more](./dynamic#max-option) ## Option `min` -This option is validation. -This option is dynamic and is not part of the main options. +This option is for validation. +This option is dynamic and is not part of the core options set. -[More information](./dynamic#option-min) +[Learn more](./dynamic#min-option) + +::: ## Option `prepare` -This option is not validation. +This option is not for validation. It is used to prepare the passed value. ::: warning Use the `prepare` option carefully and only for simple preparatory actions. For example, as shown below. -Any logic that is more complex than that in the example below is better applied through the [`make`](../actions/usage) action. +Any logic that is more complex than the example below should be implemented through the [`make`](../actions/usage) action. ::: diff --git a/docs/ru/datory/getting-started.md b/docs/ru/datory/getting-started.md index 0863b58..14b0375 100644 --- a/docs/ru/datory/getting-started.md +++ b/docs/ru/datory/getting-started.md @@ -1,14 +1,20 @@ --- title: Начало работы с Datory -description: Требования, соглашения, установка и пример базовой подготовки +description: Руководство по установке и настройке Datory prev: false next: false --- # Начало работы с Datory +## Что такое Datory? + +Datory — это библиотека для сериализации и десериализации данных в Ruby/Rails приложениях. Она основана на Servactory и предоставляет удобный API для работы с данными. + ## Поддержка версий +Datory поддерживает следующие версии Ruby и Rails: + | Ruby/Rails | 8.0 | 7.2 | 7.1 | 7.0 | 6.1 | 6.0 | 5.2 | 5.1 | 5.0 | |-------------|---|---|---|---|---|---|---|---|---| | 3.5 Preview | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | @@ -19,13 +25,17 @@ next: false ## Установка -Добавьте это в файл `Gemfile`: +### Добавление гема + +Добавьте Datory в ваш `Gemfile`: ```ruby gem "datory" ``` -Затем выполните: +### Установка зависимостей + +Выполните команду для установки гема: ```shell bundle install @@ -60,3 +70,36 @@ end ``` ::: + +## Создание первого DTO + +### Пример DTO + +```ruby +class UserDto < ApplicationDTO::Base + # Базовые атрибуты + uuid! :id + string! :email + string! :name + + # Вложенные данные + one! :profile, include: ProfileDto + many! :posts, include: PostDto + + # Даты + date! :createdAt, to: :created_at + date? :updatedAt, to: :updated_at +end +``` + +### Использование + +```ruby +# Сериализация +user = User.find(1) +user_data = UserDto.serialize(user) + +# Десериализация +user_data = { id: "uuid", email: "user@example.com", name: "John Doe" } +result = UserDto.deserialize(user_data) +``` diff --git a/docs/ru/datory/guide/data/attributes.md b/docs/ru/datory/guide/data/attributes.md index 7325bb6..8e52cfd 100644 --- a/docs/ru/datory/guide/data/attributes.md +++ b/docs/ru/datory/guide/data/attributes.md @@ -1,16 +1,20 @@ --- title: Атрибуты — Datory -description: Описание и примеры использования +description: Описание и примеры использования атрибутов в Datory prev: false next: false --- # Атрибуты -## Базовые +Атрибуты в Datory позволяют определять структуру данных для сериализации и десериализации. Они поддерживают различные типы данных и опции для валидации. + +## Базовые атрибуты ### attribute +Базовый метод для определения атрибута с полным контролем над типами и опциями. + ::: code-group ```ruby [Обязательный] @@ -25,6 +29,8 @@ attribute :uuid, from: [String, NilClass], to: :id, as: [String, NilClass], form ### string +Хелпер для определения строкового атрибута. + ::: code-group ```ruby [Обязательный] @@ -39,6 +45,8 @@ string? :uuid, to: :id ### integer +Хелпер для определения целочисленного атрибута с поддержкой диапазона значений. + ::: code-group ```ruby [Обязательный] @@ -53,6 +61,8 @@ integer? :rating, min: 1, max: 10 ### float +Хелпер для определения атрибута с плавающей точкой. + ::: code-group ```ruby [Обязательный] @@ -67,6 +77,8 @@ float? :rating ### boolean +Хелпер для определения булевого атрибута. + ::: code-group ```ruby [Обязательный] @@ -94,10 +106,12 @@ boolean! :published О поддерживаемых значениях для `format` вы можете узнать [здесь](../../../guide/options/dynamic.md#опция-format). -## Хелперы +## Специальные хелперы ### uuid +Хелпер для работы с UUID. + ::: code-group ```ruby [Пример] @@ -124,6 +138,8 @@ string? :id, format: :uuid ### money +Хелпер для работы с денежными значениями. + ::: code-group ```ruby [Пример] @@ -152,6 +168,8 @@ string? :box_office_currency ### duration +Хелпер для работы с длительностью. + ::: code-group ```ruby [Пример] @@ -178,6 +196,8 @@ attribute :episode_duration, from: [String, NilClass], as: [ActiveSupport::Durat ### date +Хелпер для работы с датами. + ::: code-group ```ruby [Пример] @@ -204,6 +224,8 @@ attribute :premiered_on, from: [String, NilClass], as: [Date, NilClass], format: ### time +Хелпер для работы со временем. + ::: code-group ```ruby [Пример] @@ -230,6 +252,8 @@ attribute :premiered_at, from: [String, NilClass], as: [Time, NilClass], format: ### datetime +Хелпер для работы с датой и временем. + ::: code-group ```ruby [Пример] @@ -253,3 +277,4 @@ attribute :premiered_at, from: [String, NilClass], as: [DateTime, NilClass], for ``` ::: + diff --git a/docs/ru/datory/guide/data/nesting.md b/docs/ru/datory/guide/data/nesting.md index c6f4d7f..2a1040a 100644 --- a/docs/ru/datory/guide/data/nesting.md +++ b/docs/ru/datory/guide/data/nesting.md @@ -1,13 +1,17 @@ --- title: Вложенные данные — Datory -description: Описание и примеры использования +description: Описание и примеры использования вложенных данных в Datory prev: false next: false --- # Вложенные данные -## Single +Datory поддерживает работу с вложенными данными через два основных метода: `one` для одиночных объектов и `many` для коллекций. + +## Одиночные объекты (Single) + +Метод `one` используется для определения атрибута, который содержит один вложенный объект. ::: code-group @@ -21,7 +25,27 @@ one? :poster, include: ImageDto ::: -## Multiple +### Пример использования + +```ruby +class MovieDto < ApplicationDTO::Base + uuid! :id + string! :title + + # Вложенный объект для постера фильма + one! :poster, include: ImageDto +end + +class ImageDto < ApplicationDTO::Base + uuid! :id + string! :url + string! :alt +end +``` + +## Коллекции (Multiple) + +Метод `many` используется для определения атрибута, который содержит коллекцию вложенных объектов. ::: code-group @@ -34,3 +58,21 @@ many? :seasons, include: SeasonDto ``` ::: + +### Пример использования + +```ruby +class SeriesDto < ApplicationDTO::Base + uuid! :id + string! :title + + # Коллекция сезонов + many! :seasons, include: SeasonDto +end + +class SeasonDto < ApplicationDTO::Base + uuid! :id + integer! :number + string! :title +end +``` diff --git a/docs/ru/datory/guide/info.md b/docs/ru/datory/guide/info.md index 45863b1..e814c26 100644 --- a/docs/ru/datory/guide/info.md +++ b/docs/ru/datory/guide/info.md @@ -1,17 +1,18 @@ --- title: Информация об объекте Datory -description: Описание и примеры использования получения информации об объекте Datory +description: Описание и примеры получения информации об объекте Datory prev: false next: false --- # Информация -О каждом объекте Datory можно получить информацию. -Для этого существует два варианта. +Datory предоставляет два метода для получения информации об объекте: `info` и `describe`. Эти методы помогают понять структуру и конфигурацию DTO. ## Метод `info` +Метод `info` возвращает подробную информацию о всех атрибутах объекта, включая их типы, опции и конфигурацию. + ::: code-group ```ruby [Пример] @@ -54,6 +55,8 @@ SerialDto.info ## Метод `describe` +Метод `describe` возвращает информацию в виде удобной таблицы, которая показывает основные характеристики атрибутов. + ::: code-group ```ruby [Пример] diff --git a/docs/ru/datory/guide/usage/deserialization.md b/docs/ru/datory/guide/usage/deserialization.md index 2f16988..9df20d0 100644 --- a/docs/ru/datory/guide/usage/deserialization.md +++ b/docs/ru/datory/guide/usage/deserialization.md @@ -1,6 +1,6 @@ --- title: Десериализация — Datory -description: Описание и примеры использования +description: Описание и примеры использования десериализации в Datory prev: false next: false --- diff --git a/docs/ru/datory/guide/usage/serialization.md b/docs/ru/datory/guide/usage/serialization.md index 1b50244..1edd5cd 100644 --- a/docs/ru/datory/guide/usage/serialization.md +++ b/docs/ru/datory/guide/usage/serialization.md @@ -1,6 +1,6 @@ --- title: Сериализация — Datory -description: Описание и примеры использования +description: Описание и примеры использования сериализации в Datory prev: false next: false --- diff --git a/docs/ru/featury/getting-started.md b/docs/ru/featury/getting-started.md index db8d363..38025df 100644 --- a/docs/ru/featury/getting-started.md +++ b/docs/ru/featury/getting-started.md @@ -1,19 +1,29 @@ --- title: Начало работы с Featury -description: Требования, соглашения, установка и пример базовой подготовки +description: Руководство по установке и настройке Featury prev: false next: false --- # Начало работы с Featury -## Соглашения +## Что такое Featury? -- Все классы фичей являются подклассами `Featury::Base` и располагаются в директории `app/features`. Общепринятой практикой является создание и наследование от класса `ApplicationFeature::Base`, который является подклассом `Featury::Base`. -- Называйте фичи по тому, к процессу которому они относятся. Используйте существительные в именах, а также старайтесь по возможности приравнивать к именам моделей. Например, назовите класс фичи `User::OnboardingFeature` вместо `User::OnboardFeature`. +Featury — это библиотека для управления функциональными флагами (feature flags) в Ruby/Rails приложениях. Она предоставляет удобный API для работы с фича-флагами и их группами. + +## Соглашения по разработке + +Featury следует определенным соглашениям для обеспечения единообразия кода: + +- Все классы фичей должны наследоваться от `Featury::Base` и размещаться в директории `app/features` +- Рекомендуется создавать базовый класс `ApplicationFeature::Base`, наследующийся от `Featury::Base` +- Имена фичей должны отражать их принадлежность к процессу +- Используйте существительные в именах фичей (например, `User::OnboardingFeature` вместо `User::OnboardFeature`) ## Поддержка версий +Featury поддерживает следующие версии Ruby и Rails: + | Ruby/Rails | 8.0 | 7.2 | 7.1 | 7.0 | 6.1 | 6.0 | 5.2 | 5.1 | 5.0 | |-------------|---|---|---|---|---|---|---|---|---| | 3.5 Preview | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | @@ -24,33 +34,40 @@ next: false ## Установка -Добавьте это в файл `Gemfile`: +### Добавление гема + +Добавьте Featury в ваш `Gemfile`: ```ruby gem "featury" ``` -Затем выполните: +### Установка зависимостей + +Выполните команду для установки гема: ```shell bundle install ``` -## Подготовка +## Подготовка окружения + +### Создание базового класса Для начала рекомендуется подготовить базовый класс для дальнейшего наследования. Этот базовый класс должен внутри себя содержать действия с интеграцией инструмента для фичей в проекте. Например, это может быть модель ActiveRecord, Flipper или что-нибудь другое. -### Модель ActiveRecord +### Пример с ActiveRecord -В качестве примера будет использоваться модель `FeatureFlag`. +В качестве примера будет использоваться модель `FeatureFlag`: ::: code-group ```ruby [app/features/application_feature/base.rb] module ApplicationFeature class Base < Featury::Base + # Проверка включения фичи action :enabled? do |features:, **options| features.all? do |feature| FeatureFlag @@ -59,6 +76,7 @@ module ApplicationFeature end end + # Проверка выключения фичи action :disabled? do |features:, **options| features.any? do |feature| !FeatureFlag @@ -67,6 +85,7 @@ module ApplicationFeature end end + # Включение фичи action :enable do |features:, **options| features.all? do |feature| FeatureFlag @@ -75,6 +94,7 @@ module ApplicationFeature end end + # Выключение фичи action :disable do |features:, **options| features.all? do |feature| FeatureFlag @@ -83,10 +103,12 @@ module ApplicationFeature end end + # Хук перед выполнением любого действия before do |action:, features:| Slack::API::Notify.call!(action:, features:) end + # Хук после выполнения действий enabled? и disabled? after :enabled?, :disabled? do |action:, features:| Slack::API::Notify.call!(action:, features:) end @@ -95,3 +117,43 @@ end ``` ::: + +## Создание первой фичи + +### Пример фичи + +```ruby +class User::OnboardingFeature < ApplicationFeature::Base + # Префикс для фича-флагов + prefix :onboarding + + # Ресурс пользователя + resource :user, type: User + + # Условие для работы с фичей + condition ->(resources:) { resources.user.onboarding_awaiting? } + + # Набор фича-флагов + features :passage, :integration + + # Группы фича-флагов + groups BillingFeature, + PaymentSystemFeature +end +``` + +### Использование + +```ruby +# Проверка включения фичи +User::OnboardingFeature.enabled?(user: current_user) + +# Включение фичи +User::OnboardingFeature.enable(user: current_user) + +# Проверка выключения фичи +User::OnboardingFeature.disabled?(user: current_user) + +# Выключение фичи +User::OnboardingFeature.disable(user: current_user) +``` diff --git a/docs/ru/featury/guide/info.md b/docs/ru/featury/guide/info.md index 320e0d5..2d6df2c 100644 --- a/docs/ru/featury/guide/info.md +++ b/docs/ru/featury/guide/info.md @@ -1,16 +1,18 @@ --- title: Информация об объекте Featury -description: Описание и примеры использования получения информации об объекте Featury +description: Описание и примеры получения информации о фичах в Featury prev: false next: false --- # Информация об объекте Featury -О каждом объекте Featury можно получить информацию. +Featury предоставляет методы для получения информации о фичах и их структуре. Это может быть полезно для отладки, документации и валидации. ## Метод `info` +Метод `info` возвращает подробную информацию о фиче, включая все фича-флаги и группы. + ```ruby [Пример] info = User::OnboardingFeature.info ``` diff --git a/docs/ru/getting-started.md b/docs/ru/getting-started.md index 95514c2..3c706fd 100644 --- a/docs/ru/getting-started.md +++ b/docs/ru/getting-started.md @@ -1,19 +1,25 @@ --- title: Начало работы -description: Описание и примеры использования +description: Руководство по установке и настройке Servactory prev: Почему Servactory next: Вызов сервиса и результат его работы --- # Начало работы с Servactory -## Соглашения +## Соглашения по разработке -- Все сервисы являются подклассами `Servactory::Base` и располагаются в директории `app/services`. Общепринятой практикой является создание и наследование от класса `ApplicationService::Base`, который является подклассом `Servactory::Base`. -- Называйте сервисы по тому что они делают, а не по тому что они принимают. Используйте глаголы в именах. Например, назовите сервис `UsersService::Create` вместо `UsersService::Creation`. +Servactory следует определенным соглашениям для обеспечения единообразия кода: + +- Все сервисы должны наследоваться от `Servactory::Base` и размещаться в директории `app/services` +- Рекомендуется создавать базовый класс `ApplicationService::Base`, наследующийся от `Servactory::Base` +- Имена сервисов должны отражать их действия, а не входные данные +- Используйте глаголы в именах сервисов (например, `UsersService::Create` вместо `UsersService::Creation`) ## Поддержка версий +Servactory поддерживает следующие версии Ruby и Rails: + | Ruby/Rails | 8.0 | 7.2 | 7.1 | 7.0 | 6.1 | 6.0 | 5.2 | 5.1 | 5.0 | |-------------|---|---|---|---|---|---|---|---|---| | 3.5 Preview | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | @@ -24,35 +30,37 @@ next: Вызов сервиса и результат его работы ## Установка -Добавьте это в файл `Gemfile`: +### Добавление гема + +Добавьте Servactory в ваш `Gemfile`: ```ruby gem "servactory" ``` -Затем выполните: +### Установка зависимостей + +Выполните команду для установки гема: ```shell bundle install ``` -## Подготовка +## Настройка окружения -Для начала рекомендуется подготовить базовый класс для дальнейшего наследования. +### Автоматическая настройка -### Автоматически - -Для быстрой подготовки среды для работы вы можете воспользоваться rake-задачей: +Для быстрой настройки окружения используйте генератор: ```shell bundle exec rails g servactory:install ``` -Это создаст все необходимые файлы. +Это создаст все необходимые файлы и структуру. -### Вручную +### Ручная настройка -#### ApplicationService::Exceptions +#### 1. Создание исключений ::: code-group @@ -70,7 +78,7 @@ end ::: -#### ApplicationService::Result +#### 2. Создание класса результата ::: code-group @@ -82,7 +90,7 @@ end ::: -#### ApplicationService::Base +#### 3. Создание базового класса ::: code-group @@ -104,16 +112,19 @@ end ::: -## Первый сервис +## Создание первого сервиса + +### Генерация сервиса -Теперь вы можете создать свой первый сервис. -Для этого можно воспользоваться rake-задачей: +Для создания нового сервиса используйте генератор: ```shell bundle exec rails g servactory:service users_service/create first_name middle_name last_name ``` -Также вы можете сразу подготовить спек файл для тестирования сервиса: +### Генерация тестов + +Для создания тестов используйте: ```shell bundle exec rails g servactory:rspec users_service/create first_name middle_name last_name diff --git a/docs/ru/introduction.md b/docs/ru/introduction.md index 202f037..364db8f 100644 --- a/docs/ru/introduction.md +++ b/docs/ru/introduction.md @@ -1,44 +1,52 @@ --- title: Почему Servactory +description: Обзор возможностей и преимуществ Servactory prev: false next: Начало работы --- # Почему Servactory -## Что это такое? +## Что такое Servactory? -Servactory — это стандартизация единого подхода к разработке надежных сервисов любой сложности. +Servactory — это современный фреймворк для стандартизации разработки сервисных объектов в Ruby/Rails приложениях. Он предоставляет единый подход к созданию надежных и поддерживаемых сервисов любой сложности. -При помощи Servactory можно сделать что-то простое, например: +## Простота использования + +Servactory позволяет создавать как простые, так и сложные сервисы с минимальными усилиями: + +### Простой сервис ```ruby class MinimalService < ApplicationService::Base def call - # ... + # Ваша бизнес-логика end end ``` -А затем вызвать с помощью: - ```ruby +# Использование MinimalService.call! # или MinimalService.call ``` -Или создать что-то более сложное: +### Сложный сервис ```ruby class NotificationsService::Send < ApplicationService::Base + # Определение входных параметров input :comment, type: Comment input :provider, type: NotificationProvider + # Внутренние переменные internal :user, type: User internal :status, type: String internal :response, type: NotificatorApi::Models::Notification + # Выходные данные output :notification, type: Notification + # Последовательность действий make :assign_user make :assign_status @@ -59,11 +67,17 @@ class NotificationsService::Send < ApplicationService::Base end def create_notification! - outputs.notification = Notification.create!(user:, comment: inputs.comment, provider: inputs.provider) + outputs.notification = Notification.create!( + user: internals.user, + comment: inputs.comment, + provider: inputs.provider + ) end def send_notification - service_result = NotificatorService::API::Send.call(notification: outputs.notification) + service_result = NotificatorService::API::Send.call( + notification: outputs.notification + ) return fail!(message: service_result.error.message) if service_result.failure? @@ -71,32 +85,58 @@ class NotificationsService::Send < ApplicationService::Base end def update_notification! - outputs.notification.update!(original_data: internals.response) + outputs.notification.update!( + original_data: internals.response + ) end def update_comment! - inputs.comment.update!(status: internals.status) + inputs.comment.update!( + status: internals.status + ) end end ``` -С таким вызовом: - ```ruby -# comment = Comment.first -# provider = NotificationProvider.first - +# Использование NotificationsService::Send.call!(comment:, provider:) -# Или -# NotificationsService::Send.call(comment:, provider:) +# или +NotificationsService::Send.call(comment:, provider:) ``` -## Зачем использовать? +## Преимущества использования + +### 1. Единый подход к разработке + +Ruby предоставляет множество способов решения задач, что может привести к несогласованности в коде. Servactory стандартизирует подход к разработке сервисов, предлагая: + +- Единый API для создания сервисов +- Стандартизированную структуру классов +- Предсказуемое поведение сервисов + +### 2. Надежность и безопасность + +Servactory обеспечивает: + +- Строгую типизацию входных и выходных данных +- Валидацию параметров +- Обработку ошибок +- Предсказуемое поведение при сбоях + +### 3. Удобство поддержки + +Благодаря стандартизированному подходу: + +- Код легче понимать и поддерживать +- Новые разработчики быстрее входят в проект +- Уменьшается количество ошибок +- Упрощается рефакторинг -### Единый подход +### 4. Расширяемость -Язык Ruby многогранен. -Это приводит к тому, что сервисы в приложениях начинают сильно различаться, реализуя разный подход к разработке. -Со временем это усложняет разработку в проекте и может затруднить понимание сервисов и кода в целом. +Servactory предоставляет: -Servactory стандартизирует подход к разработке, предлагая реализовать сервисы только через предложенный API, однообразно описывая логику внутри классов. +- Гибкую систему конфигурации +- Возможность создания собственных расширений +- Интеграцию с популярными инструментами тестирования diff --git a/docs/ru/releases/2.10.md b/docs/ru/releases/2.10.md index 96940f0..f7efd3c 100644 --- a/docs/ru/releases/2.10.md +++ b/docs/ru/releases/2.10.md @@ -1,16 +1,17 @@ --- title: Релиз 2.10 +description: Основные изменения и улучшения в версии 2.10 prev: false next: false --- # Релиз 2.10 -Были подготовлены и реализованы следующие изменения. +В этой версии были реализованы следующие изменения и улучшения. ## Действия -### Stage +### Улучшения в Stage #### Методы `wrap_in` и `rollback` @@ -18,7 +19,7 @@ next: false ## Тестирование -### RSpec +### Улучшения в RSpec #### Чейн `with_output` diff --git a/docs/ru/releases/2.11.md b/docs/ru/releases/2.11.md index 10be503..7698422 100644 --- a/docs/ru/releases/2.11.md +++ b/docs/ru/releases/2.11.md @@ -1,12 +1,13 @@ --- title: Релиз 2.11 +description: Основные изменения и улучшения в версии 2.11 prev: false next: false --- # Релиз 2.11 -Были подготовлены и реализованы следующие изменения. +В этой версии были реализованы следующие изменения и улучшения. ## Атрибуты @@ -15,6 +16,8 @@ next: false Изменена работа с входящими в сервис аргументами. Теперь данные во всех 3-х типах атрибутов хранятся и обрабатываются одинаково. -## Ruby +## Поддержка версий -Была проверена поддержка Ruby 3.4. +### Ruby + +- Была проверена поддержка Ruby 3.4. diff --git a/docs/ru/releases/2.12.md b/docs/ru/releases/2.12.md index 98a66dd..44a6122 100644 --- a/docs/ru/releases/2.12.md +++ b/docs/ru/releases/2.12.md @@ -1,22 +1,23 @@ --- title: Релиз 2.12 +description: Основные изменения и улучшения в версии 2.12 prev: false next: false --- # Релиз 2.12 -Были подготовлены и реализованы следующие изменения. +В этой версии были реализованы следующие изменения и улучшения. ## Атрибуты -### Опции +### Улучшения в опциях -#### Изменено `inclusion` +#### Опция `inclusion` Опция `inclusion` стала [динамической опцией](../guide/options/dynamic#опция-inclusion). -#### Изменено `schema` +#### Опция `schema` Опция `schema` стала [динамической опцией](../guide/options/dynamic#опция-schema). diff --git a/docs/ru/releases/2.13.md b/docs/ru/releases/2.13.md index 570d31c..33212fd 100644 --- a/docs/ru/releases/2.13.md +++ b/docs/ru/releases/2.13.md @@ -1,27 +1,28 @@ --- title: Релиз 2.13 +description: Основные изменения и улучшения в версии 2.13 prev: false next: false --- # Релиз 2.13 -Были подготовлены и реализованы следующие изменения. +В этой версии были реализованы следующие изменения и улучшения. ## Атрибуты -### Опции +### Улучшения в опциях -#### Улучшено `type` +#### Опция `type` -Для опции `type` была исправлена работа с дефолтным значением при использовании `TrueClass` и/или `FalseClass` в инпуте. +Исправлена работа с дефолтным значением при использовании `TrueClass` и/или `FalseClass` в инпуте. -#### Улучшено `schema` +#### Опция `schema` -Внутри опции `schema` была добавлена поддержка опции `prepare`. +Добавлены следующие улучшения: +- Добавлена поддержка опции `prepare` +- Исправлена работа с дефолтным значением при использовании в инпуте -Для опции `schema` была исправлена работа с дефолтным значением при использовании в инпуте. +#### Опция `inclusion` -#### Улучшено `inclusion` - -Для опции `inclusion` была исправлена работа с дефолтным значением при использовании в инпуте. +Исправлена работа с дефолтным значением при использовании в инпуте. diff --git a/docs/ru/releases/2.14.md b/docs/ru/releases/2.14.md index 45928fb..264bf5f 100644 --- a/docs/ru/releases/2.14.md +++ b/docs/ru/releases/2.14.md @@ -1,18 +1,21 @@ --- title: Релиз 2.14 +description: Основные изменения и улучшения в версии 2.14 prev: false next: false --- # Релиз 2.14 -Были подготовлены и реализованы следующие изменения. +В этой версии были реализованы следующие изменения и улучшения. ## Конфигурация -### Улучшено `action_shortcuts` +### Улучшения в `action_shortcuts` -Для опции `action_shortcuts` была добавлена поддержка расширенного режима. +Добавлена поддержка расширенного режима для конфигурации `action_shortcuts`, что позволяет более гибко настраивать имена методов. + +#### Пример использования ```ruby configuration do @@ -27,6 +30,8 @@ configuration do end ``` +#### Пример сервиса + ```ruby class PaymentsService::Restrictions::Create < ApplicationService::Base input :payment, type: Payment @@ -44,8 +49,9 @@ class PaymentsService::Restrictions::Create < ApplicationService::Base end ``` -## Ruby +## Поддержка версий -Была проверена поддержка Ruby 3.5 Preview 1. +### Ruby -Была удалена поддержка Ruby 3.1. +- Добавлена поддержка Ruby 3.5 Preview 1 +- Удалена поддержка Ruby 3.1 diff --git a/docs/ru/releases/2.2.md b/docs/ru/releases/2.2.md index 7d452b7..b7cb79f 100644 --- a/docs/ru/releases/2.2.md +++ b/docs/ru/releases/2.2.md @@ -1,12 +1,13 @@ --- title: Релиз 2.2 +description: Основные изменения и улучшения в версии 2.2 prev: false next: false --- # Релиз 2.2 -Были подготовлены и реализованы следующие изменения. +В этой версии были реализованы следующие изменения и улучшения. ## Атрибуты diff --git a/docs/ru/releases/2.3.md b/docs/ru/releases/2.3.md index 9ced752..efd79e6 100644 --- a/docs/ru/releases/2.3.md +++ b/docs/ru/releases/2.3.md @@ -1,17 +1,19 @@ --- title: Релиз 2.3 +description: Основные изменения и улучшения в версии 2.3 prev: false next: false --- # Релиз 2.3 -Были подготовлены и реализованы следующие изменения. +В этой версии были реализованы следующие изменения и улучшения. ## Конфигурация -Были изменены конфиги и классы от исключений. -Ниже продемонстрированы изменения. +### Изменения в исключениях + +Были изменены конфиги и классы исключений. Ниже продемонстрированы изменения. ::: code-group diff --git a/docs/ru/releases/2.4.md b/docs/ru/releases/2.4.md index fb533e8..db243a4 100644 --- a/docs/ru/releases/2.4.md +++ b/docs/ru/releases/2.4.md @@ -1,12 +1,13 @@ --- title: Релиз 2.4 +description: Основные изменения и улучшения в версии 2.4 prev: false next: false --- # Релиз 2.4 -Были подготовлены и реализованы следующие изменения. +В этой версии были реализованы следующие изменения и улучшения. ## Атрибуты diff --git a/docs/ru/releases/2.5.md b/docs/ru/releases/2.5.md index 7ea8f3d..ebd08e1 100644 --- a/docs/ru/releases/2.5.md +++ b/docs/ru/releases/2.5.md @@ -1,12 +1,13 @@ --- title: Релиз 2.5 +description: Основные изменения и улучшения в версии 2.5 prev: false next: false --- # Релиз 2.5 -Были подготовлены и реализованы следующие изменения. +В этой версии были реализованы следующие изменения и улучшения. ## Атрибуты @@ -15,9 +16,8 @@ next: false #### Динамические опции Были реализованы новые форматы для [динамической опции](../guide/options/dynamic) [format](../guide/options/dynamic#опция-format): - -- `uuid`; -- `duration`. +- `uuid` +- `duration` ## Конфигурация @@ -63,9 +63,11 @@ end Подробнее можно ознакомиться [здесь](../guide/testing/rspec). -## Ruby +## Поддержка версий + +### Ruby -Была удалена поддержка Ruby 2.7. +- Была удалена поддержка Ruby 2.7. ## Datory diff --git a/docs/ru/releases/2.6.md b/docs/ru/releases/2.6.md index 40b2072..bcb0bcb 100644 --- a/docs/ru/releases/2.6.md +++ b/docs/ru/releases/2.6.md @@ -1,12 +1,13 @@ --- title: Релиз 2.6 +description: Основные изменения и улучшения в версии 2.6 prev: false next: false --- # Релиз 2.6 -Были подготовлены и реализованы следующие изменения. +В этой версии были реализованы следующие изменения и улучшения. ## Атрибуты @@ -20,9 +21,9 @@ next: false Атрибут `service_class_name`, который доступен в некоторых опциях, был заменен на новый атрибут `service`. -Новый атрибут представляет собой объект, содержащий подготовленный набор данных: `class_name`. - -А также метод для перевода: `translate`. +Новый атрибут представляет собой объект, содержащий: +- `class_name` - подготовленный набор данных +- `translate` - метод для перевода ## Конфигурация diff --git a/docs/ru/releases/2.7.md b/docs/ru/releases/2.7.md index b64f1cd..7451932 100644 --- a/docs/ru/releases/2.7.md +++ b/docs/ru/releases/2.7.md @@ -1,16 +1,17 @@ --- title: Релиз 2.7 +description: Основные изменения и улучшения в версии 2.7 prev: false next: false --- # Релиз 2.7 -Были подготовлены и реализованы следующие изменения. +В этой версии были реализованы следующие изменения и улучшения. ## Атрибуты -### Опции +### Улучшения в опциях #### Опция `multiple_of` @@ -19,8 +20,12 @@ next: false ## Ruby -Была удалена поддержка Ruby 3.0. +## Поддержка версий -## Rails +### Ruby -Была добавлена поддержка Rails 7.2. +- Была удалена поддержка Ruby 3.0 в связи с окончанием срока поддержки. + +### Rails + +- Добавлена поддержка Rails 7.2. \ No newline at end of file diff --git a/docs/ru/releases/2.8.md b/docs/ru/releases/2.8.md index 2cf9acb..a45a876 100644 --- a/docs/ru/releases/2.8.md +++ b/docs/ru/releases/2.8.md @@ -1,18 +1,27 @@ --- title: Релиз 2.8 +description: Основные изменения и улучшения в версии 2.8 prev: false next: false --- # Релиз 2.8 -Были подготовлены и реализованы следующие изменения. +В этой версии были реализованы следующие изменения и улучшения. ## Результат сервиса -Был добавлен метод `to_h` в `Result`. +### Метод `to_h` + +Добавлен метод `to_h` в класс `Result`. ## Конфигурация -Были удалены устаревшие методы конфигурации: -`input_error_class`, `internal_error_class` и `output_error_class`. +### Удаление устаревших методов + +Удалены следующие устаревшие методы конфигурации: +- `input_error_class` +- `internal_error_class` +- `output_error_class` + +Это изменение является частью процесса очистки API от устаревшего функционала. diff --git a/docs/ru/releases/2.9.md b/docs/ru/releases/2.9.md index acdbfcf..d64daca 100644 --- a/docs/ru/releases/2.9.md +++ b/docs/ru/releases/2.9.md @@ -1,12 +1,13 @@ --- title: Релиз 2.9 +description: Основные изменения и улучшения в версии 2.9 prev: false next: false --- # Релиз 2.9 -Были подготовлены и реализованы следующие изменения. +В этой версии были реализованы следующие изменения и улучшения. ## Datory @@ -18,13 +19,13 @@ next: false Была добавлена поддержка опции `with` для хелперов `allow_*`. [Подробнее](../guide/testing/rspec.md#contains). -Была улучшена работа реализованного ранее функционала. +## Поддержка версий -## Ruby +### Ruby -Была проверена поддержка Ruby 3.4 Preview 2. +- Была проверена поддержка Ruby 3.4 Preview 2. -## Rails +### Rails -Была добавлена поддержка Rails 8.0. -Для Rails 8.0 версия Ruby 3.1 не поддерживается. +- Добавлена поддержка Rails 8.0. +- Для Rails 8.0 версия Ruby 3.1 не поддерживается.