academe-kit 0.9.5 → 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.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import React$1, { RefObject, ReactNode } from 'react';
1
+ import React$1, { RefObject, ReactNode, CSSProperties } from 'react';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import { KeycloakInitOptions, KeycloakLoginOptions } from 'keycloak-js';
4
4
  import * as openapi_fetch from 'openapi-fetch';
@@ -62,7 +62,7 @@ interface CosmicStarsCanvasProps {
62
62
  }
63
63
  declare function CosmicStarsCanvas({ containerRef }: CosmicStarsCanvasProps): react_jsx_runtime.JSX.Element;
64
64
 
65
- type FrameKind = 'pentagon' | 'hexagonWings' | 'circleLaurel' | 'hexagonRibbon' | 'shieldWings' | 'pentagonCrown';
65
+ type FrameKind = 'sphere' | 'pentagon' | 'hexagonWings' | 'circleLaurel' | 'hexagonRibbon' | 'shieldWings' | 'pentagonCrown';
66
66
 
67
67
  type JourneyStepSize = 'sm' | 'md';
68
68
  type JourneyStepType = 'challenge' | 'course' | 'tutorial' | 'publication' | 'evaluation' | 'certificate';
@@ -82,6 +82,12 @@ interface JourneyStepProps {
82
82
  }
83
83
  declare function JourneyStep({ color, stepType, frame, icon, isActive, isLocked, progress, size, ariaLabel, className, onClick, }: JourneyStepProps): react_jsx_runtime.JSX.Element;
84
84
 
85
+ interface JourneyCrystalPinProps {
86
+ className?: string;
87
+ style?: CSSProperties;
88
+ }
89
+ declare function JourneyCrystalPin({ className, style }: JourneyCrystalPinProps): react_jsx_runtime.JSX.Element;
90
+
85
91
  /**
86
92
  * This file was auto-generated by openapi-typescript.
87
93
  * Do not make direct changes to the file.
@@ -1366,6 +1372,68 @@ interface paths {
1366
1372
  patch?: never;
1367
1373
  trace?: never;
1368
1374
  };
1375
+ "/certificates/{userId}/download-all": {
1376
+ parameters: {
1377
+ query?: never;
1378
+ header?: never;
1379
+ path?: never;
1380
+ cookie?: never;
1381
+ };
1382
+ /**
1383
+ * Download all certificates of a user as a single PDF
1384
+ * @description Downloads all certificates of the given user merged into a single PDF file.
1385
+ * Each certificate occupies one page in the resulting file.
1386
+ * PDFs are downloaded from S3 in parallel and merged using pdf-lib.
1387
+ */
1388
+ get: {
1389
+ parameters: {
1390
+ query?: never;
1391
+ header?: never;
1392
+ path: {
1393
+ /** @description ID of the user whose certificates will be downloaded */
1394
+ userId: string;
1395
+ };
1396
+ cookie?: never;
1397
+ };
1398
+ requestBody?: never;
1399
+ responses: {
1400
+ /** @description Merged PDF file containing all user certificates */
1401
+ 200: {
1402
+ headers: {
1403
+ /** @description attachment; filename="Meus-Certificados.pdf" */
1404
+ "Content-Disposition"?: string;
1405
+ [name: string]: unknown;
1406
+ };
1407
+ content: {
1408
+ "application/pdf": string;
1409
+ };
1410
+ };
1411
+ 401: components["responses"]["Unauthorized"];
1412
+ /** @description No certificates found for the user */
1413
+ 404: {
1414
+ headers: {
1415
+ [name: string]: unknown;
1416
+ };
1417
+ content: {
1418
+ "application/json": {
1419
+ /** @example error */
1420
+ status?: string;
1421
+ /** @example No certificates found for this user */
1422
+ message?: string;
1423
+ };
1424
+ };
1425
+ };
1426
+ 500: components["responses"]["ServerError"];
1427
+ };
1428
+ };
1429
+ put?: never;
1430
+ post?: never;
1431
+ delete?: never;
1432
+ options?: never;
1433
+ head?: never;
1434
+ patch?: never;
1435
+ trace?: never;
1436
+ };
1369
1437
  "/certificates": {
1370
1438
  parameters: {
1371
1439
  query?: never;
@@ -1375,13 +1443,24 @@ interface paths {
1375
1443
  };
1376
1444
  /**
1377
1445
  * List all certificates
1378
- * @description Retrieve a list of all certificates in the system.
1446
+ * @description Retrieve a paginated list of all certificates in the system.
1379
1447
  * Each certificate includes course information (id, title, description) when available.
1380
1448
  * Course data is extracted from the related Quiz through QuizAttempt.
1381
1449
  */
1382
1450
  get: {
1383
1451
  parameters: {
1384
- query?: never;
1452
+ query?: {
1453
+ /** @description Filter certificates by user ID */
1454
+ userId?: string;
1455
+ /** @description Search term */
1456
+ search?: components["parameters"]["search"];
1457
+ /** @description Page number */
1458
+ page?: components["parameters"]["page"];
1459
+ /** @description Items per page */
1460
+ limit?: components["parameters"]["limit"];
1461
+ /** @description Whether to include course data in the response (default true). Pass false to skip course lookup. */
1462
+ includeCourse?: boolean;
1463
+ };
1385
1464
  header?: never;
1386
1465
  path?: never;
1387
1466
  cookie?: never;
@@ -1398,6 +1477,16 @@ interface paths {
1398
1477
  /** @example success */
1399
1478
  status?: string;
1400
1479
  data?: components["schemas"]["Certificate"][];
1480
+ meta?: {
1481
+ /** @example 10 */
1482
+ total?: number;
1483
+ /** @example 1 */
1484
+ page?: number;
1485
+ /** @example 10 */
1486
+ limit?: number;
1487
+ /** @example 1 */
1488
+ totalPages?: number;
1489
+ };
1401
1490
  };
1402
1491
  };
1403
1492
  };
@@ -1433,8 +1522,6 @@ interface paths {
1433
1522
  /** @example success */
1434
1523
  status?: string;
1435
1524
  data?: components["schemas"]["Certificate"];
1436
- /** @example Certificate created successfully */
1437
- message?: string;
1438
1525
  };
1439
1526
  };
1440
1527
  };
@@ -1512,18 +1599,11 @@ interface paths {
1512
1599
  requestBody?: never;
1513
1600
  responses: {
1514
1601
  /** @description Certificate deleted successfully */
1515
- 200: {
1602
+ 204: {
1516
1603
  headers: {
1517
1604
  [name: string]: unknown;
1518
1605
  };
1519
- content: {
1520
- "application/json": {
1521
- /** @example success */
1522
- status?: string;
1523
- /** @example Certificate deleted successfully */
1524
- message?: string;
1525
- };
1526
- };
1606
+ content?: never;
1527
1607
  };
1528
1608
  400: components["responses"]["BadRequest"];
1529
1609
  401: components["responses"]["Unauthorized"];
@@ -1563,8 +1643,6 @@ interface paths {
1563
1643
  /** @example success */
1564
1644
  status?: string;
1565
1645
  data?: components["schemas"]["Certificate"];
1566
- /** @example Certificate updated successfully */
1567
- message?: string;
1568
1646
  };
1569
1647
  };
1570
1648
  };
@@ -1576,6 +1654,123 @@ interface paths {
1576
1654
  };
1577
1655
  trace?: never;
1578
1656
  };
1657
+ "/certificates/{id}/download": {
1658
+ parameters: {
1659
+ query?: never;
1660
+ header?: never;
1661
+ path?: never;
1662
+ cookie?: never;
1663
+ };
1664
+ /**
1665
+ * Download certificate PDF
1666
+ * @description Download the PDF of a specific certificate.
1667
+ * Acts as a proxy to download from S3, avoiding CORS issues.
1668
+ * Only the certificate owner can download their certificate.
1669
+ */
1670
+ get: {
1671
+ parameters: {
1672
+ query?: never;
1673
+ header?: never;
1674
+ path: {
1675
+ /** @description Resource ID */
1676
+ id: components["parameters"]["id"];
1677
+ };
1678
+ cookie?: never;
1679
+ };
1680
+ requestBody?: never;
1681
+ responses: {
1682
+ /** @description Certificate PDF file */
1683
+ 200: {
1684
+ headers: {
1685
+ [name: string]: unknown;
1686
+ };
1687
+ content: {
1688
+ "application/pdf": string;
1689
+ };
1690
+ };
1691
+ 401: components["responses"]["Unauthorized"];
1692
+ 403: components["responses"]["Forbidden"];
1693
+ 404: components["responses"]["NotFound"];
1694
+ 500: components["responses"]["ServerError"];
1695
+ };
1696
+ };
1697
+ put?: never;
1698
+ post?: never;
1699
+ delete?: never;
1700
+ options?: never;
1701
+ head?: never;
1702
+ patch?: never;
1703
+ trace?: never;
1704
+ };
1705
+ "/certificates/generate": {
1706
+ parameters: {
1707
+ query?: never;
1708
+ header?: never;
1709
+ path?: never;
1710
+ cookie?: never;
1711
+ };
1712
+ get?: never;
1713
+ put?: never;
1714
+ /**
1715
+ * Generate a certificate PDF server-side
1716
+ * @description Generates a certificate PDF on the server and creates the certificate record.
1717
+ * This eliminates CORS issues by downloading the template image on the server.
1718
+ *
1719
+ * If the user is currently on a journey "course" step whose `courseModuleId`
1720
+ * matches the quiz's course module, that step is auto-completed as part of
1721
+ * this call (best-effort; failures here are silent and do not affect the cert).
1722
+ */
1723
+ post: {
1724
+ parameters: {
1725
+ query?: never;
1726
+ header?: never;
1727
+ path?: never;
1728
+ cookie?: never;
1729
+ };
1730
+ requestBody: {
1731
+ content: {
1732
+ "application/json": components["schemas"]["GenerateCertificateDto"];
1733
+ };
1734
+ };
1735
+ responses: {
1736
+ /** @description Certificate generated and created successfully */
1737
+ 201: {
1738
+ headers: {
1739
+ [name: string]: unknown;
1740
+ };
1741
+ content: {
1742
+ "application/json": {
1743
+ /** @example success */
1744
+ status?: string;
1745
+ data?: {
1746
+ certificate?: components["schemas"]["Certificate"];
1747
+ /** @example https://s3.amazonaws.com/bucket/certificate.pdf */
1748
+ pdfUrl?: string;
1749
+ /**
1750
+ * @description True when this generation also concluded the user's current journey "course" step
1751
+ * @example true
1752
+ */
1753
+ stepCompleted?: boolean;
1754
+ /**
1755
+ * Format: uuid
1756
+ * @description ID of the challenge_step that was auto-completed, or null when no step was matched
1757
+ */
1758
+ challengeStepId?: string | null;
1759
+ };
1760
+ };
1761
+ };
1762
+ };
1763
+ 400: components["responses"]["BadRequest"];
1764
+ 401: components["responses"]["Unauthorized"];
1765
+ 500: components["responses"]["ServerError"];
1766
+ };
1767
+ };
1768
+ delete?: never;
1769
+ options?: never;
1770
+ head?: never;
1771
+ patch?: never;
1772
+ trace?: never;
1773
+ };
1579
1774
  "/challenge-groups": {
1580
1775
  parameters: {
1581
1776
  query?: never;
@@ -11441,7 +11636,7 @@ interface paths {
11441
11636
  /**
11442
11637
  * Create new submission attempt
11443
11638
  * @description Creates a submission with status=submitted. Validations:
11444
- * - Cannot submit to a global template (clone first)
11639
+ * - institutionId is sent by the client (user's institution_registration), not derived from the challenge
11445
11640
  * - For group challenges: groupId is required and user must be a member
11446
11641
  * - For individual challenges: groupId must be omitted
11447
11642
  * - Cannot create when there is already an active submission (submitted/ai_evaluated)
@@ -11461,6 +11656,11 @@ interface paths {
11461
11656
  "application/json": {
11462
11657
  /** Format: uuid */
11463
11658
  challengeId: string;
11659
+ /**
11660
+ * Format: uuid
11661
+ * @description Institution the user is submitting under (from institution_registration)
11662
+ */
11663
+ institutionId: string;
11464
11664
  /**
11465
11665
  * Format: uuid
11466
11666
  * @description Required when challenge.isGroup=true
@@ -12457,7 +12657,7 @@ interface paths {
12457
12657
  patch?: never;
12458
12658
  trace?: never;
12459
12659
  };
12460
- "/users/me": {
12660
+ "/users-course-log/me/courses/{courseId}/progress": {
12461
12661
  parameters: {
12462
12662
  query?: never;
12463
12663
  header?: never;
@@ -12465,27 +12665,22 @@ interface paths {
12465
12665
  cookie?: never;
12466
12666
  };
12467
12667
  /**
12468
- * Get current authenticated user
12469
- * @description Returns the profile information of the currently authenticated user including:
12470
- * - User groups (userGroups)
12471
- * - User guardians (userGuardians)
12472
- * - Certificates (certificates)
12473
- * - Institution registrations with detailed classroom information (institutionRegistrations)
12474
- * - Institution data
12475
- * - Classroom assignment (institutionClassroom)
12476
- * - Classroom details (name, shift, serie)
12477
- * - Address information (address)
12668
+ * Get authenticated user's progress in a course
12669
+ * @description Returns completed/total active lessons (across every active module of the course)
12670
+ * and a percentage based on `users_course_log` completion events.
12478
12671
  */
12479
12672
  get: {
12480
12673
  parameters: {
12481
12674
  query?: never;
12482
12675
  header?: never;
12483
- path?: never;
12676
+ path: {
12677
+ courseId: string;
12678
+ };
12484
12679
  cookie?: never;
12485
12680
  };
12486
12681
  requestBody?: never;
12487
12682
  responses: {
12488
- /** @description Current user information with all related entities */
12683
+ /** @description Course progress snapshot */
12489
12684
  200: {
12490
12685
  headers: {
12491
12686
  [name: string]: unknown;
@@ -12494,59 +12689,161 @@ interface paths {
12494
12689
  "application/json": {
12495
12690
  /** @example success */
12496
12691
  status?: string;
12497
- data?: components["schemas"]["User"];
12692
+ data?: components["schemas"]["UsersCourseLogProgress"];
12498
12693
  };
12499
12694
  };
12500
12695
  };
12501
12696
  401: components["responses"]["Unauthorized"];
12502
- 500: components["responses"]["ServerError"];
12697
+ 404: components["responses"]["NotFound"];
12503
12698
  };
12504
12699
  };
12700
+ put?: never;
12701
+ post?: never;
12702
+ delete?: never;
12703
+ options?: never;
12704
+ head?: never;
12705
+ patch?: never;
12706
+ trace?: never;
12707
+ };
12708
+ "/users-course-log/me/courses/{courseId}/modules/{moduleId}/progress": {
12709
+ parameters: {
12710
+ query?: never;
12711
+ header?: never;
12712
+ path?: never;
12713
+ cookie?: never;
12714
+ };
12505
12715
  /**
12506
- * Update current authenticated user
12507
- * @description Updates the profile information of the currently authenticated user.
12508
- * Users can only update their own data (validated via JWT token).
12509
- *
12510
- * **Address Handling:**
12511
- * - If the user has no address, a new address will be created
12512
- * - If the user already has an address, it will be updated
12513
- * - Address fields are optional - only provided fields will be updated
12514
- *
12515
- * **Push Token Handling:**
12516
- * - If pushToken is provided, registers or updates the device push token
12517
- * - If the token already exists (same token string), updates it
12518
- * - If deviceId is provided and exists for this user, updates that device's token
12519
- * - Otherwise, creates a new push token record
12520
- * - Useful for registering FCM/APNs tokens on app startup or login
12716
+ * Get authenticated user's progress in a module
12717
+ * @description Returns completed/total active lessons of the module and a percentage based on
12718
+ * `users_course_log` completion events. Used by the Journey "curso" step.
12521
12719
  */
12522
- put: {
12720
+ get: {
12523
12721
  parameters: {
12524
12722
  query?: never;
12525
12723
  header?: never;
12526
- path?: never;
12724
+ path: {
12725
+ courseId: string;
12726
+ moduleId: string;
12727
+ };
12527
12728
  cookie?: never;
12528
12729
  };
12529
- requestBody: {
12530
- content: {
12531
- "application/json": {
12532
- /** @example sa@academe.com.br */
12533
- email?: string;
12534
- /** @example John */
12535
- firstName?: string;
12536
- /** @example Doe */
12537
- lastName?: string;
12538
- /** @example +5511999999999 */
12539
- phone?: string;
12540
- /** @example 12345678901 */
12541
- document?: string;
12542
- /**
12543
- * @example male
12544
- * @enum {string}
12545
- */
12546
- gender?: "male" | "female" | "other";
12547
- /**
12548
- * Format: date-time
12549
- * @example 1990-01-15T00:00:00.000Z
12730
+ requestBody?: never;
12731
+ responses: {
12732
+ /** @description Module progress snapshot */
12733
+ 200: {
12734
+ headers: {
12735
+ [name: string]: unknown;
12736
+ };
12737
+ content: {
12738
+ "application/json": {
12739
+ /** @example success */
12740
+ status?: string;
12741
+ data?: components["schemas"]["UsersCourseLogProgress"];
12742
+ };
12743
+ };
12744
+ };
12745
+ 401: components["responses"]["Unauthorized"];
12746
+ 404: components["responses"]["NotFound"];
12747
+ };
12748
+ };
12749
+ put?: never;
12750
+ post?: never;
12751
+ delete?: never;
12752
+ options?: never;
12753
+ head?: never;
12754
+ patch?: never;
12755
+ trace?: never;
12756
+ };
12757
+ "/users/me": {
12758
+ parameters: {
12759
+ query?: never;
12760
+ header?: never;
12761
+ path?: never;
12762
+ cookie?: never;
12763
+ };
12764
+ /**
12765
+ * Get current authenticated user
12766
+ * @description Returns the profile information of the currently authenticated user including:
12767
+ * - User groups (userGroups)
12768
+ * - User guardians (userGuardians)
12769
+ * - Certificates (certificates)
12770
+ * - Institution registrations with detailed classroom information (institutionRegistrations)
12771
+ * - Institution data
12772
+ * - Classroom assignment (institutionClassroom)
12773
+ * - Classroom details (name, shift, serie)
12774
+ * - Address information (address)
12775
+ */
12776
+ get: {
12777
+ parameters: {
12778
+ query?: never;
12779
+ header?: never;
12780
+ path?: never;
12781
+ cookie?: never;
12782
+ };
12783
+ requestBody?: never;
12784
+ responses: {
12785
+ /** @description Current user information with all related entities */
12786
+ 200: {
12787
+ headers: {
12788
+ [name: string]: unknown;
12789
+ };
12790
+ content: {
12791
+ "application/json": {
12792
+ /** @example success */
12793
+ status?: string;
12794
+ data?: components["schemas"]["User"];
12795
+ };
12796
+ };
12797
+ };
12798
+ 401: components["responses"]["Unauthorized"];
12799
+ 500: components["responses"]["ServerError"];
12800
+ };
12801
+ };
12802
+ /**
12803
+ * Update current authenticated user
12804
+ * @description Updates the profile information of the currently authenticated user.
12805
+ * Users can only update their own data (validated via JWT token).
12806
+ *
12807
+ * **Address Handling:**
12808
+ * - If the user has no address, a new address will be created
12809
+ * - If the user already has an address, it will be updated
12810
+ * - Address fields are optional - only provided fields will be updated
12811
+ *
12812
+ * **Push Token Handling:**
12813
+ * - If pushToken is provided, registers or updates the device push token
12814
+ * - If the token already exists (same token string), updates it
12815
+ * - If deviceId is provided and exists for this user, updates that device's token
12816
+ * - Otherwise, creates a new push token record
12817
+ * - Useful for registering FCM/APNs tokens on app startup or login
12818
+ */
12819
+ put: {
12820
+ parameters: {
12821
+ query?: never;
12822
+ header?: never;
12823
+ path?: never;
12824
+ cookie?: never;
12825
+ };
12826
+ requestBody: {
12827
+ content: {
12828
+ "application/json": {
12829
+ /** @example sa@academe.com.br */
12830
+ email?: string;
12831
+ /** @example John */
12832
+ firstName?: string;
12833
+ /** @example Doe */
12834
+ lastName?: string;
12835
+ /** @example +5511999999999 */
12836
+ phone?: string;
12837
+ /** @example 12345678901 */
12838
+ document?: string;
12839
+ /**
12840
+ * @example male
12841
+ * @enum {string}
12842
+ */
12843
+ gender?: "male" | "female" | "other";
12844
+ /**
12845
+ * Format: date-time
12846
+ * @example 1990-01-15T00:00:00.000Z
12550
12847
  */
12551
12848
  birthdate?: string;
12552
12849
  /**
@@ -12930,7 +13227,19 @@ interface paths {
12930
13227
  head?: never;
12931
13228
  /**
12932
13229
  * Update user
12933
- * @description Update user information
13230
+ * @description Update user information.
13231
+ *
13232
+ * **Profile and seat code behavior:**
13233
+ * - Send `groupId` to change the user's profile/group.
13234
+ * - When `groupId` changes, the system will:
13235
+ * 1. Release the previous seat code used by the user (`isReserved = false`)
13236
+ * 2. Allocate a seat code for the new group in the same institution registration
13237
+ * 3. Create a new seat code automatically if none is available for that group
13238
+ *
13239
+ * **Important:**
13240
+ * - The target group must exist.
13241
+ * - The institution must have a seat configured for the target group.
13242
+ * - If any institution registration cannot be migrated to the new group, the operation fails.
12934
13243
  */
12935
13244
  patch: {
12936
13245
  parameters: {
@@ -14748,6 +15057,29 @@ interface components {
14748
15057
  /** Format: date-time */
14749
15058
  updatedAt?: string;
14750
15059
  };
15060
+ /** @description Aggregated progress of a user on a course or module, derived from users_course_log completion events */
15061
+ UsersCourseLogProgress: {
15062
+ /**
15063
+ * @description Number of active lessons completed by the user
15064
+ * @example 3
15065
+ */
15066
+ completedLessons?: number;
15067
+ /**
15068
+ * @description Total number of active lessons in scope
15069
+ * @example 5
15070
+ */
15071
+ totalLessons?: number;
15072
+ /**
15073
+ * @description Completion percentage rounded to nearest integer
15074
+ * @example 60
15075
+ */
15076
+ percent?: number;
15077
+ /**
15078
+ * @description True when totalLessons > 0 and completedLessons >= totalLessons
15079
+ * @example false
15080
+ */
15081
+ isCompleted?: boolean;
15082
+ };
14751
15083
  Submission: {
14752
15084
  /** Format: uuid */
14753
15085
  id?: string;
@@ -15855,6 +16187,27 @@ interface components {
15855
16187
  /** Format: uri */
15856
16188
  url?: string;
15857
16189
  };
16190
+ GenerateCertificateDto: {
16191
+ /** Format: uuid */
16192
+ userId: string;
16193
+ /** Format: uuid */
16194
+ quizAttemptId?: string;
16195
+ /** Format: uuid */
16196
+ certificateTemplateId: string;
16197
+ /** @example João Silva */
16198
+ studentName: string;
16199
+ /** @example Introdução ao JavaScript */
16200
+ quizTitle: string;
16201
+ /** @example 85 */
16202
+ score?: number;
16203
+ /** @example CERT-2024-000001 */
16204
+ certificateNumber?: string;
16205
+ /**
16206
+ * Format: date-time
16207
+ * @example 2024-01-01T00:00:00.000Z
16208
+ */
16209
+ issuedAt?: string;
16210
+ };
15858
16211
  CreateGuardianDto: {
15859
16212
  /**
15860
16213
  * Format: email
@@ -22238,7 +22591,6 @@ declare function createCertificateService(apiClient: AcademeApiClient): {
22238
22591
  "application/json": {
22239
22592
  status?: string;
22240
22593
  data?: components["schemas"]["Certificate"];
22241
- message?: string;
22242
22594
  };
22243
22595
  };
22244
22596
  };
@@ -22285,7 +22637,6 @@ declare function createCertificateService(apiClient: AcademeApiClient): {
22285
22637
  "application/json": {
22286
22638
  status?: string;
22287
22639
  data?: components["schemas"]["Certificate"];
22288
- message?: string;
22289
22640
  };
22290
22641
  };
22291
22642
  };
@@ -22321,16 +22672,11 @@ declare function createCertificateService(apiClient: AcademeApiClient): {
22321
22672
  };
22322
22673
  requestBody?: never;
22323
22674
  responses: {
22324
- 200: {
22675
+ 204: {
22325
22676
  headers: {
22326
22677
  [name: string]: unknown;
22327
22678
  };
22328
- content: {
22329
- "application/json": {
22330
- status?: string;
22331
- message?: string;
22332
- };
22333
- };
22679
+ content?: never;
22334
22680
  };
22335
22681
  400: components["responses"]["BadRequest"];
22336
22682
  401: components["responses"]["Unauthorized"];
@@ -25104,6 +25450,353 @@ declare function createStepService(apiClient: AcademeApiClient): {
25104
25450
  };
25105
25451
  type StepService = ReturnType<typeof createStepService>;
25106
25452
 
25453
+ type GetSubmissionsParams = paths["/submissions"]["get"]["parameters"]["query"];
25454
+ type CreateSubmissionBody = paths["/submissions"]["post"]["requestBody"]["content"]["application/json"] & {
25455
+ /** Institution under which the user is submitting (from institution_registration) */
25456
+ institutionId: string;
25457
+ };
25458
+ type AttachFilesBody = paths["/submissions/{id}/files"]["post"]["requestBody"]["content"]["application/json"];
25459
+ type AiEvaluationBody = paths["/submissions/{id}/ai-evaluation"]["post"]["requestBody"]["content"]["application/json"];
25460
+ type TeacherEvaluationBody = paths["/submissions/{id}/teacher-evaluation"]["patch"]["requestBody"]["content"]["application/json"];
25461
+ declare function createSubmissionService(apiClient: AcademeApiClient): {
25462
+ /**
25463
+ * List submissions with filters and pagination
25464
+ */
25465
+ getAll(params?: GetSubmissionsParams): Promise<openapi_fetch.FetchResponse<{
25466
+ parameters: {
25467
+ query?: {
25468
+ challengeId?: string;
25469
+ userId?: string;
25470
+ groupId?: string;
25471
+ institutionId?: string;
25472
+ status?: "submitted" | "ai_evaluated" | "approved" | "rejected";
25473
+ page?: components["parameters"]["page"];
25474
+ limit?: components["parameters"]["limit"];
25475
+ };
25476
+ header?: never;
25477
+ path?: never;
25478
+ cookie?: never;
25479
+ };
25480
+ requestBody?: never;
25481
+ responses: {
25482
+ 200: {
25483
+ headers: {
25484
+ [name: string]: unknown;
25485
+ };
25486
+ content: {
25487
+ "application/json": {
25488
+ status?: string;
25489
+ data?: components["schemas"]["Submission"][];
25490
+ meta?: components["schemas"]["PaginationMeta"];
25491
+ };
25492
+ };
25493
+ };
25494
+ 401: components["responses"]["Unauthorized"];
25495
+ };
25496
+ }, {
25497
+ params: {
25498
+ query: {
25499
+ challengeId?: string;
25500
+ userId?: string;
25501
+ groupId?: string;
25502
+ institutionId?: string;
25503
+ status?: "submitted" | "ai_evaluated" | "approved" | "rejected";
25504
+ page?: components["parameters"]["page"];
25505
+ limit?: components["parameters"]["limit"];
25506
+ } | undefined;
25507
+ };
25508
+ }, `${string}/${string}`>>;
25509
+ /**
25510
+ * Get submission with files and per-criterion scores
25511
+ */
25512
+ getById(id: string): Promise<openapi_fetch.FetchResponse<{
25513
+ parameters: {
25514
+ query?: never;
25515
+ header?: never;
25516
+ path: {
25517
+ id: components["parameters"]["id"];
25518
+ };
25519
+ cookie?: never;
25520
+ };
25521
+ requestBody?: never;
25522
+ responses: {
25523
+ 200: {
25524
+ headers: {
25525
+ [name: string]: unknown;
25526
+ };
25527
+ content: {
25528
+ "application/json": {
25529
+ status?: string;
25530
+ data?: components["schemas"]["Submission"] & {
25531
+ files?: components["schemas"]["SubmissionFile"][];
25532
+ criterionScores?: components["schemas"]["SubmissionCriterionScore"][];
25533
+ };
25534
+ };
25535
+ };
25536
+ };
25537
+ 401: components["responses"]["Unauthorized"];
25538
+ 404: components["responses"]["NotFound"];
25539
+ };
25540
+ }, {
25541
+ params: {
25542
+ path: {
25543
+ id: string;
25544
+ };
25545
+ };
25546
+ }, `${string}/${string}`>>;
25547
+ /**
25548
+ * Create a new submission attempt (status=submitted)
25549
+ * - Cannot submit to a global template (clone first)
25550
+ * - For group challenges: groupId is required and user must be a member
25551
+ * - For individual challenges: groupId must be omitted
25552
+ * - Cannot create when there is already an active submission
25553
+ * - attempt_number is computed server-side
25554
+ */
25555
+ create(data: CreateSubmissionBody): Promise<openapi_fetch.FetchResponse<{
25556
+ parameters: {
25557
+ query?: never;
25558
+ header?: never;
25559
+ path?: never;
25560
+ cookie?: never;
25561
+ };
25562
+ requestBody: {
25563
+ content: {
25564
+ "application/json": {
25565
+ challengeId: string;
25566
+ institutionId: string;
25567
+ groupId?: string;
25568
+ description?: string;
25569
+ };
25570
+ };
25571
+ };
25572
+ responses: {
25573
+ 201: {
25574
+ headers: {
25575
+ [name: string]: unknown;
25576
+ };
25577
+ content: {
25578
+ "application/json": {
25579
+ status?: string;
25580
+ data?: components["schemas"]["Submission"];
25581
+ };
25582
+ };
25583
+ };
25584
+ 400: components["responses"]["BadRequest"];
25585
+ 403: components["responses"]["Forbidden"];
25586
+ 404: components["responses"]["NotFound"];
25587
+ 409: components["responses"]["Conflict"];
25588
+ };
25589
+ }, {
25590
+ body: never;
25591
+ }, `${string}/${string}`>>;
25592
+ /**
25593
+ * Attach files or links to a submission (batch)
25594
+ * Each item must have exactly ONE of fileId or url (XOR).
25595
+ * - submissionType in [images, videos, audio, files] → items must have fileId
25596
+ * - submissionType === 'links' → items must have url
25597
+ */
25598
+ attachFiles(submissionId: string, data: AttachFilesBody): Promise<openapi_fetch.FetchResponse<{
25599
+ parameters: {
25600
+ query?: never;
25601
+ header?: never;
25602
+ path: {
25603
+ id: components["parameters"]["id"];
25604
+ };
25605
+ cookie?: never;
25606
+ };
25607
+ requestBody: {
25608
+ content: {
25609
+ "application/json": {
25610
+ items: {
25611
+ fileId?: string | null;
25612
+ url?: string | null;
25613
+ index?: number;
25614
+ }[];
25615
+ };
25616
+ };
25617
+ };
25618
+ responses: {
25619
+ 201: {
25620
+ headers: {
25621
+ [name: string]: unknown;
25622
+ };
25623
+ content: {
25624
+ "application/json": {
25625
+ status?: string;
25626
+ data?: components["schemas"]["SubmissionFile"][];
25627
+ };
25628
+ };
25629
+ };
25630
+ 400: components["responses"]["BadRequest"];
25631
+ 404: components["responses"]["NotFound"];
25632
+ 409: components["responses"]["Conflict"];
25633
+ };
25634
+ }, {
25635
+ params: {
25636
+ path: {
25637
+ id: string;
25638
+ };
25639
+ };
25640
+ body: {
25641
+ items: {
25642
+ fileId?: string | null;
25643
+ url?: string | null;
25644
+ index?: number;
25645
+ }[];
25646
+ };
25647
+ }, `${string}/${string}`>>;
25648
+ /**
25649
+ * Remove a file or link from a submission
25650
+ * Only allowed when submission is in status submitted or ai_evaluated
25651
+ */
25652
+ removeFile(submissionId: string, fileRowId: string): Promise<openapi_fetch.FetchResponse<{
25653
+ parameters: {
25654
+ query?: never;
25655
+ header?: never;
25656
+ path: {
25657
+ id: components["parameters"]["id"];
25658
+ fileRowId: string;
25659
+ };
25660
+ cookie?: never;
25661
+ };
25662
+ requestBody?: never;
25663
+ responses: {
25664
+ 204: {
25665
+ headers: {
25666
+ [name: string]: unknown;
25667
+ };
25668
+ content?: never;
25669
+ };
25670
+ 400: components["responses"]["BadRequest"];
25671
+ 404: components["responses"]["NotFound"];
25672
+ };
25673
+ }, {
25674
+ params: {
25675
+ path: {
25676
+ id: string;
25677
+ fileRowId: string;
25678
+ };
25679
+ };
25680
+ }, `${string}/${string}`>>;
25681
+ /**
25682
+ * Register AI evaluation (called by the AI service callback).
25683
+ * Moves status from submitted → ai_evaluated.
25684
+ */
25685
+ aiEvaluate(submissionId: string, data: AiEvaluationBody): Promise<openapi_fetch.FetchResponse<{
25686
+ parameters: {
25687
+ query?: never;
25688
+ header?: never;
25689
+ path: {
25690
+ id: components["parameters"]["id"];
25691
+ };
25692
+ cookie?: never;
25693
+ };
25694
+ requestBody: {
25695
+ content: {
25696
+ "application/json": {
25697
+ aiScore: number;
25698
+ aiFeedback?: string;
25699
+ aiExtractedContent?: Record<string, never>;
25700
+ criterionScores?: {
25701
+ challengeEvaluationCriterionId: string;
25702
+ score: number;
25703
+ comment?: string;
25704
+ }[];
25705
+ };
25706
+ };
25707
+ };
25708
+ responses: {
25709
+ 200: {
25710
+ headers: {
25711
+ [name: string]: unknown;
25712
+ };
25713
+ content: {
25714
+ "application/json": {
25715
+ status?: string;
25716
+ data?: components["schemas"]["Submission"];
25717
+ };
25718
+ };
25719
+ };
25720
+ 400: {
25721
+ headers: {
25722
+ [name: string]: unknown;
25723
+ };
25724
+ content: {
25725
+ "application/json": components["schemas"]["Error"];
25726
+ };
25727
+ };
25728
+ 404: components["responses"]["NotFound"];
25729
+ 409: components["responses"]["Conflict"];
25730
+ };
25731
+ }, {
25732
+ params: {
25733
+ path: {
25734
+ id: string;
25735
+ };
25736
+ };
25737
+ body: {
25738
+ aiScore: number;
25739
+ aiFeedback?: string;
25740
+ aiExtractedContent?: Record<string, never>;
25741
+ criterionScores?: {
25742
+ challengeEvaluationCriterionId: string;
25743
+ score: number;
25744
+ comment?: string;
25745
+ }[];
25746
+ };
25747
+ }, `${string}/${string}`>>;
25748
+ /**
25749
+ * Teacher approves or rejects a submission.
25750
+ * Only allowed when status is submitted or ai_evaluated.
25751
+ */
25752
+ teacherEvaluate(submissionId: string, data: TeacherEvaluationBody): Promise<openapi_fetch.FetchResponse<{
25753
+ parameters: {
25754
+ query?: never;
25755
+ header?: never;
25756
+ path: {
25757
+ id: components["parameters"]["id"];
25758
+ };
25759
+ cookie?: never;
25760
+ };
25761
+ requestBody: {
25762
+ content: {
25763
+ "application/json": {
25764
+ status: "approved" | "rejected";
25765
+ teacherScore?: number;
25766
+ teacherFeedback?: string;
25767
+ };
25768
+ };
25769
+ };
25770
+ responses: {
25771
+ 200: {
25772
+ headers: {
25773
+ [name: string]: unknown;
25774
+ };
25775
+ content: {
25776
+ "application/json": {
25777
+ status?: string;
25778
+ data?: components["schemas"]["Submission"];
25779
+ };
25780
+ };
25781
+ };
25782
+ 400: components["responses"]["BadRequest"];
25783
+ 404: components["responses"]["NotFound"];
25784
+ };
25785
+ }, {
25786
+ params: {
25787
+ path: {
25788
+ id: string;
25789
+ };
25790
+ };
25791
+ body: {
25792
+ status: "approved" | "rejected";
25793
+ teacherScore?: number;
25794
+ teacherFeedback?: string;
25795
+ };
25796
+ }, `${string}/${string}`>>;
25797
+ };
25798
+ type SubmissionService = ReturnType<typeof createSubmissionService>;
25799
+
25107
25800
  type AcademeApiClient = ReturnType<typeof openapi_fetch__default<paths>>;
25108
25801
  declare function createAcademeApiClient(baseUrl: string): AcademeApiClient;
25109
25802
  interface AcademeServices {
@@ -25127,6 +25820,7 @@ interface AcademeServices {
25127
25820
  storageFile: StorageFileService;
25128
25821
  challenge: ChallengeService;
25129
25822
  step: StepService;
25823
+ submission: SubmissionService;
25130
25824
  }
25131
25825
 
25132
25826
  type AcademeKeycloakContextProps = {
@@ -25222,5 +25916,5 @@ declare enum NINA_ROLES {
25222
25916
  ACCESS_APPLICATION = "Acessar aplica\u00E7\u00E3o"
25223
25917
  }
25224
25918
 
25225
- export { AcademeAuthProvider, BACKOFFICE_ROLES, Button, CosmicDecor, CosmicStarsCanvas, DASHBOARD_ROLES, GLOBAL_ROLES, JourneyStep, MIKE_ROLES, NINA_ROLES, ProtectedApp, ProtectedComponent, ProtectedRouter, STREAMING_ROLES, Spinner, WIDGET_ROLES, academeApi_d as apiTypes, cn, createAcademeApiClient, index_d as types, useAcademeAuth, useProtectedAppColors };
25226
- export type { AcademeApiClient, AcademeKeycloakContextProps, AcademeServices, AcademeUser, ButtonProps, CosmicDecorProps, CosmicDecorVariant, CosmicPlanet, CosmicStarsCanvasProps, FrameKind, JourneyStepProps, JourneyStepSize, JourneyStepType, KeycloakUser, RequiredClientRoles, SecurityContextType, SecurityProviderProps };
25919
+ export { AcademeAuthProvider, BACKOFFICE_ROLES, Button, CosmicDecor, CosmicStarsCanvas, DASHBOARD_ROLES, GLOBAL_ROLES, JourneyCrystalPin, JourneyStep, MIKE_ROLES, NINA_ROLES, ProtectedApp, ProtectedComponent, ProtectedRouter, STREAMING_ROLES, Spinner, WIDGET_ROLES, academeApi_d as apiTypes, cn, createAcademeApiClient, index_d as types, useAcademeAuth, useProtectedAppColors };
25920
+ export type { AcademeApiClient, AcademeKeycloakContextProps, AcademeServices, AcademeUser, ButtonProps, CosmicDecorProps, CosmicDecorVariant, CosmicPlanet, CosmicStarsCanvasProps, FrameKind, JourneyCrystalPinProps, JourneyStepProps, JourneyStepSize, JourneyStepType, KeycloakUser, RequiredClientRoles, SecurityContextType, SecurityProviderProps };