Skip to content

Commit b165915

Browse files
Merge pull request #63 from NYCU-SDC/refactor/refactor-answer-request-model
Refactor answer request models and update response structures
2 parents e4f07ef + 91fb8ec commit b165915

4 files changed

Lines changed: 90 additions & 30 deletions

File tree

src/form/answer/models.tsp

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,55 @@
11
using Http;
22

33
namespace CoreSystem.Responses {
4-
@example(#{ questionId: "ee894524-4bd8-4a64-8fd2-a53b39ca94cd", questionType: CoreSystem.Forms.QuestionTypes.shortText, value: #["John Doe"] })
4+
@example(#{ questionId: "ee894524-4bd8-4a64-8fd2-a53b39ca94cd", questionType: CoreSystem.Forms.QuestionTypes.shortText, value: "John Doe" })
5+
model StringAnswer {
6+
@doc("The question being answered.")
7+
questionId: uuid;
8+
9+
@doc("The type of the question being answered.")
10+
questionType: CoreSystem.Forms.QuestionTypes.shortText | CoreSystem.Forms.QuestionTypes.longText | CoreSystem.Forms.QuestionTypes.hyperlink;
11+
12+
@doc("The answer value (format depends on questionType from questionId).")
13+
value: string;
14+
}
15+
516
@example(#{
617
questionId: "2b2bc4f4-71c1-478b-9e36-516eac6b36c3",
718
questionType: CoreSystem.Forms.QuestionTypes.multipleChoice,
819
value: #["f421cfc2-2b84-4da9-9629-011af609935a", "2ca86a6d-7735-4f17-8676-29b4724b524f"],
920
})
1021
@doc("Request model for submitting an individual answer")
11-
model AnswerJSON {
22+
model StringArrayAnswer {
1223
@doc("The question being answered.")
1324
questionId: uuid;
1425

1526
@doc("The type of the question being answered.")
1627
questionType:
17-
| CoreSystem.Forms.QuestionTypes.shortText
18-
| CoreSystem.Forms.QuestionTypes.longText
1928
| CoreSystem.Forms.QuestionTypes.singleChoice
2029
| CoreSystem.Forms.QuestionTypes.multipleChoice
2130
| CoreSystem.Forms.QuestionTypes.dropdown
2231
| CoreSystem.Forms.QuestionTypes.detailedMultipleChoice
23-
| CoreSystem.Forms.QuestionTypes.date
24-
| CoreSystem.Forms.QuestionTypes.ranking
25-
| CoreSystem.Forms.QuestionTypes.hyperlink;
32+
| CoreSystem.Forms.QuestionTypes.ranking;
2633

2734
@doc("The answer value (format depends on questionType from questionId).")
2835
value: string[];
2936
}
3037

38+
@example(#{ questionId: "2b2bc4f4-71c1-478b-9e36-516eac6b36c3", questionType: CoreSystem.Forms.QuestionTypes.date, value: utcDateTime.fromISO("2024-05-06T12:20-12Z") })
39+
model DateAnswer {
40+
@doc("The question being answered.")
41+
questionId: uuid;
42+
43+
@doc("The type of the question being answered.")
44+
questionType: CoreSystem.Forms.QuestionTypes.date;
45+
46+
@doc("The answer value for date question in ISO format (e.g., '2024-12-31').")
47+
value: utcDateTime;
48+
}
49+
3150
@example(#{ questionId: "2b2bc4f4-71c1-478b-9e36-516eac6b36c3", questionType: CoreSystem.Forms.QuestionTypes.linearScale, value: 4 })
3251
@doc("Request model for submitting an individual scale answer")
33-
model ScaleAnswerJSON {
52+
model ScaleAnswer {
3453
@doc("The question being answered.")
3554
questionId: uuid;
3655

@@ -41,32 +60,38 @@ namespace CoreSystem.Responses {
4160
value: int32;
4261
}
4362

44-
@example(#{ questionId: "2b2bc4f4-71c1-478b-9e36-516eac6b36c3", questionType: CoreSystem.Forms.QuestionTypes.oauthConnect, avatarUrl: "https://example.com/avatar.jpg", username: "JohnDoe" })
63+
@example(#{
64+
questionId: "2b2bc4f4-71c1-478b-9e36-516eac6b36c3",
65+
questionType: CoreSystem.Forms.QuestionTypes.oauthConnect,
66+
value: #{ username: "johndoe", avatarUrl: "https://example.com/avatar.jpg" },
67+
})
4568
@doc("Response model for an OAuth answer")
46-
model OauthAnswerJSON {
69+
model OauthAnswer {
4770
@doc("The question being answered.")
4871
questionId: uuid;
4972

5073
@doc("The type of the question being answered.")
5174
questionType: CoreSystem.Forms.QuestionTypes.oauthConnect;
5275

53-
@doc("The avatar URL from the OAuth provider.")
54-
avatarUrl: string;
76+
value: {
77+
@doc("The avatar URL from the OAuth provider.")
78+
avatarUrl: string;
5579

56-
@doc("The username from the OAuth provider.")
57-
username: string;
80+
@doc("The username from the OAuth provider.")
81+
username: string;
82+
};
5883
}
5984

6085
@doc("Request model for update or submit the form response.")
6186
@example(#{
6287
answers: #[
63-
#{ questionId: "ee894524-4bd8-4a64-8fd2-a53b39ca94cd", questionType: CoreSystem.Forms.QuestionTypes.shortText, value: #["John Doe"] },
88+
#{ questionId: "ee894524-4bd8-4a64-8fd2-a53b39ca94cd", questionType: CoreSystem.Forms.QuestionTypes.shortText, value: "John Doe" },
6489
#{ questionId: "2b2bc4f4-71c1-478b-9e36-516eac6b36c3", questionType: CoreSystem.Forms.QuestionTypes.linearScale, value: 4 }
6590
],
6691
})
6792
model AnswersRequest {
6893
@doc("The answers to be saved. Can contain a partial subset for drafts or the full set for submission.")
69-
answers: (AnswerJSON | ScaleAnswerJSON)[];
94+
answers: (StringAnswer | StringArrayAnswer | ScaleAnswer | DateAnswer)[];
7095
}
7196

7297
@doc("Request model for uploading files as answers to a specific question in a response.")
@@ -81,7 +106,7 @@ namespace CoreSystem.Responses {
81106
id: uuid;
82107

83108
@doc("The auto-created/updated answer with file URLs.")
84-
questionAnswerPair: AnswerJSON;
109+
questionAnswerPair: StringArrayAnswer;
85110
}
86111

87112
@doc("Model for a question with its answer in preview view")
@@ -93,7 +118,7 @@ namespace CoreSystem.Responses {
93118
displayValue: string;
94119

95120
@doc("The structured answer data for submission. Null if not answered yet.")
96-
answerData?: AnswerJSON | ScaleAnswerJSON | OauthAnswerJSON;
121+
answerData?: StringAnswer | StringArrayAnswer | ScaleAnswer | DateAnswer | OauthAnswer;
97122
}
98123

99124
@example(#{
@@ -106,11 +131,11 @@ namespace CoreSystem.Responses {
106131
})
107132
@doc("Response model for getting an answer of a specific question.")
108133
model GetQuestionResponse {
109-
@doc("The response's unique identifier.")
134+
@doc("Response ID that this question answer belongs to.")
110135
id: uuid;
111136

112137
@doc("A question with its answer for this response..")
113-
questionAnswerPair: AnswerJSON;
138+
questionAnswerPair: StringAnswer | StringArrayAnswer | ScaleAnswer | DateAnswer | OauthAnswer;
114139
}
115140

116141
@doc("Response model for a single answer in question answers view")
@@ -125,7 +150,7 @@ namespace CoreSystem.Responses {
125150
submittedBy: uuid;
126151

127152
@doc("The answer data. Type depends on the question type.")
128-
answer: AnswerJSON | ScaleAnswerJSON | OauthAnswerJSON;
153+
answer: StringAnswer | StringArrayAnswer | ScaleAnswer | DateAnswer | OauthAnswer;
129154

130155
@doc("The creation timestamp of the answer.")
131156
createdAt: utcDateTime;

src/form/answer/operations.tsp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,7 @@ namespace CoreSystem.Responses {
3232
@doc("Upload files as answers for a specific question in the response. This operation automatically creates or updates the answer for this question with the uploaded file URLs.")
3333
@route("/responses/{responseId}/questions/{questionId}/files")
3434
@post
35-
op uploadQuestionFiles(
36-
@path responseId: uuid,
37-
@path questionId: uuid,
38-
@header("content-type") contentType: "multipart/form-data",
39-
@multipartBody body: QuestionFilesUploadRequest,
40-
): {
35+
op uploadQuestionFiles(@path responseId: uuid, @path questionId: uuid, @header("content-type") contentType: "multipart/form-data", @multipartBody body: QuestionFilesUploadRequest): {
4136
@statusCode statusCode: 200;
4237
@body response: QuestionFilesUploadResponse;
4338
} | {

src/form/question/models.tsp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,24 @@ namespace CoreSystem.Forms {
162162
description?: string;
163163
}
164164

165+
@doc("Options for date questions.")
166+
model DateOption {
167+
@doc("Whether the year component is required for the date.")
168+
hasYear: boolean;
169+
170+
@doc("Whether the month component is required for the date.")
171+
hasMonth: boolean;
172+
173+
@doc("Whether the day component is required for the date.")
174+
hasDay: boolean;
175+
176+
@doc("Minimum date range in utcDateTime (e.g., 2025-01-01T00:00:00Z for 2025/1/1 00:00:00 UTC). If specified, use the first day of the month/year for the minimum value.")
177+
minDate?: utcDateTime;
178+
179+
@doc("Maximum date range in utcDateTime (e.g., 2025-05-31T23:59:59Z for 2025/5/31 23:59:59 UTC). If specified, use the last day of the month/year for the maximum value.")
180+
maxDate?: utcDateTime;
181+
}
182+
165183
@doc("Response model for the detailed structure of a question.")
166184
model QuestionResponse {
167185
@doc("The question's unique identifier.")
@@ -191,6 +209,9 @@ namespace CoreSystem.Forms {
191209
@doc("Available options for file upload questions.")
192210
uploadFile?: UploadFileOption;
193211

212+
@doc("Available options for date questions.")
213+
date?: DateOption;
214+
194215
@doc("Available options for OAuth connect questions.")
195216
oauthConnect?: CoreSystem.Auth.OAuthProviders;
196217

@@ -273,6 +294,22 @@ namespace CoreSystem.Forms {
273294
order: 12,
274295
oauthConnect: CoreSystem.Auth.OAuthProviders.github,
275296
})
297+
@example(#{
298+
required: true,
299+
type: QuestionTypes.date,
300+
title: "When will you graduate?",
301+
description: "Please select your graduation date",
302+
order: 13,
303+
date: #{ hasYear: true, hasMonth: true, hasDay: true },
304+
})
305+
@example(#{
306+
required: true,
307+
type: QuestionTypes.date,
308+
title: "Which year did you join?",
309+
description: "Select year and month only",
310+
order: 14,
311+
date: #{ hasYear: true, hasMonth: true, hasDay: false },
312+
})
276313
model QuestionRequest {
277314
@doc("Whether the question is required to answer or not.")
278315
required: boolean;
@@ -298,6 +335,9 @@ namespace CoreSystem.Forms {
298335
@doc("Available options for file upload questions.")
299336
uploadFile?: UploadFileOption;
300337

338+
@doc("Available options for date questions.")
339+
date?: DateOption;
340+
301341
@doc("Available options for OAuth connect questions.")
302342
oauthConnect?: CoreSystem.Auth.OAuthProviders;
303343

src/form/response/models.tsp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ namespace CoreSystem.Responses {
1616
updatedAt: utcDateTime;
1717

1818
@doc("The updated answer data.")
19-
answers: (AnswerJSON | ScaleAnswerJSON | OauthAnswerJSON)[];
19+
answers: (StringAnswer | StringArrayAnswer | ScaleAnswer | DateAnswer)[];
2020
}
2121

2222
@doc("Response model for a single response in list view")
23-
model ResponseJSON {
23+
model Response {
2424
@doc("The response's unique identifier.")
2525
id: uuid;
2626

@@ -40,7 +40,7 @@ namespace CoreSystem.Responses {
4040
formId: uuid;
4141

4242
@doc("All responses for this form.")
43-
responses: ResponseJSON[];
43+
responses: Response[];
4444
}
4545

4646
@doc("Model for a single section in preview view")

0 commit comments

Comments
 (0)