Inherit relations from child to parents
When two Stories are connected, connect their Features
{
"pipeline": [
{
"type": "source:targetprocess:EntityChanged",
"entityTypes": [
"Relation"
],
"modifications": {
"created": true,
"deleted": false,
"updated": false
}
},
{
"or": [
{
"and": [
{
"value": {
"type": "constant",
"value": "UserStory"
},
"target": {
"name": "Name",
"type": "field",
"target": {
"name": "EntityType",
"type": "field",
"target": {
"name": "Inbound",
"type": "field",
"target": {
"type": "pipelineBlockOutput"
}
}
}
},
"operator": {
"type": "is"
}
},
{
"value": {
"type": "constant",
"value": "UserStory"
},
"target": {
"name": "Name",
"type": "field",
"target": {
"name": "EntityType",
"type": "field",
"target": {
"name": "Outbound",
"type": "field",
"target": {
"type": "pipelineBlockOutput"
}
}
}
},
"operator": {
"type": "is"
}
},
{
"value": null,
"target": {
"name": "Feature",
"type": "field",
"target": {
"name": "Inbound",
"type": "field",
"target": {
"type": "pipelineBlockOutput"
}
}
},
"operator": {
"type": "exists"
}
},
{
"value": null,
"target": {
"name": "Feature",
"type": "field",
"target": {
"name": "Outbound",
"type": "field",
"target": {
"type": "pipelineBlockOutput"
}
}
},
"operator": {
"type": "exists"
}
},
{
"value": {
"name": "Feature",
"type": "field",
"target": {
"name": "Outbound",
"type": "field",
"target": {
"type": "pipelineBlockOutput"
}
}
},
"target": {
"name": "Feature",
"type": "field",
"target": {
"name": "Inbound",
"type": "field",
"target": {
"type": "pipelineBlockOutput"
}
}
},
"operator": {
"type": "is not"
}
}
]
}
],
"type": "filter:Relational"
},
{
"type": "filter:JavaScript",
"script": "const api = context.getService(\"targetprocess/api/v2\");\nconst count = await api.queryAsync(\"Relation\", {\n result: \"count\",\n where: `SlaveFeature.UserStories.Count(Id=${args.Current.Outbound.Id}) > 0 and ` +\n `MasterFeature.UserStories.Count(Id=${args.Current.Inbound.Id}) > 0`\n});\n\nreturn count == 0;\n\n"
},
{
"type": "action:targetprocess:CreateEntity",
"fields": {
"Inbound": {
"name": "Id",
"type": "field",
"target": {
"name": "Feature",
"type": "field",
"target": {
"name": "Inbound",
"type": "field",
"target": {
"type": "pipelineBlockOutput"
}
}
}
},
"Outbound": {
"name": "Id",
"type": "field",
"target": {
"name": "Feature",
"type": "field",
"target": {
"name": "Outbound",
"type": "field",
"target": {
"type": "pipelineBlockOutput"
}
}
}
},
"RelationType": {
"name": "Id",
"type": "field",
"target": {
"name": "RelationType",
"type": "field",
"target": {
"type": "pipelineBlockOutput"
}
}
}
},
"entityType": {
"type": "constant",
"value": "Relation"
}
}
]
}
When Story is added to a Feature, connect this Feature to the Features of related Stories
[
{
"type": "source:targetprocess:EntityChanged",
"entityTypes": [
"UserStory"
],
"modifications": {
"created": true,
"deleted": false,
"updated": [
"Feature"
]
}
},
{
"or": [
{
"and": [
{
"value": null,
"target": {
"name": "Feature",
"type": "field",
"target": {
"type": "pipelineBlockOutput"
}
},
"operator": {
"type": "exists"
}
}
]
}
],
"type": "filter:Relational"
},
{
"type": "action:JavaScript",
"script": "const childType = args.ResourceType;\nconst parentType = \"Feature\";\nconst directions = [\"inbound\", \"outbound\"];\n\nconst leftRelation = { \"inbound\": \"master\", \"outbound\": \"slave\" };\nconst rigthRelation = { \"inbound\": \"slave\" , \"outbound\": \"master\" };\n\nconst api = context.getService(\"targetprocess/api/v2\");\nconst getRelations = function () {\n return directions.map(direction => {\n const left = leftRelation[direction];\n const rigth = rigthRelation[direction];\n return `${direction}:` +\n `${left}Relations.Where(${left}.EntityType.Name=\"${childType}\" and ${left}${childType}.${parentType} != null).` +\n `Select({${left}:${left}${childType}.${parentType}.Id,${rigth}:${rigth}${childType}.${parentType}.Id,type:RelationType.Id}),` +\n `${parentType}${direction}:` +\n `${parentType}.${left}Relations.Where(${left}.EntityType.Name=\"${parentType}\").` +\n `Select({${left}:${left}.Id,${rigth}:${rigth}.Id})`\n }).join(\",\");\n}\n\nconst children = await api.queryAsync(args.ResourceType, {\n select: `{${getRelations()}}`,\n where: \"id=\" + args.ResourceId\n});\nif (!children || !children.length) { return; }\nconst child = children[0];\nconsole.log(JSON.stringify(child));\n\nconst commands = [];\nfor (let direction of directions) {\n for (let relation of child[direction]) {\n const left = leftRelation[direction];\n const rigth = rigthRelation[direction];\n let search = child[parentType + direction].filter(r => {\n return r[left] === relation[left] && r[rigth] === relation[rigth];;\n });\n if (!search || !search.length) {\n child[parentType + direction].push({\n [left]: relation[left],\n [rigth]: relation[rigth]\n });\n commands.push({\n command: \"targetprocess:CreateResource\",\n payload: {\n resourceType: \"Relation\",\n fields: {\n [left]: { Id: relation[left] },\n [rigth]: { Id: relation[rigth] },\n RelationType: { Id: relation.type }\n }\n }\n });\n }\n }\n}\nreturn commands;"
}
]
Updated over 2 years ago