create-auto-app 0.13.3 → 0.15.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.
@@ -1,393 +0,0 @@
1
- import {
2
- command,
3
- query,
4
- experience,
5
- narrative,
6
- describe,
7
- it,
8
- specs,
9
- rule,
10
- example,
11
- gql,
12
- source,
13
- data,
14
- sink,
15
- type Command,
16
- type Event,
17
- type State,
18
- } from '@auto-engineer/narrative';
19
-
20
- type SendQuestionnaireLink = Command<
21
- 'SendQuestionnaireLink',
22
- {
23
- questionnaireId: string;
24
- participantId: string;
25
- }
26
- >;
27
-
28
- type QuestionnaireLinkSent = Event<
29
- 'QuestionnaireLinkSent',
30
- {
31
- questionnaireId: string;
32
- participantId: string;
33
- link: string;
34
- sentAt: Date;
35
- }
36
- >;
37
-
38
- type QuestionAnswered = Event<
39
- 'QuestionAnswered',
40
- {
41
- questionnaireId: string;
42
- participantId: string;
43
- questionId: string;
44
- answer: unknown;
45
- savedAt: Date;
46
- }
47
- >;
48
-
49
- type QuestionnaireSubmitted = Event<
50
- 'QuestionnaireSubmitted',
51
- {
52
- questionnaireId: string;
53
- participantId: string;
54
- submittedAt: Date;
55
- }
56
- >;
57
-
58
- type QuestionnaireEditRejected = Event<
59
- 'QuestionnaireEditRejected',
60
- {
61
- questionnaireId: string;
62
- participantId: string;
63
- reason: string;
64
- attemptedAt: Date;
65
- }
66
- >;
67
-
68
- type AnswerQuestion = Command<
69
- 'AnswerQuestion',
70
- {
71
- questionnaireId: string;
72
- participantId: string;
73
- questionId: string;
74
- answer: unknown;
75
- }
76
- >;
77
-
78
- type SubmitQuestionnaire = Command<
79
- 'SubmitQuestionnaire',
80
- {
81
- questionnaireId: string;
82
- participantId: string;
83
- }
84
- >;
85
-
86
- type QuestionnaireConfig = State<
87
- 'QuestionnaireConfig',
88
- {
89
- questionnaireId: string;
90
- numberOfQuestions: number;
91
- }
92
- >;
93
-
94
- type QuestionnaireProgress = State<
95
- 'QuestionnaireProgress',
96
- {
97
- questionnaireId: string;
98
- participantId: string;
99
- status: 'in_progress' | 'ready_to_submit' | 'submitted';
100
- currentQuestionId: string | null;
101
- remainingQuestions: string[];
102
- answers: { questionId: string; value: unknown }[];
103
- }
104
- >;
105
-
106
- narrative('Questionnaires', 'Q9m2Kp4Lx', () => {
107
- command('sends the questionnaire link', 'S2b5Cp7Dz')
108
- .server(() => {
109
- specs(() => {
110
- rule('questionnaire link is sent to participant', 'r0A1Bo8X', () => {
111
- example('sends the questionnaire link successfully')
112
- .when<SendQuestionnaireLink>({
113
- questionnaireId: 'q-001',
114
- participantId: 'participant-abc',
115
- })
116
- .then<QuestionnaireLinkSent>({
117
- questionnaireId: 'q-001',
118
- participantId: 'participant-abc',
119
- link: 'https://app.example.com/q/q-001?participant=participant-abc',
120
- sentAt: new Date('2030-01-01T09:00:00Z'),
121
- });
122
- });
123
- });
124
- data([sink().event('QuestionnaireLinkSent').toStream('questionnaire-participantId')]);
125
- })
126
- .request(gql`
127
- mutation SendQuestionnaireLink($input: SendQuestionnaireLinkInput!) {
128
- sendQuestionnaireLink(input: $input) {
129
- success
130
- }
131
- }
132
- `)
133
- .client(() => {
134
- describe('Questionnaire Link', () => {
135
- it('display a confirmation message when the link is sent');
136
- it('handle errors when the link cannot be sent');
137
- });
138
- });
139
- query('views the questionnaire', 'V7n8Rq5M')
140
- .server(() => {
141
- specs(() => {
142
- rule('questionnaires show current progress', 'r1A3Bp9W', () => {
143
- example('a question has already been answered')
144
- .given<QuestionnaireLinkSent>({
145
- questionnaireId: 'q-001',
146
- participantId: 'participant-abc',
147
- link: 'https://app.example.com/q/q-001?participant=participant-abc',
148
- sentAt: new Date('2030-01-01T09:00:00Z'),
149
- })
150
- .when<QuestionAnswered>({
151
- questionnaireId: 'q-001',
152
- participantId: 'participant-abc',
153
- questionId: 'q1',
154
- answer: 'Yes',
155
- savedAt: new Date('2030-01-01T09:05:00Z'),
156
- })
157
- .then<QuestionnaireProgress>({
158
- questionnaireId: 'q-001',
159
- participantId: 'participant-abc',
160
- status: 'in_progress',
161
- currentQuestionId: 'q2',
162
- remainingQuestions: ['q2'],
163
- answers: [{ questionId: 'q1', value: 'Yes' }],
164
- });
165
- example('no questions have been answered yet')
166
- .given<QuestionnaireLinkSent>({
167
- questionnaireId: 'q-001',
168
- participantId: 'participant-abc',
169
- link: 'https://app.example.com/q/q-001?participant=participant-abc',
170
- sentAt: new Date('2030-01-01T09:00:00Z'),
171
- })
172
- .when({})
173
- .then<QuestionnaireProgress>({
174
- questionnaireId: 'q-001',
175
- participantId: 'participant-abc',
176
- status: 'in_progress',
177
- currentQuestionId: 'q1',
178
- remainingQuestions: ['q1', 'q2'],
179
- answers: [],
180
- });
181
- });
182
- });
183
- data([source().state('QuestionnaireProgress').fromProjection('Questionnaires', 'questionnaireId-participantId')]);
184
- })
185
- .request(gql`
186
- query QuestionnaireProgress($participantId: ID!) {
187
- questionnaireProgress(participantId: $participantId) {
188
- questionnaireId
189
- participantId
190
- currentQuestionId
191
- remainingQuestions
192
- status
193
- answers {
194
- questionId
195
- value
196
- }
197
- }
198
- }
199
- `)
200
- .client(() => {
201
- describe('Questionnaire Progress', () => {
202
- it('focus on the current question based on the progress state');
203
- it('display the list of answered questions');
204
- it('display the list of remaining questions');
205
- it('show a progress indicator that is always visible as the user scrolls');
206
- });
207
- });
208
-
209
- command('submits a questionnaire answer', 'S4j6Nt8Z')
210
- .server(() => {
211
- specs(() => {
212
- rule('answers are allowed while the questionnaire has not been submitted', 'r2D5Eq0Y', () => {
213
- example('no questions have been answered yet')
214
- .when<AnswerQuestion>({
215
- questionnaireId: 'q-001',
216
- participantId: 'participant-abc',
217
- questionId: 'q1',
218
- answer: 'Yes',
219
- })
220
- .then<QuestionAnswered>({
221
- questionnaireId: 'q-001',
222
- participantId: 'participant-abc',
223
- questionId: 'q1',
224
- answer: 'Yes',
225
- savedAt: new Date('2030-01-01T09:05:00Z'),
226
- });
227
-
228
- example('all questions have already been answered and submitted')
229
- .given<QuestionnaireSubmitted>({
230
- questionnaireId: 'q-001',
231
- participantId: 'participant-abc',
232
- submittedAt: new Date('2030-01-01T09:00:00Z'),
233
- })
234
- .when<AnswerQuestion>({
235
- questionnaireId: 'q-001',
236
- participantId: 'participant-abc',
237
- questionId: 'q1',
238
- answer: 'Yes',
239
- })
240
- .then<QuestionnaireEditRejected>({
241
- questionnaireId: 'q-001',
242
- participantId: 'participant-abc',
243
- reason: 'Questionnaire already submitted',
244
- attemptedAt: new Date('2030-01-01T09:05:00Z'),
245
- });
246
- });
247
- });
248
- data([
249
- sink().event('QuestionAnswered').toStream('questionnaire-participantId'),
250
- sink().event('QuestionnaireEditRejected').toStream('questionnaire-participantId'),
251
- ]);
252
- })
253
- .request(gql`
254
- mutation AnswerQuestion($input: AnswerQuestionInput!) {
255
- answerQuestion(input: $input) {
256
- success
257
- }
258
- }
259
- `)
260
- .client(() => {
261
- describe('Submissions', () => {
262
- it('displays a success message when the answer is submitted');
263
- it('display an error message when the answer submission is rejected');
264
- });
265
- });
266
-
267
- query('questionnaire ready for submission', 'R3f7Hu1X')
268
- .server(() => {
269
- specs(() => {
270
- rule('questionnaire is ready for submission when all questions are answered', 'r3G8Iv2W', () => {
271
- example('all questions have been answered')
272
- .given<QuestionnaireConfig>({
273
- questionnaireId: 'q-001',
274
- numberOfQuestions: 2,
275
- })
276
- .and<QuestionnaireLinkSent>({
277
- questionnaireId: 'q-001',
278
- participantId: 'participant-abc',
279
- link: 'https://app.example.com/q/q-001?participant=participant-abc',
280
- sentAt: new Date('2030-01-01T09:00:00Z'),
281
- })
282
- .and<QuestionAnswered>({
283
- questionnaireId: 'q-001',
284
- participantId: 'participant-abc',
285
- questionId: 'q1',
286
- answer: 'Yes',
287
- savedAt: new Date('2030-01-01T09:05:00Z'),
288
- })
289
- .and<QuestionAnswered>({
290
- questionnaireId: 'q-001',
291
- participantId: 'participant-abc',
292
- questionId: 'q2',
293
- answer: 'No',
294
- savedAt: new Date('2030-01-01T09:05:00Z'),
295
- })
296
- .when({}) // FIX ME
297
- .then<QuestionnaireProgress>({
298
- questionnaireId: 'q-001',
299
- participantId: 'participant-abc',
300
- status: 'ready_to_submit',
301
- currentQuestionId: null,
302
- remainingQuestions: [],
303
- answers: [
304
- { questionId: 'q1', value: 'Yes' },
305
- { questionId: 'q2', value: 'No' },
306
- ],
307
- });
308
- example('some questions are still unanswered')
309
- .given<QuestionnaireLinkSent>({
310
- questionnaireId: 'q-001',
311
- participantId: 'participant-abc',
312
- link: 'https://app.example.com/q/q-001?participant=participant-abc',
313
- sentAt: new Date('2030-01-01T09:00:00Z'),
314
- })
315
- .when<QuestionAnswered>({
316
- questionnaireId: 'q-001',
317
- participantId: 'participant-abc',
318
- questionId: 'q1',
319
- answer: 'Yes',
320
- savedAt: new Date('2030-01-01T09:05:00Z'),
321
- })
322
- .then<QuestionnaireProgress>({
323
- questionnaireId: 'q-001',
324
- participantId: 'participant-abc',
325
- status: 'in_progress',
326
- currentQuestionId: 'q2',
327
- remainingQuestions: ['q2'],
328
- answers: [{ questionId: 'q1', value: 'Yes' }],
329
- });
330
- });
331
- });
332
- data([
333
- source().state('QuestionnaireProgress').fromProjection('Questionnaires', 'questionnaireId-participantId'),
334
- source().state('QuestionnaireConfig').fromDatabase('QuestionnaireConfigAPI'),
335
- ]);
336
- })
337
- .request(gql`
338
- query QuestionnaireProgress($participantId: ID!) {
339
- questionnaireProgress(participantId: $participantId) {
340
- questionnaireId
341
- participantId
342
- status
343
- currentQuestionId
344
- remainingQuestions
345
- answers {
346
- questionId
347
- value
348
- }
349
- }
350
- }
351
- `)
352
- .client(() => {
353
- describe('Submission Readiness', () => {
354
- it('enable the submit button when all questions are answered');
355
- it('disable the submit button when all questions have not been answered');
356
- });
357
- });
358
-
359
- command('submits the questionnaire', 'T5k9Jw3V')
360
- .server(() => {
361
- specs(() => {
362
- rule('questionnaire allowed to be submitted when all questions are answered', 'r4H0Lx4U', () => {
363
- example('submits the questionnaire successfully')
364
- .when<SubmitQuestionnaire>({
365
- questionnaireId: 'q-001',
366
- participantId: 'participant-abc',
367
- })
368
- .then<QuestionnaireSubmitted>({
369
- questionnaireId: 'q-001',
370
- participantId: 'participant-abc',
371
- submittedAt: new Date('2030-01-01T09:00:00Z'),
372
- });
373
- });
374
- });
375
- data([sink().event('QuestionnaireSubmitted').toStream('questionnaire-participantId')]);
376
- })
377
- .request(gql`
378
- mutation SubmitQuestionnaire($input: SubmitQuestionnaireInput!) {
379
- submitQuestionnaire(input: $input) {
380
- success
381
- }
382
- }
383
- `)
384
- .client(() => {
385
- describe('Submission Confirmation', () => {
386
- it('display a confirmation message upon successful submission');
387
- });
388
- });
389
- });
390
-
391
- // notifications are updated
392
- // they are taken back home
393
- // homepage status shows "Pre-Registration Complete"
@@ -1,16 +0,0 @@
1
- import { experience, narrative, it } from '@auto-engineer/narrative';
2
- narrative('App Structure', 'vLkxrmhz6', () => {
3
- experience('App Structure', 'k6JkQZQnc').client(() => {
4
- it('display persistent sidebar on left for navigation');
5
- it(
6
- 'sidebar includes links: Home, Create Survey, Analytics, Templates, Completion Tracker, Response Goals, Response History',
7
- );
8
- it('highlight current active link in sidebar');
9
- it('sidebar collapsible for smaller screens');
10
- it('top bar includes app logo, profile menu, and notifications icon');
11
- it('bottom or top persistent bar shows global widgets: total responses, active surveys, completion rate progress');
12
- it('content area changes dynamically based on selected navigation link');
13
- it('maintain layout consistency across all screens');
14
- it('support responsive design with sidebar collapsing into hamburger menu on mobile');
15
- });
16
- });
@@ -1,30 +0,0 @@
1
- {
2
- "name": "questionnaires",
3
- "private": true,
4
- "type": "module",
5
- "scripts": {
6
- "auto": "node ../../packages/cli/dist/bin/auto.js",
7
- "auto:debug": "DEBUG=auto:* node ../../packages/cli/dist/bin/auto.js",
8
- "start": "dotenv -e .env -- pnpm --parallel start"
9
- },
10
- "dependencies": {
11
- "@auto-engineer/cli": "workspace:*",
12
- "@auto-engineer/design-system-importer": "workspace:*",
13
- "@auto-engineer/narrative": "workspace:*",
14
- "@auto-engineer/frontend-checks": "workspace:*",
15
- "@auto-engineer/frontend-generator-react-graphql": "workspace:*",
16
- "@auto-engineer/frontend-implementer": "workspace:*",
17
- "@auto-engineer/information-architect": "workspace:*",
18
- "@auto-engineer/message-bus": "workspace:*",
19
- "@auto-engineer/server-checks": "workspace:*",
20
- "@auto-engineer/server-generator-apollo-emmett": "workspace:*",
21
- "@auto-engineer/server-implementer": "workspace:*"
22
- },
23
- "devDependencies": {
24
- "@types/node": "^24.3.1",
25
- "chokidar": "^3.6.0",
26
- "dotenv": "^16.4.5",
27
- "dotenv-cli": "^9.0.0",
28
- "tsx": "^3.12.7"
29
- }
30
- }
@@ -1,7 +0,0 @@
1
- {
2
- "name": "questionnaires",
3
- "displayName": "Questionnaires App",
4
- "description": "Collect user input through a series of questions",
5
- "type": "template",
6
- "preset": "full"
7
- }
@@ -1,15 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "ESNext",
5
- "moduleResolution": "bundler",
6
- "skipLibCheck": true,
7
- "emitDecoratorMetadata": true,
8
- "experimentalDecorators": true,
9
- "outDir": "./dist",
10
- "noEmit": false,
11
- "strictNullChecks": true
12
- },
13
- "include": ["**/*", "vitest.config.ts"],
14
- "exclude": ["dist", "node_modules"]
15
- }