academe-kit 0.9.6 → 0.9.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.
@@ -132,7 +132,6 @@ export declare function createCertificateService(apiClient: AcademeApiClient): {
132
132
  "application/json": {
133
133
  status?: string;
134
134
  data?: components["schemas"]["Certificate"];
135
- message?: string;
136
135
  };
137
136
  };
138
137
  };
@@ -179,7 +178,6 @@ export declare function createCertificateService(apiClient: AcademeApiClient): {
179
178
  "application/json": {
180
179
  status?: string;
181
180
  data?: components["schemas"]["Certificate"];
182
- message?: string;
183
181
  };
184
182
  };
185
183
  };
@@ -215,16 +213,11 @@ export declare function createCertificateService(apiClient: AcademeApiClient): {
215
213
  };
216
214
  requestBody?: never;
217
215
  responses: {
218
- 200: {
216
+ 204: {
219
217
  headers: {
220
218
  [name: string]: unknown;
221
219
  };
222
- content: {
223
- "application/json": {
224
- status?: string;
225
- message?: string;
226
- };
227
- };
220
+ content?: never;
228
221
  };
229
222
  400: components["responses"]["BadRequest"];
230
223
  401: components["responses"]["Unauthorized"];
@@ -0,0 +1,349 @@
1
+ import type { AcademeApiClient } from "./index";
2
+ import type { paths } from "../types/academe-api";
3
+ type GetSubmissionsParams = paths["/submissions"]["get"]["parameters"]["query"];
4
+ type CreateSubmissionBody = paths["/submissions"]["post"]["requestBody"]["content"]["application/json"] & {
5
+ /** Institution under which the user is submitting (from institution_registration) */
6
+ institutionId: string;
7
+ };
8
+ type AttachFilesBody = paths["/submissions/{id}/files"]["post"]["requestBody"]["content"]["application/json"];
9
+ type AiEvaluationBody = paths["/submissions/{id}/ai-evaluation"]["post"]["requestBody"]["content"]["application/json"];
10
+ type TeacherEvaluationBody = paths["/submissions/{id}/teacher-evaluation"]["patch"]["requestBody"]["content"]["application/json"];
11
+ export declare function createSubmissionService(apiClient: AcademeApiClient): {
12
+ /**
13
+ * List submissions with filters and pagination
14
+ */
15
+ getAll(params?: GetSubmissionsParams): Promise<import("openapi-fetch").FetchResponse<{
16
+ parameters: {
17
+ query?: {
18
+ challengeId?: string;
19
+ userId?: string;
20
+ groupId?: string;
21
+ institutionId?: string;
22
+ status?: "submitted" | "ai_evaluated" | "approved" | "rejected";
23
+ page?: import("../types/academe-api").components["parameters"]["page"];
24
+ limit?: import("../types/academe-api").components["parameters"]["limit"];
25
+ };
26
+ header?: never;
27
+ path?: never;
28
+ cookie?: never;
29
+ };
30
+ requestBody?: never;
31
+ responses: {
32
+ 200: {
33
+ headers: {
34
+ [name: string]: unknown;
35
+ };
36
+ content: {
37
+ "application/json": {
38
+ status?: string;
39
+ data?: import("../types/academe-api").components["schemas"]["Submission"][];
40
+ meta?: import("../types/academe-api").components["schemas"]["PaginationMeta"];
41
+ };
42
+ };
43
+ };
44
+ 401: import("../types/academe-api").components["responses"]["Unauthorized"];
45
+ };
46
+ }, {
47
+ params: {
48
+ query: {
49
+ challengeId?: string;
50
+ userId?: string;
51
+ groupId?: string;
52
+ institutionId?: string;
53
+ status?: "submitted" | "ai_evaluated" | "approved" | "rejected";
54
+ page?: import("../types/academe-api").components["parameters"]["page"];
55
+ limit?: import("../types/academe-api").components["parameters"]["limit"];
56
+ } | undefined;
57
+ };
58
+ }, `${string}/${string}`>>;
59
+ /**
60
+ * Get submission with files and per-criterion scores
61
+ */
62
+ getById(id: string): Promise<import("openapi-fetch").FetchResponse<{
63
+ parameters: {
64
+ query?: never;
65
+ header?: never;
66
+ path: {
67
+ id: import("../types/academe-api").components["parameters"]["id"];
68
+ };
69
+ cookie?: never;
70
+ };
71
+ requestBody?: never;
72
+ responses: {
73
+ 200: {
74
+ headers: {
75
+ [name: string]: unknown;
76
+ };
77
+ content: {
78
+ "application/json": {
79
+ status?: string;
80
+ data?: import("../types/academe-api").components["schemas"]["Submission"] & {
81
+ files?: import("../types/academe-api").components["schemas"]["SubmissionFile"][];
82
+ criterionScores?: import("../types/academe-api").components["schemas"]["SubmissionCriterionScore"][];
83
+ };
84
+ };
85
+ };
86
+ };
87
+ 401: import("../types/academe-api").components["responses"]["Unauthorized"];
88
+ 404: import("../types/academe-api").components["responses"]["NotFound"];
89
+ };
90
+ }, {
91
+ params: {
92
+ path: {
93
+ id: string;
94
+ };
95
+ };
96
+ }, `${string}/${string}`>>;
97
+ /**
98
+ * Create a new submission attempt (status=submitted)
99
+ * - Cannot submit to a global template (clone first)
100
+ * - For group challenges: groupId is required and user must be a member
101
+ * - For individual challenges: groupId must be omitted
102
+ * - Cannot create when there is already an active submission
103
+ * - attempt_number is computed server-side
104
+ */
105
+ create(data: CreateSubmissionBody): Promise<import("openapi-fetch").FetchResponse<{
106
+ parameters: {
107
+ query?: never;
108
+ header?: never;
109
+ path?: never;
110
+ cookie?: never;
111
+ };
112
+ requestBody: {
113
+ content: {
114
+ "application/json": {
115
+ challengeId: string;
116
+ institutionId: string;
117
+ groupId?: string;
118
+ description?: string;
119
+ };
120
+ };
121
+ };
122
+ responses: {
123
+ 201: {
124
+ headers: {
125
+ [name: string]: unknown;
126
+ };
127
+ content: {
128
+ "application/json": {
129
+ status?: string;
130
+ data?: import("../types/academe-api").components["schemas"]["Submission"];
131
+ };
132
+ };
133
+ };
134
+ 400: import("../types/academe-api").components["responses"]["BadRequest"];
135
+ 403: import("../types/academe-api").components["responses"]["Forbidden"];
136
+ 404: import("../types/academe-api").components["responses"]["NotFound"];
137
+ 409: import("../types/academe-api").components["responses"]["Conflict"];
138
+ };
139
+ }, {
140
+ body: never;
141
+ }, `${string}/${string}`>>;
142
+ /**
143
+ * Attach files or links to a submission (batch)
144
+ * Each item must have exactly ONE of fileId or url (XOR).
145
+ * - submissionType in [images, videos, audio, files] → items must have fileId
146
+ * - submissionType === 'links' → items must have url
147
+ */
148
+ attachFiles(submissionId: string, data: AttachFilesBody): Promise<import("openapi-fetch").FetchResponse<{
149
+ parameters: {
150
+ query?: never;
151
+ header?: never;
152
+ path: {
153
+ id: import("../types/academe-api").components["parameters"]["id"];
154
+ };
155
+ cookie?: never;
156
+ };
157
+ requestBody: {
158
+ content: {
159
+ "application/json": {
160
+ items: {
161
+ fileId?: string | null;
162
+ url?: string | null;
163
+ index?: number;
164
+ }[];
165
+ };
166
+ };
167
+ };
168
+ responses: {
169
+ 201: {
170
+ headers: {
171
+ [name: string]: unknown;
172
+ };
173
+ content: {
174
+ "application/json": {
175
+ status?: string;
176
+ data?: import("../types/academe-api").components["schemas"]["SubmissionFile"][];
177
+ };
178
+ };
179
+ };
180
+ 400: import("../types/academe-api").components["responses"]["BadRequest"];
181
+ 404: import("../types/academe-api").components["responses"]["NotFound"];
182
+ 409: import("../types/academe-api").components["responses"]["Conflict"];
183
+ };
184
+ }, {
185
+ params: {
186
+ path: {
187
+ id: string;
188
+ };
189
+ };
190
+ body: {
191
+ items: {
192
+ fileId?: string | null;
193
+ url?: string | null;
194
+ index?: number;
195
+ }[];
196
+ };
197
+ }, `${string}/${string}`>>;
198
+ /**
199
+ * Remove a file or link from a submission
200
+ * Only allowed when submission is in status submitted or ai_evaluated
201
+ */
202
+ removeFile(submissionId: string, fileRowId: string): Promise<import("openapi-fetch").FetchResponse<{
203
+ parameters: {
204
+ query?: never;
205
+ header?: never;
206
+ path: {
207
+ id: import("../types/academe-api").components["parameters"]["id"];
208
+ fileRowId: string;
209
+ };
210
+ cookie?: never;
211
+ };
212
+ requestBody?: never;
213
+ responses: {
214
+ 204: {
215
+ headers: {
216
+ [name: string]: unknown;
217
+ };
218
+ content?: never;
219
+ };
220
+ 400: import("../types/academe-api").components["responses"]["BadRequest"];
221
+ 404: import("../types/academe-api").components["responses"]["NotFound"];
222
+ };
223
+ }, {
224
+ params: {
225
+ path: {
226
+ id: string;
227
+ fileRowId: string;
228
+ };
229
+ };
230
+ }, `${string}/${string}`>>;
231
+ /**
232
+ * Register AI evaluation (called by the AI service callback).
233
+ * Moves status from submitted → ai_evaluated.
234
+ */
235
+ aiEvaluate(submissionId: string, data: AiEvaluationBody): Promise<import("openapi-fetch").FetchResponse<{
236
+ parameters: {
237
+ query?: never;
238
+ header?: never;
239
+ path: {
240
+ id: import("../types/academe-api").components["parameters"]["id"];
241
+ };
242
+ cookie?: never;
243
+ };
244
+ requestBody: {
245
+ content: {
246
+ "application/json": {
247
+ aiScore: number;
248
+ aiFeedback?: string;
249
+ aiExtractedContent?: Record<string, never>;
250
+ criterionScores?: {
251
+ challengeEvaluationCriterionId: string;
252
+ score: number;
253
+ comment?: string;
254
+ }[];
255
+ };
256
+ };
257
+ };
258
+ responses: {
259
+ 200: {
260
+ headers: {
261
+ [name: string]: unknown;
262
+ };
263
+ content: {
264
+ "application/json": {
265
+ status?: string;
266
+ data?: import("../types/academe-api").components["schemas"]["Submission"];
267
+ };
268
+ };
269
+ };
270
+ 400: {
271
+ headers: {
272
+ [name: string]: unknown;
273
+ };
274
+ content: {
275
+ "application/json": import("../types/academe-api").components["schemas"]["Error"];
276
+ };
277
+ };
278
+ 404: import("../types/academe-api").components["responses"]["NotFound"];
279
+ 409: import("../types/academe-api").components["responses"]["Conflict"];
280
+ };
281
+ }, {
282
+ params: {
283
+ path: {
284
+ id: string;
285
+ };
286
+ };
287
+ body: {
288
+ aiScore: number;
289
+ aiFeedback?: string;
290
+ aiExtractedContent?: Record<string, never>;
291
+ criterionScores?: {
292
+ challengeEvaluationCriterionId: string;
293
+ score: number;
294
+ comment?: string;
295
+ }[];
296
+ };
297
+ }, `${string}/${string}`>>;
298
+ /**
299
+ * Teacher approves or rejects a submission.
300
+ * Only allowed when status is submitted or ai_evaluated.
301
+ */
302
+ teacherEvaluate(submissionId: string, data: TeacherEvaluationBody): Promise<import("openapi-fetch").FetchResponse<{
303
+ parameters: {
304
+ query?: never;
305
+ header?: never;
306
+ path: {
307
+ id: import("../types/academe-api").components["parameters"]["id"];
308
+ };
309
+ cookie?: never;
310
+ };
311
+ requestBody: {
312
+ content: {
313
+ "application/json": {
314
+ status: "approved" | "rejected";
315
+ teacherScore?: number;
316
+ teacherFeedback?: string;
317
+ };
318
+ };
319
+ };
320
+ responses: {
321
+ 200: {
322
+ headers: {
323
+ [name: string]: unknown;
324
+ };
325
+ content: {
326
+ "application/json": {
327
+ status?: string;
328
+ data?: import("../types/academe-api").components["schemas"]["Submission"];
329
+ };
330
+ };
331
+ };
332
+ 400: import("../types/academe-api").components["responses"]["BadRequest"];
333
+ 404: import("../types/academe-api").components["responses"]["NotFound"];
334
+ };
335
+ }, {
336
+ params: {
337
+ path: {
338
+ id: string;
339
+ };
340
+ };
341
+ body: {
342
+ status: "approved" | "rejected";
343
+ teacherScore?: number;
344
+ teacherFeedback?: string;
345
+ };
346
+ }, `${string}/${string}`>>;
347
+ };
348
+ export type SubmissionService = ReturnType<typeof createSubmissionService>;
349
+ export {};
@@ -20,6 +20,7 @@ import { type CategoryService } from './CategoryService';
20
20
  import { type StorageFileService } from './StorageFileService';
21
21
  import { type ChallengeService } from './ChallengeService';
22
22
  import { type StepService } from './StepService';
23
+ import { type SubmissionService } from './SubmissionService';
23
24
  export type AcademeApiClient = ReturnType<typeof createClient<paths>>;
24
25
  export declare function createAcademeApiClient(baseUrl: string): AcademeApiClient;
25
26
  export interface AcademeServices {
@@ -43,6 +44,7 @@ export interface AcademeServices {
43
44
  storageFile: StorageFileService;
44
45
  challenge: ChallengeService;
45
46
  step: StepService;
47
+ submission: SubmissionService;
46
48
  }
47
49
  export declare function createAcademeServices(apiClient: AcademeApiClient): AcademeServices;
48
50
  export { createUserService, type UserService } from "./userService";
@@ -64,3 +66,4 @@ export { createCategoryService, type CategoryService } from './CategoryService';
64
66
  export { createStorageFileService, type StorageFileService } from './StorageFileService';
65
67
  export { createChallengeService, type ChallengeService } from './ChallengeService';
66
68
  export { createStepService, type StepService } from './StepService';
69
+ export { createSubmissionService, type SubmissionService } from './SubmissionService';