academe-kit 0.14.0 → 0.15.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.
@@ -20,6 +20,7 @@ export { createAcademeApiClient } from "./services";
20
20
  export type { AcademeApiClient, AcademeServices } from "./services";
21
21
  export type { ChallengeUserQuizAttempt, ChallengeUserQuizAttemptsResponse, } from "./services/ChallengeService";
22
22
  export type { JourneyStepView, JourneyChallengeView, JourneyView, } from "./services/UserProgressService";
23
+ export type { ChallengeGroupDTO, ChallengeGroupMember, ChallengeGroupUserRef, GroupInviteDTO, GroupInviteStatus, EligibleClassmate, ClassmateMembership, CreateGroupInput, ListInvitesParams, } from "./services/ChallengeGroupService";
23
24
  export type { AccessibleSerie, ClassroomSummary, UserEnrollment, } from "./services/userService";
24
25
  export type { VitrineHome, VitrinePlaylist, VitrineCard, VitrineCardKind, VitrinePlaylistSource, VitrineCardOrientation, } from "./services/VitrineService";
25
26
  export type { WatchlistItem, WatchlistResponse, WatchlistType, } from "./services/WatchlistService";
@@ -0,0 +1,124 @@
1
+ import type { AcademeApiClient } from "./index";
2
+ /**
3
+ * Service de GRUPOS e CONVITES de desafio (desafios em grupo).
4
+ *
5
+ * Espelha app-academe-v2/src/services/academe/challenge-group.service.ts.
6
+ *
7
+ * ⚠️ Os endpoints de convite (`/challenge-group-invites`) e o de colegas
8
+ * elegíveis (`/challenges/{id}/eligible-classmates`) ainda NÃO estão no schema
9
+ * OpenAPI gerado deste kit, então usamos o mesmo padrão do mobile:
10
+ * `(apiClient.X as any)` + tipos escritos à mão. Ao regerar o schema com
11
+ * `npm run generate:api-types` (backend em http://localhost:3002), trocar os
12
+ * casts por chamadas tipadas e derivar os DTOs de `components["schemas"]`.
13
+ *
14
+ * NÃO confundir com `GroupService` (`services.group`), que trata de grupos
15
+ * RBAC/Keycloak (usuários↔roles) — sem relação com desafios em grupo.
16
+ */
17
+ /** Envelope padrão das respostas do backend: `{ status, data }`. */
18
+ type ApiEnvelope<T> = {
19
+ data?: {
20
+ status?: string;
21
+ data?: T;
22
+ };
23
+ error?: unknown;
24
+ };
25
+ export interface ChallengeGroupUserRef {
26
+ id: string;
27
+ firstName?: string | null;
28
+ lastName?: string | null;
29
+ /** Avatar resolvido pelo backend (padrão do app). Preferir a `avatarFile`. */
30
+ avatarUrl?: string | null;
31
+ avatarFile?: {
32
+ url?: string | null;
33
+ } | null;
34
+ }
35
+ export interface ChallengeGroupMember {
36
+ id: string;
37
+ groupId: string;
38
+ userId: string;
39
+ user?: ChallengeGroupUserRef | null;
40
+ createdAt?: string;
41
+ }
42
+ export interface ChallengeGroupDTO {
43
+ id: string;
44
+ challengeId: string;
45
+ name: string;
46
+ description?: string | null;
47
+ members?: ChallengeGroupMember[];
48
+ createdAt?: string;
49
+ updatedAt?: string;
50
+ }
51
+ /** Estado do colega frente aos grupos deste desafio. */
52
+ export type ClassmateMembership = "free" | "in_group" | "invited";
53
+ export interface EligibleClassmate {
54
+ userId: string;
55
+ name: string;
56
+ avatarUrl: string | null;
57
+ classroomId: string | null;
58
+ classroomName: string | null;
59
+ membership: ClassmateMembership;
60
+ }
61
+ export type GroupInviteStatus = "pending" | "accepted" | "declined" | "cancelled";
62
+ export interface GroupInviteDTO {
63
+ id: string;
64
+ groupId: string;
65
+ challengeId: string;
66
+ inviterUserId: string;
67
+ inviteeUserId: string;
68
+ status: GroupInviteStatus;
69
+ respondedAt?: string | null;
70
+ createdAt?: string;
71
+ updatedAt?: string;
72
+ group?: ChallengeGroupDTO | null;
73
+ challenge?: {
74
+ id: string;
75
+ title?: string;
76
+ } | null;
77
+ inviter?: ChallengeGroupUserRef | null;
78
+ invitee?: ChallengeGroupUserRef | null;
79
+ }
80
+ export interface CreateGroupInput {
81
+ challengeId: string;
82
+ name: string;
83
+ description?: string;
84
+ /** Quando true, o usuário autenticado entra como primeiro membro (líder). */
85
+ joinAsMember?: boolean;
86
+ }
87
+ export interface ListInvitesParams {
88
+ role?: "received" | "sent";
89
+ status?: GroupInviteStatus;
90
+ }
91
+ export declare function createChallengeGroupService(apiClient: AcademeApiClient): {
92
+ /** Lista os grupos de um desafio (com membros). */
93
+ listGroups(challengeId: string): Promise<ApiEnvelope<ChallengeGroupDTO[]>>;
94
+ /** Detalha um grupo (com desafio e membros). */
95
+ getGroup(groupId: string): Promise<ApiEnvelope<ChallengeGroupDTO>>;
96
+ /** Cria um grupo. Com `joinAsMember`, o criador entra como líder. */
97
+ createGroup(body: CreateGroupInput): Promise<ApiEnvelope<ChallengeGroupDTO>>;
98
+ /** Lista membros de um grupo. */
99
+ listMembers(groupId: string): Promise<ApiEnvelope<ChallengeGroupMember[]>>;
100
+ /** Remove um membro do grupo (sair/expulsar). */
101
+ removeMember(groupId: string, userId: string): Promise<ApiEnvelope<null>>;
102
+ /** Remove o grupo. */
103
+ deleteGroup(groupId: string): Promise<ApiEnvelope<null>>;
104
+ /**
105
+ * Colegas de turma elegíveis para convidar (mesma turma do aluno, anotados
106
+ * com `membership`: free | in_group | invited).
107
+ */
108
+ getEligibleClassmates(challengeId: string, institutionId?: string): Promise<ApiEnvelope<EligibleClassmate[]>>;
109
+ /** Meus convites (recebidos por padrão), opcionalmente filtrados por status. */
110
+ listInvites(params?: ListInvitesParams): Promise<ApiEnvelope<GroupInviteDTO[]>>;
111
+ /** Convida um colega para um grupo. */
112
+ createInvite(body: {
113
+ groupId: string;
114
+ inviteeUserId: string;
115
+ }): Promise<ApiEnvelope<GroupInviteDTO>>;
116
+ /** Aceita um convite recebido (cria a membership no backend). */
117
+ acceptInvite(inviteId: string): Promise<ApiEnvelope<GroupInviteDTO>>;
118
+ /** Recusa um convite recebido. */
119
+ declineInvite(inviteId: string): Promise<ApiEnvelope<GroupInviteDTO>>;
120
+ /** Cancela um convite pendente que EU enviei. */
121
+ cancelInvite(inviteId: string): Promise<ApiEnvelope<GroupInviteDTO>>;
122
+ };
123
+ export type ChallengeGroupService = ReturnType<typeof createChallengeGroupService>;
124
+ export {};
@@ -397,6 +397,7 @@ export declare function createChallengeService(apiClient: AcademeApiClient): {
397
397
  tutorialTitle?: string;
398
398
  tutorialDescription?: string;
399
399
  tutorialVideoUrl?: string;
400
+ redirectUrl?: string;
400
401
  isActive?: boolean;
401
402
  };
402
403
  };
@@ -431,6 +432,7 @@ export declare function createChallengeService(apiClient: AcademeApiClient): {
431
432
  tutorialTitle?: string;
432
433
  tutorialDescription?: string;
433
434
  tutorialVideoUrl?: string;
435
+ redirectUrl?: string;
434
436
  isActive?: boolean;
435
437
  };
436
438
  }, `${string}/${string}`>>;
@@ -161,12 +161,12 @@ export declare function createQuizService(apiClient: AcademeApiClient): {
161
161
  "application/json": {
162
162
  status?: string;
163
163
  data?: {
164
- question_text: string;
165
- question_type: "multiple_choice" | "true_false";
166
- points: number;
167
- options: {
168
- text: string;
169
- is_correct: boolean;
164
+ question_text?: string;
165
+ question_type?: "multiple_choice" | "true_false";
166
+ points?: number;
167
+ options?: {
168
+ text?: string;
169
+ is_correct?: boolean;
170
170
  }[];
171
171
  }[];
172
172
  };
@@ -494,8 +494,8 @@ export declare function createQuizService(apiClient: AcademeApiClient): {
494
494
  type: "multiple_choice" | "true_false" | "open";
495
495
  points?: number;
496
496
  options?: {
497
- text: string;
498
- is_correct: boolean;
497
+ text?: string;
498
+ is_correct?: boolean;
499
499
  }[];
500
500
  }[];
501
501
  };
@@ -525,8 +525,8 @@ export declare function createQuizService(apiClient: AcademeApiClient): {
525
525
  type: "multiple_choice" | "true_false" | "open";
526
526
  points?: number;
527
527
  options?: {
528
- text: string;
529
- is_correct: boolean;
528
+ text?: string;
529
+ is_correct?: boolean;
530
530
  }[];
531
531
  }[];
532
532
  };
@@ -10,7 +10,7 @@ export declare function createStepService(apiClient: AcademeApiClient): {
10
10
  getAll(params?: GetStepsParams): Promise<import("openapi-fetch").FetchResponse<{
11
11
  parameters: {
12
12
  query?: {
13
- type?: "challenge" | "course" | "tutorial" | "publication" | "evaluation" | "certificate";
13
+ type?: "challenge" | "course" | "tutorial" | "publication" | "evaluation" | "certificate" | "redirect";
14
14
  isActive?: boolean;
15
15
  };
16
16
  header?: never;
@@ -36,7 +36,7 @@ export declare function createStepService(apiClient: AcademeApiClient): {
36
36
  }, {
37
37
  params: {
38
38
  query: {
39
- type?: "challenge" | "course" | "tutorial" | "publication" | "evaluation" | "certificate";
39
+ type?: "challenge" | "course" | "tutorial" | "publication" | "evaluation" | "certificate" | "redirect";
40
40
  isActive?: boolean;
41
41
  } | undefined;
42
42
  };
@@ -94,7 +94,7 @@ export declare function createStepService(apiClient: AcademeApiClient): {
94
94
  name: string;
95
95
  color: string;
96
96
  icon: string;
97
- type: "challenge" | "course" | "tutorial" | "publication" | "evaluation" | "certificate";
97
+ type: "challenge" | "course" | "tutorial" | "publication" | "evaluation" | "certificate" | "redirect";
98
98
  isActive?: boolean;
99
99
  };
100
100
  };
@@ -120,7 +120,7 @@ export declare function createStepService(apiClient: AcademeApiClient): {
120
120
  name: string;
121
121
  color: string;
122
122
  icon: string;
123
- type: "challenge" | "course" | "tutorial" | "publication" | "evaluation" | "certificate";
123
+ type: "challenge" | "course" | "tutorial" | "publication" | "evaluation" | "certificate" | "redirect";
124
124
  isActive?: boolean;
125
125
  };
126
126
  }, `${string}/${string}`>>;
@@ -142,7 +142,7 @@ export declare function createStepService(apiClient: AcademeApiClient): {
142
142
  name?: string;
143
143
  color?: string;
144
144
  icon?: string;
145
- type?: "challenge" | "course" | "tutorial" | "publication" | "evaluation" | "certificate";
145
+ type?: "challenge" | "course" | "tutorial" | "publication" | "evaluation" | "certificate" | "redirect";
146
146
  isActive?: boolean;
147
147
  };
148
148
  };
@@ -174,7 +174,7 @@ export declare function createStepService(apiClient: AcademeApiClient): {
174
174
  name?: string;
175
175
  color?: string;
176
176
  icon?: string;
177
- type?: "challenge" | "course" | "tutorial" | "publication" | "evaluation" | "certificate";
177
+ type?: "challenge" | "course" | "tutorial" | "publication" | "evaluation" | "certificate" | "redirect";
178
178
  isActive?: boolean;
179
179
  };
180
180
  }, `${string}/${string}`>>;
@@ -6,7 +6,7 @@ type CreateSubmissionBody = paths["/submissions"]["post"]["requestBody"]["conten
6
6
  institutionId: string;
7
7
  };
8
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"];
9
+ type AiEvaluationBody = Record<string, unknown>;
10
10
  type TeacherEvaluationBody = paths["/submissions/{id}/teacher-evaluation"]["patch"]["requestBody"]["content"]["application/json"];
11
11
  export declare function createSubmissionService(apiClient: AcademeApiClient): {
12
12
  /**
@@ -274,69 +274,7 @@ export declare function createSubmissionService(apiClient: AcademeApiClient): {
274
274
  * Register AI evaluation (called by the AI service callback).
275
275
  * Moves status from submitted → ai_evaluated.
276
276
  */
277
- aiEvaluate(submissionId: string, data: AiEvaluationBody): Promise<import("openapi-fetch").FetchResponse<{
278
- parameters: {
279
- query?: never;
280
- header?: never;
281
- path: {
282
- id: import("../types/academe-api").components["parameters"]["id"];
283
- };
284
- cookie?: never;
285
- };
286
- requestBody: {
287
- content: {
288
- "application/json": {
289
- aiScore: number;
290
- aiFeedback?: string;
291
- aiExtractedContent?: Record<string, never>;
292
- criterionScores?: {
293
- challengeEvaluationCriterionId: string;
294
- score: number;
295
- comment?: string;
296
- }[];
297
- };
298
- };
299
- };
300
- responses: {
301
- 200: {
302
- headers: {
303
- [name: string]: unknown;
304
- };
305
- content: {
306
- "application/json": {
307
- status?: string;
308
- data?: import("../types/academe-api").components["schemas"]["Submission"];
309
- };
310
- };
311
- };
312
- 400: {
313
- headers: {
314
- [name: string]: unknown;
315
- };
316
- content: {
317
- "application/json": import("../types/academe-api").components["schemas"]["Error"];
318
- };
319
- };
320
- 404: import("../types/academe-api").components["responses"]["NotFound"];
321
- 409: import("../types/academe-api").components["responses"]["Conflict"];
322
- };
323
- }, {
324
- params: {
325
- path: {
326
- id: string;
327
- };
328
- };
329
- body: {
330
- aiScore: number;
331
- aiFeedback?: string;
332
- aiExtractedContent?: Record<string, never>;
333
- criterionScores?: {
334
- challengeEvaluationCriterionId: string;
335
- score: number;
336
- comment?: string;
337
- }[];
338
- };
339
- }, `${string}/${string}`>>;
277
+ aiEvaluate(submissionId: string, data: AiEvaluationBody): any;
340
278
  /**
341
279
  * Teacher approves or rejects a submission.
342
280
  * Only allowed when status is submitted or ai_evaluated.
@@ -90,7 +90,13 @@ export declare function createUserProgressService(apiClient: AcademeApiClient):
90
90
  };
91
91
  cookie?: never;
92
92
  };
93
- requestBody?: never;
93
+ requestBody?: {
94
+ content: {
95
+ "application/json": {
96
+ fromStepId?: string;
97
+ };
98
+ };
99
+ };
94
100
  responses: {
95
101
  200: {
96
102
  headers: {
@@ -100,8 +106,11 @@ export declare function createUserProgressService(apiClient: AcademeApiClient):
100
106
  "application/json": {
101
107
  status?: string;
102
108
  data?: {
103
- action?: "started" | "completed" | "finished";
109
+ action?: "started" | "completed" | "finished" | "noop" | "waiting";
104
110
  challengeId?: string;
111
+ groupWaiting?: boolean;
112
+ completedMembers?: number;
113
+ totalMembers?: number;
105
114
  currentStep?: {
106
115
  id?: string;
107
116
  index?: number;
@@ -238,6 +247,12 @@ export declare function createUserProgressService(apiClient: AcademeApiClient):
238
247
  };
239
248
  401: components["responses"]["Unauthorized"];
240
249
  404: components["responses"]["NotFound"];
250
+ 409: {
251
+ headers: {
252
+ [name: string]: unknown;
253
+ };
254
+ content?: never;
255
+ };
241
256
  };
242
257
  }, {
243
258
  params: {
@@ -24,6 +24,7 @@ import { type SubmissionService } from './SubmissionService';
24
24
  import { type UserProgressService } from './UserProgressService';
25
25
  import { type VitrineService } from './VitrineService';
26
26
  import { type WatchlistService } from './WatchlistService';
27
+ import { type ChallengeGroupService } from './ChallengeGroupService';
27
28
  export type AcademeApiClient = ReturnType<typeof createClient<paths>>;
28
29
  export declare function createAcademeApiClient(baseUrl: string): AcademeApiClient;
29
30
  export interface AcademeServices {
@@ -51,6 +52,7 @@ export interface AcademeServices {
51
52
  userProgress: UserProgressService;
52
53
  vitrine: VitrineService;
53
54
  watchlist: WatchlistService;
55
+ challengeGroup: ChallengeGroupService;
54
56
  }
55
57
  export declare function createAcademeServices(apiClient: AcademeApiClient): AcademeServices;
56
58
  export { createUserService, type UserService } from "./userService";
@@ -76,3 +78,4 @@ export { createSubmissionService, type SubmissionService } from './SubmissionSer
76
78
  export { createUserProgressService, type UserProgressService } from './UserProgressService';
77
79
  export { createVitrineService, type VitrineService } from './VitrineService';
78
80
  export { createWatchlistService, type WatchlistService } from './WatchlistService';
81
+ export { createChallengeGroupService, type ChallengeGroupService, type ChallengeGroupDTO, type ChallengeGroupMember, type ChallengeGroupUserRef, type GroupInviteDTO, type GroupInviteStatus, type EligibleClassmate, type ClassmateMembership, type CreateGroupInput, type ListInvitesParams, } from './ChallengeGroupService';