ferrisoxide / brocade.io

Open GTIN / barcode & product database
https://www.brocade.io
GNU Affero General Public License v3.0
114 stars 7 forks source link

Introduce GPC Bricks #22

Open ferrisoxide opened 4 years ago

ferrisoxide commented 4 years ago

Background

Already baked into the app is the notion of a property set, basic collections of facts about a product.

Each property set defines the name, type and potentially the title of product information elements:

  NUTRITION_FACTS = {
    serving_size: { type: :text },
    servings_per_container: { type: :text },
    calories: { type: :number },
    fat_calories: { type: :number, title: 'Calories from Fat' },
   ...

This scheme is a bit clumsy and likely to become more complicated as more complex types are added. There is also no way currently in the system to validate data against property sets.

Proposal

1. Use JSON Schema

Rather than build out a complete type system, use the existing standards and tooling around JSON Schema. Under this model, a property set definition would look something like this:

{
  "$id": "https://brocade.io/nutrition-facts.schema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Nutrition Facts",
  "type": "object",
  "properties": {
    "servingSize": {
      "type": "string",
      "description": "Details of typical serving portion"
    },
    ....
    "calories": {
      "type": "integer",
      "description": "Number of calories per serving"
    },
    ....

There are numerous resources for validating JSON data, including multiple ruby gems:

We can probably push a lot of this down to the database level, validating / typing data within PostgreSQL itself:

2. Use Property Definitions From GS1

GS1 publishes standard property definitions for different product types and industries. Rather than invent our our, we should defer to the GS1 standards for property name and type information.

For example, the published Australasian_Liquor_Industry attributes includes a liquorAge integer type attribute.

Attribute Name Definition Example Rationale Data Type
liquorAge How old in years - 1 to 100 for premium spirits, some fortified & liqueursco 15 Required by the Australasian Liquor Industry for Local Data Synchronisation requirements integer

Other attributes include enums (alcoholicStrengthDescription), floats (standardDrinks) and a number of attributes that are constrained by various rules - potentially mappable to JSON Schema regex type definitions.

If we were to record data for alcoholic products - at least for the Australian market - we would map all these into a specific JSON Schema document for validating data.

3. Move Title Translations Into I18N

This may be an edge case, but there might be reasons to provide translations of property names. Rather than bake this into the schemas, we can push this off to Rails' I18N mechanism, translating based on keys, e.g.

  calories: 'calorías'
ferrisoxide commented 4 years ago

More info regarding attribute types:

https://www.gs1.org/voc/?show=properties

And possibly a source of property set definitions:

https://www.gs1.org/voc/?show=classes

ferrisoxide commented 3 years ago

NOTES

Am proceeding with this, using GS1's "bricks" as a reference

ferrisoxide commented 3 years ago

NOTES

This is the basic model using in GS1

Segment --has many--> Family --has many--> Class --has many--> Block -- has many --> Attribute 
                                                                 |                      ^
                                                                 |                      |
                                                                 +--- core attribute ---+