@case-framework/survey-assistant 0.7.0 → 0.8.0
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/README.md +58 -3
- package/dist/{attachments-B0hg3vpT.mjs → attachments-BuNni5vB.mjs} +1 -1
- package/dist/{attachments-B0hg3vpT.mjs.map → attachments-BuNni5vB.mjs.map} +1 -1
- package/dist/{authoring-references-BJQ_1nMX.mjs → authoring-references-DbuOKerg.mjs} +12 -3
- package/dist/authoring-references-DbuOKerg.mjs.map +1 -0
- package/dist/{capabilities-DVTfogjv.d.mts → capabilities-CmeeAjEc.d.mts} +3 -4
- package/dist/capabilities-CmeeAjEc.d.mts.map +1 -0
- package/dist/{capabilities-1KNnNO1_.mjs → capabilities-DCMA71PP.mjs} +4 -19
- package/dist/capabilities-DCMA71PP.mjs.map +1 -0
- package/dist/capabilities-default.d.mts +13 -12
- package/dist/capabilities-default.d.mts.map +1 -1
- package/dist/capabilities-default.mjs +2 -411
- package/dist/{constants-Be91Gay9.d.mts → constants-B6HzpEsx.d.mts} +7 -28
- package/dist/constants-B6HzpEsx.d.mts.map +1 -0
- package/dist/{constants-0UHGFcRJ.mjs → constants-Ct-vv9cu.mjs} +1 -1
- package/dist/{constants-0UHGFcRJ.mjs.map → constants-Ct-vv9cu.mjs.map} +1 -1
- package/dist/controller-proxy-D7uQfm5f.d.mts +65 -0
- package/dist/controller-proxy-D7uQfm5f.d.mts.map +1 -0
- package/dist/{controller-proxy-BH05e-C2.mjs → controller-proxy-DEeFl9IA.mjs} +10 -20
- package/dist/controller-proxy-DEeFl9IA.mjs.map +1 -0
- package/dist/default-fhSon2RM.mjs +760 -0
- package/dist/default-fhSon2RM.mjs.map +1 -0
- package/dist/{digest-SJmoYVaK.d.mts → digest-C39WyAWG.d.mts} +2 -3
- package/dist/digest-C39WyAWG.d.mts.map +1 -0
- package/dist/digest.d.mts +1 -1
- package/dist/digest.mjs.map +1 -1
- package/dist/{engine-Bo85Oyj0.mjs → engine-nXoCWYpQ.mjs} +755 -590
- package/dist/engine-nXoCWYpQ.mjs.map +1 -0
- package/dist/engine.d.mts +3 -3
- package/dist/engine.mjs +3 -3
- package/dist/{fair-guidance-CRYCRxQm.mjs → fair-guidance-BmO4PswW.mjs} +1 -1
- package/dist/{fair-guidance-CRYCRxQm.mjs.map → fair-guidance-BmO4PswW.mjs.map} +1 -1
- package/dist/{index-Tnqv-yKW.d.mts → index-Ciq7vHIs.d.mts} +80 -141
- package/dist/index-Ciq7vHIs.d.mts.map +1 -0
- package/dist/{index-nhrgbgO5.d.mts → index-D7wT6P3t.d.mts} +277 -60
- package/dist/index-D7wT6P3t.d.mts.map +1 -0
- package/dist/{index-l_EK4yK7.d.mts → index-WB5kfnz0.d.mts} +15 -71
- package/dist/index-WB5kfnz0.d.mts.map +1 -0
- package/dist/{index-x0qprHgK.d.mts → index-r5riv4md.d.mts} +33 -24
- package/dist/index-r5riv4md.d.mts.map +1 -0
- package/dist/{lifecycle-Bx0aq_4S.d.mts → lifecycle-Dm8u7QFh.d.mts} +34 -18
- package/dist/lifecycle-Dm8u7QFh.d.mts.map +1 -0
- package/dist/{memory-thread-repository-KWHQWFEW.mjs → memory-thread-repository-DAnOGIB3.mjs} +51 -27
- package/dist/memory-thread-repository-DAnOGIB3.mjs.map +1 -0
- package/dist/{protocol-BhzQbx81.mjs → protocol-CF4Bh_Ch.mjs} +118 -36
- package/dist/protocol-CF4Bh_Ch.mjs.map +1 -0
- package/dist/protocol.d.mts +4 -4
- package/dist/protocol.mjs +3 -3
- package/dist/{react-B3ybjJ-X.mjs → react-C_GY-Fsc.mjs} +146 -39
- package/dist/react-C_GY-Fsc.mjs.map +1 -0
- package/dist/react-integration.d.mts +2 -2
- package/dist/react-integration.mjs +2 -2
- package/dist/react.d.mts +3 -3
- package/dist/react.mjs +3 -3
- package/dist/references/assistant-operations.md +100 -31
- package/dist/references/core-rules.md +6 -3
- package/dist/references/embedded-forms.md +34 -14
- package/dist/references/expressions.md +220 -58
- package/dist/references/fair-by-design.md +9 -9
- package/dist/references/item-types.md +305 -71
- package/dist/references/response-variables.md +38 -0
- package/dist/references/source-material-surveys.md +4 -3
- package/dist/references/survey-data-model.md +23 -8
- package/dist/{request-context-CG4SWijt.mjs → request-context-Dg4jSwN1.mjs} +4 -10
- package/dist/request-context-Dg4jSwN1.mjs.map +1 -0
- package/dist/{request-guardrails-TmgQtqp4.mjs → request-guardrails-C0ugBOp0.mjs} +6 -5
- package/dist/request-guardrails-C0ugBOp0.mjs.map +1 -0
- package/dist/server-agent.d.mts +37 -39
- package/dist/server-agent.d.mts.map +1 -1
- package/dist/server-agent.mjs +45 -20
- package/dist/server-agent.mjs.map +1 -1
- package/dist/server-runtime.d.mts +23 -42
- package/dist/server-runtime.d.mts.map +1 -1
- package/dist/server-runtime.mjs +12 -12
- package/dist/server-runtime.mjs.map +1 -1
- package/dist/server-tasks.d.mts +2 -2
- package/dist/server-tasks.mjs +2 -313
- package/dist/server-tools.d.mts +1 -1
- package/dist/server-tools.mjs +1 -1
- package/dist/server.d.mts +13 -36
- package/dist/server.d.mts.map +1 -1
- package/dist/server.mjs +5 -5
- package/dist/server.mjs.map +1 -1
- package/dist/storage-postgres.d.mts +9 -25
- package/dist/storage-postgres.d.mts.map +1 -1
- package/dist/storage-postgres.mjs +5 -4
- package/dist/storage-postgres.mjs.map +1 -1
- package/dist/{tasks-CYqrcaRO.d.mts → tasks-B9h3LPam.d.mts} +18 -34
- package/dist/tasks-B9h3LPam.d.mts.map +1 -0
- package/dist/tasks-BZEiwgxA.mjs +396 -0
- package/dist/tasks-BZEiwgxA.mjs.map +1 -0
- package/dist/thread-documents-DrHbaXqP.d.mts +119 -0
- package/dist/thread-documents-DrHbaXqP.d.mts.map +1 -0
- package/dist/{thread-handlers-DBAaU7BA.d.mts → thread-handlers-Bef0td9N.d.mts} +8 -40
- package/dist/thread-handlers-Bef0td9N.d.mts.map +1 -0
- package/dist/{tools-BvSovehT.mjs → tools-CEsv-WoO.mjs} +296 -105
- package/dist/tools-CEsv-WoO.mjs.map +1 -0
- package/dist/ui.css +1 -1
- package/dist/ui.d.mts +15 -54
- package/dist/ui.d.mts.map +1 -1
- package/dist/ui.mjs +172 -137
- package/dist/ui.mjs.map +1 -1
- package/docs/integration.md +11 -1
- package/package.json +40 -35
- package/dist/authoring-references-BJQ_1nMX.mjs.map +0 -1
- package/dist/capabilities-1KNnNO1_.mjs.map +0 -1
- package/dist/capabilities-DVTfogjv.d.mts.map +0 -1
- package/dist/capabilities-default.mjs.map +0 -1
- package/dist/constants-Be91Gay9.d.mts.map +0 -1
- package/dist/controller-proxy-BH05e-C2.mjs.map +0 -1
- package/dist/controller-proxy-Bd0ZHBPF.d.mts +0 -85
- package/dist/controller-proxy-Bd0ZHBPF.d.mts.map +0 -1
- package/dist/digest-SJmoYVaK.d.mts.map +0 -1
- package/dist/engine-Bo85Oyj0.mjs.map +0 -1
- package/dist/index-Tnqv-yKW.d.mts.map +0 -1
- package/dist/index-l_EK4yK7.d.mts.map +0 -1
- package/dist/index-nhrgbgO5.d.mts.map +0 -1
- package/dist/index-x0qprHgK.d.mts.map +0 -1
- package/dist/lifecycle-Bx0aq_4S.d.mts.map +0 -1
- package/dist/memory-thread-repository-KWHQWFEW.mjs.map +0 -1
- package/dist/protocol-BhzQbx81.mjs.map +0 -1
- package/dist/react-B3ybjJ-X.mjs.map +0 -1
- package/dist/request-context-CG4SWijt.mjs.map +0 -1
- package/dist/request-guardrails-TmgQtqp4.mjs.map +0 -1
- package/dist/server-tasks.mjs.map +0 -1
- package/dist/tasks-CYqrcaRO.d.mts.map +0 -1
- package/dist/thread-documents-rmd6nyX9.d.mts +0 -107
- package/dist/thread-documents-rmd6nyX9.d.mts.map +0 -1
- package/dist/thread-handlers-DBAaU7BA.d.mts.map +0 -1
- package/dist/tools-BvSovehT.mjs.map +0 -1
|
@@ -14,7 +14,7 @@ Expression JSON has four node types:
|
|
|
14
14
|
|
|
15
15
|
```json
|
|
16
16
|
{ "type": "const", "value": { "type": "boolean", "value": true } }
|
|
17
|
-
{ "type": "responseVariable", "variableRef": "<
|
|
17
|
+
{ "type": "responseVariable", "variableRef": { "slotId": "<slotId>", "method": "get" } }
|
|
18
18
|
{ "type": "contextVariable", "contextType": "locale" }
|
|
19
19
|
{ "type": "function", "functionName": "and", "arguments": [] }
|
|
20
20
|
```
|
|
@@ -28,34 +28,38 @@ Response values are typed objects:
|
|
|
28
28
|
- string: `{ "type": "string", "value": "abc" }`
|
|
29
29
|
- number: `{ "type": "number", "value": 42 }`
|
|
30
30
|
- boolean: `{ "type": "boolean", "value": true }`
|
|
31
|
-
- date: `{ "type": "date", "value":
|
|
31
|
+
- date: `{ "type": "date", "value": "2026-01-01" }`
|
|
32
32
|
- duration: `{ "type": "duration", "value": 3, "unit": "days" }`
|
|
33
33
|
- reference: `{ "type": "reference", "value": "<optionId>" }`
|
|
34
34
|
- arrays use `string[]`, `number[]`, `date[]`, `duration[]`, `reference[]`.
|
|
35
35
|
|
|
36
|
-
Response variable refs
|
|
37
|
-
`<itemId>...<method>...<slotId>`
|
|
36
|
+
Response variable refs are structured objects: `{ "slotId": "<persistent-slot-id>", "method": "get" }`. There is no item ID, dotted path, variable name, or encoded string in a reference.
|
|
38
37
|
|
|
39
38
|
Methods:
|
|
40
39
|
|
|
41
|
-
- `get`: returns the current slot value.
|
|
42
|
-
- `isDefined`: returns boolean true when
|
|
40
|
+
- `get`: returns the current active slot value.
|
|
41
|
+
- `isDefined`: returns boolean true when an active response exists.
|
|
43
42
|
|
|
44
|
-
`isDefined` means only "
|
|
43
|
+
`isDefined` means only "this slot currently has an active answer." It never means a particular answer
|
|
45
44
|
such as Yes, selected, eligible, consented, or has children. When the user's condition names or
|
|
46
45
|
implies a choice, inspect the source choice item's exact option ids and labels, then compare the
|
|
47
46
|
`get` response with that option's reference using `eq` (single choice) or `list_contains`
|
|
48
47
|
(multiple choice). Do not substitute `isDefined` merely because the exact option id is not yet
|
|
49
48
|
known.
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
dependencies,
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
50
|
+
Visibility dependencies must be acyclic. The runtime rejects self-reference, mutual
|
|
51
|
+
question dependencies, parent groups controlled by their descendants, and cycles through
|
|
52
|
+
conditional components or computed scores. Prefills do not make these cycles valid.
|
|
53
|
+
Use an independent controlling answer or serialized custom context value. A component may
|
|
54
|
+
reference another slot in the same item only when its active value does not depend on that
|
|
55
|
+
component's visibility. Repair rejected changes using the returned retry linkage.
|
|
56
|
+
|
|
57
|
+
Hidden answers remain stored for the session and return when shown again, but are unavailable
|
|
58
|
+
to expressions, validation, scoring and submission while hidden. `get` returns undefined and
|
|
59
|
+
`isDefined` returns false for an inactive answer. This includes hidden groups, matrix rows,
|
|
60
|
+
form groups, hidden choice options and unselected embedded fields. Display conditions with
|
|
61
|
+
undefined or non-boolean results hide their target. Visibility cannot use `customExpression`
|
|
62
|
+
callbacks; supply serialized `customValue` context instead.
|
|
59
63
|
|
|
60
64
|
Never invent response refs. Use the current context response-slots scope or item details.
|
|
61
65
|
This rule is item-type independent: preserve every item id, slot id, component/validation key,
|
|
@@ -73,13 +77,12 @@ in its `create-item.item` object in one `survey_change` call. When a genuine dep
|
|
|
73
77
|
separate calls, inspect the updated request-scoped draft and use `survey_expression` against the
|
|
74
78
|
newly available ids and response slots.
|
|
75
79
|
|
|
76
|
-
Each response slot
|
|
77
|
-
`<sourceItemId>...get...<slotId>`, with a boolean presence check at
|
|
78
|
-
`<sourceItemId>...isDefined...<slotId>`. Use the slot's actual value type to choose the
|
|
80
|
+
Each declared response slot is available as `{ "slotId": "<slotId>", "method": "get" }`, with a presence check using the same slot ID and `method: "isDefined"`. Use the slot's actual value type to choose the
|
|
79
81
|
function and constant. For example, a single-choice `reference` slot uses `eq` with a
|
|
80
82
|
`reference` const; this is only one typed case, not a restriction on source item types.
|
|
81
83
|
Always check the response slot value type before choosing a function:
|
|
82
84
|
|
|
85
|
+
- Consent items return `boolean` in their persistent `config.slotId`; compare with `eq` and boolean `true` for agreement or `false` for refusal. Unanswered is neither. `isDefined` means either decision was recorded. Display conditions hide dependent content while retaining session answers; hidden items are omitted from submission.
|
|
83
86
|
- Single-choice choice items return `reference`; compare them with `eq` and a `reference` const.
|
|
84
87
|
- Multiple-choice choice items return `reference[]`; check selected options with `list_contains` and a `reference` const.
|
|
85
88
|
- `list_contains` must receive `string[]` + `string` or `reference[]` + `reference`. Never use it with a single `reference` response.
|
|
@@ -93,7 +96,26 @@ List containment: `list_contains`.
|
|
|
93
96
|
Equality/comparison: `eq`, `gt`, `gte`, `lt`, `lte`, `in_range`.
|
|
94
97
|
Numeric aggregation: `sum`, `min`, `max`.
|
|
95
98
|
String equality: `str_eq`.
|
|
96
|
-
|
|
99
|
+
Calendar dates use `YYYY`, `YYYY-MM`, or `YYYY-MM-DD`; numeric timestamps and date-time strings are invalid. Preserve the answer's precision.
|
|
100
|
+
|
|
101
|
+
Date comparisons: `date_eq`, `date_gt`, `date_gte`, `date_lt`, `date_lte` (two date arguments).
|
|
102
|
+
Equality includes precision; ordering requires matching precision and returns undefined otherwise.
|
|
103
|
+
`date_min` / `date_max` take one or more dates of matching precision and return a date.
|
|
104
|
+
`date_add_days`, `date_add_months`, `date_add_years` take a date and a signed integer number.
|
|
105
|
+
Offsets retain precision; month/year offsets clamp to the last day of the destination month.
|
|
106
|
+
Nonzero day offsets require full dates, nonzero month offsets require at least month precision.
|
|
107
|
+
`date_diff(a, b)` returns signed `a - b`, in days for full dates, months for month values,
|
|
108
|
+
or years for year values. Both arguments must have matching precision. Missing arguments' values
|
|
109
|
+
propagate undefined; do not use timestamps or divide by seconds to calculate calendar differences.
|
|
110
|
+
|
|
111
|
+
Form and form-matrix `minDate` / `maxDate` rules can use `valueExpression` instead of `value`.
|
|
112
|
+
Use a date response reference or date arithmetic expression. For example, a latest date seven days
|
|
113
|
+
after another answer uses `date_add_days(responseVariable(...), const(number, 7))`.
|
|
114
|
+
Use the form-field or matrix configuration operation to set these field rules. The normal expression
|
|
115
|
+
operations remain appropriate for item validations, prefills, and display conditions.
|
|
116
|
+
Bounds are inclusive: minimum uses the start of its calendar period, maximum uses its end.
|
|
117
|
+
The entire answer period must fit within the bound. An unanswered optional date remains valid;
|
|
118
|
+
a supplied answer with an unresolved bound fails validation until the source is available.
|
|
97
119
|
|
|
98
120
|
Example: show an item when option "yes" is selected on choice item q1:
|
|
99
121
|
|
|
@@ -102,8 +124,20 @@ Example: show an item when option "yes" is selected on choice item q1:
|
|
|
102
124
|
"type": "function",
|
|
103
125
|
"functionName": "eq",
|
|
104
126
|
"arguments": [
|
|
105
|
-
{
|
|
106
|
-
|
|
127
|
+
{
|
|
128
|
+
"type": "responseVariable",
|
|
129
|
+
"variableRef": {
|
|
130
|
+
"slotId": "q1",
|
|
131
|
+
"method": "get"
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"type": "const",
|
|
136
|
+
"value": {
|
|
137
|
+
"type": "reference",
|
|
138
|
+
"value": "yes"
|
|
139
|
+
}
|
|
140
|
+
}
|
|
107
141
|
]
|
|
108
142
|
}
|
|
109
143
|
```
|
|
@@ -115,8 +149,20 @@ Example: multiple-select contains option "apple" when the inspected response slo
|
|
|
115
149
|
"type": "function",
|
|
116
150
|
"functionName": "list_contains",
|
|
117
151
|
"arguments": [
|
|
118
|
-
{
|
|
119
|
-
|
|
152
|
+
{
|
|
153
|
+
"type": "responseVariable",
|
|
154
|
+
"variableRef": {
|
|
155
|
+
"slotId": "q2",
|
|
156
|
+
"method": "get"
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"type": "const",
|
|
161
|
+
"value": {
|
|
162
|
+
"type": "reference",
|
|
163
|
+
"value": "apple"
|
|
164
|
+
}
|
|
165
|
+
}
|
|
120
166
|
]
|
|
121
167
|
}
|
|
122
168
|
```
|
|
@@ -131,91 +177,175 @@ raw item, never inside `config` or `translations`.
|
|
|
131
177
|
[
|
|
132
178
|
{
|
|
133
179
|
"kind": "create-item",
|
|
134
|
-
"target": {
|
|
180
|
+
"target": {
|
|
181
|
+
"parentItemId": "<parent-group-id>"
|
|
182
|
+
},
|
|
135
183
|
"item": {
|
|
136
184
|
"id": "routing_choice",
|
|
137
|
-
"key": "routing_choice",
|
|
138
185
|
"itemType": "choiceItem",
|
|
139
186
|
"config": {
|
|
140
187
|
"id": "routing_choice",
|
|
141
188
|
"maxSelection": 1,
|
|
142
189
|
"shuffleOptions": false,
|
|
143
190
|
"options": [
|
|
144
|
-
{
|
|
145
|
-
|
|
146
|
-
|
|
191
|
+
{
|
|
192
|
+
"id": "option_a",
|
|
193
|
+
"code": "option_a"
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"id": "option_b",
|
|
197
|
+
"code": "option_b"
|
|
198
|
+
}
|
|
199
|
+
],
|
|
200
|
+
"variableName": "routing_choice"
|
|
147
201
|
}
|
|
148
202
|
},
|
|
149
203
|
"translations": [
|
|
150
|
-
{
|
|
151
|
-
|
|
152
|
-
|
|
204
|
+
{
|
|
205
|
+
"locale": "en",
|
|
206
|
+
"contentKey": "title",
|
|
207
|
+
"plainText": "Choose an option"
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
"locale": "en",
|
|
211
|
+
"contentKey": "options.option_a.label",
|
|
212
|
+
"plainText": "Option A"
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
"locale": "en",
|
|
216
|
+
"contentKey": "options.option_b.label",
|
|
217
|
+
"plainText": "Option B"
|
|
218
|
+
}
|
|
153
219
|
]
|
|
154
220
|
},
|
|
155
221
|
{
|
|
156
222
|
"kind": "create-item",
|
|
157
|
-
"target": {
|
|
223
|
+
"target": {
|
|
224
|
+
"parentItemId": "<parent-group-id>"
|
|
225
|
+
},
|
|
158
226
|
"item": {
|
|
159
227
|
"id": "follow_up_a",
|
|
160
|
-
"key": "follow_up_a",
|
|
161
228
|
"itemType": "choiceItem",
|
|
162
229
|
"config": {
|
|
163
230
|
"id": "follow_up_a",
|
|
164
231
|
"maxSelection": 1,
|
|
165
232
|
"shuffleOptions": false,
|
|
166
233
|
"options": [
|
|
167
|
-
{
|
|
168
|
-
|
|
169
|
-
|
|
234
|
+
{
|
|
235
|
+
"id": "yes",
|
|
236
|
+
"code": "yes"
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
"id": "no",
|
|
240
|
+
"code": "no"
|
|
241
|
+
}
|
|
242
|
+
],
|
|
243
|
+
"variableName": "follow_up_a"
|
|
170
244
|
},
|
|
171
245
|
"displayConditions": {
|
|
172
246
|
"root": {
|
|
173
247
|
"type": "function",
|
|
174
248
|
"functionName": "eq",
|
|
175
249
|
"arguments": [
|
|
176
|
-
{
|
|
177
|
-
|
|
250
|
+
{
|
|
251
|
+
"type": "responseVariable",
|
|
252
|
+
"variableRef": {
|
|
253
|
+
"slotId": "routing_choice",
|
|
254
|
+
"method": "get"
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
"type": "const",
|
|
259
|
+
"value": {
|
|
260
|
+
"type": "reference",
|
|
261
|
+
"value": "option_a"
|
|
262
|
+
}
|
|
263
|
+
}
|
|
178
264
|
]
|
|
179
265
|
}
|
|
180
266
|
}
|
|
181
267
|
},
|
|
182
268
|
"translations": [
|
|
183
|
-
{
|
|
184
|
-
|
|
185
|
-
|
|
269
|
+
{
|
|
270
|
+
"locale": "en",
|
|
271
|
+
"contentKey": "title",
|
|
272
|
+
"plainText": "Follow-up for option A"
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"locale": "en",
|
|
276
|
+
"contentKey": "options.yes.label",
|
|
277
|
+
"plainText": "Yes"
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
"locale": "en",
|
|
281
|
+
"contentKey": "options.no.label",
|
|
282
|
+
"plainText": "No"
|
|
283
|
+
}
|
|
186
284
|
]
|
|
187
285
|
},
|
|
188
286
|
{
|
|
189
287
|
"kind": "create-item",
|
|
190
|
-
"target": {
|
|
288
|
+
"target": {
|
|
289
|
+
"parentItemId": "<parent-group-id>"
|
|
290
|
+
},
|
|
191
291
|
"item": {
|
|
192
292
|
"id": "follow_up_b",
|
|
193
|
-
"key": "follow_up_b",
|
|
194
293
|
"itemType": "choiceItem",
|
|
195
294
|
"config": {
|
|
196
295
|
"id": "follow_up_b",
|
|
197
296
|
"maxSelection": 1,
|
|
198
297
|
"shuffleOptions": false,
|
|
199
298
|
"options": [
|
|
200
|
-
{
|
|
201
|
-
|
|
202
|
-
|
|
299
|
+
{
|
|
300
|
+
"id": "yes",
|
|
301
|
+
"code": "yes"
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
"id": "no",
|
|
305
|
+
"code": "no"
|
|
306
|
+
}
|
|
307
|
+
],
|
|
308
|
+
"variableName": "follow_up_b"
|
|
203
309
|
},
|
|
204
310
|
"displayConditions": {
|
|
205
311
|
"root": {
|
|
206
312
|
"type": "function",
|
|
207
313
|
"functionName": "eq",
|
|
208
314
|
"arguments": [
|
|
209
|
-
{
|
|
210
|
-
|
|
315
|
+
{
|
|
316
|
+
"type": "responseVariable",
|
|
317
|
+
"variableRef": {
|
|
318
|
+
"slotId": "routing_choice",
|
|
319
|
+
"method": "get"
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
"type": "const",
|
|
324
|
+
"value": {
|
|
325
|
+
"type": "reference",
|
|
326
|
+
"value": "option_b"
|
|
327
|
+
}
|
|
328
|
+
}
|
|
211
329
|
]
|
|
212
330
|
}
|
|
213
331
|
}
|
|
214
332
|
},
|
|
215
333
|
"translations": [
|
|
216
|
-
{
|
|
217
|
-
|
|
218
|
-
|
|
334
|
+
{
|
|
335
|
+
"locale": "en",
|
|
336
|
+
"contentKey": "title",
|
|
337
|
+
"plainText": "Follow-up for option B"
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
"locale": "en",
|
|
341
|
+
"contentKey": "options.yes.label",
|
|
342
|
+
"plainText": "Yes"
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
"locale": "en",
|
|
346
|
+
"contentKey": "options.no.label",
|
|
347
|
+
"plainText": "No"
|
|
348
|
+
}
|
|
219
349
|
]
|
|
220
350
|
}
|
|
221
351
|
]
|
|
@@ -241,8 +371,20 @@ Item visibility:
|
|
|
241
371
|
"type": "function",
|
|
242
372
|
"functionName": "eq",
|
|
243
373
|
"arguments": [
|
|
244
|
-
{
|
|
245
|
-
|
|
374
|
+
{
|
|
375
|
+
"type": "responseVariable",
|
|
376
|
+
"variableRef": {
|
|
377
|
+
"slotId": "q1",
|
|
378
|
+
"method": "get"
|
|
379
|
+
}
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
"type": "const",
|
|
383
|
+
"value": {
|
|
384
|
+
"type": "reference",
|
|
385
|
+
"value": "yes"
|
|
386
|
+
}
|
|
387
|
+
}
|
|
246
388
|
]
|
|
247
389
|
}
|
|
248
390
|
}
|
|
@@ -299,10 +441,24 @@ Prefill shape:
|
|
|
299
441
|
```json
|
|
300
442
|
{
|
|
301
443
|
"id": "prefill-1",
|
|
302
|
-
"target": {
|
|
303
|
-
|
|
444
|
+
"target": {
|
|
445
|
+
"type": "itemResponse"
|
|
446
|
+
},
|
|
447
|
+
"when": {
|
|
448
|
+
"type": "const",
|
|
449
|
+
"value": {
|
|
450
|
+
"type": "boolean",
|
|
451
|
+
"value": true
|
|
452
|
+
}
|
|
453
|
+
},
|
|
304
454
|
"apply": "ifEmpty",
|
|
305
|
-
"source": {
|
|
455
|
+
"source": {
|
|
456
|
+
"type": "static",
|
|
457
|
+
"value": {
|
|
458
|
+
"type": "string",
|
|
459
|
+
"value": "x"
|
|
460
|
+
}
|
|
461
|
+
}
|
|
306
462
|
}
|
|
307
463
|
```
|
|
308
464
|
|
|
@@ -327,7 +483,13 @@ Template value shape:
|
|
|
327
483
|
{
|
|
328
484
|
"type": "default",
|
|
329
485
|
"returnType": "string",
|
|
330
|
-
"expression": {
|
|
486
|
+
"expression": {
|
|
487
|
+
"type": "const",
|
|
488
|
+
"value": {
|
|
489
|
+
"type": "string",
|
|
490
|
+
"value": "x"
|
|
491
|
+
}
|
|
492
|
+
}
|
|
331
493
|
}
|
|
332
494
|
```
|
|
333
495
|
|
|
@@ -335,6 +497,6 @@ Date formatting template values use `type: "date2string"`, `returnType: "string"
|
|
|
335
497
|
|
|
336
498
|
## Bounded context and atomic batches
|
|
337
499
|
|
|
338
|
-
`survey_expression` action `context` filters response slots and expression locations with `itemIds` (
|
|
500
|
+
`survey_expression` action `context` filters response slots and expression locations with `itemIds` (exact persistent item IDs). Follow `nextCursor` with the same filter and `limit` until absent; restart after a draft mutation. The returned model text contains the actual page and distinguishes filtered totals from the survey-wide response-slot count. For a controlling question outside the filter, omit itemIds and cursor to retrieve the survey-wide catalog. Unresolved identifiers are reported explicitly, not as evidence that an item has no response.
|
|
339
501
|
|
|
340
502
|
A `prepare` mutation array is executed in order within one atomic delta. Later mutations see earlier additions, replacements, and removals, including new containers and shifted prefill indexes. If any mutation fails, none of the delta is staged. Retry all requested mutations from that rejected delta; `pendingRepairs` tracks every remaining operation and surface. For missing or invalid targets, use the indicated `retryOfChangeIds` with the complete corrected input. If an expression location is already empty, inspect and acknowledge that rejected request with a linked `survey_change` using `operations: []`; other identifiable pending edits remain required. Clearing a condition is not a repair of a requested condition change.
|
|
@@ -14,7 +14,7 @@ not a universal override of the user's request or an established survey conventi
|
|
|
14
14
|
|
|
15
15
|
1. **Presentation:** respondent-visible questions, instructions, and answer labels. These are
|
|
16
16
|
localized content and may be reworded.
|
|
17
|
-
2. **Stored identifiers and codes:** stable item and option identifiers,
|
|
17
|
+
2. **Stored identifiers and codes:** stable item and option identifiers, variable names, typed values,
|
|
18
18
|
and standard formats. These are for machines and should not depend on display language.
|
|
19
19
|
3. **Metadata:** definitions, labels for codes, units, data types, missing-value meanings, versions,
|
|
20
20
|
provenance, and mappings to standards. Meaning belongs here rather than being packed into a
|
|
@@ -22,13 +22,13 @@ not a universal override of the user's request or an established survey conventi
|
|
|
22
22
|
|
|
23
23
|
Do not use a respondent-visible label as though it were a stable stored code. Do not expose a raw
|
|
24
24
|
identifier as respondent wording. In CASE, visible item, option, field, and validation text belongs
|
|
25
|
-
in locale translations;
|
|
25
|
+
in locale translations; IDs, variable names, option codes, and response-slot references remain exact data.
|
|
26
26
|
|
|
27
|
-
## Identifiers and
|
|
27
|
+
## Identifiers and variable names
|
|
28
28
|
|
|
29
|
-
- Preserve stable internal ids and existing
|
|
29
|
+
- Preserve stable internal ids and existing variable names unless the user asks to change them. Never
|
|
30
30
|
silently repurpose an existing identifier when meaning changes.
|
|
31
|
-
- When FAIR
|
|
31
|
+
- When FAIR-oriented variable naming is relevant, start with a letter; use lowercase ASCII letters, digits,
|
|
32
32
|
and underscores; use `snake_case`; stay at or below 32 characters; avoid programming and
|
|
33
33
|
database reserved words; prefer a stable, language-neutral English concept name; reuse the same
|
|
34
34
|
concept name across waves and studies; use established instrument prefixes and sortable item
|
|
@@ -37,7 +37,7 @@ in locale translations; ids, keys, option values, and response-slot references r
|
|
|
37
37
|
metadata.
|
|
38
38
|
- For a standard instrument, preserve its established identity and predictable structure, such as
|
|
39
39
|
an instrument prefix plus a zero-padded item number, rather than inventing unrelated names.
|
|
40
|
-
- Choice option
|
|
40
|
+
- Choice option IDs and export codes should be stable and coding-friendly. Their localized labels
|
|
41
41
|
remain separate translations.
|
|
42
42
|
- Follow an explicit user-supplied identifier or established local convention when FAIR naming was
|
|
43
43
|
not requested. If a FAIR alternative would materially help, explain the tradeoff rather than
|
|
@@ -51,9 +51,7 @@ in locale translations; ids, keys, option values, and response-slot references r
|
|
|
51
51
|
- Reuse established code lists and formats when the task calls for interoperability: ISO 8601 for
|
|
52
52
|
dates, ISO 3166 for countries, ISO 639 for languages, UCUM for units, and appropriate domain
|
|
53
53
|
vocabularies such as LOINC or SNOMED CT when supported and relevant.
|
|
54
|
-
-
|
|
55
|
-
reasons. Never invent an ordinary numeric value such as `99` or `-9` that could be analyzed as a
|
|
56
|
-
real response unless the surrounding data model explicitly declares and documents it as missing.
|
|
54
|
+
- The current response envelope distinguishes typed answers from missing answers. It does not encode every missingness reason. Explain that limitation; do not claim skipped, refused, not asked and not applicable are automatically distinguishable. Explicit questionnaire options can represent such meanings when deliberately authored. Never conflate absent answers with zero, false, or an empty selection. Do not invent sentinel values.
|
|
57
55
|
- Do not invent CASE fields or ad hoc codes to simulate missing-value semantics that the installed
|
|
58
56
|
editor capabilities do not support. Explain the capability gap instead.
|
|
59
57
|
|
|
@@ -78,3 +76,5 @@ capabilities before changing existing identifiers, codes, values, or metadata. D
|
|
|
78
76
|
rewrite a survey merely because this reference was loaded. Apply the parts material to the user's
|
|
79
77
|
goal, state important tradeoffs, and identify platform-level FAIR requirements that remain outside
|
|
80
78
|
the editor.
|
|
79
|
+
|
|
80
|
+
These naming rules are CASE project conventions supporting FAIR practice, not requirements imposed by FAIR. Names alone do not make data FAIR; metadata, provenance, access, licensing and documented meaning remain necessary.
|