create-auto-app 0.1.5 → 0.1.7
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/dist/index.js +126 -106
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/templates/shopping-app/.context/auto-ia-scheme.json +8 -29
- package/templates/shopping-app/.context/design-system.md +59 -35
- package/templates/shopping-app/.context/figma-variables.json +335 -1024
- package/templates/shopping-app/.context/schema.json +3 -7
- package/templates/shopping-app/.context/shadcn-filter.ts +2 -4
- package/templates/shopping-app/auto.config.ts +2 -2
- package/templates/shopping-app/client/src/gql/fragment-masking.ts +22 -22
- package/templates/shopping-app/client/src/gql/gql.ts +12 -5
- package/templates/shopping-app/client/src/gql/graphql.ts +125 -11
- package/templates/shopping-app/client/src/gql/index.ts +2 -2
- package/templates/shopping-app/client/src/graphql/mutations.ts +9 -9
- package/templates/shopping-app/client/src/graphql/queries.ts +10 -10
- package/templates/shopping-app/flows/shopping-assistant.flow.ts +2 -2
- package/templates/shopping-app/package.json +1 -1
- package/templates/shopping-app/pnpm-workspace.yaml +2 -2
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/commands.ts +2 -2
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/decide.specs.ts +20 -20
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/decide.ts +8 -11
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/events.ts +2 -2
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/evolve.ts +3 -3
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/handle.ts +8 -15
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/mutation.resolver.ts +5 -9
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/register.ts +4 -7
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/creates-a-chat-session-/react.specs.ts +19 -31
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/creates-a-chat-session-/react.ts +6 -12
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/creates-a-chat-session-/register.ts +4 -11
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/commands.ts +2 -2
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/decide.specs.ts +14 -14
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/decide.ts +8 -11
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/events.ts +2 -2
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/evolve.ts +3 -3
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/handle.ts +8 -15
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/mutation.resolver.ts +5 -9
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/register.ts +4 -7
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/commands.ts +2 -2
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/decide.specs.ts +23 -23
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/decide.ts +9 -13
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/events.ts +2 -2
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/evolve.ts +3 -3
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/handle.ts +11 -18
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/mutation.resolver.ts +5 -9
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/register.ts +4 -7
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/views-suggested-items/projection.specs.ts +35 -35
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/views-suggested-items/projection.ts +8 -11
- package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/views-suggested-items/query.resolver.ts +4 -7
- package/templates/shopping-app/server/src/domain/shared/ReadModel.d.ts +7 -7
- package/templates/shopping-app/server/src/domain/shared/ReadModel.js +17 -17
- package/templates/shopping-app/server/src/domain/shared/index.d.ts +1 -1
- package/templates/shopping-app/server/src/domain/shared/index.js +1 -1
- package/templates/shopping-app/server/src/domain/shared/reactorSpecification.d.ts +42 -21
- package/templates/shopping-app/server/src/domain/shared/reactorSpecification.js +148 -140
- package/templates/shopping-app/server/src/domain/shared/sendCommand.d.ts +5 -2
- package/templates/shopping-app/server/src/domain/shared/sendCommand.js +14 -15
- package/templates/shopping-app/server/src/domain/shared/types.d.ts +10 -10
- package/templates/shopping-app/server/src/domain/shared/types.js +37 -36
- package/templates/shopping-app/server/src/integrations/ai-integration.ts +1 -1
- package/templates/shopping-app/server/src/integrations/cart-integration.ts +1 -1
- package/templates/shopping-app/server/src/integrations/index.ts +1 -1
- package/templates/shopping-app/server/src/integrations/product-catalogue-integration.ts +1 -1
- package/templates/shopping-app/server/src/utils/index.d.ts +1 -1
- package/templates/shopping-app/server/src/utils/index.js +1 -1
- package/templates/shopping-app/server/src/utils/loadProjections.d.ts +1 -1
- package/templates/shopping-app/server/src/utils/loadProjections.js +18 -16
- package/templates/shopping-app/server/src/utils/loadRegisterFiles.d.ts +2 -2
- package/templates/shopping-app/server/src/utils/loadRegisterFiles.js +19 -21
- package/templates/shopping-app/server/src/utils/loadResolvers.d.ts +2 -2
- package/templates/shopping-app/server/src/utils/loadResolvers.js +22 -22
- package/templates/shopping-app/server/tsconfig.json +2 -8
- package/templates/shopping-app/tsconfig.json +2 -8
|
@@ -103,9 +103,7 @@
|
|
|
103
103
|
},
|
|
104
104
|
"destination": {
|
|
105
105
|
"type": "integration",
|
|
106
|
-
"systems": [
|
|
107
|
-
"AI"
|
|
108
|
-
],
|
|
106
|
+
"systems": ["AI"],
|
|
109
107
|
"message": {
|
|
110
108
|
"name": "DoChat",
|
|
111
109
|
"type": "command"
|
|
@@ -119,9 +117,7 @@
|
|
|
119
117
|
},
|
|
120
118
|
"origin": {
|
|
121
119
|
"type": "integration",
|
|
122
|
-
"systems": [
|
|
123
|
-
"product-catalog"
|
|
124
|
-
]
|
|
120
|
+
"systems": ["product-catalog"]
|
|
125
121
|
}
|
|
126
122
|
}
|
|
127
123
|
},
|
|
@@ -580,4 +576,4 @@
|
|
|
580
576
|
"source": "@auto-engineer/product-catalog-integration"
|
|
581
577
|
}
|
|
582
578
|
]
|
|
583
|
-
}
|
|
579
|
+
}
|
|
@@ -8,9 +8,7 @@ export function filter(components) {
|
|
|
8
8
|
let str = comp.name.trim();
|
|
9
9
|
|
|
10
10
|
// Normalize the name
|
|
11
|
-
str = str.includes(
|
|
12
|
-
? str.split("/")[0].trim()
|
|
13
|
-
: str.split(" ")[0].trim();
|
|
11
|
+
str = str.includes('/') ? str.split('/')[0].trim() : str.split(' ')[0].trim();
|
|
14
12
|
|
|
15
13
|
if (!str) return null;
|
|
16
14
|
|
|
@@ -28,4 +26,4 @@ export function filter(components) {
|
|
|
28
26
|
seen.add(c.name);
|
|
29
27
|
return true;
|
|
30
28
|
});
|
|
31
|
-
}
|
|
29
|
+
}
|
|
@@ -13,9 +13,9 @@ export default {
|
|
|
13
13
|
'@auto-engineer/react-graphql-generator',
|
|
14
14
|
'@auto-engineer/server-implementer',
|
|
15
15
|
],
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
aliases: {
|
|
18
18
|
// If multiple packages tried to register 'check:types', you'd resolve it:
|
|
19
19
|
// 'test:types': checkTypesCommandHandler, // auto test → runs check:types via specific handler
|
|
20
|
-
}
|
|
20
|
+
},
|
|
21
21
|
};
|
|
@@ -1,48 +1,48 @@
|
|
|
1
|
-
import { ResultOf, TypedDocumentNode as DocumentNode
|
|
1
|
+
import { ResultOf, TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
? TKey extends string
|
|
10
|
-
? { ' $fragmentRefs'?: { [key in TKey]: TType } }
|
|
3
|
+
export type FragmentType<TDocumentType extends DocumentNode<any, any>> =
|
|
4
|
+
TDocumentType extends DocumentNode<infer TType, any>
|
|
5
|
+
? TType extends { ' $fragmentName'?: infer TKey }
|
|
6
|
+
? TKey extends string
|
|
7
|
+
? { ' $fragmentRefs'?: { [key in TKey]: TType } }
|
|
8
|
+
: never
|
|
11
9
|
: never
|
|
12
|
-
: never
|
|
13
|
-
: never;
|
|
10
|
+
: never;
|
|
14
11
|
|
|
15
12
|
// return non-nullable if `fragmentType` is non-nullable
|
|
16
13
|
export function useFragment<TType>(
|
|
17
14
|
_documentNode: DocumentNode<TType, any>,
|
|
18
|
-
fragmentType: FragmentType<DocumentNode<TType, any
|
|
15
|
+
fragmentType: FragmentType<DocumentNode<TType, any>>,
|
|
19
16
|
): TType;
|
|
20
17
|
// return nullable if `fragmentType` is nullable
|
|
21
18
|
export function useFragment<TType>(
|
|
22
19
|
_documentNode: DocumentNode<TType, any>,
|
|
23
|
-
fragmentType: FragmentType<DocumentNode<TType, any>> | null | undefined
|
|
20
|
+
fragmentType: FragmentType<DocumentNode<TType, any>> | null | undefined,
|
|
24
21
|
): TType | null | undefined;
|
|
25
22
|
// return array of non-nullable if `fragmentType` is array of non-nullable
|
|
26
23
|
export function useFragment<TType>(
|
|
27
24
|
_documentNode: DocumentNode<TType, any>,
|
|
28
|
-
fragmentType: ReadonlyArray<FragmentType<DocumentNode<TType, any
|
|
25
|
+
fragmentType: ReadonlyArray<FragmentType<DocumentNode<TType, any>>>,
|
|
29
26
|
): ReadonlyArray<TType>;
|
|
30
27
|
// return array of nullable if `fragmentType` is array of nullable
|
|
31
28
|
export function useFragment<TType>(
|
|
32
29
|
_documentNode: DocumentNode<TType, any>,
|
|
33
|
-
fragmentType: ReadonlyArray<FragmentType<DocumentNode<TType, any>>> | null | undefined
|
|
30
|
+
fragmentType: ReadonlyArray<FragmentType<DocumentNode<TType, any>>> | null | undefined,
|
|
34
31
|
): ReadonlyArray<TType> | null | undefined;
|
|
35
32
|
export function useFragment<TType>(
|
|
36
33
|
_documentNode: DocumentNode<TType, any>,
|
|
37
|
-
fragmentType:
|
|
34
|
+
fragmentType:
|
|
35
|
+
| FragmentType<DocumentNode<TType, any>>
|
|
36
|
+
| ReadonlyArray<FragmentType<DocumentNode<TType, any>>>
|
|
37
|
+
| null
|
|
38
|
+
| undefined,
|
|
38
39
|
): TType | ReadonlyArray<TType> | null | undefined {
|
|
39
40
|
return fragmentType as any;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
F
|
|
45
|
-
|
|
46
|
-
>(data: FT, _fragment: F): FragmentType<F> {
|
|
43
|
+
export function makeFragmentData<F extends DocumentNode, FT extends ResultOf<F>>(
|
|
44
|
+
data: FT,
|
|
45
|
+
_fragment: F,
|
|
46
|
+
): FragmentType<F> {
|
|
47
47
|
return data as FragmentType<F>;
|
|
48
|
-
}
|
|
48
|
+
}
|
|
@@ -13,8 +13,10 @@ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/
|
|
|
13
13
|
* Therefore it is highly recommended to use the babel or swc plugin for production.
|
|
14
14
|
*/
|
|
15
15
|
const documents = {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
'\nmutation EnterShoppingCriteria($input: EnterShoppingCriteriaInput!) {\n enterShoppingCriteria(input: $input) {\n success\n error {\n type\n message\n }\n }\n }\n':
|
|
17
|
+
types.EnterShoppingCriteriaDocument,
|
|
18
|
+
'\nquery GetSuggestedItems($sessionId: ID!) {\n suggestedItems(sessionId: $sessionId) {\n items {\n productId\n name\n quantity\n reason\n }\n }\n }\n':
|
|
19
|
+
types.GetSuggestedItemsDocument,
|
|
18
20
|
};
|
|
19
21
|
|
|
20
22
|
/**
|
|
@@ -34,14 +36,19 @@ export function graphql(source: string): unknown;
|
|
|
34
36
|
/**
|
|
35
37
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
36
38
|
*/
|
|
37
|
-
export function graphql(
|
|
39
|
+
export function graphql(
|
|
40
|
+
source: '\nmutation EnterShoppingCriteria($input: EnterShoppingCriteriaInput!) {\n enterShoppingCriteria(input: $input) {\n success\n error {\n type\n message\n }\n }\n }\n',
|
|
41
|
+
): (typeof documents)['\nmutation EnterShoppingCriteria($input: EnterShoppingCriteriaInput!) {\n enterShoppingCriteria(input: $input) {\n success\n error {\n type\n message\n }\n }\n }\n'];
|
|
38
42
|
/**
|
|
39
43
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
40
44
|
*/
|
|
41
|
-
export function graphql(
|
|
45
|
+
export function graphql(
|
|
46
|
+
source: '\nquery GetSuggestedItems($sessionId: ID!) {\n suggestedItems(sessionId: $sessionId) {\n items {\n productId\n name\n quantity\n reason\n }\n }\n }\n',
|
|
47
|
+
): (typeof documents)['\nquery GetSuggestedItems($sessionId: ID!) {\n suggestedItems(sessionId: $sessionId) {\n items {\n productId\n name\n quantity\n reason\n }\n }\n }\n'];
|
|
42
48
|
|
|
43
49
|
export function graphql(source: string) {
|
|
44
50
|
return (documents as any)[source] ?? {};
|
|
45
51
|
}
|
|
46
52
|
|
|
47
|
-
export type DocumentType<TDocumentNode extends DocumentNode<any, any>> =
|
|
53
|
+
export type DocumentType<TDocumentNode extends DocumentNode<any, any>> =
|
|
54
|
+
TDocumentNode extends DocumentNode<infer TType, any> ? TType : never;
|
|
@@ -31,17 +31,14 @@ export type Mutation = {
|
|
|
31
31
|
suggestShoppingItems: MutationResponse;
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
-
|
|
35
34
|
export type MutationAddItemsToCartArgs = {
|
|
36
35
|
input: AddItemsToCartInput;
|
|
37
36
|
};
|
|
38
37
|
|
|
39
|
-
|
|
40
38
|
export type MutationEnterShoppingCriteriaArgs = {
|
|
41
39
|
input: EnterShoppingCriteriaInput;
|
|
42
40
|
};
|
|
43
41
|
|
|
44
|
-
|
|
45
42
|
export type MutationSuggestShoppingItemsArgs = {
|
|
46
43
|
input: SuggestShoppingItemsInput;
|
|
47
44
|
};
|
|
@@ -63,7 +60,6 @@ export type Query = {
|
|
|
63
60
|
suggestedItems: Array<SuggestedItems>;
|
|
64
61
|
};
|
|
65
62
|
|
|
66
|
-
|
|
67
63
|
export type QuerySuggestedItemsArgs = {
|
|
68
64
|
sessionId?: InputMaybe<Scalars['ID']>;
|
|
69
65
|
};
|
|
@@ -91,16 +87,134 @@ export type EnterShoppingCriteriaMutationVariables = Exact<{
|
|
|
91
87
|
input: EnterShoppingCriteriaInput;
|
|
92
88
|
}>;
|
|
93
89
|
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
export type EnterShoppingCriteriaMutation = {
|
|
91
|
+
__typename?: 'Mutation';
|
|
92
|
+
enterShoppingCriteria: {
|
|
93
|
+
__typename?: 'MutationResponse';
|
|
94
|
+
success: boolean;
|
|
95
|
+
error?: { __typename?: 'MutationError'; type: string; message?: string | null } | null;
|
|
96
|
+
};
|
|
97
|
+
};
|
|
96
98
|
|
|
97
99
|
export type GetSuggestedItemsQueryVariables = Exact<{
|
|
98
100
|
sessionId: Scalars['ID'];
|
|
99
101
|
}>;
|
|
100
102
|
|
|
103
|
+
export type GetSuggestedItemsQuery = {
|
|
104
|
+
__typename?: 'Query';
|
|
105
|
+
suggestedItems: Array<{
|
|
106
|
+
__typename?: 'SuggestedItems';
|
|
107
|
+
items: Array<{
|
|
108
|
+
__typename?: 'SuggestedItemsItems';
|
|
109
|
+
productId: string;
|
|
110
|
+
name: string;
|
|
111
|
+
quantity: number;
|
|
112
|
+
reason: string;
|
|
113
|
+
}>;
|
|
114
|
+
}>;
|
|
115
|
+
};
|
|
101
116
|
|
|
102
|
-
export
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
117
|
+
export const EnterShoppingCriteriaDocument = {
|
|
118
|
+
kind: 'Document',
|
|
119
|
+
definitions: [
|
|
120
|
+
{
|
|
121
|
+
kind: 'OperationDefinition',
|
|
122
|
+
operation: 'mutation',
|
|
123
|
+
name: { kind: 'Name', value: 'EnterShoppingCriteria' },
|
|
124
|
+
variableDefinitions: [
|
|
125
|
+
{
|
|
126
|
+
kind: 'VariableDefinition',
|
|
127
|
+
variable: { kind: 'Variable', name: { kind: 'Name', value: 'input' } },
|
|
128
|
+
type: {
|
|
129
|
+
kind: 'NonNullType',
|
|
130
|
+
type: { kind: 'NamedType', name: { kind: 'Name', value: 'EnterShoppingCriteriaInput' } },
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
selectionSet: {
|
|
135
|
+
kind: 'SelectionSet',
|
|
136
|
+
selections: [
|
|
137
|
+
{
|
|
138
|
+
kind: 'Field',
|
|
139
|
+
name: { kind: 'Name', value: 'enterShoppingCriteria' },
|
|
140
|
+
arguments: [
|
|
141
|
+
{
|
|
142
|
+
kind: 'Argument',
|
|
143
|
+
name: { kind: 'Name', value: 'input' },
|
|
144
|
+
value: { kind: 'Variable', name: { kind: 'Name', value: 'input' } },
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
selectionSet: {
|
|
148
|
+
kind: 'SelectionSet',
|
|
149
|
+
selections: [
|
|
150
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'success' } },
|
|
151
|
+
{
|
|
152
|
+
kind: 'Field',
|
|
153
|
+
name: { kind: 'Name', value: 'error' },
|
|
154
|
+
selectionSet: {
|
|
155
|
+
kind: 'SelectionSet',
|
|
156
|
+
selections: [
|
|
157
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'type' } },
|
|
158
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'message' } },
|
|
159
|
+
],
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
} as unknown as DocumentNode<EnterShoppingCriteriaMutation, EnterShoppingCriteriaMutationVariables>;
|
|
170
|
+
export const GetSuggestedItemsDocument = {
|
|
171
|
+
kind: 'Document',
|
|
172
|
+
definitions: [
|
|
173
|
+
{
|
|
174
|
+
kind: 'OperationDefinition',
|
|
175
|
+
operation: 'query',
|
|
176
|
+
name: { kind: 'Name', value: 'GetSuggestedItems' },
|
|
177
|
+
variableDefinitions: [
|
|
178
|
+
{
|
|
179
|
+
kind: 'VariableDefinition',
|
|
180
|
+
variable: { kind: 'Variable', name: { kind: 'Name', value: 'sessionId' } },
|
|
181
|
+
type: { kind: 'NonNullType', type: { kind: 'NamedType', name: { kind: 'Name', value: 'ID' } } },
|
|
182
|
+
},
|
|
183
|
+
],
|
|
184
|
+
selectionSet: {
|
|
185
|
+
kind: 'SelectionSet',
|
|
186
|
+
selections: [
|
|
187
|
+
{
|
|
188
|
+
kind: 'Field',
|
|
189
|
+
name: { kind: 'Name', value: 'suggestedItems' },
|
|
190
|
+
arguments: [
|
|
191
|
+
{
|
|
192
|
+
kind: 'Argument',
|
|
193
|
+
name: { kind: 'Name', value: 'sessionId' },
|
|
194
|
+
value: { kind: 'Variable', name: { kind: 'Name', value: 'sessionId' } },
|
|
195
|
+
},
|
|
196
|
+
],
|
|
197
|
+
selectionSet: {
|
|
198
|
+
kind: 'SelectionSet',
|
|
199
|
+
selections: [
|
|
200
|
+
{
|
|
201
|
+
kind: 'Field',
|
|
202
|
+
name: { kind: 'Name', value: 'items' },
|
|
203
|
+
selectionSet: {
|
|
204
|
+
kind: 'SelectionSet',
|
|
205
|
+
selections: [
|
|
206
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'productId' } },
|
|
207
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
|
|
208
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'quantity' } },
|
|
209
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'reason' } },
|
|
210
|
+
],
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
],
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
],
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
} as unknown as DocumentNode<GetSuggestedItemsQuery, GetSuggestedItemsQueryVariables>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
1
|
+
export * from './fragment-masking';
|
|
2
|
+
export * from './gql';
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { graphql } from '../gql';
|
|
2
2
|
|
|
3
3
|
export const EnterShoppingCriteria = graphql(`
|
|
4
|
-
mutation EnterShoppingCriteria($input: EnterShoppingCriteriaInput!) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
}
|
|
4
|
+
mutation EnterShoppingCriteria($input: EnterShoppingCriteriaInput!) {
|
|
5
|
+
enterShoppingCriteria(input: $input) {
|
|
6
|
+
success
|
|
7
|
+
error {
|
|
8
|
+
type
|
|
9
|
+
message
|
|
12
10
|
}
|
|
13
|
-
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
`);
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { graphql } from '../gql';
|
|
2
2
|
|
|
3
3
|
export const GetSuggestedItems = graphql(`
|
|
4
|
-
query GetSuggestedItems($sessionId: ID!) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
}
|
|
4
|
+
query GetSuggestedItems($sessionId: ID!) {
|
|
5
|
+
suggestedItems(sessionId: $sessionId) {
|
|
6
|
+
items {
|
|
7
|
+
productId
|
|
8
|
+
name
|
|
9
|
+
quantity
|
|
10
|
+
reason
|
|
13
11
|
}
|
|
14
|
-
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
`);
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
registerIntegrations,
|
|
19
19
|
} from '@auto-engineer/flowlang';
|
|
20
20
|
|
|
21
|
-
import
|
|
21
|
+
import { AI, ProductCatalog, type DoChat, type ChatCompleted, type Products } from '../server/src/integrations';
|
|
22
22
|
|
|
23
23
|
registerIntegrations(ProductCatalog, AI);
|
|
24
24
|
|
|
@@ -366,4 +366,4 @@ flow('Seasonal Assistant', () => {
|
|
|
366
366
|
]);
|
|
367
367
|
});
|
|
368
368
|
});
|
|
369
|
-
});
|
|
369
|
+
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
packages:
|
|
2
|
+
- '*'
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import { describe, it } from
|
|
2
|
-
import { DeciderSpecification } from
|
|
3
|
-
import { decide } from
|
|
4
|
-
import { evolve } from
|
|
5
|
-
import { initialState } from
|
|
1
|
+
import { describe, it } from 'vitest';
|
|
2
|
+
import { DeciderSpecification } from '@event-driven-io/emmett';
|
|
3
|
+
import { decide } from './decide';
|
|
4
|
+
import { evolve } from './evolve';
|
|
5
|
+
import { initialState } from './state';
|
|
6
6
|
|
|
7
|
-
describe(
|
|
7
|
+
describe('Seasonal Assistant | accepts items and adds to their cart', () => {
|
|
8
8
|
const given = DeciderSpecification.for({
|
|
9
9
|
decide,
|
|
10
10
|
evolve,
|
|
11
11
|
initialState,
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
-
it(
|
|
14
|
+
it('should emit ItemsAddedToCart for valid AddItemsToCart', () => {
|
|
15
15
|
given([])
|
|
16
16
|
.when({
|
|
17
|
-
type:
|
|
17
|
+
type: 'AddItemsToCart',
|
|
18
18
|
data: {
|
|
19
|
-
sessionId:
|
|
19
|
+
sessionId: 'session-abc',
|
|
20
20
|
items: [
|
|
21
|
-
{ productId:
|
|
22
|
-
{ productId:
|
|
23
|
-
{ productId:
|
|
24
|
-
{ productId:
|
|
21
|
+
{ productId: 'prod-soccer-ball', quantity: 1 },
|
|
22
|
+
{ productId: 'prod-craft-kit', quantity: 1 },
|
|
23
|
+
{ productId: 'prod-laptop-bag', quantity: 1 },
|
|
24
|
+
{ productId: 'prod-mtg-starter', quantity: 1 },
|
|
25
25
|
],
|
|
26
26
|
},
|
|
27
27
|
metadata: { now: new Date() },
|
|
@@ -29,16 +29,16 @@ describe("Seasonal Assistant | accepts items and adds to their cart", () => {
|
|
|
29
29
|
|
|
30
30
|
.then([
|
|
31
31
|
{
|
|
32
|
-
type:
|
|
32
|
+
type: 'ItemsAddedToCart',
|
|
33
33
|
data: {
|
|
34
|
-
sessionId:
|
|
34
|
+
sessionId: 'session-abc',
|
|
35
35
|
items: [
|
|
36
|
-
{ productId:
|
|
37
|
-
{ productId:
|
|
38
|
-
{ productId:
|
|
39
|
-
{ productId:
|
|
36
|
+
{ productId: 'prod-soccer-ball', quantity: 1 },
|
|
37
|
+
{ productId: 'prod-craft-kit', quantity: 1 },
|
|
38
|
+
{ productId: 'prod-laptop-bag', quantity: 1 },
|
|
39
|
+
{ productId: 'prod-mtg-starter', quantity: 1 },
|
|
40
40
|
],
|
|
41
|
-
timestamp: new Date(
|
|
41
|
+
timestamp: new Date('2025-08-28T04:56:47.409Z'),
|
|
42
42
|
},
|
|
43
43
|
},
|
|
44
44
|
]);
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import { IllegalStateError } from
|
|
2
|
-
import type { State } from
|
|
3
|
-
import type { AddItemsToCart } from
|
|
4
|
-
import type { ItemsAddedToCart } from
|
|
1
|
+
import { IllegalStateError } from '@event-driven-io/emmett';
|
|
2
|
+
import type { State } from './state';
|
|
3
|
+
import type { AddItemsToCart } from './commands';
|
|
4
|
+
import type { ItemsAddedToCart } from './events';
|
|
5
5
|
|
|
6
|
-
export const decide = (
|
|
7
|
-
command: AddItemsToCart,
|
|
8
|
-
state: State,
|
|
9
|
-
): ItemsAddedToCart => {
|
|
6
|
+
export const decide = (command: AddItemsToCart, state: State): ItemsAddedToCart => {
|
|
10
7
|
switch (command.type) {
|
|
11
|
-
case
|
|
8
|
+
case 'AddItemsToCart': {
|
|
12
9
|
/**
|
|
13
10
|
* ## IMPLEMENTATION INSTRUCTIONS ##
|
|
14
11
|
*
|
|
@@ -28,9 +25,9 @@ export const decide = (
|
|
|
28
25
|
// data: { ...command.data },
|
|
29
26
|
// } as ItemsAddedToCart;
|
|
30
27
|
|
|
31
|
-
throw new IllegalStateError(
|
|
28
|
+
throw new IllegalStateError('Not yet implemented: ' + command.type);
|
|
32
29
|
}
|
|
33
30
|
default:
|
|
34
|
-
throw new IllegalStateError(
|
|
31
|
+
throw new IllegalStateError('Unexpected command type: ' + command.type);
|
|
35
32
|
}
|
|
36
33
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Event } from
|
|
1
|
+
import type { Event } from '@event-driven-io/emmett';
|
|
2
2
|
|
|
3
3
|
export type ItemsAddedToCart = Event<
|
|
4
|
-
|
|
4
|
+
'ItemsAddedToCart',
|
|
5
5
|
{
|
|
6
6
|
sessionId: string;
|
|
7
7
|
items: Array<{ productId: string; quantity: number }>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { State } from
|
|
2
|
-
import type { ItemsAddedToCart } from
|
|
1
|
+
import type { State } from './state';
|
|
2
|
+
import type { ItemsAddedToCart } from './events';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* ## IMPLEMENTATION INSTRUCTIONS ##
|
|
@@ -16,7 +16,7 @@ import type { ItemsAddedToCart } from "./events";
|
|
|
16
16
|
|
|
17
17
|
export const evolve = (state: State, event: ItemsAddedToCart): State => {
|
|
18
18
|
switch (event.type) {
|
|
19
|
-
case
|
|
19
|
+
case 'ItemsAddedToCart': {
|
|
20
20
|
// TODO: Update state based on ItemsAddedToCart
|
|
21
21
|
return {
|
|
22
22
|
...state,
|
|
@@ -1,22 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
} from
|
|
6
|
-
import { evolve } from "./evolve";
|
|
7
|
-
import { initialState } from "./state";
|
|
8
|
-
import { decide } from "./decide";
|
|
9
|
-
import type { AddItemsToCart } from "./commands";
|
|
1
|
+
import { CommandHandler, type EventStore, type MessageHandlerResult } from '@event-driven-io/emmett';
|
|
2
|
+
import { evolve } from './evolve';
|
|
3
|
+
import { initialState } from './state';
|
|
4
|
+
import { decide } from './decide';
|
|
5
|
+
import type { AddItemsToCart } from './commands';
|
|
10
6
|
|
|
11
7
|
const handler = CommandHandler({
|
|
12
8
|
evolve,
|
|
13
9
|
initialState,
|
|
14
10
|
});
|
|
15
11
|
|
|
16
|
-
export const handle = async (
|
|
17
|
-
eventStore: EventStore,
|
|
18
|
-
command: AddItemsToCart,
|
|
19
|
-
): Promise<MessageHandlerResult> => {
|
|
12
|
+
export const handle = async (eventStore: EventStore, command: AddItemsToCart): Promise<MessageHandlerResult> => {
|
|
20
13
|
const streamId = `shopping-session-${command.data.sessionId}`;
|
|
21
14
|
|
|
22
15
|
try {
|
|
@@ -24,8 +17,8 @@ export const handle = async (
|
|
|
24
17
|
return; // success (returns void)
|
|
25
18
|
} catch (error: any) {
|
|
26
19
|
return {
|
|
27
|
-
type:
|
|
28
|
-
reason: `Command failed: ${error?.message ??
|
|
20
|
+
type: 'SKIP',
|
|
21
|
+
reason: `Command failed: ${error?.message ?? 'Unknown'}`,
|
|
29
22
|
};
|
|
30
23
|
}
|
|
31
24
|
};
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import { Mutation, Resolver, Arg, Ctx, Field, InputType } from
|
|
2
|
-
import {
|
|
3
|
-
type GraphQLContext,
|
|
4
|
-
sendCommand,
|
|
5
|
-
MutationResponse,
|
|
6
|
-
} from "../../../shared";
|
|
1
|
+
import { Mutation, Resolver, Arg, Ctx, Field, InputType } from 'type-graphql';
|
|
2
|
+
import { type GraphQLContext, sendCommand, MutationResponse } from '../../../shared';
|
|
7
3
|
|
|
8
4
|
@InputType()
|
|
9
5
|
export class AddItemsToCartInput {
|
|
@@ -17,12 +13,12 @@ export class AddItemsToCartInput {
|
|
|
17
13
|
export class AddItemsToCartResolver {
|
|
18
14
|
@Mutation(() => MutationResponse)
|
|
19
15
|
async addItemsToCart(
|
|
20
|
-
@Arg(
|
|
16
|
+
@Arg('input', () => AddItemsToCartInput) input: AddItemsToCartInput,
|
|
21
17
|
@Ctx() ctx: GraphQLContext,
|
|
22
18
|
): Promise<MutationResponse> {
|
|
23
19
|
return await sendCommand(ctx.messageBus, {
|
|
24
|
-
type:
|
|
25
|
-
kind:
|
|
20
|
+
type: 'AddItemsToCart',
|
|
21
|
+
kind: 'Command',
|
|
26
22
|
data: { ...input },
|
|
27
23
|
});
|
|
28
24
|
}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import type { CommandProcessor, EventStore } from
|
|
2
|
-
import { handle } from
|
|
3
|
-
import type { AddItemsToCart } from
|
|
1
|
+
import type { CommandProcessor, EventStore } from '@event-driven-io/emmett';
|
|
2
|
+
import { handle } from './handle';
|
|
3
|
+
import type { AddItemsToCart } from './commands';
|
|
4
4
|
|
|
5
5
|
export function register(messageBus: CommandProcessor, eventStore: EventStore) {
|
|
6
|
-
messageBus.handle(
|
|
7
|
-
(command: AddItemsToCart) => handle(eventStore, command),
|
|
8
|
-
"AddItemsToCart",
|
|
9
|
-
);
|
|
6
|
+
messageBus.handle((command: AddItemsToCart) => handle(eventStore, command), 'AddItemsToCart');
|
|
10
7
|
}
|