@superapp_men/submit-assessment-results 1.0.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 +196 -0
- package/dist/index.d.ts +202 -0
- package/dist/index.esm.js +516 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +524 -0
- package/dist/index.js.map +1 -0
- package/dist/superapp.d.ts +114 -0
- package/dist/superapp.esm.js +22 -0
- package/dist/superapp.esm.js.map +1 -0
- package/dist/superapp.js +22 -0
- package/dist/superapp.js.map +1 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# @superapp_men/submit-assessment-results
|
|
2
|
+
|
|
3
|
+
Package for **partner applications** (running inside the SuperApp iframe or Capacitor WebView) to submit assessment results to the SuperApp. The SuperApp forwards the payload to the `SubmitAssessmentResults` backend endpoint (adding `academicYearId` and `periodWeekSubjectId`) and returns the **exact backend response** to the partner.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Builder / factory** to construct skills and questions data in a type-safe way.
|
|
8
|
+
- **Client-side validation** before calling the SuperApp: the same rules as the backend `SubmitAssessmentResultsValidator` run first. Invalid payloads get immediate `400`-style errors with field-level messages without a round-trip.
|
|
9
|
+
- **No `academicYearId` or `periodWeekSubjectId`** in the partner payload — the SuperApp adds them when calling the API.
|
|
10
|
+
- **Exact backend response** returned: success (200), validation errors (400), functional errors (422), and technical errors (404, 409, 429, 500).
|
|
11
|
+
|
|
12
|
+
**Current limitation (upcoming feature):** `subSkills` must be `null` or an empty array `[]`. Sub-skills are not yet supported; each skill must use `questions` only. Support for nested sub-skills will be added in a future release.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @superapp_men/submit-assessment-results
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage (Partner App)
|
|
21
|
+
|
|
22
|
+
Each skill must contain **questions** (not sub-skills). The `subSkills` property must be omitted, `null`, or an empty array `[]`; non-empty `subSkills` will fail validation until the feature is released.
|
|
23
|
+
|
|
24
|
+
### 1. Build payload with the builder
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import {
|
|
28
|
+
AssessmentSubmissionClient,
|
|
29
|
+
AssessmentSubmission,
|
|
30
|
+
QuestionRole,
|
|
31
|
+
} from "@superapp_men/submit-assessment-results";
|
|
32
|
+
|
|
33
|
+
const skill1 = AssessmentSubmission.skill("MATH_ADD_01", 1, true)
|
|
34
|
+
.questions([
|
|
35
|
+
AssessmentSubmission.question("Q001", true, QuestionRole.VALIDATION)
|
|
36
|
+
.order(1)
|
|
37
|
+
.responseTime(5000)
|
|
38
|
+
.build(),
|
|
39
|
+
AssessmentSubmission.question("Q002", false, QuestionRole.VALIDATION)
|
|
40
|
+
.order(2)
|
|
41
|
+
.build(),
|
|
42
|
+
])
|
|
43
|
+
.build();
|
|
44
|
+
|
|
45
|
+
const payload = AssessmentSubmission.builder()
|
|
46
|
+
.setStudentId("3fa85f64-5717-4562-b3fc-2c963f66afa6")
|
|
47
|
+
.setPartnerCode("PARTNER001")
|
|
48
|
+
.setAttemptId("unique-attempt-id-12345")
|
|
49
|
+
.setAser(false)
|
|
50
|
+
.setTotalSkillsInWeek(10)
|
|
51
|
+
.addSkill(skill1)
|
|
52
|
+
.build();
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 2. Adding multiple skills (e.g. 3 skills)
|
|
56
|
+
|
|
57
|
+
Use **`addSkill()`** for each skill or **`addSkills()`** with an array.
|
|
58
|
+
|
|
59
|
+
**Option A — One `addSkill()` per skill:**
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
const skill1 = AssessmentSubmission.skill("MATH_ADD_01", 1, true)
|
|
63
|
+
.questions([
|
|
64
|
+
AssessmentSubmission.question("Q001", true, QuestionRole.VALIDATION).order(1).build(),
|
|
65
|
+
AssessmentSubmission.question("Q002", false, QuestionRole.VALIDATION).order(2).build(),
|
|
66
|
+
])
|
|
67
|
+
.build();
|
|
68
|
+
|
|
69
|
+
const skill2 = AssessmentSubmission.skill("MATH_SUB_01", 2, true)
|
|
70
|
+
.questions([
|
|
71
|
+
AssessmentSubmission.question("Q003", true, QuestionRole.VALIDATION).order(1).build(),
|
|
72
|
+
AssessmentSubmission.question("Q004", true, QuestionRole.VALIDATION).order(2).build(),
|
|
73
|
+
])
|
|
74
|
+
.build();
|
|
75
|
+
|
|
76
|
+
const skill3 = AssessmentSubmission.skill("MATH_MUL_01", 3, false)
|
|
77
|
+
.questions([
|
|
78
|
+
AssessmentSubmission.question("Q005", false, QuestionRole.VALIDATION).order(1).build(),
|
|
79
|
+
])
|
|
80
|
+
.build();
|
|
81
|
+
|
|
82
|
+
const payload = AssessmentSubmission.builder()
|
|
83
|
+
.setStudentId(studentId)
|
|
84
|
+
.setPartnerCode("PARTNER001")
|
|
85
|
+
.setAttemptId("attempt-" + Date.now())
|
|
86
|
+
.setTotalSkillsInWeek(3)
|
|
87
|
+
.addSkill(skill1)
|
|
88
|
+
.addSkill(skill2)
|
|
89
|
+
.addSkill(skill3)
|
|
90
|
+
.build();
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Option B — Build an array and use `addSkills()`:**
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
const skills = [
|
|
97
|
+
AssessmentSubmission.skill("MATH_ADD_01", 1, true)
|
|
98
|
+
.questions([
|
|
99
|
+
AssessmentSubmission.question("Q001", true, QuestionRole.VALIDATION).order(1).build(),
|
|
100
|
+
AssessmentSubmission.question("Q002", false, QuestionRole.VALIDATION).order(2).build(),
|
|
101
|
+
])
|
|
102
|
+
.build(),
|
|
103
|
+
AssessmentSubmission.skill("MATH_SUB_01", 2, true)
|
|
104
|
+
.questions([
|
|
105
|
+
AssessmentSubmission.question("Q003", true, QuestionRole.VALIDATION).order(1).build(),
|
|
106
|
+
])
|
|
107
|
+
.build(),
|
|
108
|
+
AssessmentSubmission.skill("MATH_MUL_01", 3, false)
|
|
109
|
+
.questions([
|
|
110
|
+
AssessmentSubmission.question("Q005", false, QuestionRole.VALIDATION).order(1).build(),
|
|
111
|
+
])
|
|
112
|
+
.build(),
|
|
113
|
+
];
|
|
114
|
+
|
|
115
|
+
const payload = AssessmentSubmission.builder()
|
|
116
|
+
.setStudentId(studentId)
|
|
117
|
+
.setPartnerCode("PARTNER001")
|
|
118
|
+
.setAttemptId("attempt-" + Date.now())
|
|
119
|
+
.setTotalSkillsInWeek(3)
|
|
120
|
+
.addSkills(skills)
|
|
121
|
+
.build();
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Make sure **`setTotalSkillsInWeek(n)`** matches the number of skills you submit (e.g. `3` when you add 3 skills).
|
|
125
|
+
|
|
126
|
+
### 3. Submit and handle response
|
|
127
|
+
|
|
128
|
+
`client.submit(payload)` runs **client-side validation** first (same rules as the backend). If validation fails, it returns immediately with `ok: false`, `statusCode: 400`, and `body.errors` (field paths and messages). If validation passes, it sends the payload to the SuperApp and returns the backend response.
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
const client = new AssessmentSubmissionClient({ timeout: 30000, debug: true });
|
|
132
|
+
|
|
133
|
+
const result = await client.submit(payload);
|
|
134
|
+
|
|
135
|
+
if (result.ok) {
|
|
136
|
+
console.log("Success:", result.body.attemptId, result.body.status);
|
|
137
|
+
// result.body is SubmitAssessmentResultsResponse
|
|
138
|
+
} else {
|
|
139
|
+
console.log("Error:", result.statusCode, result.body);
|
|
140
|
+
// result.body is ValidationProblemDetails (400) or ProblemDetails (404/409/422/429/500)
|
|
141
|
+
if (result.statusCode === 400 && "errors" in result.body) {
|
|
142
|
+
console.log("Validation errors:", result.body.errors);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### 4. Optional: validate without submitting
|
|
148
|
+
|
|
149
|
+
You can run the same validation without sending to the SuperApp (e.g. to show errors in the UI before submit):
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
import { validateSubmitAssessmentPayload, toValidationProblemDetails } from "@superapp_men/submit-assessment-results";
|
|
153
|
+
|
|
154
|
+
const validation = validateSubmitAssessmentPayload(payload);
|
|
155
|
+
if (!validation.valid) {
|
|
156
|
+
const details = toValidationProblemDetails(validation.errors);
|
|
157
|
+
console.log("Validation errors:", details.errors); // Record<path, string[]>
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## API
|
|
162
|
+
|
|
163
|
+
- **`AssessmentSubmission.builder()`** — Fluent builder for the full partner payload.
|
|
164
|
+
- **`AssessmentSubmission.skill(code, order, passed)`** — Builder for one skill. Use `.questions(...)` only; `.subSkills(...)` with a non-empty array is not yet supported (validation will fail).
|
|
165
|
+
- **`AssessmentSubmission.question(code, isCorrect, questionRole)`** — Builder for one question.
|
|
166
|
+
- **`new AssessmentSubmissionClient(config)`** — Client with `submit(payload)` returning `Promise<SubmitAssessmentResultsApiResult>`. Runs client-side validation before sending.
|
|
167
|
+
- **`validateSubmitAssessmentPayload(payload)`** — Returns `{ valid, errors }` using the same rules as the backend validator.
|
|
168
|
+
- **`toValidationProblemDetails(errors)`** — Converts `ValidationError[]` to a backend-style `{ status: 400, title, errors }` object.
|
|
169
|
+
- **`SubmitAssessmentResultsApiResult`** — `{ ok: true, statusCode, body }` or `{ ok: false, statusCode, body }` with the exact backend response (or client-side validation errors when invalid).
|
|
170
|
+
|
|
171
|
+
## SuperApp integration
|
|
172
|
+
|
|
173
|
+
The SuperApp must:
|
|
174
|
+
|
|
175
|
+
1. Listen for messages with `type: "assessment:submit-request"`.
|
|
176
|
+
2. Enrich the payload with `academicYearId` and `periodWeekSubjectId`.
|
|
177
|
+
3. Call `POST api/v1.0/submit-results` with the enriched body and forward the HTTP status and response body back to the partner via postMessage with `type: "assessment:submit-response"`.
|
|
178
|
+
|
|
179
|
+
See the main SuperApp repo for `IframeCommunicationHandler` and the service that calls the SubmitAssessmentResults endpoint.
|
|
180
|
+
|
|
181
|
+
## Types (superapp entry)
|
|
182
|
+
|
|
183
|
+
For SuperApp-side code that handles these messages:
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
import type {
|
|
187
|
+
AssessmentSubmitRequestMessage,
|
|
188
|
+
AssessmentSubmitResponseMessage,
|
|
189
|
+
SubmitAssessmentResultsPartnerPayload,
|
|
190
|
+
} from "@superapp_men/submit-assessment-results/superapp";
|
|
191
|
+
import { AssessmentMessageType } from "@superapp_men/submit-assessment-results/superapp";
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## License
|
|
195
|
+
|
|
196
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for @superapp_men/submit-assessment-results
|
|
3
|
+
* Aligned with SubmitAssessmentResults API (academicYearId and periodWeekSubjectId
|
|
4
|
+
* are omitted in partner payload; SuperApp adds them when calling the endpoint).
|
|
5
|
+
*/
|
|
6
|
+
/** Question role in the assessment (matches backend enum). */
|
|
7
|
+
declare enum QuestionRole {
|
|
8
|
+
POSITIONING = 1,
|
|
9
|
+
VALIDATION = 2,
|
|
10
|
+
REMEDIATION = 3,
|
|
11
|
+
BONUS = 4
|
|
12
|
+
}
|
|
13
|
+
/** Response time: milliseconds (number) or "hh:mm:ss" string. */
|
|
14
|
+
type ResponseTimeInput = number | string;
|
|
15
|
+
/** Single question result (partner payload). */
|
|
16
|
+
interface SubmittedQuestionResultPayload {
|
|
17
|
+
questionCode: string;
|
|
18
|
+
isCorrect: boolean;
|
|
19
|
+
questionOrder: number;
|
|
20
|
+
questionRole: QuestionRole;
|
|
21
|
+
responseTime?: ResponseTimeInput;
|
|
22
|
+
attemptsCount?: number;
|
|
23
|
+
questionTextFr?: string;
|
|
24
|
+
questionTextAr?: string;
|
|
25
|
+
}
|
|
26
|
+
/** Single skill result; must have either subSkills or questions. */
|
|
27
|
+
interface SubmittedSkillResultPayload {
|
|
28
|
+
skillCode: string;
|
|
29
|
+
skillOrder: number;
|
|
30
|
+
passed: boolean;
|
|
31
|
+
titleFr?: string;
|
|
32
|
+
titleAr?: string;
|
|
33
|
+
descriptionFr?: string;
|
|
34
|
+
descriptionAr?: string;
|
|
35
|
+
subSkills?: SubmittedSkillResultPayload[];
|
|
36
|
+
questions?: SubmittedQuestionResultPayload[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Partner payload for submit assessment results.
|
|
40
|
+
* academicYearId and periodWeekSubjectId are NOT included; the SuperApp
|
|
41
|
+
* adds them when calling the backend.
|
|
42
|
+
*/
|
|
43
|
+
interface SubmitAssessmentResultsPartnerPayload {
|
|
44
|
+
studentId: string;
|
|
45
|
+
partnerCode: string;
|
|
46
|
+
attemptId: string;
|
|
47
|
+
isAser?: boolean;
|
|
48
|
+
totalSkillsInWeek: number;
|
|
49
|
+
skills: SubmittedSkillResultPayload[];
|
|
50
|
+
}
|
|
51
|
+
/** Success response from SubmitAssessmentResults endpoint. */
|
|
52
|
+
interface SubmitAssessmentResultsResponse {
|
|
53
|
+
attemptId: string;
|
|
54
|
+
isDuplicate: boolean;
|
|
55
|
+
status: string;
|
|
56
|
+
message: string | null;
|
|
57
|
+
serverTimeUtc: string;
|
|
58
|
+
}
|
|
59
|
+
/** ValidationProblemDetails (400). */
|
|
60
|
+
interface ValidationProblemDetails {
|
|
61
|
+
type?: string;
|
|
62
|
+
title?: string;
|
|
63
|
+
status: number;
|
|
64
|
+
detail?: string;
|
|
65
|
+
instance?: string;
|
|
66
|
+
errors?: Record<string, string[]>;
|
|
67
|
+
}
|
|
68
|
+
/** ProblemDetails (404, 409, 422, 429, 500). */
|
|
69
|
+
interface ProblemDetails {
|
|
70
|
+
type?: string;
|
|
71
|
+
title?: string;
|
|
72
|
+
status?: number;
|
|
73
|
+
detail?: string;
|
|
74
|
+
instance?: string;
|
|
75
|
+
[key: string]: unknown;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Result of calling submit: either the success response or an error response
|
|
79
|
+
* with statusCode and body as returned by the backend.
|
|
80
|
+
*/
|
|
81
|
+
type SubmitAssessmentResultsApiResult = {
|
|
82
|
+
ok: true;
|
|
83
|
+
statusCode: number;
|
|
84
|
+
body: SubmitAssessmentResultsResponse;
|
|
85
|
+
} | {
|
|
86
|
+
ok: false;
|
|
87
|
+
statusCode: number;
|
|
88
|
+
body: ValidationProblemDetails | ProblemDetails;
|
|
89
|
+
};
|
|
90
|
+
/** Message types for iframe/Capacitor communication. */
|
|
91
|
+
declare enum AssessmentMessageType {
|
|
92
|
+
REQUEST = "assessment:submit-request",
|
|
93
|
+
RESPONSE = "assessment:submit-response"
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
interface AssessmentSubmissionClientConfig {
|
|
97
|
+
/** Request timeout in ms (default 30000). */
|
|
98
|
+
timeout?: number;
|
|
99
|
+
/** Enable debug logs (default false). */
|
|
100
|
+
debug?: boolean;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Client for partner applications to submit assessment results to the SuperApp.
|
|
104
|
+
* Sends the payload via postMessage to the parent (SuperApp); the SuperApp
|
|
105
|
+
* adds academicYearId and periodWeekSubjectId and calls the backend, then
|
|
106
|
+
* returns the exact backend response (success, validation errors, functional
|
|
107
|
+
* errors, or technical errors).
|
|
108
|
+
*/
|
|
109
|
+
declare class AssessmentSubmissionClient {
|
|
110
|
+
private bridge;
|
|
111
|
+
private config;
|
|
112
|
+
constructor(config?: AssessmentSubmissionClientConfig);
|
|
113
|
+
/**
|
|
114
|
+
* Submit assessment results. Runs client-side validation first (same rules as backend);
|
|
115
|
+
* if invalid, returns immediately with statusCode 400 and errors. Otherwise sends to
|
|
116
|
+
* SuperApp and returns the exact backend response.
|
|
117
|
+
*/
|
|
118
|
+
submit(payload: SubmitAssessmentResultsPartnerPayload): Promise<SubmitAssessmentResultsApiResult>;
|
|
119
|
+
setDebug(enabled: boolean): void;
|
|
120
|
+
destroy(): void;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Fluent builder for a single question result.
|
|
125
|
+
*/
|
|
126
|
+
declare class QuestionResultBuilder {
|
|
127
|
+
private data;
|
|
128
|
+
constructor(questionCode: string, isCorrect: boolean, questionRole: QuestionRole);
|
|
129
|
+
order(questionOrder: number): this;
|
|
130
|
+
responseTime(value: number | string): this;
|
|
131
|
+
attemptsCount(count: number): this;
|
|
132
|
+
questionText(fr?: string, ar?: string): this;
|
|
133
|
+
build(): SubmittedQuestionResultPayload;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Fluent builder for a single skill result (with questions or sub-skills).
|
|
137
|
+
*/
|
|
138
|
+
declare class SkillResultBuilder {
|
|
139
|
+
private data;
|
|
140
|
+
constructor(skillCode: string, skillOrder: number, passed: boolean);
|
|
141
|
+
title(titleFr?: string, titleAr?: string): this;
|
|
142
|
+
description(descriptionFr?: string, descriptionAr?: string): this;
|
|
143
|
+
questions(questions: SubmittedQuestionResultPayload[]): this;
|
|
144
|
+
subSkills(subSkills: SubmittedSkillResultPayload[]): this;
|
|
145
|
+
build(): SubmittedSkillResultPayload;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Fluent builder for the full partner payload (no academicYearId / periodWeekSubjectId).
|
|
149
|
+
*/
|
|
150
|
+
declare class AssessmentSubmissionBuilder {
|
|
151
|
+
private studentId;
|
|
152
|
+
private partnerCode;
|
|
153
|
+
private attemptId;
|
|
154
|
+
private isAser;
|
|
155
|
+
private totalSkillsInWeek;
|
|
156
|
+
private skills;
|
|
157
|
+
setStudentId(studentId: string): this;
|
|
158
|
+
setPartnerCode(partnerCode: string): this;
|
|
159
|
+
setAttemptId(attemptId: string): this;
|
|
160
|
+
setAser(isAser: boolean): this;
|
|
161
|
+
setTotalSkillsInWeek(total: number): this;
|
|
162
|
+
addSkill(skill: SubmittedSkillResultPayload): this;
|
|
163
|
+
addSkills(skillList: SubmittedSkillResultPayload[]): this;
|
|
164
|
+
build(): SubmitAssessmentResultsPartnerPayload;
|
|
165
|
+
}
|
|
166
|
+
/** Factory helpers. */
|
|
167
|
+
declare const AssessmentSubmission: {
|
|
168
|
+
builder(): AssessmentSubmissionBuilder;
|
|
169
|
+
skill(skillCode: string, skillOrder: number, passed: boolean): SkillResultBuilder;
|
|
170
|
+
question(questionCode: string, isCorrect: boolean, questionRole?: QuestionRole): QuestionResultBuilder;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Client-side validation mirroring backend SubmitAssessmentResultsValidator.
|
|
175
|
+
* Run before sending to SuperApp so partners get immediate validation errors
|
|
176
|
+
* without a round-trip to the API.
|
|
177
|
+
*/
|
|
178
|
+
|
|
179
|
+
interface ValidationError {
|
|
180
|
+
/** Property path (e.g. "StudentId", "Skills[0].SkillCode"). */
|
|
181
|
+
key: string;
|
|
182
|
+
message: string;
|
|
183
|
+
}
|
|
184
|
+
interface ValidationResult {
|
|
185
|
+
valid: boolean;
|
|
186
|
+
errors: ValidationError[];
|
|
187
|
+
}
|
|
188
|
+
/** Flatten to backend-style errors record (key -> string[]). */
|
|
189
|
+
declare function toValidationProblemDetails(errors: ValidationError[]): {
|
|
190
|
+
status: number;
|
|
191
|
+
title: string;
|
|
192
|
+
errors: Record<string, string[]>;
|
|
193
|
+
};
|
|
194
|
+
/**
|
|
195
|
+
* Validate the partner payload using the same rules as the backend
|
|
196
|
+
* SubmitAssessmentResultsValidator. Call this before submit() to get
|
|
197
|
+
* immediate validation errors without calling the SuperApp/backend.
|
|
198
|
+
*/
|
|
199
|
+
declare function validateSubmitAssessmentPayload(payload: SubmitAssessmentResultsPartnerPayload): ValidationResult;
|
|
200
|
+
|
|
201
|
+
export { AssessmentMessageType, AssessmentSubmission, AssessmentSubmissionBuilder, AssessmentSubmissionClient, QuestionResultBuilder, QuestionRole, SkillResultBuilder, toValidationProblemDetails, validateSubmitAssessmentPayload };
|
|
202
|
+
export type { AssessmentSubmissionClientConfig, ProblemDetails, ResponseTimeInput, SubmitAssessmentResultsApiResult, SubmitAssessmentResultsPartnerPayload, SubmitAssessmentResultsResponse, SubmittedQuestionResultPayload, SubmittedSkillResultPayload, ValidationError, ValidationProblemDetails, ValidationResult };
|