Skip to content

Commit 9a22767

Browse files
committed
feat(tool-picker): add user answers on recommendation query
1 parent d97d34b commit 9a22767

File tree

4 files changed

+54
-31
lines changed

4 files changed

+54
-31
lines changed

apps/tool_picker/graphql/types.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,23 @@
88
RecommendationResult,
99
Tool,
1010
ToolAnswer,
11+
UserAnswer,
1112
)
1213
from utils.graphql.types import DjangoFileType
1314

1415

16+
@strawberry_django.type(Question)
17+
class QuestionTitleType:
18+
id: strawberry.ID
19+
title: strawberry.auto
20+
question_type: strawberry.auto
21+
description: strawberry.auto
22+
23+
1524
@strawberry_django.type(CheckboxOption)
1625
class CheckboxOptionType:
1726
id: strawberry.ID
18-
question_id: strawberry.ID
27+
question: QuestionTitleType
1928
order: strawberry.auto
2029
text: strawberry.auto
2130

@@ -49,16 +58,16 @@ class CatalogType:
4958
class ToolAnswerType:
5059
id: strawberry.ID
5160
tool_id: strawberry.ID
52-
question_id: strawberry.ID
61+
question: QuestionTitleType
5362
description: strawberry.auto
54-
ordinal_value: int
63+
ordinal_value: int | None
5564
selected_options: list[CheckboxOptionType]
5665

5766

5867
@strawberry_django.type(UserAnswer)
5968
class UserAnswerType:
60-
question: strawberry.auto
61-
ordinal_value: int
69+
question: QuestionTitleType
70+
ordinal_value: int | None
6271
selected_options: list[CheckboxOptionType]
6372

6473

@@ -79,12 +88,13 @@ class ToolType:
7988
class UserSubmissionType:
8089
id: strawberry.ID
8190
catalog_id: strawberry.ID
91+
answers: list[UserAnswerType]
8292

8393

8494
@strawberry_django.type(RecommendationResult)
8595
class RecommendationResultType:
8696
id: strawberry.auto
87-
submission: strawberry.auto
97+
submission: UserSubmissionType
8898
rank: strawberry.auto
8999
score: strawberry.auto
90100
tool: ToolType

apps/tool_picker/serializers.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from apps.tool_picker.models import (
88
CheckboxOption,
9+
OrdinalTypeEnum,
910
Question,
1011
QuestionTypeEnum,
1112
UserAnswer,
@@ -72,16 +73,6 @@ def validate(self, attrs: dict[str, typing.Any]):
7273
% question.get_question_type_display(),
7374
},
7475
)
75-
76-
else:
77-
raise serializers.ValidationError(
78-
{
79-
"non_field_errors": gettext(
80-
"Unsupported question type",
81-
),
82-
},
83-
)
84-
8576
return attrs
8677

8778

@@ -105,12 +96,17 @@ def validate(self, attrs: dict[str, typing.Any]):
10596
raise serializers.ValidationError(
10697
{"answer": gettext("At least one answer is required.")},
10798
)
108-
10999
# All the question related to the selected catalog catalog.
110100
catalog_questions = set(
111101
catalog.questions.values_list("id", flat=True),
112102
)
113103

104+
ordinal_answers = [ans for ans in answers if ans["question"].question_type == QuestionTypeEnum.ORDINAL]
105+
if ordinal_answers and all(ans["ordinal_value"] == OrdinalTypeEnum.NOT_AVAILABLE for ans in ordinal_answers):
106+
raise serializers.ValidationError(
107+
gettext("All ordinal answers should not be N/A. please choose one must be a different value."),
108+
)
109+
114110
# All the question answered by user.
115111
answered_questions = {ans["question"].id for ans in answers}
116112

apps/tool_picker/tests/query_test.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,10 @@ class Query:
5656
answers {
5757
id
5858
description
59-
questionId
59+
question {
60+
id
61+
title
62+
}
6063
toolId
6164
}
6265
}
@@ -91,7 +94,10 @@ class Query:
9194
labelNa
9295
options {
9396
id
94-
questionId
97+
question{
98+
id
99+
title
100+
}
95101
text
96102
order
97103
}
@@ -179,7 +185,10 @@ def _query():
179185
options=[
180186
dict(
181187
id=self.gID(self.options.pk),
182-
questionId=self.gID(self.question.pk),
188+
question=dict(
189+
id=self.gID(self.question.pk),
190+
title=self.question.title,
191+
),
183192
text=self.options.text,
184193
order=self.options.order,
185194
),
@@ -252,7 +261,10 @@ def _query():
252261
dict(
253262
id=self.gID(self.tool_answer.pk),
254263
description=self.tool_answer.description,
255-
questionId=self.gID(self.question.pk),
264+
question=dict(
265+
id=self.gID(self.question.pk),
266+
title=self.question.title,
267+
),
256268
toolId=self.gID(self.tool.pk),
257269
),
258270
],

schema.graphql

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ type CatalogTypeOffsetPaginated {
8686
"""Model representing option of checkbox question."""
8787
type CheckboxOptionType {
8888
id: ID!
89-
questionId: ID!
89+
question: QuestionTitleType!
9090
order: Int!
9191
text: String!
9292
}
@@ -132,10 +132,6 @@ type DjangoFileType {
132132
url: String!
133133
}
134134

135-
type DjangoModelType {
136-
pk: ID!
137-
}
138-
139135
input IDBaseFilterLookup {
140136
"""Exact match. Filter will be skipped on `null` value"""
141137
exact: ID
@@ -223,6 +219,14 @@ type Query {
223219
enums: AppEnumCollection!
224220
}
225221

222+
"""Model representing question within a catalog."""
223+
type QuestionTitleType {
224+
id: ID!
225+
title: String!
226+
questionType: QuestionTypeEnum!
227+
description: String!
228+
}
229+
226230
"""Model representing question within a catalog."""
227231
type QuestionType {
228232
id: ID!
@@ -262,7 +266,7 @@ input RecommendationResultOrder @oneOf {
262266
"""Model representing recommended tools for a submission."""
263267
type RecommendationResultType {
264268
id: ID!
265-
submission: DjangoModelType!
269+
submission: UserSubmissionType!
266270
rank: Int!
267271

268272
"""Proximity score - lower is better (closer match)"""
@@ -284,9 +288,9 @@ type RecommendationResultTypeOffsetPaginated {
284288
type ToolAnswerType {
285289
id: ID!
286290
toolId: ID!
287-
questionId: ID!
291+
question: QuestionTitleType!
288292
description: String!
289-
ordinalValue: Int!
293+
ordinalValue: Int
290294
selectedOptions: [CheckboxOptionType!]!
291295
}
292296

@@ -335,8 +339,8 @@ input UserAnswerInput {
335339

336340
"""Model representing a user's answer to a specific question."""
337341
type UserAnswerType {
338-
question: DjangoModelType!
339-
ordinalValue: Int!
342+
question: QuestionTitleType!
343+
ordinalValue: Int
340344
selectedOptions: [CheckboxOptionType!]!
341345
}
342346

@@ -367,6 +371,7 @@ input UserSubmissionInput {
367371
type UserSubmissionType {
368372
id: ID!
369373
catalogId: ID!
374+
answers: [UserAnswerType!]!
370375
}
371376

372377
type UserSubmissionTypeMutationResponseType {

0 commit comments

Comments
 (0)