Loading Projects¶
The Project Configurator service is capable of creating Projects with nested folders, plans, assortments, showcases, and boards. With the use of identifiers on all of these entities we are able to both create and update using this service. The service accepts relationships and properties for all of the entities as well.
Service DTO¶
ProjectConfiguration¶
export class ProjectConfiguration {
projectName: string;
identifier: string;
principals: string[];
commonConfig: CommonConfiguration;
assortments: AssortmentConfiguration[];
subFolders: Folder[];
}
-
identifier: This will be used as the federatedId to update or create the project. THIS SHOULD BE UNIQUE FOR THE ENTIRE ORG.
-
projectName: Used to set the name of the project.
-
principals: A list of group names and user emails that are allowed in the project with roles attached to each. i.e. [“Global Merch|ADMIN”, “EMEA|MEMBER”, “btp@vibeiq.com|ADMIN”]
-
commonConfig: This is a json blob that can hold any property. Any property that is defined in the commonConfig can be referenced in any string throughout the rest of the template by using {}.
i.e. If the commonConfig had a property ‘season’ set to 'Fall 2020' you can reference it like this:
“{season} - Global”. This will result in “Fall 2020 - Global”.
-
assortments: This is the list of assortments you wish to have at the project root level. An assortment can be created on its own or it can have an associated plan, board, or showcase. This is described further down below.
-
subFolders: This describe the subfolders you want to be created at the root level. A subfolder can have nested subfolders of its own, along with assortments at all the nested levels.
AssortmentConfiguration¶
export class AssortmentConfiguration {
identifier: string;
name: string;
type: AssortmentType;
sourceAssortmentIdentifier?: string;
composedFromAssortmentIdentifiers?: string[];
ownerAtts?: {[key: string]: any};
assortmentAtts?: {[key: string]: any};
}
-
identifier: This will be used as the federatedId to update or create the assortment or assortment owner. THIS SHOULD BE UNIQUE FOR THE ENTIRE ORG.
-
name: Used to set the name of the assortment and assortment owner name.
-
type: The available assortment types are “ASSORTMENT“ which is assortment only, “BOARD”, “PLAN”, and “SHOWCASE“ which will create the owner and an assortment.
-
sourceAssortmentIdentifier: This is the identifier of the assortment you want to set as the source to this assortment. If it is not restricted, leave this empty. NOTE: This is the identifier of the explicitly created Entity. Even if it is type "PLAN" it will use the assortment associated with the plan.
-
composedFromAssortmentIdentifiers: These are the identifiers of the assortments you want to set as the children of this assortment. If this is not a composite assortment, leave this empty. NOTE: These are the identifiers of the explicitly created Entities. Even if it is type "PLAN" it will use the assortment associated with the plan.
-
ownerAtts: This is a json blob of properties that should be put on the assortment owner (The plan, board, or showcase). Leave this blank if you dont wish to add extra properties.
-
assortmentAtts: This is a json blob of properties that should be put on the assortment. Leave this blank if you dont wish to add extra properties.
NOTE: Assortments can have a relationship with other assortments created at any level.
Folder¶
export class Folder {
identifier: string;
name: string;
principals: string[];
assortments: AssortmentConfiguration[];
subFolders: Folder[];
}
-
identifier: This will be used as the federatedId to update or create the folder. THIS SHOULD BE UNIQUE FOR THE ENTIRE ORG.
-
name: Used to set the name of the folder.
-
principals: A list of group names and user emails that are allowed in the project with roles attached to each. i.e. [“Global Merch|ADMIN”, “EMEA|MEMBER”, “btp@vibeiq.com|ADMIN”]
-
assortments: This is the list of assortments you wish to have at this folder root level.
-
subFolders: This describe the subfolders you want to be created at this folder root level.
API Usage¶
To use this api the caller must be an org admin.
The url is "https://api.vibeiq.com/prod/api/project-configurator" and the only call type supported is POST. In the example below replace "PROJECT_IDENTIFIER" with actual project identifier and "PROJECT_NAME" with actual project name. The project configuration obj used below is just for reference and can be configured according to the needs.
import { Entities, Request, Types } from "@contrail/sdk";
const projectConfiguration = {
"projectName": "{projectName}",
"identifier": "{projectIdentifier}",
"commonConfig": {
"projectIdentifier": "PROJECT_IDENTIFIER",
"projectName": "PROJECT_NAME"
},
"subFolders": [
{
"name": "Apparel",
"identifier": "{projectIdentifier}:apparel.folder",
"assortments": [
{
"identifier": "{projectIdentifier}:apparel:global.plan",
"name": "{projectName} Apparel Global",
"type": "PLAN",
"assortmentAtts": {
"typePath": "item:product:apparel",
"identifier": "{projectIdentifier}:apparel:global.assortment"
}
}
]
},
{
"name": "Accessories",
"identifier": "{projectIdentifier}:accessories.folder",
"assortments": [
{
"identifier": "{projectIdentifier}:accessories:global.plan",
"name": "{projectName} Accessories Global",
"type": "PLAN",
"assortmentAtts": {
"typePath": "item:product:accessories",
"identifier": "{projectIdentifier}:apparel:global.assortment"
}
}
]
},
{
"name": "Equipment",
"identifier": "{projectIdentifier}:equipment.folder",
"assortments": [
{
"identifier": "{projectIdentifier}:equipment:global.plan",
"name": "{projectName} Equipment Global",
"type": "PLAN",
"assortmentAtts": {
"typePath": "item:product:equipment",
"identifier": "{projectIdentifier}:equipment:global.assortment"
}
}
]
},
{
"name": "Footwear",
"identifier": "{projectIdentifier}:footwear.folder",
"assortments": [
{
"identifier": "{projectIdentifier}:footwear:global.plan",
"name": "{projectName} Footwear Global",
"type": "PLAN",
"assortmentAtts": {
"typePath": "item:product:footwear",
"identifier": "{projectIdentifier}:footwear:global.assortment"
}
}
]
}
]
}
await Request.request("/project-configurator", {
method: "POST",
body: JSON.stringify(projectConfiguration),
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
})
curl --request POST \
--url https://api.vibeiq.com/prod/api/project-configurator
--header 'Content-Type: application/json' \
--header 'X-Api-Key: API_KEY' \
--header 'X-Api-Org: ORG_KEY' \
--data '{
"projectName": "{projectName}",
"identifier": "{projectIdentifier}",
"commonConfig": {
"projectIdentifier": "PROJECT_IDENTIFIER",
"projectName": "PROJECT_NAME"
},
"subFolders": [
{
"name": "Apparel",
"identifier": "{projectIdentifier}:apparel.folder",
"assortments": [
{
"identifier": "{projectIdentifier}:apparel:global.plan",
"name": "{projectName} Apparel Global",
"type": "PLAN",
"assortmentAtts": {
"typePath": "item:product:apparel",
"identifier": "{projectIdentifier}:apparel:global.assortment"
}
}
]
},
{
"name": "Accessories",
"identifier": "{projectIdentifier}:accessories.folder",
"assortments": [
{
"identifier": "{projectIdentifier}:accessories:global.plan",
"name": "{projectName} Accessories Global",
"type": "PLAN",
"assortmentAtts": {
"typePath": "item:product:accessories",
"identifier": "{projectIdentifier}:apparel:global.assortment"
}
}
]
},
{
"name": "Equipment",
"identifier": "{projectIdentifier}:equipment.folder",
"assortments": [
{
"identifier": "{projectIdentifier}:equipment:global.plan",
"name": "{projectName} Equipment Global",
"type": "PLAN",
"assortmentAtts": {
"typePath": "item:product:equipment",
"identifier": "{projectIdentifier}:equipment:global.assortment"
}
}
]
},
{
"name": "Footwear",
"identifier": "{projectIdentifier}:footwear.folder",
"assortments": [
{
"identifier": "{projectIdentifier}:footwear:global.plan",
"name": "{projectName} Footwear Global",
"type": "PLAN",
"assortmentAtts": {
"typePath": "item:product:footwear",
"identifier": "{projectIdentifier}:footwear:global.assortment"
}
}
]
}
]
}'
The expected body of the POST is the ProjectConfiguration shape described above.
CLI Usage¶
The CLI has one command to load/update a project:
contrail projects load <File Paths>
This YAML file is used to set up the configuration for loading projects.
projectConfiguration:
projectName: "{projectName}"
identifier: "{projectIdentifier}"
commonConfig:
projectIdentifier: PROJECT_IDENTIFIER
projectName: PROJECT_NAME
subFolders:
- name: Apparel
identifier: "{projectIdentifier}:apparel.folder"
assortments:
- identifier: "{projectIdentifier}:apparel:global.plan"
name: "{projectName} Apparel Global"
type: PLAN
assortmentAtts:
typePath: item:product:apparel
identifier: "{projectIdentifier}:apparel:global.assortment"
- name: Accessories
identifier: "{projectIdentifier}:accessories.folder"
assortments:
- identifier: "{projectIdentifier}:accessories:global.plan"
name: "{projectName} Accessories Global"
type: PLAN
assortmentAtts:
typePath: item:product:accessories
identifier: "{projectIdentifier}:apparel:global.assortment"
- name: Equipment
identifier: "{projectIdentifier}:equipment.folder"
assortments:
- identifier: "{projectIdentifier}:equipment:global.plan"
name: "{projectName} Equipment Global"
type: PLAN
assortmentAtts:
typePath: item:product:equipment
identifier: "{projectIdentifier}:equipment:global.assortment"
- name: Footwear
identifier: "{projectIdentifier}:footwear.folder"
assortments:
- identifier: "{projectIdentifier}:footwear:global.plan"
name: "{projectName} Footwear Global"
type: PLAN
assortmentAtts:
typePath: item:product:footwear
identifier: "{projectIdentifier}:footwear:global.assortment"