@cyberismo/assets 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +702 -0
- package/README.md +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +612 -0
- package/dist/schemas.d.ts +1132 -0
- package/dist/static/defaultReport/.schema +7 -0
- package/dist/static/defaultReport/index.adoc.hbs +3 -0
- package/dist/static/defaultReport/parameterSchema.json +18 -0
- package/dist/static/defaultReport/query.lp.hbs +2 -0
- package/package.json +30 -0
- package/src/calculations/common/base.lp +71 -0
- package/src/calculations/common/queryLanguage.lp +418 -0
- package/src/calculations/queries/card.lp +129 -0
- package/src/calculations/queries/onCreation.lp +44 -0
- package/src/calculations/queries/onTransition.lp +26 -0
- package/src/calculations/queries/tree.lp +6 -0
- package/src/calculations/test/model.lp +9 -0
- package/src/declarations.d.ts +9 -0
- package/src/graphvizReport/index.adoc.hbs +34 -0
- package/src/graphvizReport/query.lp.hbs +141 -0
- package/src/index.ts +52 -0
- package/src/schema/cardBaseSchema.json +76 -0
- package/src/schema/cardTreeDirectorySchema.json +663 -0
- package/src/schema/cardsConfigSchema.json +49 -0
- package/src/schema/csvSchema.json +30 -0
- package/src/schema/dotSchema.json +25 -0
- package/src/schema/macros/createCardsMacroSchema.json +39 -0
- package/src/schema/macros/graphMacroBaseSchema.json +17 -0
- package/src/schema/macros/reportMacroBaseSchema.json +13 -0
- package/src/schema/macros/scoreCardMacroSchema.json +24 -0
- package/src/schema/resources/cardTypeSchema.json +65 -0
- package/src/schema/resources/fieldTypeSchema.json +47 -0
- package/src/schema/resources/graphModelSchema.json +28 -0
- package/src/schema/resources/graphViewSchema.json +28 -0
- package/src/schema/resources/linkTypeSchema.json +56 -0
- package/src/schema/resources/reportSchema.json +28 -0
- package/src/schema/resources/templateSchema.json +28 -0
- package/src/schema/resources/workflowSchema.json +75 -0
- package/src/schema/schema.json +166 -0
- package/src/schemas.ts +54 -0
- package/src/static/defaultReport/.schema +7 -0
- package/src/static/defaultReport/index.adoc.hbs +3 -0
- package/src/static/defaultReport/parameterSchema.json +18 -0
- package/src/static/defaultReport/query.lp.hbs +2 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{{#each cardKeys}}
|
|
2
|
+
createdCard({{this}}).
|
|
3
|
+
{{/each}}
|
|
4
|
+
|
|
5
|
+
updateField(Card, CreateTransition, AffectedCard, Field, NewValue) :-
|
|
6
|
+
createdCard(Card),
|
|
7
|
+
onTransitionSetField(Card, CreateTransition, AffectedCard, Field, NewValue),
|
|
8
|
+
field(Card, "cardType", CardType),
|
|
9
|
+
field(CardType, "workflow", Workflow),
|
|
10
|
+
workflowTransition(Workflow, CreateTransition, "", _),
|
|
11
|
+
not editingFieldDenied(AffectedCard, Field, _).
|
|
12
|
+
|
|
13
|
+
executeTransition(Card, CreateTransition, AffectedCard, TransitionToExecute) :-
|
|
14
|
+
createdCard(Card),
|
|
15
|
+
onTransitionExecuteTransition(Card, CreateTransition, AffectedCard, TransitionToExecute),
|
|
16
|
+
field(Card, "cardType", CardType),
|
|
17
|
+
field(CardType, "workflow", Workflow),
|
|
18
|
+
workflowTransition(Workflow, CreateTransition, "", _),
|
|
19
|
+
not transitionDenied(AffectedCard, TransitionToExecute, _).
|
|
20
|
+
|
|
21
|
+
selectAll.
|
|
22
|
+
|
|
23
|
+
result(transitionSideEffects).
|
|
24
|
+
|
|
25
|
+
childResult(transitionSideEffects, @concatenate("updateFields", Card, CreateTransition, AffectedCard, Field, NewValue), "updateFields") :-
|
|
26
|
+
updateField(Card, CreateTransition, AffectedCard, Field, NewValue).
|
|
27
|
+
|
|
28
|
+
field(@concatenate("updateFields", Card, CreateTransition, AffectedCard, Field, NewValue), "card", AffectedCard) :-
|
|
29
|
+
updateField(Card, CreateTransition, AffectedCard, Field, NewValue).
|
|
30
|
+
|
|
31
|
+
field(@concatenate("updateFields", Card, CreateTransition, AffectedCard, Field, NewValue), "field", Field) :-
|
|
32
|
+
updateField(Card, CreateTransition, AffectedCard, Field, NewValue).
|
|
33
|
+
|
|
34
|
+
field(@concatenate("updateFields", Card, CreateTransition, AffectedCard, Field, NewValue), "newValue", NewValue) :-
|
|
35
|
+
updateField(Card, CreateTransition, AffectedCard, Field, NewValue).
|
|
36
|
+
|
|
37
|
+
childResult(transitionSideEffects, @concatenate("executeTransition", Card, CreateTransition, AffectedCard, TransitionToExecute), "executeTransition") :-
|
|
38
|
+
executeTransition(Card, CreateTransition, AffectedCard, TransitionToExecute).
|
|
39
|
+
|
|
40
|
+
field(@concatenate("executeTransition", Card, CreateTransition, AffectedCard, TransitionToExecute), "card", AffectedCard) :-
|
|
41
|
+
executeTransition(Card, CreateTransition, AffectedCard, TransitionToExecute).
|
|
42
|
+
|
|
43
|
+
field(@concatenate("executeTransition", Card, CreateTransition, AffectedCard, TransitionToExecute), "transitionToExecute", TransitionToExecute) :-
|
|
44
|
+
executeTransition(Card, CreateTransition, AffectedCard, TransitionToExecute).
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
selectAll.
|
|
2
|
+
|
|
3
|
+
result(transitionSideEffects).
|
|
4
|
+
|
|
5
|
+
childResult(transitionSideEffects, @concatenate("updateFields", {{cardKey}}, "{{transition}}", AffectedCard, Field, NewValue), "updateFields") :-
|
|
6
|
+
onTransitionSetField({{cardKey}}, "{{transition}}", AffectedCard, Field, NewValue),
|
|
7
|
+
not editingFieldDenied(AffectedCard, Field, _).
|
|
8
|
+
|
|
9
|
+
field(@concatenate("updateFields", {{cardKey}}, "{{transition}}", AffectedCard, Field, NewValue), "card", AffectedCard) :-
|
|
10
|
+
onTransitionSetField({{cardKey}}, "{{transition}}", AffectedCard, Field, NewValue).
|
|
11
|
+
|
|
12
|
+
field(@concatenate("updateFields", {{cardKey}}, "{{transition}}", AffectedCard, Field, NewValue), "field", Field) :-
|
|
13
|
+
onTransitionSetField({{cardKey}}, "{{transition}}", AffectedCard, Field, NewValue).
|
|
14
|
+
|
|
15
|
+
field(@concatenate("updateFields", {{cardKey}}, "{{transition}}", AffectedCard, Field, NewValue), "newValue", NewValue) :-
|
|
16
|
+
onTransitionSetField({{cardKey}}, "{{transition}}", AffectedCard, Field, NewValue).
|
|
17
|
+
|
|
18
|
+
childResult(transitionSideEffects, @concatenate("executeTransition", {{cardKey}}, "{{transition}}", AffectedCard, TransitionToExecute), "executeTransition") :-
|
|
19
|
+
onTransitionExecuteTransition({{cardKey}}, "{{transition}}", AffectedCard, TransitionToExecute),
|
|
20
|
+
not transitionDenied(AffectedCard, TransitionToExecute, _).
|
|
21
|
+
|
|
22
|
+
field(@concatenate("executeTransition", {{cardKey}}, "{{transition}}", AffectedCard, TransitionToExecute), "card", AffectedCard) :-
|
|
23
|
+
onTransitionExecuteTransition({{cardKey}}, "{{transition}}", AffectedCard, TransitionToExecute).
|
|
24
|
+
|
|
25
|
+
field(@concatenate("executeTransition", {{cardKey}}, "{{transition}}", AffectedCard, TransitionToExecute), "transitionToExecute", TransitionToExecute) :-
|
|
26
|
+
onTransitionExecuteTransition({{cardKey}}, "{{transition}}", AffectedCard, TransitionToExecute).
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
select("title";"statusIndicator";"progress";"rank";"cardType").
|
|
2
|
+
result(Card) :- card(Card), not parent(Card, _), not hiddenInTreeView(Card).
|
|
3
|
+
childResult(Parent, Card, "children") :- card(Card), parent(Card, Parent), not hiddenInTreeView(Card).
|
|
4
|
+
order(Level, "children", 1, "rank", "ASC") :-
|
|
5
|
+
level(Level).
|
|
6
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{{#*inline "subgraph"}}
|
|
2
|
+
subgraph cluster_{{this.key}} {
|
|
3
|
+
graph [{{#each attrs}}{{this.attr}}={{{formatAttributeValue this.value}}} {{/each}}]
|
|
4
|
+
{{#each edges}}
|
|
5
|
+
"{{this.[source]}}" -> "{{this.destination}}" [{{#each attrs}}{{this.attr}}={{{formatAttributeValue this.value}}} {{/each}}]
|
|
6
|
+
{{/each}}
|
|
7
|
+
{{#each children}}
|
|
8
|
+
{{#if this.isNode}}
|
|
9
|
+
"{{this.cardKey}}" [{{#each attrs}}{{this.attr}}={{{formatAttributeValue this.value}}} {{/each}}]
|
|
10
|
+
{{/if}}
|
|
11
|
+
{{#if this.isGraph}}
|
|
12
|
+
{{> subgraph}}
|
|
13
|
+
{{/if}}
|
|
14
|
+
{{/each}}
|
|
15
|
+
}
|
|
16
|
+
{{/inline}}
|
|
17
|
+
{{#each results}}
|
|
18
|
+
{{#each digraphs}}
|
|
19
|
+
digraph {{this.key}} {
|
|
20
|
+
graph [{{#each attrs}}{{this.attr}}={{{formatAttributeValue this.value}}} {{/each}}]
|
|
21
|
+
{{#each edges}}
|
|
22
|
+
"{{this.[source]}}" -> "{{this.destination}}" [{{#each attrs}}{{this.attr}}={{{formatAttributeValue this.value}}} {{/each}}]
|
|
23
|
+
{{/each}}
|
|
24
|
+
{{#each children}}
|
|
25
|
+
{{#if this.isNode}}
|
|
26
|
+
"{{this.cardKey}}" [{{#each attrs}}{{this.attr}}={{{formatAttributeValue this.value}}} {{/each}}]
|
|
27
|
+
{{/if}}
|
|
28
|
+
{{#if this.isGraph}}
|
|
29
|
+
{{> subgraph}}
|
|
30
|
+
{{/if}}
|
|
31
|
+
{{/each}}
|
|
32
|
+
}
|
|
33
|
+
{{/each}}
|
|
34
|
+
{{/each}}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
% model
|
|
2
|
+
% note: not escaped
|
|
3
|
+
{{{model}}}
|
|
4
|
+
|
|
5
|
+
% include the view:
|
|
6
|
+
{{{view}}}
|
|
7
|
+
|
|
8
|
+
selectAll.
|
|
9
|
+
|
|
10
|
+
result(result).
|
|
11
|
+
|
|
12
|
+
% We need to format the label attributes without double quotes,
|
|
13
|
+
% because labels already use HTML < and >, but we'll enclose other
|
|
14
|
+
% attributes in double quotes, so here is a helper term to identify label attributes:
|
|
15
|
+
labelAttribute("label").
|
|
16
|
+
labelAttribute(label).
|
|
17
|
+
|
|
18
|
+
% top-level graph
|
|
19
|
+
childResult(result, Graph, "digraphs") :-
|
|
20
|
+
graph(Graph).
|
|
21
|
+
|
|
22
|
+
childResult(Graph, ((graph, Graph), Field), "attrs") :-
|
|
23
|
+
graph(Graph),
|
|
24
|
+
attr(graph, Graph, Field, _).
|
|
25
|
+
|
|
26
|
+
field(((graph, Graph), Field), "attr", Field) :-
|
|
27
|
+
graph(Graph),
|
|
28
|
+
attr(graph, Graph, Field, _).
|
|
29
|
+
|
|
30
|
+
field(((graph, Graph), Field), "value", Value) :-
|
|
31
|
+
graph(Graph),
|
|
32
|
+
attr(graph, Graph, Field, Value),
|
|
33
|
+
labelAttribute(Field).
|
|
34
|
+
|
|
35
|
+
field(((graph, Graph), Field), "value", Value) :-
|
|
36
|
+
graph(Graph),
|
|
37
|
+
attr(graph, Graph, Field, Value),
|
|
38
|
+
not labelAttribute(Field).
|
|
39
|
+
|
|
40
|
+
% subgraphs
|
|
41
|
+
childResult(Parent, Graph, "children") :-
|
|
42
|
+
graph(Graph, Parent).
|
|
43
|
+
|
|
44
|
+
field(Graph, "isGraph", "void") :-
|
|
45
|
+
childResult(_, Graph, "children"),
|
|
46
|
+
graph(Graph, _).
|
|
47
|
+
|
|
48
|
+
childResult(Graph, ((graph, Graph), Field), "attrs") :-
|
|
49
|
+
graph(Graph, _),
|
|
50
|
+
attr(graph, Graph, Field, _).
|
|
51
|
+
|
|
52
|
+
field(((graph, Graph), Field), "attr", Field) :-
|
|
53
|
+
graph(Graph, _),
|
|
54
|
+
attr(graph, Graph, Field, _).
|
|
55
|
+
|
|
56
|
+
field(((graph, Graph), Field), "value", Value) :-
|
|
57
|
+
graph(Graph, _),
|
|
58
|
+
attr(graph, Graph, Field, Value),
|
|
59
|
+
labelAttribute(Field).
|
|
60
|
+
|
|
61
|
+
field(((graph, Graph), Field), "value", Value) :-
|
|
62
|
+
graph(Graph, _),
|
|
63
|
+
attr(graph, Graph, Field, Value),
|
|
64
|
+
not labelAttribute(Field).
|
|
65
|
+
|
|
66
|
+
% nodes
|
|
67
|
+
|
|
68
|
+
% TODO: For some reason, we need to use (node, Node) instead of Node, or
|
|
69
|
+
% the solving will not succeed
|
|
70
|
+
|
|
71
|
+
field((node, Node), "rank", Rank) :- field(Node, "rank", Rank), node(Node, _).
|
|
72
|
+
|
|
73
|
+
field((node, Node), "isNode", "void") :-
|
|
74
|
+
childResult(_, (node, Node), "children"),
|
|
75
|
+
node(Node, _).
|
|
76
|
+
|
|
77
|
+
childResult(Graph, (node, Node), "children") :-
|
|
78
|
+
childResult(_, Graph, _),
|
|
79
|
+
node(Node, Graph).
|
|
80
|
+
|
|
81
|
+
field((node, Node), "cardKey", Node) :-
|
|
82
|
+
childResult(_, Graph, _),
|
|
83
|
+
node(Node, Graph).
|
|
84
|
+
|
|
85
|
+
childResult((node, Node), ((node, Node), Field), "attrs") :-
|
|
86
|
+
node(Node, Graph),
|
|
87
|
+
attr(node, Node, Field, _).
|
|
88
|
+
|
|
89
|
+
field(((node, Node), Field), "attr", Field) :-
|
|
90
|
+
node(Node, Graph),
|
|
91
|
+
attr(node, Node, Field, _).
|
|
92
|
+
|
|
93
|
+
field(((node, Node), Field), "value", Value) :-
|
|
94
|
+
node(Node, Graph),
|
|
95
|
+
attr(node, Node, Field, Value),
|
|
96
|
+
labelAttribute(Field).
|
|
97
|
+
|
|
98
|
+
field(((node, Node), Field), "value", Value) :-
|
|
99
|
+
node(Node, Graph),
|
|
100
|
+
attr(node, Node, Field, Value),
|
|
101
|
+
not labelAttribute(Field).
|
|
102
|
+
|
|
103
|
+
graph(default) :-
|
|
104
|
+
node(_).
|
|
105
|
+
|
|
106
|
+
graph(default) :-
|
|
107
|
+
edge(_).
|
|
108
|
+
|
|
109
|
+
node(X, default) :-
|
|
110
|
+
node(X).
|
|
111
|
+
|
|
112
|
+
edge((XR, YR), default) :-
|
|
113
|
+
edge((XR, YR)).
|
|
114
|
+
|
|
115
|
+
edge((XR, YR, ""), Graph) :-
|
|
116
|
+
edge((XR, YR), Graph).
|
|
117
|
+
|
|
118
|
+
% edges
|
|
119
|
+
childResult(Graph, (edge, (XR, YR, Description)), "edges") :-
|
|
120
|
+
childResult(_, Graph, _),
|
|
121
|
+
edge((XR, YR, Description), Graph).
|
|
122
|
+
|
|
123
|
+
childResult((edge, (XR, YR, Description)), ((edge, (XR, YR, Description)), Field), "attrs") :-
|
|
124
|
+
childResult(_, (edge, (XR, YR, Description)), _),
|
|
125
|
+
attr(edge, (XR, YR, Description), Field, _).
|
|
126
|
+
|
|
127
|
+
field(((edge, (XR, YR, Description)), Field), "attr", Field) :-
|
|
128
|
+
childResult(_, (edge, (XR, YR, Description)), _),
|
|
129
|
+
attr(edge, (XR, YR, Description), Field, Value).
|
|
130
|
+
|
|
131
|
+
field(((edge, (XR, YR, Description)), Field), "value", Value) :-
|
|
132
|
+
childResult(_, (edge, (XR, YR, Description)), _),
|
|
133
|
+
attr(edge, (XR, YR, Description), Field, Value).
|
|
134
|
+
|
|
135
|
+
field((edge, (XR, YR, Description)), "source", XR) :-
|
|
136
|
+
edge((XR, YR, Description), _).
|
|
137
|
+
|
|
138
|
+
field((edge, (XR, YR, Description)), "destination", YR) :-
|
|
139
|
+
edge((XR, YR, Description), _).
|
|
140
|
+
|
|
141
|
+
order(N, Collection, 1, "rank", "ASC") :- resultLevel(_, N, Collection).
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export * from './schemas.js';
|
|
2
|
+
|
|
3
|
+
// Manually import each resource
|
|
4
|
+
// They rarely change and we get 100% type safety this way
|
|
5
|
+
import commonBase from './calculations/common/base.lp';
|
|
6
|
+
import commonQueryLanguage from './calculations/common/queryLanguage.lp';
|
|
7
|
+
import queriesCard from './calculations/queries/card.lp';
|
|
8
|
+
import queriesOnCreation from './calculations/queries/onCreation.lp';
|
|
9
|
+
import queriesOnTransition from './calculations/queries/onTransition.lp';
|
|
10
|
+
import queriesTree from './calculations/queries/tree.lp';
|
|
11
|
+
import testModel from './calculations/test/model.lp';
|
|
12
|
+
|
|
13
|
+
import graphvizReportQuery from './graphvizReport/query.lp.hbs';
|
|
14
|
+
import graphvizReportIndex from './graphvizReport/index.adoc.hbs';
|
|
15
|
+
|
|
16
|
+
export const graphvizReport = {
|
|
17
|
+
query: graphvizReportQuery,
|
|
18
|
+
content: graphvizReportIndex,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const lpFiles = {
|
|
22
|
+
common: {
|
|
23
|
+
base: commonBase,
|
|
24
|
+
queryLanguage: commonQueryLanguage,
|
|
25
|
+
},
|
|
26
|
+
queries: {
|
|
27
|
+
card: queriesCard,
|
|
28
|
+
onCreation: queriesOnCreation,
|
|
29
|
+
onTransition: queriesOnTransition,
|
|
30
|
+
tree: queriesTree,
|
|
31
|
+
},
|
|
32
|
+
test: {
|
|
33
|
+
model: testModel,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// Helper function to get the absolute path to the static directory
|
|
38
|
+
export async function getStaticDirectoryPath(): Promise<string> {
|
|
39
|
+
// Return early if not running in Node.js
|
|
40
|
+
if (typeof process === 'undefined' || !process.versions?.node) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
'@cyberismo/assets: getStaticDirectoryPath can only be called in Node.js',
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
const { join } = await import('node:path');
|
|
46
|
+
|
|
47
|
+
// Get the directory of the current module
|
|
48
|
+
const currentModuleDir = import.meta.dirname;
|
|
49
|
+
|
|
50
|
+
// Look for static directory in the package
|
|
51
|
+
return join(currentModuleDir, 'static');
|
|
52
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Card",
|
|
3
|
+
"$id": "cardBaseSchema",
|
|
4
|
+
"description": "Cards represent different types of tickets, issues and documents. All cards must be valid against this parent schema.",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": true,
|
|
7
|
+
"properties": {
|
|
8
|
+
"cardType": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"minLength": 1,
|
|
11
|
+
"description": "The name of the card type",
|
|
12
|
+
"pattern": "^[A-Za-z]*/?[A-Za-z]*/?[A-Za-z-_]+$"
|
|
13
|
+
},
|
|
14
|
+
"title": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"minLength": 1,
|
|
17
|
+
"description": "A short title of the card"
|
|
18
|
+
},
|
|
19
|
+
"workflowState": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"description": "the name of the card's current state in the workflow"
|
|
22
|
+
},
|
|
23
|
+
"rank": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"description": "The rank of the card in relative to its siblings"
|
|
26
|
+
},
|
|
27
|
+
"lastTransitioned": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"format": "date-time",
|
|
30
|
+
"description": "The date and time of the last transition of the card"
|
|
31
|
+
},
|
|
32
|
+
"lastUpdated": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"format": "date-time",
|
|
35
|
+
"description": "The date and time of the last update of the card"
|
|
36
|
+
},
|
|
37
|
+
"labels": {
|
|
38
|
+
"type": "array",
|
|
39
|
+
"description": "Labels or tags that can be used for organising cards",
|
|
40
|
+
"items": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"minLength": 1
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"links": {
|
|
46
|
+
"type": "array",
|
|
47
|
+
"description": "links to or from this card to other cards",
|
|
48
|
+
"items": {
|
|
49
|
+
"type": "object",
|
|
50
|
+
"properties": {
|
|
51
|
+
"cardKey": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"minLength": 3,
|
|
54
|
+
"maxLength": 20,
|
|
55
|
+
"pattern": "^[a-z]+_[0-9a-z]+$"
|
|
56
|
+
},
|
|
57
|
+
"linkType": {
|
|
58
|
+
"description": "The name of the link type. For example, 'base/linkTypes/causes'",
|
|
59
|
+
"type": "string"
|
|
60
|
+
},
|
|
61
|
+
"linkDescription": {
|
|
62
|
+
"type": "string",
|
|
63
|
+
"description": "A description of the link"
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"required": ["cardKey", "linkType"],
|
|
67
|
+
"additionalProperties": false
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"templateCardKey": {
|
|
71
|
+
"type": "string",
|
|
72
|
+
"description": "Card key from which this card has been instantiated"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"required": ["title", "cardType", "workflowState", "rank"]
|
|
76
|
+
}
|