academe-kit 0.9.0 → 0.9.1

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/dist/index.d.ts CHANGED
@@ -270,6 +270,221 @@ interface paths {
270
270
  };
271
271
  trace?: never;
272
272
  };
273
+ "/auth/forgot-password": {
274
+ parameters: {
275
+ query?: never;
276
+ header?: never;
277
+ path?: never;
278
+ cookie?: never;
279
+ };
280
+ get?: never;
281
+ put?: never;
282
+ /**
283
+ * Request password reset email
284
+ * @description Sends a password reset email to the specified address if a user with that email exists.
285
+ *
286
+ * **Security Note:**
287
+ * For security reasons, this endpoint always returns a success response regardless of whether
288
+ * the email exists in the system. This prevents email enumeration attacks.
289
+ *
290
+ * **Flow:**
291
+ * 1. Client sends email address
292
+ * 2. Backend searches for user by email in Keycloak
293
+ * 3. If user exists, Keycloak sends password reset email with UPDATE_PASSWORD action
294
+ * 4. User receives email with link valid for 1 hour
295
+ * 5. Endpoint returns success (regardless of whether email was found)
296
+ *
297
+ * **Email Template:**
298
+ * The email sent uses the Keycloak realm's configured email template for password reset.
299
+ */
300
+ post: {
301
+ parameters: {
302
+ query?: never;
303
+ header?: never;
304
+ path?: never;
305
+ cookie?: never;
306
+ };
307
+ requestBody: {
308
+ content: {
309
+ "application/json": {
310
+ /**
311
+ * Format: email
312
+ * @description User's email address
313
+ * @example user@example.com
314
+ */
315
+ email: string;
316
+ };
317
+ };
318
+ };
319
+ responses: {
320
+ /** @description Request processed successfully (always returned for security) */
321
+ 200: {
322
+ headers: {
323
+ [name: string]: unknown;
324
+ };
325
+ content: {
326
+ "application/json": {
327
+ /** @example success */
328
+ status?: string;
329
+ /** @example If this email is registered, you will receive password reset instructions. */
330
+ message?: string;
331
+ };
332
+ };
333
+ };
334
+ /** @description Bad Request - Email not provided */
335
+ 400: {
336
+ headers: {
337
+ [name: string]: unknown;
338
+ };
339
+ content: {
340
+ "application/json": {
341
+ /** @example error */
342
+ status?: string;
343
+ /** @example Email is required */
344
+ message?: string;
345
+ };
346
+ };
347
+ };
348
+ /** @description Internal Server Error */
349
+ 500: {
350
+ headers: {
351
+ [name: string]: unknown;
352
+ };
353
+ content: {
354
+ "application/json": {
355
+ /** @example error */
356
+ status?: string;
357
+ /** @example Internal server error */
358
+ message?: string;
359
+ };
360
+ };
361
+ };
362
+ };
363
+ };
364
+ delete?: never;
365
+ options?: never;
366
+ head?: never;
367
+ patch?: never;
368
+ trace?: never;
369
+ };
370
+ "/auth/google-exchange": {
371
+ parameters: {
372
+ query?: never;
373
+ header?: never;
374
+ path?: never;
375
+ cookie?: never;
376
+ };
377
+ get?: never;
378
+ put?: never;
379
+ /**
380
+ * Exchange Google access token for Keycloak tokens
381
+ * @description Exchanges a Google access token for Keycloak tokens.
382
+ *
383
+ * **Flow:**
384
+ * 1. Client sends Google access token
385
+ * 2. Backend fetches user email from Google Userinfo API
386
+ * 3. Backend verifies the email exists in the local database
387
+ * 4. If user exists, performs Keycloak token exchange
388
+ * 5. Returns Keycloak tokens (access_token, refresh_token, etc.)
389
+ *
390
+ * **Error Cases:**
391
+ * - 400: Invalid or expired Google token
392
+ * - 404: User email not found in database
393
+ */
394
+ post: {
395
+ parameters: {
396
+ query?: never;
397
+ header?: never;
398
+ path?: never;
399
+ cookie?: never;
400
+ };
401
+ requestBody: {
402
+ content: {
403
+ "application/json": {
404
+ /**
405
+ * @description Google OAuth2 access token
406
+ * @example ya29.a0AfH6SM...
407
+ */
408
+ googleAccessToken: string;
409
+ };
410
+ };
411
+ };
412
+ responses: {
413
+ /** @description Token exchange successful */
414
+ 200: {
415
+ headers: {
416
+ [name: string]: unknown;
417
+ };
418
+ content: {
419
+ "application/json": {
420
+ /** @example success */
421
+ status?: string;
422
+ data?: {
423
+ /** @description Keycloak access token */
424
+ access_token?: string;
425
+ /** @description Keycloak refresh token */
426
+ refresh_token?: string;
427
+ /** @description Token expiration time in seconds */
428
+ expires_in?: number;
429
+ /** @description Refresh token expiration time in seconds */
430
+ refresh_expires_in?: number;
431
+ /** @example Bearer */
432
+ token_type?: string;
433
+ scope?: string;
434
+ };
435
+ };
436
+ };
437
+ };
438
+ /** @description Bad Request - Invalid Google token or missing googleAccessToken */
439
+ 400: {
440
+ headers: {
441
+ [name: string]: unknown;
442
+ };
443
+ content: {
444
+ "application/json": {
445
+ /** @example error */
446
+ status?: string;
447
+ /** @example Token do Google inválido ou expirado */
448
+ message?: string;
449
+ };
450
+ };
451
+ };
452
+ /** @description Not Found - User email not registered in database */
453
+ 404: {
454
+ headers: {
455
+ [name: string]: unknown;
456
+ };
457
+ content: {
458
+ "application/json": {
459
+ /** @example error */
460
+ status?: string;
461
+ /** @example Usuário não encontrado */
462
+ message?: string;
463
+ };
464
+ };
465
+ };
466
+ /** @description Internal Server Error */
467
+ 500: {
468
+ headers: {
469
+ [name: string]: unknown;
470
+ };
471
+ content: {
472
+ "application/json": {
473
+ /** @example error */
474
+ status?: string;
475
+ /** @example Internal server error */
476
+ message?: string;
477
+ };
478
+ };
479
+ };
480
+ };
481
+ };
482
+ delete?: never;
483
+ options?: never;
484
+ head?: never;
485
+ patch?: never;
486
+ trace?: never;
487
+ };
273
488
  "/auth/token": {
274
489
  parameters: {
275
490
  query?: never;
@@ -881,13 +1096,24 @@ interface paths {
881
1096
  };
882
1097
  /**
883
1098
  * List all certificates
884
- * @description Retrieve a list of all certificates in the system.
1099
+ * @description Retrieve a paginated list of all certificates in the system.
885
1100
  * Each certificate includes course information (id, title, description) when available.
886
1101
  * Course data is extracted from the related Quiz through QuizAttempt.
887
1102
  */
888
1103
  get: {
889
1104
  parameters: {
890
- query?: never;
1105
+ query?: {
1106
+ /** @description Filter certificates by user ID */
1107
+ userId?: string;
1108
+ /** @description Search term */
1109
+ search?: components["parameters"]["search"];
1110
+ /** @description Page number */
1111
+ page?: components["parameters"]["page"];
1112
+ /** @description Items per page */
1113
+ limit?: components["parameters"]["limit"];
1114
+ /** @description Whether to include course data in the response (default true). Pass false to skip course lookup. */
1115
+ includeCourse?: boolean;
1116
+ };
891
1117
  header?: never;
892
1118
  path?: never;
893
1119
  cookie?: never;
@@ -904,6 +1130,16 @@ interface paths {
904
1130
  /** @example success */
905
1131
  status?: string;
906
1132
  data?: components["schemas"]["Certificate"][];
1133
+ meta?: {
1134
+ /** @example 10 */
1135
+ total?: number;
1136
+ /** @example 1 */
1137
+ page?: number;
1138
+ /** @example 10 */
1139
+ limit?: number;
1140
+ /** @example 1 */
1141
+ totalPages?: number;
1142
+ };
907
1143
  };
908
1144
  };
909
1145
  };
@@ -939,8 +1175,6 @@ interface paths {
939
1175
  /** @example success */
940
1176
  status?: string;
941
1177
  data?: components["schemas"]["Certificate"];
942
- /** @example Certificate created successfully */
943
- message?: string;
944
1178
  };
945
1179
  };
946
1180
  };
@@ -1018,18 +1252,11 @@ interface paths {
1018
1252
  requestBody?: never;
1019
1253
  responses: {
1020
1254
  /** @description Certificate deleted successfully */
1021
- 200: {
1255
+ 204: {
1022
1256
  headers: {
1023
1257
  [name: string]: unknown;
1024
1258
  };
1025
- content: {
1026
- "application/json": {
1027
- /** @example success */
1028
- status?: string;
1029
- /** @example Certificate deleted successfully */
1030
- message?: string;
1031
- };
1032
- };
1259
+ content?: never;
1033
1260
  };
1034
1261
  400: components["responses"]["BadRequest"];
1035
1262
  401: components["responses"]["Unauthorized"];
@@ -1069,8 +1296,6 @@ interface paths {
1069
1296
  /** @example success */
1070
1297
  status?: string;
1071
1298
  data?: components["schemas"]["Certificate"];
1072
- /** @example Certificate updated successfully */
1073
- message?: string;
1074
1299
  };
1075
1300
  };
1076
1301
  };
@@ -1082,6 +1307,109 @@ interface paths {
1082
1307
  };
1083
1308
  trace?: never;
1084
1309
  };
1310
+ "/certificates/{id}/download": {
1311
+ parameters: {
1312
+ query?: never;
1313
+ header?: never;
1314
+ path?: never;
1315
+ cookie?: never;
1316
+ };
1317
+ /**
1318
+ * Download certificate PDF
1319
+ * @description Download the PDF of a specific certificate.
1320
+ * Acts as a proxy to download from S3, avoiding CORS issues.
1321
+ * Only the certificate owner can download their certificate.
1322
+ */
1323
+ get: {
1324
+ parameters: {
1325
+ query?: never;
1326
+ header?: never;
1327
+ path: {
1328
+ /** @description Resource ID */
1329
+ id: components["parameters"]["id"];
1330
+ };
1331
+ cookie?: never;
1332
+ };
1333
+ requestBody?: never;
1334
+ responses: {
1335
+ /** @description Certificate PDF file */
1336
+ 200: {
1337
+ headers: {
1338
+ [name: string]: unknown;
1339
+ };
1340
+ content: {
1341
+ "application/pdf": string;
1342
+ };
1343
+ };
1344
+ 401: components["responses"]["Unauthorized"];
1345
+ 403: components["responses"]["Forbidden"];
1346
+ 404: components["responses"]["NotFound"];
1347
+ 500: components["responses"]["ServerError"];
1348
+ };
1349
+ };
1350
+ put?: never;
1351
+ post?: never;
1352
+ delete?: never;
1353
+ options?: never;
1354
+ head?: never;
1355
+ patch?: never;
1356
+ trace?: never;
1357
+ };
1358
+ "/certificates/generate": {
1359
+ parameters: {
1360
+ query?: never;
1361
+ header?: never;
1362
+ path?: never;
1363
+ cookie?: never;
1364
+ };
1365
+ get?: never;
1366
+ put?: never;
1367
+ /**
1368
+ * Generate a certificate PDF server-side
1369
+ * @description Generates a certificate PDF on the server and creates the certificate record.
1370
+ * This eliminates CORS issues by downloading the template image on the server.
1371
+ */
1372
+ post: {
1373
+ parameters: {
1374
+ query?: never;
1375
+ header?: never;
1376
+ path?: never;
1377
+ cookie?: never;
1378
+ };
1379
+ requestBody: {
1380
+ content: {
1381
+ "application/json": components["schemas"]["GenerateCertificateDto"];
1382
+ };
1383
+ };
1384
+ responses: {
1385
+ /** @description Certificate generated and created successfully */
1386
+ 201: {
1387
+ headers: {
1388
+ [name: string]: unknown;
1389
+ };
1390
+ content: {
1391
+ "application/json": {
1392
+ /** @example success */
1393
+ status?: string;
1394
+ data?: {
1395
+ certificate?: components["schemas"]["Certificate"];
1396
+ /** @example https://s3.amazonaws.com/bucket/certificate.pdf */
1397
+ pdfUrl?: string;
1398
+ };
1399
+ };
1400
+ };
1401
+ };
1402
+ 400: components["responses"]["BadRequest"];
1403
+ 401: components["responses"]["Unauthorized"];
1404
+ 500: components["responses"]["ServerError"];
1405
+ };
1406
+ };
1407
+ delete?: never;
1408
+ options?: never;
1409
+ head?: never;
1410
+ patch?: never;
1411
+ trace?: never;
1412
+ };
1085
1413
  "/classrooms": {
1086
1414
  parameters: {
1087
1415
  query?: never;
@@ -9589,6 +9917,8 @@ interface paths {
9589
9917
  requestBody: {
9590
9918
  content: {
9591
9919
  "application/json": {
9920
+ /** @example sa@academe.com.br */
9921
+ email?: string;
9592
9922
  /** @example John */
9593
9923
  firstName?: string;
9594
9924
  /** @example Doe */
@@ -9988,7 +10318,19 @@ interface paths {
9988
10318
  head?: never;
9989
10319
  /**
9990
10320
  * Update user
9991
- * @description Update user information
10321
+ * @description Update user information.
10322
+ *
10323
+ * **Profile and seat code behavior:**
10324
+ * - Send `groupId` to change the user's profile/group.
10325
+ * - When `groupId` changes, the system will:
10326
+ * 1. Release the previous seat code used by the user (`isReserved = false`)
10327
+ * 2. Allocate a seat code for the new group in the same institution registration
10328
+ * 3. Create a new seat code automatically if none is available for that group
10329
+ *
10330
+ * **Important:**
10331
+ * - The target group must exist.
10332
+ * - The institution must have a seat configured for the target group.
10333
+ * - If any institution registration cannot be migrated to the new group, the operation fails.
9992
10334
  */
9993
10335
  patch: {
9994
10336
  parameters: {
@@ -10252,7 +10594,59 @@ interface paths {
10252
10594
  patch?: never;
10253
10595
  trace?: never;
10254
10596
  };
10255
- "/users/{id}/sync": {
10597
+ "/users/{id}/sync": {
10598
+ parameters: {
10599
+ query?: never;
10600
+ header?: never;
10601
+ path?: never;
10602
+ cookie?: never;
10603
+ };
10604
+ get?: never;
10605
+ put?: never;
10606
+ /**
10607
+ * Sync user with Keycloak
10608
+ * @description Synchronize user data with Keycloak identity provider
10609
+ */
10610
+ post: {
10611
+ parameters: {
10612
+ query?: never;
10613
+ header?: never;
10614
+ path: {
10615
+ /** @description Resource ID */
10616
+ id: components["parameters"]["id"];
10617
+ };
10618
+ cookie?: never;
10619
+ };
10620
+ requestBody?: never;
10621
+ responses: {
10622
+ /** @description User synchronized successfully */
10623
+ 200: {
10624
+ headers: {
10625
+ [name: string]: unknown;
10626
+ };
10627
+ content: {
10628
+ "application/json": {
10629
+ /** @example success */
10630
+ status?: string;
10631
+ data?: components["schemas"]["User"];
10632
+ /** @example User synchronized with Keycloak successfully */
10633
+ message?: string;
10634
+ };
10635
+ };
10636
+ };
10637
+ 400: components["responses"]["BadRequest"];
10638
+ 401: components["responses"]["Unauthorized"];
10639
+ 404: components["responses"]["NotFound"];
10640
+ 500: components["responses"]["ServerError"];
10641
+ };
10642
+ };
10643
+ delete?: never;
10644
+ options?: never;
10645
+ head?: never;
10646
+ patch?: never;
10647
+ trace?: never;
10648
+ };
10649
+ "/users/register-hotmart": {
10256
10650
  parameters: {
10257
10651
  query?: never;
10258
10652
  header?: never;
@@ -10262,22 +10656,123 @@ interface paths {
10262
10656
  get?: never;
10263
10657
  put?: never;
10264
10658
  /**
10265
- * Sync user with Keycloak
10266
- * @description Synchronize user data with Keycloak identity provider
10659
+ * Hotmart webhook for user registration and lifecycle
10660
+ * @description Public endpoint that receives webhook events from Hotmart.
10661
+ * Handles user creation and deactivation based on purchase events.
10662
+ *
10663
+ * **Supported Events:**
10664
+ *
10665
+ * | Event | Action |
10666
+ * |-------|--------|
10667
+ * | `PURCHASE_APPROVED` | Enqueues user creation with buyer data |
10668
+ * | `PURCHASE_CANCELED` | Deactivates (soft deletes) the user |
10669
+ * | `PURCHASE_REFUNDED` | Deactivates (soft deletes) the user |
10670
+ * | `PURCHASE_CHARGEBACK` | Deactivates (soft deletes) the user |
10671
+ *
10672
+ * **User Creation Flow (PURCHASE_APPROVED):**
10673
+ * 1. Extracts buyer information from the Hotmart payload
10674
+ * 2. Determines institution based on offer code
10675
+ * 3. Enqueues user creation request for async processing
10676
+ * 4. User is created in Keycloak and database by the worker
10677
+ *
10678
+ * **Offer-based Institution Assignment:**
10679
+ * - Offer code `d9to7y3w` → Institution `580268b1-458d-4f4c-901d-281eccf3b40d`
10680
+ *
10681
+ * **User Deactivation Flow:**
10682
+ * 1. Looks up the user by buyer email
10683
+ * 2. Soft deletes the user (marks as inactive)
10684
+ * 3. Disables the user in Keycloak
10685
+ *
10686
+ * All events return HTTP 200 to acknowledge receipt.
10687
+ * Unrecognized events are logged and ignored.
10267
10688
  */
10268
10689
  post: {
10269
10690
  parameters: {
10270
10691
  query?: never;
10271
10692
  header?: never;
10272
- path: {
10273
- /** @description Resource ID */
10274
- id: components["parameters"]["id"];
10275
- };
10693
+ path?: never;
10276
10694
  cookie?: never;
10277
10695
  };
10278
- requestBody?: never;
10696
+ requestBody: {
10697
+ content: {
10698
+ "application/json": {
10699
+ /**
10700
+ * Format: uuid
10701
+ * @description Unique webhook event ID
10702
+ * @example d96fafd0-75ed-4ca7-8fa8-c6a57f48e384
10703
+ */
10704
+ id: string;
10705
+ /**
10706
+ * @description Hotmart event type
10707
+ * @example PURCHASE_APPROVED
10708
+ * @enum {string}
10709
+ */
10710
+ event: "PURCHASE_APPROVED" | "PURCHASE_CANCELED" | "PURCHASE_REFUNDED" | "PURCHASE_CHARGEBACK" | "PURCHASE_COMPLETE" | "PURCHASE_PROTEST" | "PURCHASE_DELAYED";
10711
+ /**
10712
+ * @description Event creation timestamp (Unix milliseconds)
10713
+ * @example 1773161133350
10714
+ */
10715
+ creation_date: number;
10716
+ /**
10717
+ * @description Webhook payload version
10718
+ * @example 2.0.0
10719
+ */
10720
+ version: string;
10721
+ data: {
10722
+ buyer: {
10723
+ /**
10724
+ * Format: email
10725
+ * @example buyer@example.com
10726
+ */
10727
+ email: string;
10728
+ /** @example Teste */
10729
+ first_name: string;
10730
+ /** @example Comprador */
10731
+ last_name: string;
10732
+ /** @example Teste Comprador */
10733
+ name?: string;
10734
+ /** @example 69526128664 */
10735
+ document?: string;
10736
+ /** @example CPF */
10737
+ document_type?: string;
10738
+ /** @example 99999999900 */
10739
+ checkout_phone?: string;
10740
+ };
10741
+ purchase: {
10742
+ /** @example HP16015479281022 */
10743
+ transaction: string;
10744
+ /** @example APPROVED */
10745
+ status: string;
10746
+ offer?: {
10747
+ /**
10748
+ * @description Offer code used to determine institution assignment
10749
+ * @example d9to7y3w
10750
+ */
10751
+ code?: string;
10752
+ };
10753
+ };
10754
+ product: {
10755
+ id?: number;
10756
+ name?: string;
10757
+ /** Format: uuid */
10758
+ ucode?: string;
10759
+ };
10760
+ subscription?: {
10761
+ subscriber?: {
10762
+ code?: string;
10763
+ };
10764
+ plan?: {
10765
+ name?: string;
10766
+ id?: number;
10767
+ };
10768
+ status?: string;
10769
+ };
10770
+ };
10771
+ };
10772
+ };
10773
+ };
10279
10774
  responses: {
10280
- /** @description User synchronized successfully */
10775
+ /** @description Webhook event processed successfully */
10281
10776
  200: {
10282
10777
  headers: {
10283
10778
  [name: string]: unknown;
@@ -10286,15 +10781,21 @@ interface paths {
10286
10781
  "application/json": {
10287
10782
  /** @example success */
10288
10783
  status?: string;
10289
- data?: components["schemas"]["User"];
10290
- /** @example User synchronized with Keycloak successfully */
10291
- message?: string;
10784
+ /**
10785
+ * @description Action taken for the event
10786
+ * @example user_creation_enqueued
10787
+ * @enum {string}
10788
+ */
10789
+ action?: "user_creation_enqueued" | "user_deactivated" | "user_not_found" | "event_ignored";
10790
+ /**
10791
+ * Format: uuid
10792
+ * @description Request ID for tracking (only on user_creation_enqueued)
10793
+ * @example 550e8400-e29b-41d4-a716-446655440000
10794
+ */
10795
+ requestId?: string;
10292
10796
  };
10293
10797
  };
10294
10798
  };
10295
- 400: components["responses"]["BadRequest"];
10296
- 401: components["responses"]["Unauthorized"];
10297
- 404: components["responses"]["NotFound"];
10298
10799
  500: components["responses"]["ServerError"];
10299
10800
  };
10300
10801
  };
@@ -11549,6 +12050,20 @@ interface components {
11549
12050
  };
11550
12051
  };
11551
12052
  };
12053
+ ForgotPasswordRequest: {
12054
+ /**
12055
+ * Format: email
12056
+ * @description User's email address for password reset
12057
+ * @example user@example.com
12058
+ */
12059
+ email: string;
12060
+ };
12061
+ ForgotPasswordResponse: {
12062
+ /** @example success */
12063
+ status?: string;
12064
+ /** @example If this email is registered, you will receive password reset instructions. */
12065
+ message?: string;
12066
+ };
11552
12067
  CreateInstitutionClassroomDto: {
11553
12068
  /**
11554
12069
  * Format: uuid
@@ -11729,10 +12244,14 @@ interface components {
11729
12244
  * @description Product ID associated with this seat
11730
12245
  */
11731
12246
  productId?: string;
12247
+ /** @description Total number of seat codes for this seat */
12248
+ total?: number;
11732
12249
  /** @description Available quantity for this group in the institution */
11733
12250
  availableQuantity?: number;
11734
12251
  /** @description Number of users currently assigned to this group in the institution */
11735
12252
  usedQuantity?: number;
12253
+ /** @description Number of reserved seat codes without active registration */
12254
+ reservedQuantity?: number;
11736
12255
  /** Format: date-time */
11737
12256
  createdAt?: string;
11738
12257
  /** Format: date-time */
@@ -12221,6 +12740,27 @@ interface components {
12221
12740
  /** Format: uri */
12222
12741
  url?: string;
12223
12742
  };
12743
+ GenerateCertificateDto: {
12744
+ /** Format: uuid */
12745
+ userId: string;
12746
+ /** Format: uuid */
12747
+ quizAttemptId?: string;
12748
+ /** Format: uuid */
12749
+ certificateTemplateId: string;
12750
+ /** @example João Silva */
12751
+ studentName: string;
12752
+ /** @example Introdução ao JavaScript */
12753
+ quizTitle: string;
12754
+ /** @example 85 */
12755
+ score?: number;
12756
+ /** @example CERT-2024-000001 */
12757
+ certificateNumber?: string;
12758
+ /**
12759
+ * Format: date-time
12760
+ * @example 2024-01-01T00:00:00.000Z
12761
+ */
12762
+ issuedAt?: string;
12763
+ };
12224
12764
  CreateGuardianDto: {
12225
12765
  /**
12226
12766
  * Format: email
@@ -13102,6 +13642,7 @@ declare function createUserService(apiClient: AcademeApiClient): {
13102
13642
  requestBody: {
13103
13643
  content: {
13104
13644
  "application/json": {
13645
+ email?: string;
13105
13646
  firstName?: string;
13106
13647
  lastName?: string;
13107
13648
  phone?: string;
@@ -13156,6 +13697,7 @@ declare function createUserService(apiClient: AcademeApiClient): {
13156
13697
  requestBody: {
13157
13698
  content: {
13158
13699
  "application/json": {
13700
+ email?: string;
13159
13701
  firstName?: string;
13160
13702
  lastName?: string;
13161
13703
  phone?: string;
@@ -18516,11 +19058,16 @@ type QuizService = ReturnType<typeof createQuizService>;
18516
19058
 
18517
19059
  type CreateCertificateDto = components["schemas"]["CreateCertificateDto"];
18518
19060
  type UpdateCertificateDto = components["schemas"]["UpdateCertificateDto"];
19061
+ type GenerateCertificateDto = components["schemas"]["GenerateCertificateDto"];
18519
19062
  declare function createCertificateService(apiClient: AcademeApiClient): {
18520
19063
  /**
18521
- * List all certificates
19064
+ * Get current user's certificates
18522
19065
  */
18523
- getMe(): Promise<openapi_fetch.FetchResponse<{
19066
+ getMyCertificates(query?: {
19067
+ search?: string;
19068
+ page?: number;
19069
+ limit?: number;
19070
+ }): Promise<openapi_fetch.FetchResponse<{
18524
19071
  parameters: {
18525
19072
  query?: {
18526
19073
  search?: components["parameters"]["search"];
@@ -18553,12 +19100,32 @@ declare function createCertificateService(apiClient: AcademeApiClient): {
18553
19100
  401: components["responses"]["Unauthorized"];
18554
19101
  500: components["responses"]["ServerError"];
18555
19102
  };
18556
- }, openapi_fetch.FetchOptions<{
19103
+ }, {
19104
+ params: {
19105
+ query: {
19106
+ search?: string;
19107
+ page?: number;
19108
+ limit?: number;
19109
+ } | undefined;
19110
+ };
19111
+ }, `${string}/${string}`>>;
19112
+ /**
19113
+ * List all certificates
19114
+ */
19115
+ getAll(query?: {
19116
+ userId?: string;
19117
+ search?: string;
19118
+ page?: number;
19119
+ limit?: number;
19120
+ includeCourse?: boolean;
19121
+ }): Promise<openapi_fetch.FetchResponse<{
18557
19122
  parameters: {
18558
19123
  query?: {
19124
+ userId?: string;
18559
19125
  search?: components["parameters"]["search"];
18560
19126
  page?: components["parameters"]["page"];
18561
19127
  limit?: components["parameters"]["limit"];
19128
+ includeCourse?: boolean;
18562
19129
  };
18563
19130
  header?: never;
18564
19131
  path?: never;
@@ -18586,12 +19153,27 @@ declare function createCertificateService(apiClient: AcademeApiClient): {
18586
19153
  401: components["responses"]["Unauthorized"];
18587
19154
  500: components["responses"]["ServerError"];
18588
19155
  };
18589
- }> | undefined, `${string}/${string}`>>;
18590
- getAll(): Promise<openapi_fetch.FetchResponse<{
19156
+ }, {
19157
+ params: {
19158
+ query: {
19159
+ userId?: string;
19160
+ search?: string;
19161
+ page?: number;
19162
+ limit?: number;
19163
+ includeCourse?: boolean;
19164
+ } | undefined;
19165
+ };
19166
+ }, `${string}/${string}`>>;
19167
+ /**
19168
+ * Get certificate by ID
19169
+ */
19170
+ getById(id: string): Promise<openapi_fetch.FetchResponse<{
18591
19171
  parameters: {
18592
19172
  query?: never;
18593
19173
  header?: never;
18594
- path?: never;
19174
+ path: {
19175
+ id: components["parameters"]["id"];
19176
+ };
18595
19177
  cookie?: never;
18596
19178
  };
18597
19179
  requestBody?: never;
@@ -18603,53 +19185,32 @@ declare function createCertificateService(apiClient: AcademeApiClient): {
18603
19185
  content: {
18604
19186
  "application/json": {
18605
19187
  status?: string;
18606
- data?: components["schemas"]["Certificate"][];
19188
+ data?: components["schemas"]["Certificate"];
18607
19189
  };
18608
19190
  };
18609
19191
  };
19192
+ 400: components["responses"]["BadRequest"];
18610
19193
  401: components["responses"]["Unauthorized"];
19194
+ 404: components["responses"]["NotFound"];
18611
19195
  500: components["responses"]["ServerError"];
18612
19196
  };
18613
- }, openapi_fetch.FetchOptions<{
18614
- parameters: {
18615
- query?: never;
18616
- header?: never;
18617
- path?: never;
18618
- cookie?: never;
18619
- };
18620
- requestBody?: never;
18621
- responses: {
18622
- 200: {
18623
- headers: {
18624
- [name: string]: unknown;
18625
- };
18626
- content: {
18627
- "application/json": {
18628
- status?: string;
18629
- data?: components["schemas"]["Certificate"][];
18630
- };
18631
- };
19197
+ }, {
19198
+ params: {
19199
+ path: {
19200
+ id: string;
18632
19201
  };
18633
- 401: components["responses"]["Unauthorized"];
18634
- 500: components["responses"]["ServerError"];
18635
19202
  };
18636
- }> | undefined, `${string}/${string}`>>;
19203
+ }, `${string}/${string}`>>;
18637
19204
  /**
18638
- * Get current user's certificates
19205
+ * Download certificate PDF
18639
19206
  */
18640
- getMyCertificates(query?: {
18641
- search?: string;
18642
- page?: number;
18643
- limit?: number;
18644
- }): Promise<openapi_fetch.FetchResponse<{
19207
+ download(id: string): Promise<openapi_fetch.FetchResponse<{
18645
19208
  parameters: {
18646
- query?: {
18647
- search?: components["parameters"]["search"];
18648
- page?: components["parameters"]["page"];
18649
- limit?: components["parameters"]["limit"];
18650
- };
19209
+ query?: never;
18651
19210
  header?: never;
18652
- path?: never;
19211
+ path: {
19212
+ id: components["parameters"]["id"];
19213
+ };
18653
19214
  cookie?: never;
18654
19215
  };
18655
19216
  requestBody?: never;
@@ -18659,45 +19220,38 @@ declare function createCertificateService(apiClient: AcademeApiClient): {
18659
19220
  [name: string]: unknown;
18660
19221
  };
18661
19222
  content: {
18662
- "application/json": {
18663
- status?: string;
18664
- data?: components["schemas"]["Certificate"][];
18665
- meta?: {
18666
- total?: number;
18667
- page?: number;
18668
- limit?: number;
18669
- totalPages?: number;
18670
- };
18671
- };
19223
+ "application/pdf": string;
18672
19224
  };
18673
19225
  };
18674
19226
  401: components["responses"]["Unauthorized"];
19227
+ 403: components["responses"]["Forbidden"];
19228
+ 404: components["responses"]["NotFound"];
18675
19229
  500: components["responses"]["ServerError"];
18676
19230
  };
18677
19231
  }, {
18678
19232
  params: {
18679
- query: {
18680
- search?: string;
18681
- page?: number;
18682
- limit?: number;
18683
- } | undefined;
19233
+ path: {
19234
+ id: string;
19235
+ };
18684
19236
  };
18685
19237
  }, `${string}/${string}`>>;
18686
19238
  /**
18687
- * Get certificate by ID
19239
+ * Create a new certificate
18688
19240
  */
18689
- getById(id: string): Promise<openapi_fetch.FetchResponse<{
19241
+ create(data: CreateCertificateDto): Promise<openapi_fetch.FetchResponse<{
18690
19242
  parameters: {
18691
19243
  query?: never;
18692
19244
  header?: never;
18693
- path: {
18694
- id: components["parameters"]["id"];
18695
- };
19245
+ path?: never;
18696
19246
  cookie?: never;
18697
19247
  };
18698
- requestBody?: never;
19248
+ requestBody: {
19249
+ content: {
19250
+ "application/json": components["schemas"]["CreateCertificateDto"];
19251
+ };
19252
+ };
18699
19253
  responses: {
18700
- 200: {
19254
+ 201: {
18701
19255
  headers: {
18702
19256
  [name: string]: unknown;
18703
19257
  };
@@ -18710,20 +19264,21 @@ declare function createCertificateService(apiClient: AcademeApiClient): {
18710
19264
  };
18711
19265
  400: components["responses"]["BadRequest"];
18712
19266
  401: components["responses"]["Unauthorized"];
18713
- 404: components["responses"]["NotFound"];
18714
19267
  500: components["responses"]["ServerError"];
18715
19268
  };
18716
19269
  }, {
18717
- params: {
18718
- path: {
18719
- id: string;
18720
- };
19270
+ body: {
19271
+ userId: string;
19272
+ quizAttemptId?: string;
19273
+ certificateTemplateId: string;
19274
+ certificateNumber: string;
19275
+ url?: string;
18721
19276
  };
18722
19277
  }, `${string}/${string}`>>;
18723
19278
  /**
18724
- * Create a new certificate
19279
+ * Generate a certificate PDF server-side
18725
19280
  */
18726
- create(data: CreateCertificateDto): Promise<openapi_fetch.FetchResponse<{
19281
+ generate(data: GenerateCertificateDto): Promise<openapi_fetch.FetchResponse<{
18727
19282
  parameters: {
18728
19283
  query?: never;
18729
19284
  header?: never;
@@ -18732,7 +19287,7 @@ declare function createCertificateService(apiClient: AcademeApiClient): {
18732
19287
  };
18733
19288
  requestBody: {
18734
19289
  content: {
18735
- "application/json": components["schemas"]["CreateCertificateDto"];
19290
+ "application/json": components["schemas"]["GenerateCertificateDto"];
18736
19291
  };
18737
19292
  };
18738
19293
  responses: {
@@ -18743,8 +19298,10 @@ declare function createCertificateService(apiClient: AcademeApiClient): {
18743
19298
  content: {
18744
19299
  "application/json": {
18745
19300
  status?: string;
18746
- data?: components["schemas"]["Certificate"];
18747
- message?: string;
19301
+ data?: {
19302
+ certificate?: components["schemas"]["Certificate"];
19303
+ pdfUrl?: string;
19304
+ };
18748
19305
  };
18749
19306
  };
18750
19307
  };
@@ -18757,8 +19314,11 @@ declare function createCertificateService(apiClient: AcademeApiClient): {
18757
19314
  userId: string;
18758
19315
  quizAttemptId?: string;
18759
19316
  certificateTemplateId: string;
18760
- certificateNumber: string;
18761
- url?: string;
19317
+ studentName: string;
19318
+ quizTitle: string;
19319
+ score?: number;
19320
+ certificateNumber?: string;
19321
+ issuedAt?: string;
18762
19322
  };
18763
19323
  }, `${string}/${string}`>>;
18764
19324
  /**
@@ -18787,7 +19347,6 @@ declare function createCertificateService(apiClient: AcademeApiClient): {
18787
19347
  "application/json": {
18788
19348
  status?: string;
18789
19349
  data?: components["schemas"]["Certificate"];
18790
- message?: string;
18791
19350
  };
18792
19351
  };
18793
19352
  };
@@ -18823,16 +19382,11 @@ declare function createCertificateService(apiClient: AcademeApiClient): {
18823
19382
  };
18824
19383
  requestBody?: never;
18825
19384
  responses: {
18826
- 200: {
19385
+ 204: {
18827
19386
  headers: {
18828
19387
  [name: string]: unknown;
18829
19388
  };
18830
- content: {
18831
- "application/json": {
18832
- status?: string;
18833
- message?: string;
18834
- };
18835
- };
19389
+ content?: never;
18836
19390
  };
18837
19391
  400: components["responses"]["BadRequest"];
18838
19392
  401: components["responses"]["Unauthorized"];