Unicat is centered around projects - this is where all data, definitions, and
assets are managed. A project is the basis for any number of publications.
Each project has a hierarchical tree of records - where product-related data
is stored. The tree is built from gid/parent relationships.
A record has a number of properties to manage its state and position in the
tree - we have gid/parent for the hierarchy (it follows that we have one
'root' record, and each record can have 'children'), channels to manage which
records should be included in publications, orderings to allow for multiple
different sort orders, and a (localized) title to present it to a user.
Additionally, and more importantly since we're a product information management
application, each record has a user-defined number of extra data fields
(optionally grouped in classes). These fields can be anything from name to
description to price and image asset, and are user-defined as well, possibly
localized too.
Which fields are available on a record is specified by its definition.
A field is defined by its name and type and a number of options. The name can be used as a property in the API, so it is good practice to name it like a variable name; we prefer all lowercase letters, underscores, and digits, and nothing else. As a convention we often include the unit (for numeric types) in the name as well, e.g. net_weight__kg.
Fields can be of type text, number, barcode, image, file, record (think accessories) and more.
Additionally, a field has a label that is a human-readable version of the name (without the unit), and that is translated for each language the project supports (not automatically). Think 'Net weight'.
If a field is set to localized, that means that for projects with multiple languages, the contents for this field can differ per language, otherwise the value is the same across all languages.
Options for a field include min/max values, initial value, is_required, and others, some depending on the type of field too.
A class has a name and label too, and a list of fields that belong to this class. It is used to group sets of related fields together, so they can be assigned to a definition as a whole.
A set of classes and fields. Combined, we get a complete set of user-defined fields to attach to the record.
One of these fields will be set as the titlefield, so the record knows how to present itself.
These fields form a complete specification of the record. We don't always need
all of them for a publication, or the same set of those for different
publications. Enter fieldlists - a way to group sets of available fields
together under a common name.
We use definitions as a base type for the record, usually describing the level in the tree: catalog, chapter, category, articlegroup, article.
These base definitions only contain classes.
We use classes for related sets of fields, such as a group class (name, description, image), an article class (artnr, price, packing, stock), an internet-only meta-data class (meta_title, meta_description, meta_keywords).
These base classes are used by the base definitions.
We create additional classes for e.g. classication, so we can have a 'tv' class that has brand, diagonal__inch, width__mm, height__mm, depth__mm, hdmi_inputs; a set of fields that we can use to compare tv's.
We don't create actual definitions for these classification-classes - instead,
we add these classes to records that have a base definition assigned, and in
doing so we create what is called an extended definition.
When a record has been assigned a base definition, and we add one or more classes and/or fields, we create an extended definition. Multiple named extended definitions can exist under one parent; each has a unique name so you can tell them apart. The records that share the same extended definition form an extension group. Adding a class or field applies to every record in the extension group.
We cannot assign an extended definition in other parts of the tree beyond the
siblings that have it. Linked records always keep the same definition as their
canonical. All definition operations must be done from the canonical; they
return 422 from a linked record.
Sibling records that share the same structural extension form an
extension group: same name, same basedef (original), and the same ordered
lists of classes, fields, and fieldlists (including field order within each
fieldlist). Layout is not part of that identity — extended definitions have no
layout of their own.
When a record is moved to a new parent, its extended definition is always detached. If the destination sibling group already has a structurally matching extended definition (same ordered lists as above), the moved record is assigned that one; otherwise a copy is created. Records moved together in one bulk move keep sharing one extended definition among themselves.
For how extended definitions appear in API responses and how to keep init payloads smaller, see Optimizing performance.
In the Unicat user interface, we have a worksheet for records, where we can edit all the values for the fields. This can be generated automatically, just putting field after field after field.
A friendlier way is to define a layout for the record, where we can arrange all the fields in the worksheet in a nice, coherent way - making multi-column layouts, adding tables (showing the records children, if any), et cetera.
A layout is connected to a class or to a definition - where the definition layout can include class layouts. When we select a record and it shows up in the worksheet, the record's definition's layout is used. Extended definitions have no layout of their own; clients should synthesize a layout based on the base definition's layout and the extension classes and fields.
Assets are a collection of uploaded files and images, stored in a tree structure of folders. They are analyzed on upload, and metadata is extracted and available for seach.
From a record, we can link to files and images - if we later rename one (or a folder), this link will stay valid.
To retrieve an asset, or a preview thereof, we ask our DAM server for a transformation - this can be a simple 1-to-1 transformation, but we can also crop and resize images, allow for low/high resolution screens, change file type from eps to jpg (and others). The returned URL can be used to show or download the image.
cc.users User info like name, email, avatar.
cc.projects Project info like name, owner,
channels.
cc.projects_members Member info per
project, like status, roles.
cc.languages Available languages for
internationalization and localization.
records Record info with hierarchy, definition,
field values.
definitions Definition info with name,
classes, fields.
classes Class info with name, fields.
fields Field info with name, type, options.
layouts Layout info with hierarchy.
assets Asset info with hierarchy, type, name.