# mbwb-data-models

The purpose of this repository is to provide a decoupled yet centralized place for data models and their generic functionality to live.

These are the things you do with MBWB data models:

1. Create objects to help you validate data during definition operations (ie, data coming from a feed).
2. Create objects to represent how the model should look in a PostGres table.
3. Designate the type of model.
4. Store any additional information on the model that could be used in multiple places.

## Installation

`npm install @liveaxle/mbwb-data-models`

## Usage - Creation

1. To create a model, simply create a file named after the model you wish to represent at the root of this repository. **If the model has multiple words please use dashes in the file name**.
2. Require and export it in `./index.js`
3. Create the model code:

```
const joi = require('joi');
const Model = require('./lib/model');

module.exports = class <my model name camel case> extends Model {

}
```


  4.0 Hydrate model

  *Hydrating the model has different requirements depending on what you want to do with it:*

| Purpose  |   Requirements | Functionality  |   |   |
|---|---|---|---|---|
| definition | `Model.definition` getter  | `Model.validate`  |   |   |
| Migrations  | `Model.name`, `Model.columns`, `Model.extensions (opt)`  | `Model.factory.sql()`  |   |   |
|   |   |   |   |   |

  4.1 definition:
```
module.exports = class <my model name camel case> extends Model {
  // Use joi to create your expected schema
  static get definition()  { 
    return joi.object().keys({
      distributorNumber: joi.string().required(),
      distributorName : joi.string().required()
    })
  }

  // You can use mappings to help you reconcile a data structure with the table's column structure
  static get mappings() {
    return {
      name: 'distributorName',
      number: 'distributorNumber'
    };
  }
}
```


  4.2 Migrations:
```
module.exports = class <my model name camel case> extends Model {

  static get name() { return 'name'; } // this is the actual postgres table name, be sure to use underscores.

  static get type() { return 'table'} // can be table, enum or composite

  static get columns() {
    return {
      id: {type: 'uuid', required: true, default: 'uuid_generate_v4()', primary: true},
      other_id: {type: uuid, references: 'other_table'}
      name: {required: true, type: 'text'},
      number: {require: true, type: 'text'}
    }
  }

  static get extensions() { return ['uuid-ossp']; }
}
```

  Then, in your migrations you can:
```
const {<my model>} = require('@liveaxle/mbwb-data-models');

async funcion up(client) {
  let sql = <my model>.factory.sql();
  client.schema.raw(sql);
}
```

## Version bumping

Commit and push code changes first.

1. npm version <major|minor|patch>
2. git push
3. git push origin —tags
4. npm login (only necessary once)
5. npm publish