Skip to content

Commit f9ecb0f

Browse files
authored
Merge pull request #302 from nyaruka/flow_revision
Flow revision number
2 parents 236c15b + 9db4aa8 commit f9ecb0f

File tree

9 files changed

+29
-14
lines changed

9 files changed

+29
-14
lines changed

docs/docs.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ properties which can be accessed:
254254
255255
* `uuid` the UUID of the flow
256256
* `name` the name of the flow
257+
* `revision` the revision number of the flow
257258
258259
Examples:
259260
@@ -262,7 +263,7 @@ Examples:
262263
@run.flow → Registration
263264
@child.flow → Collect Age
264265
@run.flow.uuid → 50c3706e-fedb-42c0-8eab-dda3335714b7
265-
@(json(run.flow)) → {"name":"Registration","uuid":"50c3706e-fedb-42c0-8eab-dda3335714b7"}
266+
@(json(run.flow)) → {"name":"Registration","revision":123,"uuid":"50c3706e-fedb-42c0-8eab-dda3335714b7"}
266267
```
267268

268269
<a name="context:group"></a>

docs/index.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,12 +363,13 @@ <h2 id="flow">Flow</h2>
363363
<ul>
364364
<li><code>uuid</code> the UUID of the flow</li>
365365
<li><code>name</code> the name of the flow</li>
366+
<li><code>revision</code> the revision number of the flow</li>
366367
</ul>
367368
<p>Examples:</p>
368369
<div class="sourceCode" id="cb10"><pre class="sourceCode objectivec"><code class="sourceCode objectivec"><a class="sourceLine" id="cb10-1" data-line-number="1">@run.flow → Registration</a>
369370
<a class="sourceLine" id="cb10-2" data-line-number="2">@child.flow → Collect Age</a>
370371
<a class="sourceLine" id="cb10-3" data-line-number="3">@run.flow.uuid → 50c3706e-fedb-42c0-8eab-dda3335714b7</a>
371-
<a class="sourceLine" id="cb10-4" data-line-number="4">@(json(run.flow)) → {<span class="st">&quot;name&quot;</span>:<span class="st">&quot;Registration&quot;</span>,<span class="st">&quot;uuid&quot;</span>:<span class="st">&quot;50c3706e-fedb-42c0-8eab-dda3335714b7&quot;</span>}</a></code></pre></div>
372+
<a class="sourceLine" id="cb10-4" data-line-number="4">@(json(run.flow)) → {<span class="st">&quot;name&quot;</span>:<span class="st">&quot;Registration&quot;</span>,<span class="st">&quot;revision&quot;</span>:<span class="dv">123</span>,<span class="st">&quot;uuid&quot;</span>:<span class="st">&quot;50c3706e-fedb-42c0-8eab-dda3335714b7&quot;</span>}</a></code></pre></div>
372373
<p><a name="context:group"></a></p>
373374
<h2 id="group">Group</h2>
374375
<p>Represents a grouping of contacts. It can be static (contacts are added and removed manually through <a href="#action:add_contact_groups">actions</a>) or dynamic (contacts are added automatically by a query). It renders as its name in a template, and has the following properties which can be accessed:</p>

flows/definition/flow.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
type flow struct {
1313
uuid flows.FlowUUID
1414
name string
15+
revision int
1516
language utils.Language
1617
expireAfterMinutes int
1718

@@ -26,10 +27,11 @@ type flow struct {
2627

2728
type FlowObj = flow
2829

29-
func NewFlow(uuid flows.FlowUUID, name string, language utils.Language, expireAfterMinutes int, localization flows.Localization, nodes []flows.Node, ui map[string]interface{}) (flows.Flow, error) {
30+
func NewFlow(uuid flows.FlowUUID, name string, revision int, language utils.Language, expireAfterMinutes int, localization flows.Localization, nodes []flows.Node, ui map[string]interface{}) (flows.Flow, error) {
3031
f := &flow{
3132
uuid: uuid,
3233
name: name,
34+
revision: revision,
3335
language: language,
3436
expireAfterMinutes: expireAfterMinutes,
3537
localization: localization,
@@ -63,6 +65,7 @@ func NewFlow(uuid flows.FlowUUID, name string, language utils.Language, expireAf
6365

6466
func (f *flow) UUID() flows.FlowUUID { return f.uuid }
6567
func (f *flow) Name() string { return f.name }
68+
func (f *flow) Revision() int { return f.revision }
6669
func (f *flow) Language() utils.Language { return f.language }
6770
func (f *flow) ExpireAfterMinutes() int { return f.expireAfterMinutes }
6871
func (f *flow) Nodes() []flows.Node { return f.nodes }
@@ -107,6 +110,8 @@ func (f *flow) Resolve(env utils.Environment, key string) types.XValue {
107110
return types.NewXText(string(f.UUID()))
108111
case "name":
109112
return types.NewXText(f.name)
113+
case "revision":
114+
return types.NewXNumberFromInt(f.revision)
110115
}
111116

112117
return types.NewXResolveError(f, key)
@@ -122,7 +127,7 @@ func (f *flow) Reduce(env utils.Environment) types.XPrimitive {
122127

123128
// ToXJSON is called when this type is passed to @(json(...))
124129
func (f *flow) ToXJSON(env utils.Environment) types.XText {
125-
return types.ResolveKeys(env, f, "uuid", "name").ToXJSON(env)
130+
return types.ResolveKeys(env, f, "uuid", "name", "revision").ToXJSON(env)
126131
}
127132

128133
var _ flows.Flow = (*flow)(nil)
@@ -151,6 +156,7 @@ func (f *flow) buildNodeMap() error {
151156
type flowEnvelope struct {
152157
UUID flows.FlowUUID `json:"uuid" validate:"required,uuid4"`
153158
Name string `json:"name" validate:"required"`
159+
Revision int `json:"revision"`
154160
Language utils.Language `json:"language"`
155161
ExpireAfterMinutes int `json:"expire_after_minutes"`
156162
Localization localization `json:"localization"`
@@ -173,7 +179,7 @@ func ReadFlow(data json.RawMessage) (flows.Flow, error) {
173179
nodes[n] = envelope.Nodes[n]
174180
}
175181

176-
return NewFlow(envelope.UUID, envelope.Name, envelope.Language, envelope.ExpireAfterMinutes, envelope.Localization, nodes, nil)
182+
return NewFlow(envelope.UUID, envelope.Name, envelope.Revision, envelope.Language, envelope.ExpireAfterMinutes, envelope.Localization, nodes, nil)
177183
}
178184

179185
// MarshalJSON marshals this flow into JSON
@@ -182,6 +188,7 @@ func (f *flow) MarshalJSON() ([]byte, error) {
182188
flowEnvelope: flowEnvelope{
183189
UUID: f.uuid,
184190
Name: f.name,
191+
Revision: f.revision,
185192
Language: f.language,
186193
ExpireAfterMinutes: f.expireAfterMinutes,
187194
},

flows/interfaces.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,14 @@ type SessionAssets interface {
136136
//
137137
// * `uuid` the UUID of the flow
138138
// * `name` the name of the flow
139+
// * `revision` the revision number of the flow
139140
//
140141
// Examples:
141142
//
142143
// @run.flow -> Registration
143144
// @child.flow -> Collect Age
144145
// @run.flow.uuid -> 50c3706e-fedb-42c0-8eab-dda3335714b7
145-
// @(json(run.flow)) -> {"name":"Registration","uuid":"50c3706e-fedb-42c0-8eab-dda3335714b7"}
146+
// @(json(run.flow)) -> {"name":"Registration","revision":123,"uuid":"50c3706e-fedb-42c0-8eab-dda3335714b7"}
146147
//
147148
// @context flow
148149
type Flow interface {
@@ -151,6 +152,7 @@ type Flow interface {
151152

152153
UUID() FlowUUID
153154
Name() string
155+
Revision() int
154156
Language() utils.Language
155157
ExpireAfterMinutes() int
156158
Localization() Localization

legacy/definition.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,9 @@ func (s *decimalString) UnmarshalJSON(data []byte) error {
3232
return nil
3333
}
3434

35-
// TODO need to match what we generate at https://github.com/nyaruka/rapidpro/blob/master/temba/api/models.py#L217
3635
var legacyWebhookBody = `{
3736
"contact": {"uuid": "@contact.uuid", "name": "@contact.name", "urn": @(json(if(default(run.input.urn, default(contact.urns.0, null)), text(default(run.input.urn, default(contact.urns.0, null))), null)))},
38-
"flow": {"uuid": "@run.flow.uuid", "name": "@run.flow.name"},
37+
"flow": @(json(run.flow)),
3938
"path": @(json(run.path)),
4039
"results": @(json(run.results)),
4140
"run": {"uuid": "@run.uuid", "created_on": "@run.created_on"},
@@ -75,10 +74,11 @@ func (n *Note) Migrate() Sticky {
7574

7675
// Metadata is the metadata section of a legacy flow
7776
type Metadata struct {
78-
UUID flows.FlowUUID `json:"uuid" validate:"required,uuid4"`
79-
Name string `json:"name"`
80-
Expires int `json:"expires"`
81-
Notes []Note `json:"notes,omitempty"`
77+
UUID flows.FlowUUID `json:"uuid" validate:"required,uuid4"`
78+
Name string `json:"name"`
79+
Revision int `json:"revision"`
80+
Expires int `json:"expires"`
81+
Notes []Note `json:"notes,omitempty"`
8282
}
8383

8484
type Rule struct {
@@ -1048,6 +1048,7 @@ func (f *Flow) Migrate(includeUI bool) (flows.Flow, error) {
10481048
return definition.NewFlow(
10491049
f.Metadata.UUID,
10501050
f.Metadata.Name,
1051+
f.Metadata.Revision,
10511052
f.BaseLanguage,
10521053
f.Metadata.Expires,
10531054
localization,

legacy/testdata/actions.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
"Content-Type": "application/json",
9292
"User-Agent": "rapidpro"
9393
},
94-
"body": "{\n\t\"contact\": {\"uuid\": \"@contact.uuid\", \"name\": \"@contact.name\", \"urn\": @(json(if(default(run.input.urn, default(contact.urns.0, null)), text(default(run.input.urn, default(contact.urns.0, null))), null)))},\n\t\"flow\": {\"uuid\": \"@run.flow.uuid\", \"name\": \"@run.flow.name\"},\n\t\"path\": @(json(run.path)),\n\t\"results\": @(json(run.results)),\n\t\"run\": {\"uuid\": \"@run.uuid\", \"created_on\": \"@run.created_on\"},\n\t\"input\": @(json(run.input)),\n\t\"channel\": @(json(if(run.input, run.input.channel, null)))\n}"
94+
"body": "{\n\t\"contact\": {\"uuid\": \"@contact.uuid\", \"name\": \"@contact.name\", \"urn\": @(json(if(default(run.input.urn, default(contact.urns.0, null)), text(default(run.input.urn, default(contact.urns.0, null))), null)))},\n\t\"flow\": @(json(run.flow)),\n\t\"path\": @(json(run.path)),\n\t\"results\": @(json(run.results)),\n\t\"run\": {\"uuid\": \"@run.uuid\", \"created_on\": \"@run.created_on\"},\n\t\"input\": @(json(run.input)),\n\t\"channel\": @(json(if(run.input, run.input.channel, null)))\n}"
9595
},
9696
"expected_localization": {}
9797
},

legacy/testdata/flows.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"metadata": {
55
"uuid": "76f0a02f-3b75-4b86-9064-e9195e1b3a02",
66
"name": "Simple",
7+
"revision": 123,
78
"notes": [
89
{
910
"y": 22.3435,
@@ -41,6 +42,7 @@
4142
"expected": {
4243
"uuid": "76f0a02f-3b75-4b86-9064-e9195e1b3a02",
4344
"name": "Simple",
45+
"revision": 123,
4446
"language": "eng",
4547
"expire_after_minutes": 0,
4648
"localization": {

legacy/testdata/rulesets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@
471471
"Content-Type": "application/json",
472472
"User-Agent": "RapidPro"
473473
},
474-
"body": "{\n\t\"contact\": {\"uuid\": \"@contact.uuid\", \"name\": \"@contact.name\", \"urn\": @(json(if(default(run.input.urn, default(contact.urns.0, null)), text(default(run.input.urn, default(contact.urns.0, null))), null)))},\n\t\"flow\": {\"uuid\": \"@run.flow.uuid\", \"name\": \"@run.flow.name\"},\n\t\"path\": @(json(run.path)),\n\t\"results\": @(json(run.results)),\n\t\"run\": {\"uuid\": \"@run.uuid\", \"created_on\": \"@run.created_on\"},\n\t\"input\": @(json(run.input)),\n\t\"channel\": @(json(if(run.input, run.input.channel, null)))\n}"
474+
"body": "{\n\t\"contact\": {\"uuid\": \"@contact.uuid\", \"name\": \"@contact.name\", \"urn\": @(json(if(default(run.input.urn, default(contact.urns.0, null)), text(default(run.input.urn, default(contact.urns.0, null))), null)))},\n\t\"flow\": @(json(run.flow)),\n\t\"path\": @(json(run.path)),\n\t\"results\": @(json(run.results)),\n\t\"run\": {\"uuid\": \"@run.uuid\", \"created_on\": \"@run.created_on\"},\n\t\"input\": @(json(run.input)),\n\t\"channel\": @(json(if(run.input, run.input.channel, null)))\n}"
475475
}
476476
],
477477
"router": {

test/session.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ var sessionAssets = `[
4848
"content": {
4949
"uuid": "50c3706e-fedb-42c0-8eab-dda3335714b7",
5050
"name": "Registration",
51+
"revision": 123,
5152
"nodes": [
5253
{
5354
"uuid": "72a1f5df-49f9-45df-94c9-d86f7ea064e5",

0 commit comments

Comments
 (0)