README.md

# Helper

A set of utilties for developing microservices in ngSupplyChain

## Installation

The package can be installed by adding `helper` to your list of dependencies in `mix.exs` like so:

```elixir
def deps do
  [
    {:helper, "~> X.Y.Z", organization: :ngsc}
  ]
end
```

## Example Project

helper_examples folder has an application that demostrates the way to use the Ecto and Cache module. To test the Helper functions, use the example app by running `mix test` on the example app. 

## Helper.Ecto

Ecto helper implements a DSL (Domain Specific Language) for defining the schema in Elixir applications. The key features are below:

```elixir
def_schema do 
  #The following four lines are mandatory
  #This defines the table name for the schema. Value :embedded indicates that this module is being defined for an embedded schema which shall be embedded as a map in a column of another schema.
  source "name"

  # Name or the Module name of the schema
  name MyApp.User

  # Repo information for this schema
  repo MyApp.Repo
  repo_options []

  # This is where the actual schema is defined, just like how it is done with the Ecto.Schema.schema macro. You can also define relationships and embeds using belongs_to, has_one, has_many, many_to_many, embeds_one and embeds_many

  # For embedded schema, you can use only `field` directive
  field :name, :string, null: false, required: true

  # These are functions that add specific fields to the schema. See documentation below for the explanation. These functions cannot be used in embedded schema.
  activate
  audit
  soft_delete
  versioned

  # Validations cannot be set for embedded schema
  validation {MyApp.Module, :validation_fun, []}
end
``` 
In addition to field, you can also use belongs_to, has_one, has_many, embeds_one, embeds_many, many_to_many in regular schema. You can only use the field directive on embedded schemas

The options can be a combination of field options and field validations. The available validations are:

    1.  required => boolean (same as validate_required/3)
    2.  length => keyword (same as validate_length/3)
    3.  format => Regex.t() (same as validate_format/3)
    4.  one_of => list() (same as validate_inclusion/3)
    5.  none_of => list() (same as validate_exclusion/3)
    6.  subset_of => list() (same as validate_subset/3)
    7.  number => list() (same as validate_number/3)
    8.  custom => mfa() validates the field by calling the moudule and function with the arguments along with changeset and field name (both are default arguments)

The following functions are available both in Schema and Migration. For migration, you need to use Helper.Ecto.Migration, instead of Ecto.Migration: 

1. **activatable** : create a active? flag on the schema and helper functions activate, activate!, deactivate and deactivate!

2. **audit** : create timestamp fields (same as timestamped) and updated_by and updated_thru fields for audit purpose. The fields are not exposed to the user and populated by the backend automatically

3.  **soft_delete** : add fields mark_for_delete? and deleted_at, and check if the record is deleted or not before performing the DML operation.

4.  **timestamped** : create the inserted_at and created_at fields, of type :utc_datetime_usec. This option cannot be used with audit because audit is a superset that creates the timestamp fields

5.  **validation** : a mfa tuple which is called with the changeset (default argument). There can be multiple innstances of validations each calling a different function

6.  **versioned** : add version field and increment it during every update