diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..8c8335b --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,212 @@ +# Copilot Instructions for Polito API Spec + +## Project Overview + +This is a **TypeSpec-based REST API specification** for the Politecnico di Torino students portal. TypeSpec (`.tsp`) files define the API schema and OpenAPI 3.0 output, replacing hand-written `openapi.yaml`. + +**Key Build Flow:** +- `npm run compile` → TypeSpec compiler outputs `dist/openapi.yaml` +- `npm run generate` → OpenAPI generator creates TypeScript client SDK in `dist/client` +- `npm run build` → Runs both compile + generate +- `npm run watch` → Watches for changes and auto-compiles + +**Key Files:** +- [src/main.tsp](src/main.tsp) - Service definition, imports all routes +- [src/common.tsp](src/common.tsp) - Shared models (response aliases, common types like `Lecture`, `PlaceRef`) +- [src/routes/](src/routes/) - Feature-specific route definitions (auth, courses, exams, etc.) +- [src/examples/](src/examples/) - Example data constants (paired 1:1 with routes) + +--- + +## Architecture Patterns + +### 1. Response Wrapper Pattern + +All API responses use standardized aliases from `common.tsp`: + +```typespec +// Single object +alias OkResponse = { @statusCode statusCode: 200; @body body: T; }; + +// Data envelope (most common for lists/resources) +alias OkDataResponse = OkResponse<{ data: T; }>; + +// Error response +alias ErrorResponse = { code?: string; message?: string; }; +``` + +**Usage in routes:** +```typespec +interface Courses { + @get list(): OkDataResponse | BadRequest | ServerError; +} +``` + +The `OkDataResponse` pattern wraps results in `{ data: [...] }` - this is the standard envelope for all resource lists and single objects. + +### 2. Route Organization + +Each feature has: +- **Route file** (`src/routes/courses.tsp`) - Models + `interface` with HTTP operations +- **Example file** (`src/examples/courses.tsp`) - Example constants for that route +- Routes import their paired example file + +Operations use `@get`, `@post`, `@put`, `@patch`, `@delete` decorators with paths like `@route("/courses/{id}")`. + +### 3. Bilingual Documentation + +Operations include dual-language summaries: +```typespec +@summary("List courses | Elenca corsi") +``` + +Follow this pattern for all new endpoints. + +--- + +## Examples Pattern + +Examples are organized into two categories based on their scope: + +### 1. Field-Level Examples (Single Values) + +Individual field examples are defined directly on model properties using the `@example` decorator. + +**Location:** In model definitions within `src/routes/*.tsp` + +**Example:** +```typespec +model Course { + @example(258674) + id: integer | null; + + @example("System and device programming") + name: string; + + @example(10) + cfu: integer; + + @example("01NYHOV") + shortcode: string; +} +``` + +**Usage:** Use this for: +- Scalar values (strings, numbers, booleans, dates) +- Simple inline examples for individual properties +- Field-level documentation + +### 2. Complex Examples (Models & Operations) + +Complete model instances and operation response examples are defined as constants in dedicated example files, then referenced in route definitions. + +#### File Organization + +``` +src/ +├── routes/ +│ ├── courses.tsp ← Route definitions (with @opExample references) +│ ├── lectures.tsp +│ └── ... +├── examples/ +│ ├── courses.tsp ← Example constants (matching routes/courses.tsp) +│ ├── lectures.tsp +│ └── ... +└── common.tsp +``` + +#### Naming Convention + +- Example file: `src/examples/courses.tsp` corresponds to `src/routes/courses.tsp` +- Example constant: `_ex_{operationName}_{context}` OR `_ex_{modelName}` for complex models + - Examples: `_ex_getLectures_resp`, `_ex_course_module`, `_ex_courses_list` + - Contexts: `resp` (response), `req` (request), or resource type + - Use snake_case for readability + +#### Defining Examples + +In `src/examples/courses.tsp`: + +```typespec +const _ex_course_module = #{ + id: 251008, + name: "Programming Module A", + teachingPeriod: "2-2", + teacherId: 3001, + teacherName: "Mario Rossi", + previousEditions: #[#{ id: 251005, year: "2024" }], + isOverBooking: false, + isInPersonalStudyPlan: true, + year: "2025", +}; + +const _ex_getLectures_resp = #{ + returnType: #{ + statusCode: 200, + body: #{ + data: #[ + #{ + id: 5001, + title: "Introduction to Programming", + date: utcDateTime.fromISO("2025-02-15T10:00:00Z"), + courseId: 258674, + }, + ], + }, + }, +}; +``` + +#### Referencing Examples in Routes + +In `src/routes/courses.tsp`: + +```typespec +import "../examples/courses.tsp"; + +@example(_ex_course_module) +model CourseModule { + // ... model definition +} + +interface Lectures { + @get + @summary("List lectures | Elenca lezioni") + @opExample(_ex_getLectures_resp) + getLectures( + @query fromDate?: plainDate, + @query toDate?: plainDate, + @query(#{ explode: true }) `courseIds[]`?: numeric[], + ): OkDataResponse | BaseErrors; +} +``` + +--- + +## Best Practices + +1. **Keep it organized:** Examples that are specific to a route file live in a corresponding example file +2. **Use utcDateTime.fromISO() for dates:** Wrap ISO timestamp strings with `utcDateTime.fromISO()` for type safety and consistency +3. **Field examples first:** Add `@example` to model properties when defining the model +4. **Complex examples separate:** When a model has a full representative example, define it as a constant in the examples file +5. **Operation examples explicit:** Use `@opExample(constant_name)` on operations that need full request/response examples +6. **Real data when possible:** Use realistic example data that matches actual API behavior (see [src/examples/courses.tsp](src/examples/courses.tsp) for reference) +7. **Remove duplicates from OpenAPI:** When migrating examples from `openapi.yaml` to TypeSpec, remove the inline examples to maintain single source of truth +8. **Wrap arrays with `#[...]`:** TypeSpec array literals use hash-bracket syntax: `#[{ id: 1 }, { id: 2 }]` +9. **Use object shorthand `#{...}`:** For TypeSpec object literals, use hash-brace syntax: `#{ id: 1, name: "test" }` + +--- + +## Example: Complete Workflow + +When adding a new endpoint with examples: + +1. **Define the model** in `src/routes/myfeature.tsp` with field-level `@example` decorators +2. **Create example data** in `src/examples/myfeature.tsp` for: + - Complex model instances (if needed) + - Full operation request/response payloads +3. **Reference the examples** in the route using: + - `@example(_ex_my_model_example)` on model definitions + - `@opExample(_ex_my_operation_resp_example)` on operation methods + +This keeps the code organized, maintainable, and ensures examples are centralized and reusable. diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml new file mode 100644 index 0000000..e4d9d7a --- /dev/null +++ b/.github/workflows/checks.yml @@ -0,0 +1,53 @@ +name: Ensure code quality + +on: + push: + branches: + - main + pull_request: + types: + - opened + - reopened + - synchronize + +jobs: + checks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version-file: .nvmrc + + - name: Setup Java + uses: actions/setup-java@v5 + with: + distribution: "corretto" + java-version: "17" + + - name: Install dependencies + run: npm install + + - name: Ensure linting + run: | + npm run format + if [[ $(git status --porcelain) ]]; then + echo "Linting introduced changes. Please fix the issues."; + git --no-pager diff; + exit 1; + fi + + - name: Typespec compile + run: npm run compile + + - name: Check openapi is in sync + run: | + if [[ $(git status --porcelain) ]]; then + echo "OpenAPI spec is out of date. Did you forget to run 'npm run compile'?"; + exit 1; + fi + + - name: Openapi Generation + run: npm run generate diff --git a/.github/workflows/publish-client.yml b/.github/workflows/publish-client.yml index d4b3bf1..e0870e6 100644 --- a/.github/workflows/publish-client.yml +++ b/.github/workflows/publish-client.yml @@ -3,8 +3,8 @@ name: Publish API client derived from spec on: push: tags: - - 'v[0-9]+.[0-9]+.[0-9]+' - - 'v[0-9]+.[0-9]+.[0-9]+-ALPHA.[0-9]+' + - "v[0-9]+.[0-9]+.[0-9]+" + - "v[0-9]+.[0-9]+.[0-9]+-ALPHA.[0-9]+" permissions: contents: read @@ -16,49 +16,31 @@ jobs: steps: - uses: actions/checkout@v4 - - name: OpenAPI Generator Action - uses: openapi-generators/openapitools-generator-action@v1 + - name: Setup Node.js + uses: actions/setup-node@v6 with: - generator: typescript-fetch - openapi-file: openapi.yaml - generator-tag: v7.4.0 - # generates into -client - + node-version-file: .nvmrc + registry-url: https://npm.pkg.github.com/ + + - name: Setup Java + uses: actions/setup-java@v5 + with: + distribution: "corretto" + java-version: "17" + - id: get_version uses: battila7/get-version-action@v2.2.1 - - name: Generate package.json + - name: Generate the client env: TAG_VERSION: ${{ steps.get_version.outputs.version-without-v }} - working-directory: ./typescript-fetch-client run: | - cat < package.json - { - "name": "@polito/api-client", - "version": "$TAG_VERSION", - "repository":"https://github.com/polito/api-spec" - } - EOF - - cat package.json - - echo -e "// @ts-nocheck\n$(cat runtime.ts)" > runtime.ts - - # Fix for invalid type generated by GeoJSON spec reference - echo -e "// @ts-nocheck\n$(cat models/FeatureAllOfId.ts)" > models/FeatureAllOfId.ts - - cat < README.md - # PoliTO API Client - Autogenerated typescript-fetch client for the API of PoliTO, based on its [OpenAPI specification](https://github.com/polito/api-spec). - EOF - - - name: Setup Node.js environment - uses: actions/setup-node@v4 - with: - node-version: 18 - registry-url: 'https://npm.pkg.github.com' + echo "const version = \"$TAG_VERSION\";" > src/version.tsp + npm install + npm run build - - run: npm publish - working-directory: ./typescript-fetch-client + - name: Publish the client + run: npm publish + working-directory: ./dist/client env: NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..235323c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +dist/client diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..0317576 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v20.19.5 diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..d579fbb --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["typespec.typespec-vscode"] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b620f66 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.formatOnSave": true, +} diff --git a/dist/openapi.yaml b/dist/openapi.yaml new file mode 100644 index 0000000..4af211e --- /dev/null +++ b/dist/openapi.yaml @@ -0,0 +1,7609 @@ +openapi: 3.0.0 +info: + title: Polito Students API + version: 0.0.1 + license: + name: CC BY-NC 4.0 + url: https://creativecommons.org/licenses/by-nc/4.0/ +tags: + - name: Auth + - name: Student + - name: Bookings + - name: Courses + - name: Lectures + - name: Exams + - name: Esc + - name: News + - name: People + - name: Places + - name: Tickets + - name: Job offers + - name: Offering + - name: Surveys +paths: + /auth/client: + patch: + operationId: Auth_appInfo + summary: Update client version fields | Aggiorna i campi di versione del client + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/UpdateInfo' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Auth + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AppInfoRequest' + /auth/login: + post: + operationId: Auth_login + summary: Login + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/Identity' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Auth + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/LoginRequest' + /auth/logout: + delete: + operationId: Auth_logout + summary: Logout + description: Invalidates the provided token + parameters: [] + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Auth + /auth/mfa/challenge: + get: + operationId: Mfa_fetchChallenge + summary: Fetch pending challenge + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: object + allOf: + - $ref: '#/components/schemas/MfaChallenge' + nullable: true + required: + - data + example: + data: + serial: EDUP000123456 + challenge: dGhpcyBzaG91bGQgYmUgYW4gZWNkcyBwdWJsaWMga2V5Li4uIHdoYXQgZGlkIHlvdSB0aGluayB0aGlzIHdhcz8hIPCfp5AK + requestTs: '2025-01-01T00:00:00Z' + expirationTs: '2025-01-01T01:00:00Z' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Auth + /auth/mfa/enrol: + post: + operationId: Mfa_enrolMfa + summary: Enroll a new PUSH token + parameters: [] + responses: + '201': + description: The request has succeeded and a new resource has been created as a result. + content: + application/json: + schema: + type: object + properties: + data: + type: object + properties: + serial: + type: string + example: EDUP000123456 + required: + - serial + required: + - data + example: + data: + serial: EDUP000123456 + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Auth + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EnrolMfaRequest' + /auth/mfa/status: + get: + operationId: Mfa_getMfaStatus + summary: Get MFA status for the current user + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/MfaStatusResponse' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Auth + /auth/mfa/validate: + post: + operationId: Mfa_validateMfa + summary: Validate a challenge + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: object + properties: + success: + type: boolean + example: true + required: + - success + required: + - data + example: + data: + success: true + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Auth + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ValidateMfaRequest' + /auth/serviceLink/liveClass/{meetingID}: + get: + operationId: ServiceLink_getLiveClassLink + summary: Get authorised service link for LiveClass meeting + parameters: + - name: meetingID + in: path + required: true + description: LiveClass meeting identifier + schema: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/LinkToService' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Auth + /auth/serviceLink/mail: + get: + operationId: ServiceLink_getMailLink + summary: Get authorised service link for Mail + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/LinkToService' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Auth + /auth/serviceLink/moodle/{course}: + get: + operationId: ServiceLink_getMoodleLink + summary: Get authorised service link for Moodle course + parameters: + - name: course + in: path + required: true + description: Moodle course identifier + schema: + type: integer + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/LinkToService' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Auth + /auth/switch-career: + post: + operationId: Auth_switchCareer + summary: Switch career | Cambia carriera + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/Identity' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Auth + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SwitchCareerRequest' + /booking-topics: + get: + operationId: BookingTopics_getBookingTopics + summary: List booking topics | Elenca ambiti di prenotazione + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/BookingTopic' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Bookings + /booking-topics/{bookingTopicId}/slots: + get: + operationId: BookingTopics_getBookingSlots + summary: Show booking slots | Mostra turni prenotabili + parameters: + - name: bookingTopicId + in: path + required: true + schema: + type: string + - name: fromDate + in: query + required: false + description: First day - defaults to monday of current week + schema: + type: string + format: date + explode: false + - name: toDate + in: query + required: false + description: Last day - defaults to sunday of current week + schema: + type: string + format: date + explode: false + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/BookingSlot' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Bookings + /booking-topics/{bookingTopicId}/slots/{bookingSlotId}/seats: + get: + operationId: BookingTopics_getBookingSeats + summary: Show seats for a booking slots | Mostra posti prenotabili + parameters: + - name: bookingTopicId + in: path + required: true + schema: + type: string + - name: bookingSlotId + in: path + required: true + schema: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/BookingSeats' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Bookings + /bookings: + get: + operationId: BookingsManagement_getBookings + summary: List bookings | Elenca prenotazioni + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Booking' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Bookings + post: + operationId: BookingsManagement_createBooking + summary: Create booking | Crea prenotazione + parameters: [] + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Bookings + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateBookingRequest' + /bookings/{bookingId}: + delete: + operationId: BookingsManagement_deleteBooking + summary: Delete booking | Cancella prenotazione + parameters: + - name: bookingId + in: path + required: true + schema: + type: integer + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Bookings + patch: + operationId: BookingsManagement_updateBooking + summary: Update booking | Aggiorna prenotazione + parameters: + - name: bookingId + in: path + required: true + schema: + type: integer + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Bookings + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateBookingRequest' + /courses/{courseId}: + get: + operationId: Courses_getCourse + summary: Show course | Mostra corso + parameters: + - name: courseId + in: path + required: true + schema: + type: integer + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/Course' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Courses + /courses/{courseId}/assignments: + get: + operationId: Courses_getCourseAssignments + summary: List assignments | Elenca elaborati + parameters: + - name: courseId + in: path + required: true + schema: + type: integer + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/CourseAssignment' + required: + - data + example: + data: + - id: 1003948 + description: extrapoints2 + mimeType: application/x-zip-compressed + filename: extrapoints2.zip + uploadedAt: '2022-01-21T14:38:00Z' + deletedAt: null + url: https://file.didattica.polito.it/down/ELABORATI_PRE/1003948/S290683/14576f69df588d55b631c3c3c30de3f5/6305eae6 + sizeInKiloBytes: 195 + - id: 993784 + description: extrapoints1 + mimeType: application/x-zip-compressed + filename: extrapoints1.zip + uploadedAt: '2022-01-10T18:53:00Z' + deletedAt: null + url: https://file.didattica.polito.it/down/ELABORATI_PRE/993784/S290683/15c275f7f7682c6acb5acd07d24590a9/6305eae6 + sizeInKiloBytes: 401 + - id: 982517 + description: lab_09 + mimeType: application/zip + filename: lab_09.zip + uploadedAt: '2021-12-16T22:48:00Z' + deletedAt: null + url: https://file.didattica.polito.it/down/ELABORATI_PRE/982517/S290683/29288344d27567de6ddf0fa718b980a5/6305eae6 + sizeInKiloBytes: 126 + - id: 934034 + description: lab_01 + mimeType: application/x-zip-compressed + filename: lab_01.zip + uploadedAt: '2021-10-13T11:20:00Z' + deletedAt: null + url: https://file.didattica.polito.it/down/ELABORATI_PRE/934034/S290683/fd675d8a411d0747885b24e473a5d683/6305eae6 + sizeInKiloBytes: 144 + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Courses + post: + operationId: Courses_uploadCourseAssignment + summary: Upload assignment | Carica elaborato + parameters: + - name: courseId + in: path + required: true + schema: + type: integer + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Courses + requestBody: + required: true + content: + multipart/form-data: + schema: + $ref: '#/components/schemas/CourseAssignmentUpload' + /courses/{courseId}/assignments/{assignmentId}: + patch: + operationId: Courses_updateAssignment + summary: Update assignment | Aggiorna elaborato + parameters: + - name: courseId + in: path + required: true + schema: + type: integer + - name: assignmentId + in: path + required: true + schema: + type: integer + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Courses + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateAssignmentRequest' + /courses/{courseId}/files: + get: + operationId: Courses_getCourseFiles + summary: List files | Elenca file + parameters: + - name: courseId + in: path + required: true + schema: + type: integer + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/CourseDirectoryContent' + required: + - data + example: + data: + - id: '33248655' + name: videolectures + type: directory + files: + - id: '33248890' + name: HCI2021-L01 2021-09-28 13-06-26.m4v + sizeInKiloBytes: 123428 + mimeType: video/x-m4v + createdAt: '2021-09-28T16:31:43Z' + type: file + checksum: deadbeefcafebabe0000000000000000 + - id: '33251708' + name: HCI2021-L02 2021-09-30 08-34-32.mp4 + sizeInKiloBytes: 248172 + mimeType: video/mp4 + createdAt: '2021-09-30T10:20:50Z' + type: file + checksum: deadbeefcafebabe0000000000000001 + - id: '33256476' + name: HCI2021-L03 2021-10-05 13-06-47.mp4 + sizeInKiloBytes: 243792 + mimeType: video/mp4 + createdAt: '2021-10-05T15:00:15Z' + type: file + checksum: deadbeefcafebabe0000000000000002 + - id: '33257988' + name: HCI2021-L04 2021-10-07 08-35-46.mp4 + sizeInKiloBytes: 244993 + mimeType: video/mp4 + createdAt: '2021-10-07T11:12:25Z' + type: file + checksum: deadbeefcafebabe0000000000000003 + - id: '33262287' + name: HCI2021-L05 2021-10-12 13-05-46.mp4 + sizeInKiloBytes: 298172 + mimeType: video/mp4 + createdAt: '2021-10-12T16:11:46Z' + type: file + checksum: deadbeefcafebabe0000000000000004 + - id: '33265387' + name: HCI2021-L06 2021-10-14 08-35-12.mp4 + sizeInKiloBytes: 285926 + mimeType: video/mp4 + createdAt: '2021-10-14T11:25:20Z' + type: file + checksum: deadbeefcafebabe0000000000000005 + - id: '33269079' + name: HCI2021-L07 2021-10-19 13-10-40.mp4 + sizeInKiloBytes: 234466 + mimeType: video/mp4 + createdAt: '2021-10-19T15:02:22Z' + type: file + checksum: deadbeefcafebabe0000000000000006 + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Courses + /courses/{courseId}/files/{fileId}: + get: + operationId: Courses_getCourseFile + summary: Download file | Scarica file + parameters: + - name: courseId + in: path + required: true + schema: + type: integer + - name: fileId + in: path + required: true + schema: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + nullable: true + '302': + description: Redirection + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: The server cannot find the requested resource. + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Courses + /courses/{courseId}/guide: + get: + operationId: Courses_getCourseGuide + summary: Show guide | Mostra guida + parameters: + - name: courseId + in: path + required: true + schema: + type: integer + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/GuideSection' + required: + - data + example: + data: + - title: Presentazione + content: Nowadays, computing devices are ubiquitously present and integrated in our daily life. Sensors and actuators are embedded in home appliances, lights, or cars. This course provides a strong foundation in human-centered design principles. + - title: Risultati attesi + content: 'Knowledge: Concepts of Usability, User Experience, User centered design processes. Skills: Developing a working prototype, mastering novel interaction technologies, joint development in teams.' + - title: Prerequisiti + content: Programming skills, knowledge on web technologies (HTML, JS, client-server architectures), attitude towards working in teams. + - title: Programma + content: Introduction to Human-Computer Interaction, building interactive applications with human-centered design process, beyond WIMP paradigms (AI-powered systems, tangible interaction, voice, wearables). + - title: Note + content: '' + - title: Organizzazione dell'insegnamento + content: Project-based and problem-based learning with teams working towards a common goal. Project-related activities start since the beginning with deliverables before given deadlines. + - title: Bibliografia + content: Course slides and related materials. Selected chapters from Human Computer Interaction texts by Dix et al., and Shneiderman et al. + - title: Regole d'esame + content: Exam consists of written test (40% of score) and group project evaluation (60% of score). Both parts are mandatory and must be taken in the same academic year. + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Courses + /courses/{courseId}/nextLecture: + get: + operationId: Courses_getNextLecture + summary: Get next lecture | Ottieni prossima lezione + parameters: + - name: courseId + in: path + required: true + schema: + type: integer + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/Lecture' + required: + - data + example: + data: + id: 12131312 + startsAt: '2021-09-28T14:30:00Z' + endsAt: '2021-09-28T17:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: + - id: 149336 + title: CYB / lecture 28.09.2021 (TLS, slides 1-40) + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Courses + /courses/{courseId}/notices: + get: + operationId: Courses_getCourseNotices + summary: List notices | Elenca avvisi + parameters: + - name: courseId + in: path + required: true + schema: + type: integer + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/CourseNotices' + required: + - data + example: + data: + - id: 332559 + publishedAt: '2021-09-22T14:00:00Z' + expiresAt: null + content: "

Dear students,

\r\r

welcome to the 2021 edition of the Human Computer Interaction course (HCI, for short)!

\r\r

Some useful information to get started...

\r\r

The first class will be on Tuesday, September 28, in Room 7T, from 13:00 to 14:30.
\rDon't forget to book a spot in the room, starting from tomorrow, on the Portale della Didattica: the rooms given to this course are currently bigger than the number of enrolled students, so there should be space for everybody!

\r\r

All teaching material, information, and course schedule will be posted on the page: http://bit.ly/polito-hci (we will not use the Portale della Didattica).

\r\r

All messages and communications with the teachers, and among students, will be on Slack. We will completely avoid email communications.
\rPlease, join the HCI Slack workspace at the address:
\r  https://join.slack.com/t/polito-hci-2021/signup
\rPlease note: to have access to the workspace, you must use your @studenti.polito.it email address. You are free to choose your nickname as you prefer. 

\r\r

Finally, all lectures — not labs — will be video-recorded and made available both on YouTube and on the Portale della Didattica. The YouTube playlist is:
\r  https://www.youtube.com/playlist?list=PLs7DWGc_wmwT-1N2vbRkLWrM6LIker9A-

\r\r

See you on Tuesday!

\r\r

Thanks,

\r\r

Luigi and Fulvio

\r" + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Courses + /courses/{courseId}/preferences: + patch: + operationId: Courses_updateCoursePreferences + summary: Update course preferences | Aggiorna preferenze del corso + parameters: + - name: courseId + in: path + required: true + schema: + type: integer + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Courses + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CoursePreferencesRequest' + /courses/{courseId}/videolectures: + get: + operationId: Courses_getCourseVideolectures + summary: List videolectures | Elenca videolezioni + parameters: + - name: courseId + in: path + required: true + schema: + type: integer + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/VideoLecture' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Courses + /courses/{courseId}/virtual-classrooms: + get: + operationId: Courses_getCourseVirtualClassrooms + summary: List virtual classrooms | Elenca virtual classroom + parameters: + - name: courseId + in: path + required: true + schema: + type: integer + - name: live + in: query + required: false + description: Filter virtual classrooms by their live status + schema: + type: boolean + explode: false + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/VirtualClassroom' + required: + - data + example: + data: + - id: 149336 + title: CYB / lecture 28.09.2021 (TLS, slides 1-40) + teacherId: 1847 + coverUrl: https://lucapezzolla.com/cover.jpg + videoUrl: https://video.polito.it/dl/BE7C779FC37D50996EE1FF32B6BC7FAE/6305E087/vc2021/252258/64cdcfc29ac1cd827d20ff1fa62c512eade6b3c0-1632832182985.mp4 + createdAt: '2021-09-28T14:29:00Z' + duration: 02h 56m + type: recording + - id: 150397 + title: CYB / lecture 01.10.2021 (TLS, slides 41-55) + teacherId: 1847 + coverUrl: https://lucapezzolla.com/cover.jpg + videoUrl: https://video.polito.it/dl/0BC53A27F4776D8A6809D28EB4CB3C9F/6305E087/vc2021/252258/e5e7a53da68cebd5cff1a585659092fcfeca651a-1633074845891.mp4 + createdAt: '2021-10-01T09:54:00Z' + duration: 01h 31m + type: recording + - id: 151650 + title: CYB / lecture 5.10.2021 (TLS, slides 56-end, + SSH all slides) + teacherId: 1847 + coverUrl: https://lucapezzolla.com/cover.jpg + videoUrl: https://video.polito.it/dl/56DA5556ECD96ED30EC6F8CBAB704285/6305E087/vc2021/252258/c30092cca256f522f64774e19538d43909ce558b-1633437688385.mp4 + createdAt: '2021-10-05T14:41:00Z' + duration: 02h 43m + type: recording + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Courses + /deadlines: + get: + operationId: StudentNs_getDeadlines + summary: List deadlines | Elenca scadenze + parameters: + - name: fromDate + in: query + required: false + description: First day - defaults to 7 days before today + schema: + type: string + format: date + explode: false + - name: toDate + in: query + required: false + description: Last day - defaults to 7 days after today + schema: + type: string + format: date + explode: false + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Deadline' + required: + - data + example: + data: + - name: Termine per l'iscrizione e pagamento della prima rata, per gli studenti di anni successivi al primo + type: Iscrizioni e pagamento tasse + date: '2022-10-11' + url: null + - name: Trasferimento da altri Atenei italiani + type: Trasferimenti e valutazioni carriere precedenti + date: '2022-10-14' + url: null + - name: Termine per superare gli esami + type: Sessioni esami di laurea + date: '2022-11-12' + url: null + - name: Termine iscrizione esame finale + type: Sessioni esami di laurea + date: '2022-11-14' + url: null + - name: Periodo per la compilazione del piano carriera / carico didattico + type: Iscrizioni e pagamento tasse + date: '2022-11-25' + url: null + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Student + /departments: + get: + operationId: Departments_getDepartments + summary: List departments | Elenca dipartimenti + parameters: + - name: siteId + in: query + required: false + schema: + type: string + explode: false + - name: departmentType + in: query + required: false + schema: + type: string + explode: false + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Department' + required: + - data + example: + data: + - id: DAUIN + name: Dipartimento di Automatica e Informatica + type: DIP. + - id: DIMEAS + name: Dipartimento di Ingegneria Meccanica e Aerospaziale + type: DIP. + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Places + /emergencecies: + get: + operationId: StudentNs_getEmergencies + summary: Show emergencecies text and number | Mostra testi e numeri di emergenza + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + $ref: '#/components/schemas/EmergencyResponse' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Student + /esc: + delete: + operationId: Esc_escDelete + summary: Delete all Student data on the ESC-Router (and all student's cards) | Cancella tutti i dati dello studente sul Router ESC (e tutte le carte dello studente) + parameters: [] + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + anyOf: + - $ref: '#/components/schemas/ErrorResponse' + - type: object + properties: + code: + type: integer + message: + type: string + errors: + type: array + items: + $ref: '#/components/schemas/EscError' + required: + - errors + tags: + - Esc + get: + operationId: Esc_escGet + summary: retrieve european student card | recupera la european student card + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/EuropeanStudentCard' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Esc + /esc/create: + post: + operationId: Esc_escRequest + summary: request european student card | richiedi la european student card + parameters: [] + responses: + '201': + description: The request has succeeded and a new resource has been created as a result. + content: + application/json: + schema: + nullable: true + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Esc + /exams: + get: + operationId: Exams_getExams + summary: List exams | Elenca esami + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Exam' + required: + - data + example: + data: + - id: 888137 + courseId: 262147 + courseShortcode: 01UDROV + courseName: Cybersecurity (AA-ZZ) + teacherId: 1847 + type: Scritto + status: booked + bookingStartsAt: null + bookingEndsAt: '2022-08-23T14:00:00Z' + examStartsAt: '2022-08-29T08:00:00Z' + examEndsAt: '2022-08-29T10:00:00Z' + bookedCount: 12 + availableCount: 8 + moduleNumber: 1 + notes: null + places: [] + isReschedulable: false + question: null + feedback: Esiste già una prenotazione per l'esame in questione + requestReason: null + requestDetails: null + - id: 887981 + courseId: 262789 + courseShortcode: 01NYHOV + courseName: System and device programming (AA-ZZ) + teacherId: 2893 + type: Esami scritti a risposta aperta o chiusa tramite PC + status: available + bookingStartsAt: null + bookingEndsAt: '2022-09-02T14:00:00Z' + examStartsAt: '2022-09-08T14:00:00Z' + examEndsAt: '2022-09-08T18:00:00Z' + bookedCount: 42 + availableCount: 108 + moduleNumber: 1 + notes: null + places: [] + isReschedulable: false + question: null + feedback: null + requestReason: null + requestDetails: null + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Exams + /exams/{examId}/booking: + delete: + operationId: Exams_deleteExamBookingById + summary: Delete exam booking | Annulla prenotazione esame + parameters: + - name: examId + in: path + required: true + schema: + type: integer + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Exams + post: + operationId: Exams_bookExam + summary: Book exam | Prenota esame + parameters: + - name: examId + in: path + required: true + schema: + type: integer + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Exams + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/BookExamRequest' + /exams/{examId}/rescheduleRequest: + post: + operationId: Exams_rescheduleExam + summary: Ask to reschedule an exam | Chiedi di spostare un esame + parameters: + - name: examId + in: path + required: true + schema: + type: integer + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Exams + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/RescheduleExamRequest' + /grades: + get: + operationId: StudentNs_getStudentGrades + summary: Retrieve student grades | Recupera i voti dello studente + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/ExamGrade' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Student + /guides: + get: + operationId: StudentNs_getGuides + summary: Get guides | Mostra guide + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Guide' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Student + /job-offers: + get: + operationId: JobOffers_getJobOffers + summary: List job offers | Elenca offerte di lavoro + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/JobOfferOverview' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Job offers + /job-offers/{jobOfferId}: + get: + operationId: JobOffers_getJobOffer + summary: Show a job offer | Mostra un'offerta di lavoro + parameters: + - name: jobOfferId + in: path + required: true + schema: + type: integer + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/JobOffer' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Job offers + /lectures: + get: + operationId: Lectures_getLectures + summary: List lectures | Elenca lezioni + parameters: + - name: fromDate + in: query + required: false + description: First day - defaults to 7 days before today + schema: + type: string + format: date + explode: false + - name: toDate + in: query + required: false + description: Last day - defaults to 7 days after today + schema: + type: string + format: date + explode: false + - name: courseIds[] + in: query + required: false + description: Only include lectures belonging to these courses + schema: + type: array + items: + type: number + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Lecture' + required: + - data + example: + data: + - id: 12131312 + startsAt: '2021-09-28T14:30:00Z' + endsAt: '2021-09-28T17:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: + - id: 149336 + title: CYB / lecture 28.09.2021 (TLS, slides 1-40) + - id: 12131313 + startsAt: '2021-10-01T10:00:00Z' + endsAt: '2021-10-01T11:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: + - id: 150397 + title: CYB / lecture 01.10.2021 (TLS, slides 41-55) + - id: 12131314 + startsAt: '2021-10-05T14:30:00Z' + endsAt: '2021-10-05T17:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131315 + startsAt: '2021-10-08T10:00:00Z' + endsAt: '2021-10-08T11:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Esercitazione aula + description: Demos about TLS and SSH. Introduction to the laboratory. + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131316 + startsAt: '2021-10-12T08:30:00Z' + endsAt: '2021-10-12T10:00:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131317 + startsAt: '2021-10-12T10:00:00Z' + endsAt: '2021-10-12T11:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131318 + startsAt: '2021-10-12T14:30:00Z' + endsAt: '2021-10-12T17:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131319 + startsAt: '2021-10-15T10:00:00Z' + endsAt: '2021-10-15T11:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131320 + startsAt: '2021-10-19T08:30:00Z' + endsAt: '2021-10-19T10:00:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131321 + startsAt: '2021-10-19T10:00:00Z' + endsAt: '2021-10-19T11:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131322 + startsAt: '2021-10-19T14:30:00Z' + endsAt: '2021-10-19T17:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131323 + startsAt: '2021-10-22T10:00:00Z' + endsAt: '2021-10-22T11:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131324 + startsAt: '2021-10-26T08:30:00Z' + endsAt: '2021-10-26T10:00:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131325 + startsAt: '2021-10-26T10:00:00Z' + endsAt: '2021-10-26T11:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131326 + startsAt: '2021-10-26T14:30:00Z' + endsAt: '2021-10-26T17:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131327 + startsAt: '2021-11-02T08:30:00Z' + endsAt: '2021-11-02T10:00:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131328 + startsAt: '2021-11-02T10:00:00Z' + endsAt: '2021-11-02T11:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131329 + startsAt: '2021-11-02T14:30:00Z' + endsAt: '2021-11-02T17:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131330 + startsAt: '2021-11-05T10:00:00Z' + endsAt: '2021-11-05T11:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131331 + startsAt: '2021-11-09T08:30:00Z' + endsAt: '2021-11-09T10:00:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Esercitazione Laboratorio con titolo esageratamente lungo che poi boh + description: squadra 1 + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131332 + startsAt: '2021-11-09T10:00:00Z' + endsAt: '2021-11-09T11:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Esercitazione Laboratorio + description: squadra 1 + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131333 + startsAt: '2021-11-09T14:30:00Z' + endsAt: '2021-11-09T17:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131334 + startsAt: '2021-11-16T08:30:00Z' + endsAt: '2021-11-16T10:00:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Esercitazione Laboratorio + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131335 + startsAt: '2021-11-16T10:00:00Z' + endsAt: '2021-11-16T11:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Esercitazione Laboratorio + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131336 + startsAt: '2021-11-16T14:30:00Z' + endsAt: '2021-11-16T17:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131337 + startsAt: '2021-11-23T08:30:00Z' + endsAt: '2021-11-23T10:00:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Esercitazione Laboratorio + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131338 + startsAt: '2021-11-23T10:00:00Z' + endsAt: '2021-11-23T11:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Esercitazione Laboratorio + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131339 + startsAt: '2021-11-23T14:30:00Z' + endsAt: '2021-11-23T17:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131340 + startsAt: '2021-11-30T08:30:00Z' + endsAt: '2021-11-30T10:00:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Esercitazione Laboratorio + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131341 + startsAt: '2021-11-30T10:00:00Z' + endsAt: '2021-11-30T11:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Esercitazione Laboratorio + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131342 + startsAt: '2021-11-30T14:30:00Z' + endsAt: '2021-11-30T17:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Esercitazione aula + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131343 + startsAt: '2021-12-03T10:00:00Z' + endsAt: '2021-12-03T11:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131344 + startsAt: '2021-12-07T08:30:00Z' + endsAt: '2021-12-07T10:00:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131345 + startsAt: '2021-12-07T10:00:00Z' + endsAt: '2021-12-07T11:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131346 + startsAt: '2021-12-07T14:30:00Z' + endsAt: '2021-12-07T17:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131347 + startsAt: '2021-12-10T10:00:00Z' + endsAt: '2021-12-10T11:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131348 + startsAt: '2021-12-14T08:30:00Z' + endsAt: '2021-12-14T10:00:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131349 + startsAt: '2021-12-14T10:00:00Z' + endsAt: '2021-12-14T11:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131350 + startsAt: '2021-12-14T14:30:00Z' + endsAt: '2021-12-14T17:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + - id: 12131351 + startsAt: '2021-12-17T10:00:00Z' + endsAt: '2021-12-17T11:30:00Z' + place: + buildingId: TO_CIT22 + floorId: XPTE + name: Aula 1P + roomId: '036' + siteId: TO_CIT + type: Lezione / Esercitazione + description: null + courseId: 252258 + courseName: Human Computer Interaction + teacherId: 1847 + virtualClassrooms: [] + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Lectures + /me: + get: + operationId: StudentNs_getStudent + summary: Retrieve student profile | Recupera il profilo studente + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/Student' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Student + /messages: + get: + operationId: Messages_getMessages + summary: List messages | Elenca messaggi + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Message' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Student + /messages/{messageId}: + delete: + operationId: Messages_deleteMessage + summary: Delete a message | Cancella un messaggio + parameters: + - name: messageId + in: path + required: true + schema: + type: integer + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Student + /messages/{messageId}/read: + put: + operationId: Messages_markMessageAsRead + summary: Mark a message as read | Segna un messaggio come letto + parameters: + - name: messageId + in: path + required: true + schema: + type: integer + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Student + /news: + get: + operationId: News_getNews + summary: List news | Lista news + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/NewsItemOverview' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - News + /news/{newsItemId}: + get: + operationId: News_getNewsItem + summary: Show news | Mostra news + parameters: + - name: newsItemId + in: path + required: true + schema: + type: number + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/NewsItem' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - News + /notifications: + get: + operationId: Notifications_getNotifications + summary: List notifications | Elenca notifiche + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Notification' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Student + /notifications/preferences: + get: + operationId: Notifications_getNotificationPreferences + summary: Get notification preferences | Ottieni preferenze notifiche + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/NotificationPreferences' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Student + patch: + operationId: Notifications_updateNotificationPreferences + summary: Update notification preferences | Aggiorna preferenze notifiche + parameters: [] + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Student + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateNotificationPreferencesRequest' + /notifications/{notificationId}: + delete: + operationId: Notifications_deleteNotification + summary: Delete a notification | Cancella una notifica + parameters: + - name: notificationId + in: path + required: true + schema: + type: integer + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Student + /notifications/{notificationId}/read: + put: + operationId: Notifications_markNotificationAsRead + summary: Mark a notification as read | Segna una notifica come letta + parameters: + - name: notificationId + in: path + required: true + schema: + type: integer + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Student + /offering: + get: + operationId: Offering_getOffering + summary: Get offering | Mostra offerta formativa + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/OfferingResponse' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Offering + /offering/courses/{courseShortcode}: + get: + operationId: Offering_getOfferingCourse + summary: Show offering course | Mostra corso dell'offerta formativa + parameters: + - name: courseShortcode + in: path + required: true + schema: + type: string + - name: year + in: query + required: false + schema: + type: string + explode: false + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/OfferingCourse' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Offering + /offering/courses/{courseShortcode}/statistics: + get: + operationId: Offering_getCourseStatistics + summary: Retrieve course statistics | Recupera le statistiche dell'insegnamento + parameters: + - name: courseShortcode + in: path + required: true + schema: + type: string + - name: year + in: query + required: false + schema: + type: string + explode: false + - name: teacherId + in: query + required: false + schema: + type: string + explode: false + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/CourseStatistics' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Offering + /offering/degrees/{degreeId}: + get: + operationId: Offering_getOfferingDegree + summary: Show a degree | Mostra un corso di laurea + parameters: + - name: degreeId + in: path + required: true + schema: + type: string + - name: year + in: query + required: false + schema: + type: string + explode: false + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/Degree' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Offering + /people: + get: + operationId: People_getPeople + summary: Search people | Cerca persone + parameters: + - name: search + in: query + required: true + description: Filter people containing 'search' in their full name + schema: + type: string + explode: false + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/PersonOverview' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - People + /people/{personId}: + get: + operationId: People_getPerson + summary: Show person | Mostra persona + parameters: + - name: personId + in: path + required: true + schema: + type: number + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/Person' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - People + /preferences: + patch: + operationId: StudentNs_updateDevicePreferences + summary: Update device preferences | Aggiorna preferenze del dispositivo + parameters: [] + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Student + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdatePreferencesRequest' + /provisional-grades: + get: + operationId: ProvisionalGrades_getStudentProvisionalGrades + summary: Retrieve student provisional grades | Recupera le valutazioni provvisorie dello studente + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/ProvisionalGrade' + states: + type: array + items: + $ref: '#/components/schemas/ProvisionalGradeState' + required: + - data + - states + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Student + /provisional-grades/{provisionalGradeId}/accept: + post: + operationId: ProvisionalGrades_acceptProvisionalGrade + summary: Accept provisional grade | Accetta valutazione provvisoria + parameters: + - name: provisionalGradeId + in: path + required: true + schema: + type: integer + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Student + /provisional-grades/{provisionalGradeId}/reject: + post: + operationId: ProvisionalGrades_rejectProvisionalGrade + summary: Reject provisional grade | Rifiuta valutazione provvisoria + parameters: + - name: provisionalGradeId + in: path + required: true + schema: + type: integer + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Student + /surveys: + get: + operationId: Surveys_getSurveys + summary: Get surveys | Mostra survey + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Survey' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Surveys + /ticket-faqs: + get: + operationId: TicketFAQs_searchTicketFAQs + summary: Search ticket FAQs | Ricerca FAQ ticket + parameters: + - name: accept-language + in: header + required: false + schema: + type: string + enum: + - it + - en + default: it + - name: search + in: query + required: true + description: Find FAQs containing 'search' in the question + schema: + type: string + explode: false + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/TicketFAQ' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Tickets + /ticket-topics: + get: + operationId: TicketTopics_getTicketTopics + summary: List ticket topics | Elenca ambiti ticket + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/TicketTopic' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Tickets + /tickets: + get: + operationId: Tickets_getTickets + summary: List tickets | Elenca ticket + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/TicketOverview' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Tickets + post: + operationId: Tickets_createTicket + summary: Create ticket | Crea ticket + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/TicketOverview' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Tickets + requestBody: + required: true + content: + multipart/form-data: + schema: + $ref: '#/components/schemas/CreateTicketRequest' + /tickets/{ticketId}: + get: + operationId: Tickets_getTicket + summary: Show a ticket | Mostra un ticket + parameters: + - name: ticketId + in: path + required: true + schema: + type: integer + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/Ticket' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Tickets + /tickets/{ticketId}/attachments/{attachmentId}: + get: + operationId: Tickets_getTicketAttachment + summary: Download ticket attachment | Scarica allegato del ticket + parameters: + - name: ticketId + in: path + required: true + schema: + type: integer + - name: attachmentId + in: path + required: true + schema: + type: integer + responses: + '200': + description: The request has succeeded. + content: + application/octet-stream: + schema: + type: string + format: binary + '302': + description: Redirection + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: The server cannot find the requested resource. + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Tickets + /tickets/{ticketId}/close: + put: + operationId: Tickets_markTicketAsClosed + summary: Mark a ticket as closed | Segna un ticket come chiuso + parameters: + - name: ticketId + in: path + required: true + schema: + type: integer + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Tickets + /tickets/{ticketId}/read: + put: + operationId: Tickets_markTicketAsRead + summary: Mark a ticket as read | Segna un ticket come letto + parameters: + - name: ticketId + in: path + required: true + schema: + type: integer + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Tickets + /tickets/{ticketId}/replies: + post: + operationId: Tickets_replyToTicket + summary: Reply to a ticket | Rispondi ad un ticket + parameters: + - name: ticketId + in: path + required: true + schema: + type: integer + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Tickets + requestBody: + required: true + content: + multipart/form-data: + schema: + $ref: '#/components/schemas/ReplyTicketRequest' + /tickets/{ticketId}/replies/{replyId}/attachments/{attachmentId}: + get: + operationId: Tickets_getTicketReplyAttachment + summary: Download ticket reply attachment | Scarica allegato di una risposta al ticket + parameters: + - name: ticketId + in: path + required: true + schema: + type: integer + - name: replyId + in: path + required: true + schema: + type: integer + - name: attachmentId + in: path + required: true + schema: + type: integer + responses: + '200': + description: The request has succeeded. + content: + application/octet-stream: + schema: + type: string + format: binary + '302': + description: Redirection + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: The server cannot find the requested resource. + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Tickets + /unreadEmails: + get: + operationId: StudentNs_getUnreadEmailsNumber + summary: Retrieve student's unread emails number | Recupera il numero di email non lette dello studente + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/EmailBadge' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Student + /v2/courses: + get: + operationId: CoursesV2_getCourses + summary: List courses | Elenca corsi + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/CourseOverview' + required: + - data + example: + data: + - id: null + name: System and device programming + shortcode: 01NYHOV + cfu: 10 + teachingPeriod: 2-2 + teacherId: 2893 + teacherName: Stefano Quer + previousEditions: [] + isOverBooking: false + isInPersonalStudyPlan: true + year: '2025' + modules: + - id: 251008 + name: Programming Module A + teachingPeriod: 2-2 + teacherId: 3001 + teacherName: Mario Rossi + previousEditions: + - id: 251005 + year: '2024' + isOverBooking: false + isInPersonalStudyPlan: true + year: '2025' + - id: 251009 + name: Programming Module B + teachingPeriod: 2-2 + teacherId: 3002 + teacherName: Giovanni Verdi + previousEditions: + - id: 251006 + year: '2024' + isOverBooking: false + isInPersonalStudyPlan: true + year: '2025' + - id: 252121 + name: Web Applications II + shortcode: 01TXSOV + cfu: 6 + teachingPeriod: 2-2 + teacherId: 2235 + teacherName: Giovanni Malnati + previousEditions: [] + isOverBooking: false + isInPersonalStudyPlan: true + year: '2025' + modules: null + - id: 252126 + name: Security verification and testing + shortcode: 01TYAOV + cfu: 6 + teachingPeriod: 1-1 + teacherId: 1943 + teacherName: Riccardo Sisto + previousEditions: [] + isOverBooking: false + isInPersonalStudyPlan: true + year: '2025' + modules: null + - id: 252138 + name: Information systems security + shortcode: 01TYMOV + cfu: 6 + teachingPeriod: 1-1 + teacherId: 1847 + teacherName: Antonio Lioy + previousEditions: [] + isOverBooking: false + isInPersonalStudyPlan: true + year: '2025' + modules: null + - id: 252258 + name: Cybersecurity + shortcode: 01UDROV + cfu: 6 + teachingPeriod: 2-2 + teacherId: 1847 + teacherName: Antonio Lioy + previousEditions: [] + isOverBooking: false + isInPersonalStudyPlan: true + year: '2025' + modules: null + - id: 252788 + name: Architetture dei sistemi di elaborazione + shortcode: 02GOLOV + cfu: 10 + teachingPeriod: 1-1 + teacherId: 12684 + teacherName: Edgar Ernesto Sanchez Sanchez + previousEditions: [] + isOverBooking: false + isInPersonalStudyPlan: true + year: '2025' + modules: null + - id: 252842 + name: Human Computer Interaction + shortcode: 02JSKOV + cfu: 6 + teachingPeriod: 1-1 + teacherId: 25734 + teacherName: Luigi De Russis + previousEditions: [] + isOverBooking: false + isInPersonalStudyPlan: true + year: '2025' + modules: null + - id: 253378 + name: Cryptography + shortcode: 03LPYOV + cfu: 6 + teachingPeriod: 2-2 + teacherId: 13461 + teacherName: Antonio Jose Di Scala + previousEditions: [] + isOverBooking: false + isInPersonalStudyPlan: true + year: '2025' + modules: null + - id: null + name: Tesi + shortcode: 29EBHOV + cfu: 30 + teachingPeriod: 1-1 + teacherId: null + teacherName: null + previousEditions: [] + isOverBooking: false + isInPersonalStudyPlan: true + year: '2025' + modules: null + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Courses + /v2/place-categories: + get: + operationId: PlaceCategories_getPlaceCategories + summary: List place categories | Elenca categorie luoghi + parameters: + - name: siteId + in: query + required: false + schema: + type: string + explode: false + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/RootPlaceCategory' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Places + /v2/places: + get: + operationId: Places_getPlaces + summary: Search places | Cerca luoghi + parameters: + - name: search + in: query + required: false + description: Filter places containing 'search' in their name + schema: + type: string + explode: false + - name: placeCategoryId + in: query + required: false + schema: + type: string + explode: false + - name: placeSubCategoryId[] + in: query + required: false + schema: + type: array + items: + type: string + - name: siteId + in: query + required: false + schema: + type: string + explode: false + - name: buildingId + in: query + required: false + schema: + type: string + explode: false + - name: floorId + in: query + required: false + schema: + type: string + explode: false + - name: departmentId + in: query + required: false + schema: + type: string + explode: false + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/PlaceOverview' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Places + /v2/places/{placeId}: + get: + operationId: Places_getPlace + summary: Show place | Mostra luogo + parameters: + - name: placeId + in: path + required: true + schema: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + $ref: '#/components/schemas/Place' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Places + /v2/sites: + get: + operationId: Sites_getSites + summary: List sites | Elenca sedi + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Site' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Places + /v2/sites/{siteId}/buildings: + get: + operationId: Sites_getBuildings + summary: List buildings | Elenca edifici + parameters: + - name: siteId + in: path + required: true + schema: + type: string + - name: search + in: query + required: false + description: Filter buildings containing 'search' in their name + schema: + type: string + explode: false + - name: placeCategoryId + in: query + required: false + schema: + type: string + explode: false + - name: placeSubCategoryId[] + in: query + required: false + schema: + type: array + items: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Building' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Places + /v2/sites/{siteId}/free-rooms: + get: + operationId: Sites_getFreeRooms + summary: List free rooms | Elenca aule libere + parameters: + - name: date + in: query + required: true + description: Date + schema: + type: string + explode: false + - name: timeFrom + in: query + required: true + description: Start time + schema: + type: string + explode: false + - name: timeTo + in: query + required: true + description: End time + schema: + type: string + explode: false + - name: siteId + in: path + required: true + schema: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/FreeRoom' + required: + - data + '400': + description: The server could not understand the request due to invalid syntax. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + tags: + - Places +components: + schemas: + AppInfoRequest: + type: object + properties: + buildNumber: + type: string + example: '1060200' + appVersion: + type: string + example: 1.6.2 + fcmRegistrationToken: + type: string + example: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4 + BookExamRequest: + type: object + required: + - courseShortcode + properties: + courseShortcode: + type: string + example: 01UDROV + questionId: + type: integer + questionOption: + type: integer + requestReason: + type: string + Booking: + type: object + required: + - id + - description + - topic + - subtopic + - startsAt + - endsAt + - seat + - cancelableUntil + - location + properties: + id: + type: integer + example: 258674 + description: + type: string + example: '' + topic: + $ref: '#/components/schemas/BookingTopicOverview' + subtopic: + type: object + allOf: + - $ref: '#/components/schemas/BookingTopicOverview' + nullable: true + startsAt: + type: string + format: date-time + example: '2021-10-05T10:00:00Z' + endsAt: + type: string + format: date-time + example: '2021-10-05T10:15:00Z' + seat: + type: object + properties: + id: + type: integer + row: + type: string + column: + type: string + nullable: true + cancelableUntil: + type: string + format: date-time + example: '2021-10-05T09:00:00Z' + location: + $ref: '#/components/schemas/BookingPlaceRef' + locationCheck: + $ref: '#/components/schemas/BookingLocationCheck' + BookingLocationCheck: + type: object + required: + - enabled + - checked + - latitude + - longitude + - radiusInKm + properties: + enabled: + type: boolean + checked: + type: boolean + latitude: + type: string + nullable: true + longitude: + type: string + nullable: true + radiusInKm: + type: number + nullable: true + BookingPhysicalPlaceRef: + type: object + required: + - description + properties: + description: + type: string + allOf: + - $ref: '#/components/schemas/PlaceRef' + BookingPlaceRef: + type: object + oneOf: + - $ref: '#/components/schemas/BookingPhysicalPlaceRef' + - $ref: '#/components/schemas/BookingVirtualPlaceRef' + discriminator: + propertyName: type + mapping: + place: '#/components/schemas/BookingPhysicalPlaceRef' + virtualPlace: '#/components/schemas/BookingVirtualPlaceRef' + BookingSeatCell: + type: object + required: + - id + - status + - label + properties: + id: + type: integer + example: 20018 + status: + type: string + enum: + - available + - booked + - unavailable + example: available + label: + type: string + example: A5 + BookingSeats: + type: object + required: + - totalCount + - availableCount + - rows + properties: + totalCount: + type: integer + availableCount: + type: integer + rows: + type: array + items: + $ref: '#/components/schemas/BookingSeatsRow' + BookingSeatsRow: + type: object + required: + - label + - seats + properties: + id: + type: integer + label: + type: string + seats: + type: array + items: + $ref: '#/components/schemas/BookingSeatCell' + BookingSlot: + type: object + required: + - id + - description + - isBooked + - canBeBooked + - hasSeats + - hasSeatSelection + - places + - bookedPlaces + - feedback + - location + - startsAt + - endsAt + - bookingStartsAt + - bookingEndsAt + properties: + id: + type: integer + example: 103051 + description: + type: string + example: '' + isBooked: + type: boolean + example: false + canBeBooked: + type: boolean + example: false + hasSeats: + type: boolean + example: false + hasSeatSelection: + type: boolean + example: false + places: + type: integer + example: 2 + bookedPlaces: + type: integer + example: 2 + feedback: + type: string + example: Il turno è pieno + location: + type: object + properties: + name: + type: string + description: + type: string + type: + type: string + address: + type: string + startsAt: + type: string + format: date-time + example: '2021-10-05T10:00:00Z' + endsAt: + type: string + format: date-time + example: '2021-10-05T10:15:00Z' + bookingStartsAt: + type: string + format: date-time + example: '2021-10-01T00:00:00Z' + bookingEndsAt: + type: string + format: date-time + example: '2021-10-05T09:00:00Z' + example: + id: 103051 + description: '' + isBooked: false + canBeBooked: false + hasSeats: false + hasSeatSelection: false + places: 2 + bookedPlaces: 2 + feedback: Il turno è pieno + location: + name: Virtual Classroom della Segreteria Generale Studenti + description: '' + type: VC + address: https://didattica.polito.it/pls/portal30/sviluppo.bbb_corsi.queueRoom?id=SEGRETERIA_GENERALE&p_tipo=SEGRETERIA_GENERALE + startsAt: '2021-10-05T10:00:00Z' + endsAt: '2021-10-05T10:15:00Z' + bookingStartsAt: '2021-10-01T00:00:00Z' + bookingEndsAt: '2021-10-05T09:00:00Z' + BookingSubtopic: + type: object + required: + - requirements + properties: + requirements: + type: array + items: + type: object + properties: + name: + type: string + url: + type: string + allOf: + - $ref: '#/components/schemas/BookingTopicLeaf' + BookingTopic: + type: object + required: + - subtopics + properties: + subtopics: + type: array + items: + $ref: '#/components/schemas/BookingSubtopic' + allOf: + - $ref: '#/components/schemas/BookingTopicLeaf' + example: + id: DIDATTICA_ING + title: Segreteria Didattica Ingegneria + description: Servizi della Segreteria Didattica Ingegneria + isEnabled: true + disclaimer: '' + showCalendar: true + slotLength: 15 + slotsPerHour: 4 + startDate: null + startHour: 8 + endHour: 18 + maxBookingsPerDay: 2 + canBeCancelled: true + daysPerWeek: 5 + agendaView: false + subtopics: + - id: DID_ING_VC_EN + title: Aspetti didattici di carriera - Sportello virtuale in inglese + description: '' + isEnabled: true + disclaimer: '' + showCalendar: true + slotLength: 15 + slotsPerHour: 4 + startDate: null + startHour: 8 + endHour: 18 + maxBookingsPerDay: 2 + canBeCancelled: true + daysPerWeek: 5 + agendaView: false + requirements: [] + BookingTopicLeaf: + type: object + required: + - isEnabled + - disclaimer + - showCalendar + - slotLength + - slotsPerHour + - startDate + - startHour + - endHour + - maxBookingsPerDay + - canBeCancelled + - daysPerWeek + - agendaView + properties: + isEnabled: + type: boolean + example: true + disclaimer: + type: string + example: '' + showCalendar: + type: boolean + example: true + slotLength: + type: integer + example: 15 + slotsPerHour: + type: integer + example: 4 + startDate: + type: string + format: date + nullable: true + description: Start date of the booking period + startHour: + type: integer + example: 8 + endHour: + type: integer + example: 18 + maxBookingsPerDay: + type: integer + example: 2 + canBeCancelled: + type: boolean + example: true + daysPerWeek: + type: integer + description: Number of days per week the booking is available, starting from startDate weekday, or monday if missing + example: 5 + agendaView: + type: boolean + description: Specifies if the topic requires the agenda display + example: false + allOf: + - $ref: '#/components/schemas/BookingTopicOverview' + BookingTopicOverview: + type: object + required: + - id + - title + - description + properties: + id: + type: string + example: DIDATTICA_ING + title: + type: string + example: Segreteria Didattica Ingegneria + description: + type: string + example: Servizi della Segreteria Didattica Ingegneria + BookingVirtualPlaceRef: + type: object + required: + - name + - url + properties: + name: + type: string + url: + type: string + Building: + type: object + required: + - id + - name + - siteId + - category + - latitude + - longitude + properties: + id: + type: string + name: + type: string + siteId: + type: string + category: + $ref: '#/components/schemas/PlaceCategoryOverview' + geoJson: + $ref: '#/components/schemas/GeoJsonPolygon' + latitude: + type: number + example: 45.064254 + longitude: + type: number + example: 7.657823 + BuildingOverview: + type: object + required: + - id + - name + - siteId + - category + properties: + id: + type: string + name: + type: string + siteId: + type: string + category: + $ref: '#/components/schemas/PlaceCategoryOverview' + geoJson: + $ref: '#/components/schemas/GeoJsonPolygon' + Client: + type: object + required: + - buildNumber + - appVersion + - name + properties: + buildNumber: + type: string + example: '1060200' + appVersion: + type: string + example: 1.6.2 + fcmRegistrationToken: + type: string + example: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4 + name: + type: string + example: Students app + id: + type: string + example: 5a54f626-4b7e-488e-a0e3-300f54051510 + ClientVersionRequest: + type: object + required: + - buildNumber + - appVersion + properties: + buildNumber: + type: string + example: '1060200' + appVersion: + type: string + example: 1.6.2 + Course: + type: object + required: + - id + - name + - shortcode + - cfu + - teachingPeriod + - teacherId + - isOverBooking + - isInPersonalStudyPlan + - year + - links + - moodleCourses + - vcPreviousYears + - vcOtherCourses + - notifications + - staff + properties: + id: + type: integer + nullable: true + description: The identifier for the current instance of this course. If null this is not a teaching (such as thesis), it won't have a course page + example: 258674 + name: + type: string + example: System and device programming + shortcode: + type: string + example: 01NYHOV + cfu: + type: integer + example: 10 + teachingPeriod: + type: string + description: The semester(s) this course belongs to + example: 2-2 + teacherId: + type: integer + nullable: true + example: 2893 + isOverBooking: + type: boolean + example: false + isInPersonalStudyPlan: + type: boolean + description: Included in the PSP | Incluso nel carico didattico + example: true + year: + type: string + example: '2022' + links: + type: array + items: + type: object + properties: + url: + type: string + example: https://docs.google.com/document/d/13hpWEDQxziSkhSU0PuqxMXntqZYp3ffDKZ2-umQ7Ywo/edit?usp=sharing + description: + type: string + example: Calendario settimanale dei contenuti del corso + required: + - url + moodleCourses: + type: array + items: + type: object + properties: + name: + type: string + example: Analisi Matematica I + id: + type: string + example: '645376' + nullable: true + vcPreviousYears: + type: array + items: + $ref: '#/components/schemas/CourseModuleEdition' + example: + - id: 244577 + year: '2021' + vcOtherCourses: + type: array + items: + type: object + properties: + year: + type: string + example: '2021' + id: + type: integer + example: 244577 + name: + type: string + example: Fisica II + required: + - year + - id + - name + description: Other editions/courses to be included in virtual classrooms + notifications: + type: object + properties: + notices: + type: boolean + example: true + files: + type: boolean + example: true + lectures: + type: boolean + example: true + required: + - notices + - files + - lectures + staff: + type: array + items: + type: object + properties: + role: + type: string + id: + type: number + example: 244577 + required: + - role + - id + CourseAssignment: + type: object + required: + - id + - description + - mimeType + - filename + - uploadedAt + - deletedAt + - url + - sizeInKiloBytes + properties: + id: + type: integer + example: 947503 + description: + type: string + example: laboratorio 3 + mimeType: + type: string + example: application/x-zip-compressed + filename: + type: string + example: lab_03.zip + uploadedAt: + type: string + format: date-time + example: '2022-09-02T14:00:00Z' + deletedAt: + type: string + format: date-time + nullable: true + url: + type: string + example: https://file.didattica.polito.it/down/ELABORATI_PRE/1003948/S290683/6791f0016c78599138828211522fa84d/62cebc94 + sizeInKiloBytes: + type: integer + example: 305 + CourseAssignmentUpload: + type: object + properties: + description: + type: string + file: + type: string + format: binary + required: + - description + - file + CourseDirectory: + type: object + required: + - id + - name + - files + - type + properties: + id: + type: string + name: + type: string + files: + $ref: '#/components/schemas/CourseDirectoryContent' + type: + type: string + enum: + - directory + example: + name: Root + id: '1234' + type: directory + files: + - type: directory + id: '1' + name: Week 1 + files: [] + CourseDirectoryContent: + type: array + items: + $ref: '#/components/schemas/CourseDirectoryEntry' + CourseDirectoryEntry: + type: object + oneOf: + - $ref: '#/components/schemas/CourseDirectory' + - $ref: '#/components/schemas/CourseFileOverview' + discriminator: + propertyName: type + mapping: + directory: '#/components/schemas/CourseDirectory' + file: '#/components/schemas/CourseFileOverview' + CourseFileOverview: + type: object + required: + - id + - name + - sizeInKiloBytes + - mimeType + - createdAt + - type + - checksum + properties: + id: + type: string + example: '33352562' + name: + type: string + example: Laboratori + sizeInKiloBytes: + type: integer + example: 305 + mimeType: + type: string + example: application/x-zip-compressed + createdAt: + type: string + format: date-time + example: '2022-08-31T14:00:00Z' + type: + type: string + enum: + - file + checksum: + type: string + example: deadbeefcafebabe0000000000000000 + example: + type: file + id: '2' + name: Lecture1.pdf + sizeInKiloBytes: 2048 + mimeType: application/pdf + createdAt: '2024-06-01T10:00:00Z' + checksum: deadbeefcafebabe0000000000000000 + CourseHours: + type: object + properties: + lecture: + type: integer + tutoring: + type: integer + classroomExercise: + type: integer + labExercise: + type: integer + CourseModule: + type: object + required: + - id + - name + - teachingPeriod + - teacherId + - teacherName + - previousEditions + - isOverBooking + - isInPersonalStudyPlan + - year + properties: + id: + type: integer + nullable: true + description: |- + The identifier for the current instance of this course. + If null this is not a teaching (such as thesis), it won't have a course page + example: 258674 + name: + type: string + example: System and device programming + teachingPeriod: + type: string + description: The semester(s) this course belongs to + example: 2-2 + teacherId: + type: integer + nullable: true + example: 2893 + teacherName: + type: string + nullable: true + example: Mario Rossi + previousEditions: + type: array + items: + $ref: '#/components/schemas/CourseModuleEdition' + description: Previous editions of this course that were part of the student's PSP + example: + - id: 244577 + year: '2021' + isOverBooking: + type: boolean + example: false + isInPersonalStudyPlan: + type: boolean + description: Included in the PSP | Incluso nel carico didattico + example: true + year: + type: string + example: '2022' + example: + id: 251008 + name: Programming Module A + teachingPeriod: 2-2 + teacherId: 3001 + teacherName: Mario Rossi + previousEditions: + - id: 251005 + year: '2024' + isOverBooking: false + isInPersonalStudyPlan: true + year: '2025' + CourseModuleEdition: + type: object + required: + - year + - id + properties: + year: + type: string + example: '2021' + id: + type: integer + example: 244577 + CourseNotices: + type: object + required: + - id + - publishedAt + - expiresAt + - content + properties: + id: + type: integer + example: 360724 + publishedAt: + type: string + format: date-time + example: '2022-07-03T14:00:00Z' + expiresAt: + type: string + format: date-time + nullable: true + content: + type: string + example:

Conferma spostamento orario esame:

Ore 15

+ CourseOverview: + type: object + required: + - cfu + - shortcode + - modules + properties: + cfu: + type: integer + example: 10 + shortcode: + type: string + example: 01NYHOV + modules: + type: array + items: + $ref: '#/components/schemas/CourseModule' + nullable: true + allOf: + - $ref: '#/components/schemas/CourseModule' + CoursePreferencesRequest: + type: object + properties: + notifications: + type: object + properties: + notices: + type: boolean + example: true + files: + type: boolean + example: true + lectures: + type: boolean + example: true + CourseStatistics: + type: object + required: + - shortcode + - year + - teacher + - totalEnrolled + - totalSucceeded + - totalFailed + - firstYear + - otherYears + - previousYearsToCompare + - years + - teachers + properties: + shortcode: + type: string + year: + type: integer + teacher: + $ref: '#/components/schemas/Teacher' + totalEnrolled: + type: integer + totalSucceeded: + type: integer + totalFailed: + type: integer + firstYear: + $ref: '#/components/schemas/YearStatistics' + otherYears: + $ref: '#/components/schemas/YearStatistics' + previousYearsToCompare: + type: array + items: + $ref: '#/components/schemas/PreviousYearsToCompare' + years: + type: array + items: + type: integer + teachers: + type: array + items: + $ref: '#/components/schemas/Teacher' + CreateBookingRequest: + type: object + required: + - slotId + properties: + slotId: + type: integer + example: 103051 + seatId: + type: integer + example: 20018 + CreateTicketRequest: + type: object + properties: + subject: + type: string + message: + type: string + subtopicId: + type: number + attachment: + type: string + format: binary + required: + - subject + - message + - subtopicId + Deadline: + type: object + required: + - name + - type + - url + - date + properties: + id: + type: number + name: + type: string + example: Termine per l'iscrizione e pagamento della prima rata + type: + type: string + example: Iscrizioni e pagamento tasse + url: + type: string + nullable: true + date: + type: string + format: date + example: '2022-10-11' + Degree: + type: object + required: + - id + - name + - level + - department + - faculty + - location + - duration + - class + - year + - editions + - notes + - objectives + - jobOpportunities + - tracks + properties: + id: + type: string + example: 81-6 + name: + type: string + example: Design e comunicazione + level: + type: string + department: + type: object + properties: + name: + type: string + required: + - name + faculty: + type: object + properties: + id: + type: string + name: + type: string + location: + type: string + duration: + type: string + class: + type: object + properties: + code: + type: string + name: + type: string + required: + - code + - name + year: + type: number + editions: + type: array + items: + type: string + description: All the available editions of this degree + notes: + type: array + items: + type: string + example: + - Corso tenuto in italiano + objectives: + type: object + properties: + title: + type: string + example: Obiettivi formativi + content: + type: string + required: + - title + - content + jobOpportunities: + type: object + properties: + title: + type: string + content: + type: string + required: + - title + - content + tracks: + type: array + items: + $ref: '#/components/schemas/Track' + DegreeOverview: + type: object + required: + - id + - name + properties: + id: + type: string + example: 81-6 + name: + type: string + example: Design e comunicazione + example: + id: 81-6 + name: Design e comunicazione + Department: + type: object + required: + - id + - name + - type + properties: + id: + type: string + name: + type: string + nullable: true + type: + type: string + Device: + type: object + required: + - platform + properties: + name: + type: string + platform: + type: string + version: + type: string + model: + type: string + manufacturer: + type: string + EmailBadge: + type: object + required: + - unreadEmails + properties: + unreadEmails: + type: string + example: 99+ + EmergencyContent: + type: object + required: + - content + - cta + properties: + title: + type: string + example: Emergency Title + content: + type: string + example: Important information regarding the emergency. + cta: + $ref: '#/components/schemas/EmergencyCta' + EmergencyCta: + type: object + required: + - text + - action + - color + - primary + properties: + text: + type: string + example: Emergenza 112 + action: + $ref: '#/components/schemas/EmergencySite' + icon: + type: string + example: fa-phone + color: + type: string + example: '#E11D48' + primary: + type: boolean + example: true + EmergencyHour: + type: object + required: + - day + - open + - close + properties: + day: + type: string + example: Monday + open: + type: string + example: '09:00' + close: + type: string + example: '18:00' + EmergencyResponse: + type: object + required: + - icon + - name + - content + - cta + properties: + icon: + type: string + example: fa-warning + name: + type: string + example: Emergency Name + content: + type: array + items: + $ref: '#/components/schemas/EmergencyContent' + cta: + type: array + items: + $ref: '#/components/schemas/EmergencyCta' + EmergencySite: + type: object + required: + - places + - phoneNumber + - hours + - backup + properties: + places: + type: array + items: + $ref: '#/components/schemas/PlaceRef' + phoneNumber: + type: string + example: +39 011 090 1234 + hours: + type: array + items: + $ref: '#/components/schemas/EmergencyHour' + backup: + type: boolean + example: true + EnrolMfaRequest: + type: object + required: + - description + - pubkey + properties: + description: + type: string + example: some identifier you chose + pubkey: + type: string + example: dGhpcyBzaG91bGQgYmUgYW4gZWNkcyBwdWJsaWMga2V5Li4uIHdoYXQgZGlkIHlvdSB0aGluayB0aGlzIHdhcz8hIPCfp5AK + example: + description: some identifier you chose + pubkey: dGhpcyBzaG91bGQgYmUgYW4gZWNkcyBwdWJsaWMga2V5Li4uIHdoYXQgZGlkIHlvdSB0aGluayB0aGlzIHdhcz8hIPCfp5AK + ErrorResponse: + type: object + properties: + code: + type: integer + message: + type: string + EscError: + type: object + properties: + code: + type: integer + example: 500 + message: + type: string + example: An error occurred + careerId: + type: integer + example: 123456 + EuropeanStudentCard: + type: object + required: + - canBeRequested + - details + properties: + canBeRequested: + type: boolean + details: + type: object + properties: + status: + type: string + enum: + - active + - inactive + - expired + inactiveStatusReason: + type: string + nullable: true + cardNumber: + type: string + expiresAt: + type: string + qrCode: + type: string + required: + - status + - inactiveStatusReason + - cardNumber + - expiresAt + - qrCode + nullable: true + Exam: + type: object + required: + - id + - courseId + - courseShortcode + - courseName + - teacherId + - type + - status + - bookingStartsAt + - bookingEndsAt + - examStartsAt + - examEndsAt + - bookedCount + - availableCount + - question + - feedback + - isReschedulable + - notes + - moduleNumber + - requestReason + - requestDetails + properties: + id: + type: integer + courseId: + type: number + courseShortcode: + type: string + courseName: + type: string + teacherId: + type: integer + type: + type: string + places: + type: array + items: + $ref: '#/components/schemas/PlaceRef' + status: + type: string + enum: + - available + - booked + - requestable + - requested + - requestAccepted + - requestRejected + - unavailable + bookingStartsAt: + type: string + format: date-time + nullable: true + bookingEndsAt: + type: string + format: date-time + examStartsAt: + type: string + format: date-time + nullable: true + examEndsAt: + type: string + format: date-time + nullable: true + bookedCount: + type: integer + availableCount: + type: integer + question: + type: object + properties: + id: + type: integer + statement: + type: string + options: + type: array + items: + type: string + required: + - id + - statement + - options + nullable: true + feedback: + type: string + nullable: true + isReschedulable: + type: boolean + description: If true, the student can ask the professor to reschedule the exam + notes: + type: string + nullable: true + moduleNumber: + type: integer + description: The module number, if this is a module + requestReason: + type: string + nullable: true + requestDetails: + type: string + nullable: true + ExamGrade: + type: object + required: + - courseName + - credits + - grade + - date + - teacherId + - onTimeExamPoints + - shortcode + - academicYear + - creditsCountTowardsDegree + properties: + courseName: + type: string + example: System and device programming + credits: + type: number + example: 10 + grade: + type: string + example: 30L + date: + type: string + format: date + example: '2022-07-15' + teacherId: + type: integer + nullable: true + example: 2893 + onTimeExamPoints: + type: number + nullable: true + description: Points for "on-time" exams - null the student is not eligible for on-time exams or the exam does not grant on-time points + example: 2 + shortcode: + type: string + example: 01NYHOV + academicYear: + type: integer + example: 2021 + creditsCountTowardsDegree: + type: boolean + description: Defines whether the credits from the exam count toward the total required for graduation + example: true + FcmRegistrationRequest: + type: object + properties: + fcmRegistrationToken: + type: string + example: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4 + Floor: + type: object + required: + - id + - name + - level + properties: + id: + type: string + name: + type: string + level: + type: number + FreeRoom: + type: object + required: + - buildingId + - floorId + - roomId + - siteId + - name + - freeFrom + - freeTo + properties: + buildingId: + type: string + floorId: + type: string + roomId: + type: string + siteId: + type: string + name: + type: string + id: + type: string + freeFrom: + type: string + format: date-time + freeTo: + type: string + format: date-time + GeoJsonPolygon: + type: object + required: + - type + - geometry + properties: + type: + type: string + enum: + - Feature + geometry: + type: object + properties: + type: + type: string + enum: + - Polygon + coordinates: + type: array + items: + type: array + items: + type: array + items: + type: number + required: + - type + - coordinates + GeoLocation: + type: object + required: + - latitude + - longitude + properties: + latitude: + type: number + example: 45.064254 + longitude: + type: number + example: 7.657823 + example: + latitude: 45.064254 + longitude: 7.657823 + GradeCount: + type: object + required: + - grade + - count + properties: + grade: + type: string + enum: + - '18' + - '19' + - '20' + - '21' + - '22' + - '23' + - '24' + - '25' + - '26' + - '27' + - '28' + - '29' + - '30' + - 30L + count: + type: integer + Guide: + type: object + required: + - id + - listTitle + - title + - intro + - fields + - sections + properties: + id: + type: string + listTitle: + type: string + title: + type: string + intro: + type: string + fields: + type: array + items: + $ref: '#/components/schemas/GuideField' + sections: + type: array + items: + $ref: '#/components/schemas/GuideSection' + GuideField: + type: object + required: + - label + - value + properties: + label: + type: string + value: + type: string + isCopyEnabled: + type: boolean + GuideSection: + type: object + required: + - title + - content + properties: + title: + type: string + example: Title + content: + type: string + example: HTML content + Identity: + type: object + required: + - username + - type + - clientId + - token + properties: + username: + type: string + example: s290683 + type: + type: string + example: student + clientId: + type: string + example: 5a54f626-4b7e-488e-a0e3-300f54051510 + token: + type: string + example: c679fa38ff665df6a676acd833194385 + example: + username: s290683 + type: student + clientId: 5a54f626-4b7e-488e-a0e3-300f54051510 + token: c679fa38ff665df6a676acd833194385 + JobOffer: + type: object + required: + - companyLocation + - companyMission + - description + - requirements + - contractType + - salary + - contactInformation + - url + - email + - freePositions + properties: + companyLocation: + type: string + companyMission: + type: string + description: + type: string + requirements: + type: string + contractType: + type: string + salary: + type: string + contactInformation: + type: string + nullable: true + url: + type: string + nullable: true + email: + type: string + nullable: true + freePositions: + type: number + example: 2 + allOf: + - $ref: '#/components/schemas/JobOfferOverview' + JobOfferOverview: + type: object + required: + - id + - title + - location + - companyId + - companyName + - createdAtDate + - endsAtDate + properties: + id: + type: number + title: + type: string + location: + type: string + companyId: + type: number + companyName: + type: string + createdAtDate: + type: string + format: date + endsAtDate: + type: string + format: date + Lecture: + type: object + required: + - id + - startsAt + - endsAt + - type + - virtualClassrooms + - description + - courseId + - courseName + - teacherId + - place + properties: + id: + type: number + startsAt: + type: string + format: date-time + endsAt: + type: string + format: date-time + type: + type: string + virtualClassrooms: + type: array + items: + $ref: '#/components/schemas/RelatedVirtualClassroom' + description: + type: string + nullable: true + courseId: + type: integer + courseName: + type: string + teacherId: + type: integer + example: 150157 + place: + $ref: '#/components/schemas/PlaceRef' + LinkToService: + type: object + required: + - url + properties: + url: + type: string + LoginCredentialsBasic: + type: object + required: + - username + - password + - loginType + properties: + username: + type: string + example: s290683 + password: + type: string + example: moreSecret + loginType: + type: string + enum: + - basic + allOf: + - $ref: '#/components/schemas/LoginRequestBase' + LoginCredentialsSSO: + type: object + required: + - uid + - key + - loginType + properties: + uid: + type: string + example: 123456-1234-5678-123456 + key: + type: string + example: abcdef-abcd-efgh-abcdef + loginType: + type: string + enum: + - sso + allOf: + - $ref: '#/components/schemas/LoginRequestBase' + LoginRequest: + type: object + oneOf: + - $ref: '#/components/schemas/LoginCredentialsBasic' + - $ref: '#/components/schemas/LoginCredentialsSSO' + discriminator: + propertyName: loginType + mapping: + basic: '#/components/schemas/LoginCredentialsBasic' + sso: '#/components/schemas/LoginCredentialsSSO' + LoginRequestBase: + type: object + required: + - preferences + properties: + client: + $ref: '#/components/schemas/Client' + device: + $ref: '#/components/schemas/Device' + preferences: + $ref: '#/components/schemas/UpdatePreferencesRequest' + Message: + type: object + required: + - id + - title + - message + - type + - senderId + - sentAt + - isRead + properties: + id: + type: number + example: 123 + title: + type: string + example: Nuovo avviso da System and device programming + message: + type: string + nullable: true + example: Ricordati di... + type: + allOf: + - $ref: '#/components/schemas/MessageType' + example: teacher + senderId: + type: number + nullable: true + example: 2893 + sentAt: + type: string + format: date-time + example: '2022-08-31T14:00:00Z' + isRead: + type: boolean + example: false + MessageType: + type: string + enum: + - emergency + - event + - personal + - teacher + - secretariat + - exams + - mfa + example: secretariat + MfaChallenge: + type: object + required: + - serial + - challenge + - requestTs + - expirationTs + properties: + serial: + type: string + example: EDUP000123456 + challenge: + type: string + example: dGhpcyBzaG91bGQgYmUgYW4gZWNkcyBwdWJsaWMga2V5Li4uIHdoYXQgZGlkIHlvdSB0aGluayB0aGlzIHdhcz8hIPCfp5AK + requestTs: + type: string + format: date-time + example: '2025-01-01T00:00:00Z' + expirationTs: + type: string + format: date-time + example: '2025-01-01T01:00:00Z' + MfaStatusResponse: + type: object + required: + - status + - details + properties: + status: + type: string + enum: + - active + - locked + - available + - unavailable + - needsReauth + description: Current MFA status for the user + details: + type: object + properties: + lastAuth: + type: string + format: date-time + example: '2021-09-30T00:00:00Z' + authCount: + type: integer + example: 1 + serial: + type: string + example: EDUP0000123456 + description: + type: string + example: My phone + required: + - lastAuth + - authCount + nullable: true + description: |- + Additional information about the MFA session. + Present only if status is `active` or `locked` + NewsItem: + type: object + required: + - location + - htmlContent + - extras + properties: + location: + type: string + example: Energy Center - Via Paolo Borsellino 38, Torino + htmlContent: + type: string + example: Martedì 18 aprile 2023 - presso l'Auditorium dell'Energy Center del Politecnico... + extras: + type: array + items: + $ref: '#/components/schemas/NewsItemExtra' + allOf: + - $ref: '#/components/schemas/NewsItemOverview' + example: + id: 123 + title: Partecipazione, co-progettazione e impatto sociale. Sfide e opportunità per l'inclusione sociale + isEvent: false + shortDescription: Seminario di presentazione del progetto + eventStartTime: Dal 30 agosto 2023 + eventEndTime: Al 30 agosto 2023 + createdAt: '2022-08-31T14:00:00Z' + location: Energy Center - Via Paolo Borsellino 38, Torino + htmlContent: Martedì 18 aprile 2023 - presso l'Auditorium dell'Energy Center del Politecnico... + extras: + - url: https:// + description: Bando + type: image + sizeInKiloBytes: 305 + NewsItemExtra: + type: object + required: + - url + - description + - type + - sizeInKiloBytes + properties: + url: + type: string + example: https:// + description: + type: string + example: Bando + type: + type: string + enum: + - link + - file + - image + example: image + sizeInKiloBytes: + type: integer + nullable: true + example: 305 + example: + url: https:// + description: Bando + type: image + sizeInKiloBytes: 305 + NewsItemOverview: + type: object + required: + - id + - title + - isEvent + - shortDescription + - eventStartTime + - eventEndTime + - createdAt + properties: + id: + type: number + example: 123 + title: + type: string + example: Partecipazione, co-progettazione e impatto sociale. Sfide e opportunità per l'inclusione sociale + isEvent: + type: boolean + example: false + shortDescription: + type: string + example: Seminario di presentazione del progetto + eventStartTime: + type: string + nullable: true + example: Dal 30 agosto 2023 + eventEndTime: + type: string + nullable: true + example: Al 30 agosto 2023 + createdAt: + type: string + format: date-time + example: '2022-08-31T14:00:00Z' + example: + id: 123 + title: Partecipazione, co-progettazione e impatto sociale. Sfide e opportunità per l'inclusione sociale + isEvent: false + shortDescription: Seminario di presentazione del progetto + eventStartTime: Dal 30 agosto 2023 + eventEndTime: Al 30 agosto 2023 + createdAt: '2022-08-31T14:00:00Z' + Notification: + type: object + required: + - id + - title + - message + - sentAt + - isRead + properties: + id: + type: number + example: 123 + title: + type: string + example: Nuovo avviso da System and device programming + message: + type: string + nullable: true + example: Ricordati di... + scope: + type: array + items: + type: string + description: An array representing the hierarchical path to the object this notification is related to (replicates the navigation/modules structure) + example: + - courses + - '258674' + - notices + sentAt: + type: string + format: date-time + example: '2022-08-31T14:00:00Z' + isRead: + type: boolean + example: false + NotificationPreferences: + type: object + required: + - notices + - files + - lectures + - bookings + - tickets + properties: + notices: + type: boolean + example: true + files: + type: boolean + example: true + lectures: + type: boolean + example: true + bookings: + type: boolean + example: true + tickets: + type: boolean + example: true + OfferingClass: + type: object + required: + - name + - code + - degrees + properties: + name: + type: string + example: Disegno industriale + code: + type: string + example: L-4 + degrees: + type: array + items: + $ref: '#/components/schemas/DegreeOverview' + example: + name: Disegno industriale + code: L-4 + degrees: + - id: 81-6 + name: Design e comunicazione + OfferingCourse: + type: object + required: + - name + - shortcode + - cfu + - teachingPeriod + - languages + - year + - hours + - editions + - staff + - guide + properties: + name: + type: string + shortcode: + type: string + cfu: + type: integer + teachingPeriod: + type: string + description: The semester(s) this course belongs to + languages: + type: array + items: + type: string + enum: + - it + - en + year: + type: string + hours: + $ref: '#/components/schemas/CourseHours' + editions: + type: array + items: + type: string + description: All the available editions of this course + staff: + type: array + items: + $ref: '#/components/schemas/OfferingCourseStaff' + guide: + type: array + items: + $ref: '#/components/schemas/GuideSection' + OfferingCourseOverview: + type: object + required: + - name + - shortcode + - cfu + - teachingYear + - language + - group + properties: + name: + type: string + example: System and device programming + shortcode: + type: string + example: 01NYHOV + cfu: + type: integer + example: 10 + teachingYear: + type: integer + description: The year this course belongs to in this degree + example: 1 + language: + type: string + enum: + - it + - en + example: en + group: + type: string + nullable: true + example: Insegnamento a scelta 1 + example: + name: System and device programming + shortcode: 01NYHOV + cfu: 10 + teachingYear: 1 + language: en + group: Insegnamento a scelta 1 + OfferingCourseStaff: + type: object + required: + - role + - id + - courseId + properties: + role: + type: string + id: + type: number + courseId: + type: number + OfferingResponse: + type: object + properties: + bachelor: + type: array + items: + $ref: '#/components/schemas/OfferingClass' + master: + type: array + items: + $ref: '#/components/schemas/OfferingClass' + Person: + type: object + required: + - email + - phoneNumbers + - facilityShortName + - profileUrl + - courses + properties: + email: + type: string + example: fulvio.corno@polito.it + phoneNumbers: + type: array + items: + $ref: '#/components/schemas/PhoneNumber' + facilityShortName: + type: string + nullable: true + example: DAUIN + profileUrl: + type: string + example: https://www.dauin.polito.it/personale/scheda/(matricola)/002154 + courses: + type: array + items: + $ref: '#/components/schemas/PersonCourse' + nullable: true + allOf: + - $ref: '#/components/schemas/PersonOverview' + example: + id: 2154 + firstName: Fulvio + lastName: Corno + picture: https://www.swas.polito.it/_library/image_pub.asp?matricola=002154 + role: Docente + email: fulvio.corno@polito.it + phoneNumbers: + - full: '0110907053' + internal: '7053' + facilityShortName: DAUIN + profileUrl: https://www.dauin.polito.it/personale/scheda/(matricola)/002154 + courses: + - id: 258674 + shortcode: 01NYHOV + name: Computer sciences + role: Collaboratore + year: 2021 + PersonCourse: + type: object + required: + - id + - name + - role + - year + properties: + id: + type: integer + description: The identifier for this course + example: 258674 + shortcode: + type: string + description: The shortcode for this course + example: 01NYHOV + name: + type: string + description: The name of the course + example: Computer sciences + role: + type: string + description: The role of the person in this course + example: Collaboratore + year: + type: number + description: The year this course was given in + example: 2021 + example: + id: 258674 + shortcode: 01NYHOV + name: Computer sciences + role: Collaboratore + year: 2021 + PersonOverview: + type: object + required: + - id + - firstName + - lastName + - picture + - role + properties: + id: + type: number + example: 2154 + firstName: + type: string + example: Fulvio + lastName: + type: string + example: Corno + picture: + type: string + nullable: true + example: https://www.swas.polito.it/_library/image_pub.asp?matricola=002154 + role: + type: string + example: Docente + example: + id: 2154 + firstName: Fulvio + lastName: Corno + picture: https://www.swas.polito.it/_library/image_pub.asp?matricola=002154 + role: Docente + PhoneNumber: + type: object + required: + - full + - internal + properties: + full: + type: string + example: '0110907053' + internal: + type: string + example: '7053' + example: + full: '0110907053' + internal: '7053' + Place: + type: object + required: + - latitude + - longitude + - id + - room + - category + - site + - building + - floor + - department + - geoJson + - capacity + - structure + - resources + properties: + latitude: + type: number + example: 45.064254 + longitude: + type: number + example: 7.657823 + id: + type: string + room: + type: object + properties: + id: + type: string + name: + type: string + required: + - id + - name + category: + $ref: '#/components/schemas/PlaceCategoryOverview' + site: + type: object + properties: + id: + type: string + name: + type: string + required: + - id + - name + building: + $ref: '#/components/schemas/BuildingOverview' + floor: + $ref: '#/components/schemas/Floor' + department: + $ref: '#/components/schemas/Department' + geoJson: + $ref: '#/components/schemas/GeoJsonPolygon' + capacity: + type: integer + example: 300 + structure: + type: object + properties: + name: + type: string + shortName: + type: string + email: + type: string + nullable: true + phone: + type: string + nullable: true + required: + - name + - shortName + - email + - phone + nullable: true + resources: + type: array + items: + type: object + properties: + name: + type: string + description: + type: string + category: + type: string + required: + - name + - description + - category + PlaceCategory: + type: object + required: + - id + - name + properties: + id: + type: string + example: AULA + name: + type: string + example: Aula + showInMenu: + type: boolean + color: + type: string + example: lightBlue + default: gray + markerUrl: + type: string + format: url + priority: + type: number + description: A MapBox style priority number. 0 means most important, larger numbers are less important + example: 60 + default: 100 + highlighted: + type: boolean + description: If true, markers of this category should be shown initially on the map + example: false + example: + id: AULA + name: Aula + showInMenu: false + color: lightBlue + priority: 60 + highlighted: false + PlaceCategoryOverview: + type: object + required: + - id + - name + properties: + id: + type: string + example: AULA + name: + type: string + example: Aula + showInMenu: + type: boolean + color: + type: string + example: lightBlue + default: gray + markerUrl: + type: string + format: url + priority: + type: number + description: A MapBox style priority number. 0 means most important, larger numbers are less important + example: 60 + default: 100 + highlighted: + type: boolean + description: If true, markers of this category should be shown initially on the map + example: false + subCategory: + $ref: '#/components/schemas/PlaceCategory' + PlaceOverview: + type: object + required: + - latitude + - longitude + - id + - room + - category + - site + - building + - floor + - department + properties: + latitude: + type: number + example: 45.064254 + longitude: + type: number + example: 7.657823 + id: + type: string + room: + type: object + properties: + id: + type: string + name: + type: string + required: + - id + - name + category: + $ref: '#/components/schemas/PlaceCategoryOverview' + site: + type: object + properties: + id: + type: string + name: + type: string + required: + - id + - name + building: + $ref: '#/components/schemas/BuildingOverview' + floor: + $ref: '#/components/schemas/Floor' + department: + $ref: '#/components/schemas/Department' + PlaceRef: + type: object + required: + - buildingId + - floorId + - roomId + - siteId + - name + properties: + buildingId: + type: string + floorId: + type: string + roomId: + type: string + siteId: + type: string + name: + type: string + PreviousYearsToCompare: + type: object + required: + - year + - succeeded + - failed + properties: + year: + type: integer + succeeded: + type: integer + failed: + type: integer + ProvisionalGrade: + type: object + required: + - id + - examId + - courseShortcode + - courseName + - teacherId + - credits + - grade + - date + - state + - stateDescription + - teacherMessage + - isWithdrawn + - isFailure + - canBeAccepted + - canBeRejected + - confirmedAt + - rejectedAt + - rejectingExpiresAt + properties: + id: + type: number + example: 654632 + examId: + type: number + example: 887981 + courseShortcode: + type: string + example: 01NYHOV + courseName: + type: string + example: System and device programming + teacherId: + type: integer + example: 2893 + credits: + type: number + example: 10 + grade: + type: string + example: '30' + date: + type: string + format: date + example: '2022-07-15' + state: + type: string + enum: + - published + - confirmed + - rejected + example: published + stateDescription: + type: string + example: Pubblicata + teacherMessage: + type: string + nullable: true + isWithdrawn: + type: boolean + example: false + isFailure: + type: boolean + example: false + canBeAccepted: + type: boolean + example: true + canBeRejected: + type: boolean + example: true + confirmedAt: + type: string + format: date + nullable: true + rejectedAt: + type: string + format: date-time + nullable: true + rejectingExpiresAt: + type: string + format: date-time + example: '2022-07-31T23:59:59Z' + ProvisionalGradeState: + type: object + required: + - id + - name + - description + properties: + id: + type: string + example: published + name: + type: string + example: Pubblicata + description: + type: string + example: La valutazione è stata pubblicata dal docente + RelatedVirtualClassroom: + type: object + required: + - id + - title + properties: + id: + type: integer + example: 150157 + title: + type: string + example: Lecture 1 + ReplyTicketRequest: + type: object + properties: + message: + type: string + attachment: + type: string + format: binary + required: + - message + RescheduleExamRequest: + type: object + required: + - courseShortcode + - requestReason + - requestDetails + properties: + courseShortcode: + type: string + example: 01UDROV + requestReason: + type: string + requestDetails: + type: string + RootPlaceCategory: + type: object + required: + - id + - name + properties: + id: + type: string + example: AULA + name: + type: string + example: Aula + showInMenu: + type: boolean + color: + type: string + example: lightBlue + default: gray + markerUrl: + type: string + format: url + priority: + type: number + description: A MapBox style priority number. 0 means most important, larger numbers are less important + example: 60 + default: 100 + highlighted: + type: boolean + description: If true, markers of this category should be shown initially on the map + example: false + subCategories: + type: array + items: + $ref: '#/components/schemas/PlaceCategory' + Site: + type: object + required: + - id + - name + - latitude + - longitude + - floors + - city + - extent + properties: + id: + type: string + name: + type: string + latitude: + type: number + example: 45.064254 + longitude: + type: number + example: 7.657823 + floors: + type: array + items: + $ref: '#/components/schemas/Floor' + city: + type: object + properties: + id: + type: string + name: + type: string + required: + - id + - name + extent: + type: number + description: |- + A delta in degrees that applied to the centroid + coordinates of the site determines its extent + Student: + type: object + required: + - username + - firstName + - lastName + - status + - allCareerIds + - degreeId + - degreeCode + - degreeLevel + - degreeName + - firstEnrollmentYear + - lastEnrollmentYear + - isCurrentlyEnrolled + - averageGrade + - estimatedFinalGrade + - averageGradePurged + - estimatedFinalGradePurged + - usePurgedAverageFinalGrade + - mastersAdmissionAverageGrade + - totalOnTimeExamPoints + - maxOnTimeExamPoints + - excludedCreditsNumber + - totalCredits + - totalAttendedCredits + - totalAcquiredCredits + - enrollmentCredits + - enrollmentAttendedCredits + - enrollmentAcquiredCredits + - smartCardPicture + - europeanStudentCard + properties: + username: + type: string + example: s290683 + firstName: + type: string + example: Luca + lastName: + type: string + example: Pezzolla + status: + type: string + enum: + - active + - closed + - cancelled + - graduated + - career_closed + example: active + allCareerIds: + type: array + items: + type: string + description: All the ids related to this student + example: + - '290683' + - '213956' + degreeId: + type: string + example: 81-6 + degreeCode: + type: string + example: LM-32 + degreeLevel: + type: string + example: Corso di Laurea Magistrale in + degreeName: + type: string + example: INGEGNERIA INFORMATICA (COMPUTER ENGINEERING) + firstEnrollmentYear: + type: integer + example: 2021 + lastEnrollmentYear: + type: integer + example: 2022 + isCurrentlyEnrolled: + type: boolean + example: false + averageGrade: + type: number + nullable: true + example: 27.5 + estimatedFinalGrade: + type: number + nullable: true + example: 105 + averageGradePurged: + type: number + nullable: true + description: Purged grade is only available for bachelor degree students + estimatedFinalGradePurged: + type: number + nullable: true + description: Purged grade is only available for bachelor degree students + usePurgedAverageFinalGrade: + type: boolean + description: Specify whether to use purgedAverageFinalGrade or averageFinalGrade as the graduation grade shown + mastersAdmissionAverageGrade: + type: number + nullable: true + description: Master's admission grade is only available for bachelor degree students + totalOnTimeExamPoints: + type: number + nullable: true + description: Total points for "on-time" exams - null if "on-time" exams are not applicable for the student's position (max value = maxOnTimeExamPoints) + maxOnTimeExamPoints: + type: number + description: Maximum points for "on-time" exams + excludedCreditsNumber: + type: number + nullable: true + description: Credits excluded from calculating the purged grade + totalCredits: + type: integer + totalAttendedCredits: + type: integer + totalAcquiredCredits: + type: integer + enrollmentCredits: + type: integer + enrollmentAttendedCredits: + type: integer + enrollmentAcquiredCredits: + type: integer + smartCardPicture: + type: string + nullable: true + europeanStudentCard: + $ref: '#/components/schemas/EuropeanStudentCard' + Survey: + type: object + required: + - id + - title + - subtitle + - category + - type + - period + - year + - isMandatory + - isCompiled + - compileDate + - url + - startsAt + - endsAt + properties: + id: + type: number + example: 1 + title: + type: string + example: Survey title + subtitle: + type: string + nullable: true + example: Survey subtitle + category: + $ref: '#/components/schemas/SurveyTaxonomy' + type: + $ref: '#/components/schemas/SurveyTaxonomy' + period: + type: number + example: 2 + year: + type: string + example: '2024' + isMandatory: + type: boolean + example: true + isCompiled: + type: boolean + example: false + compileDate: + type: string + format: date-time + nullable: true + example: '2022-08-31T14:00:00Z' + url: + type: string + example: https:// + startsAt: + type: string + format: date-time + example: '2022-08-31T14:00:00Z' + endsAt: + type: string + format: date-time + example: '2022-08-31T14:00:00Z' + course: + type: object + allOf: + - $ref: '#/components/schemas/SurveyCourseRef' + nullable: true + example: + id: 1 + title: Survey title + subtitle: Survey subtitle + category: + id: CPD + name: CPD + type: + id: CPD + name: CPD + period: 2 + year: '2024' + isMandatory: true + isCompiled: false + compileDate: '2022-08-31T14:00:00Z' + url: https:// + startsAt: '2022-08-31T14:00:00Z' + endsAt: '2022-08-31T14:00:00Z' + course: + id: 1 + name: Course name + shortcode: 01NYHOV + SurveyCourseRef: + type: object + required: + - id + - name + - shortcode + properties: + id: + type: number + example: 1 + name: + type: string + example: Course name + shortcode: + type: string + example: 01NYHOV + example: + id: 1 + name: Course name + shortcode: 01NYHOV + SurveyTaxonomy: + type: object + required: + - id + - name + properties: + id: + type: string + example: CPD + name: + type: string + example: CPD + example: + id: CPD + name: CPD + SwitchCareerRequest: + type: object + required: + - username + properties: + username: + type: string + example: s290683 + client: + $ref: '#/components/schemas/Client' + device: + $ref: '#/components/schemas/Device' + example: + username: s290683 + Teacher: + type: object + required: + - id + - firstName + - lastName + properties: + id: + type: integer + firstName: + type: string + lastName: + type: string + Ticket: + type: object + required: + - id + - subject + - message + - status + - hasAttachments + - isFromAgent + - agentId + - unreadCount + - createdAt + - updatedAt + - replies + - attachments + properties: + id: + type: number + example: 1145890 + subject: + type: string + example: Sostituzione esame in piano carriera + message: + type: string + example: Buongiorno, vi contatto per sostituire A con B + status: + $ref: '#/components/schemas/TicketStatus' + hasAttachments: + type: boolean + example: true + isFromAgent: + type: boolean + description: If true, this ticket was opened by an agent (not by the student) + example: false + agentId: + type: number + nullable: true + unreadCount: + type: number + example: 2 + createdAt: + type: string + format: date-time + example: '2022-08-31T14:00:00Z' + updatedAt: + type: string + format: date-time + example: '2022-08-31T14:00:00Z' + replies: + type: array + items: + $ref: '#/components/schemas/TicketReply' + attachments: + type: array + items: + $ref: '#/components/schemas/TicketAttachment' + TicketAttachment: + type: object + required: + - id + - filename + - mimeType + - sizeInKiloBytes + properties: + id: + type: number + example: 0 + filename: + type: string + example: screenshot.png + mimeType: + type: string + example: image/png + sizeInKiloBytes: + type: integer + example: 305 + example: + id: 0 + filename: screenshot.png + mimeType: image/png + sizeInKiloBytes: 305 + TicketFAQ: + type: object + required: + - id + - question + - answer + properties: + id: + type: number + example: 3623 + question: + type: string + example: Ho dimenticato il mio nome utente e/o la password e non riesco più ad accedere ad Apply@Polito. Come posso fare? + answer: + type: string + example: Clicca sul link "Codice e/o Password dimenticata?" presente sulla pagina di Log-in e segui le istruzioni. + example: + id: 3623 + question: Ho dimenticato il mio nome utente e/o la password e non riesco più ad accedere ad Apply@Polito. Come posso fare? + answer: Clicca sul link "Codice e/o Password dimenticata?" presente sulla pagina di Log-in e segui le istruzioni. + TicketOverview: + type: object + required: + - id + - subject + - message + - status + - hasAttachments + - isFromAgent + - agentId + - unreadCount + - createdAt + - updatedAt + properties: + id: + type: number + example: 1145890 + subject: + type: string + example: Sostituzione esame in piano carriera + message: + type: string + example: Buongiorno, vi contatto per sostituire A con B + status: + $ref: '#/components/schemas/TicketStatus' + hasAttachments: + type: boolean + example: true + isFromAgent: + type: boolean + description: If true, this ticket was opened by an agent (not by the student) + example: false + agentId: + type: number + nullable: true + unreadCount: + type: number + example: 2 + createdAt: + type: string + format: date-time + example: '2022-08-31T14:00:00Z' + updatedAt: + type: string + format: date-time + example: '2022-08-31T14:00:00Z' + example: + id: 1145890 + subject: Sostituzione esame in piano carriera + message: Buongiorno, vi contatto per sostituire A con B + status: new + hasAttachments: true + isFromAgent: false + agentId: null + unreadCount: 2 + createdAt: '2022-08-31T14:00:00Z' + updatedAt: '2022-08-31T14:00:00Z' + TicketReply: + type: object + required: + - id + - message + - isFromAgent + - agentId + - isRead + - createdAt + - attachments + properties: + id: + type: number + example: 1145890 + message: + type: string + example: Non si può fare. + isFromAgent: + type: boolean + description: If true, this reply was sent by an agent (not by the student) + example: true + agentId: + type: number + nullable: true + example: 351 + isRead: + type: boolean + example: true + createdAt: + type: string + format: date-time + example: '2022-08-31T14:00:00Z' + attachments: + type: array + items: + $ref: '#/components/schemas/TicketAttachment' + example: + id: 1145890 + message: Non si può fare. + isFromAgent: true + agentId: 351 + isRead: true + createdAt: '2022-08-31T14:00:00Z' + attachments: [] + TicketStatus: + type: string + enum: + - new + - pending + - closed + TicketSubtopic: + type: object + required: + - id + - name + properties: + id: + type: number + example: 103 + name: + type: string + example: Accesso studenti esterni + example: + id: 103 + name: Accesso studenti esterni + TicketTopic: + type: object + required: + - id + - name + - subtopics + properties: + id: + type: number + example: 103 + name: + type: string + example: Accesso studenti esterni + subtopics: + type: array + items: + $ref: '#/components/schemas/TicketSubtopic' + example: + id: 61 + name: ACCESSO LAUREE MAGISTRALI + subtopics: + - id: 103 + name: Accesso studenti esterni + Track: + type: object + required: + - id + - name + - courses + properties: + id: + type: number + example: 2060 + name: + type: string + example: Design per la comunicazione + courses: + type: array + items: + $ref: '#/components/schemas/OfferingCourseOverview' + example: + id: 2060 + name: Design per la comunicazione + courses: + - name: System and device programming + shortcode: 01NYHOV + cfu: 10 + teachingYear: 1 + language: en + group: Insegnamento a scelta 1 + UpdateAssignmentRequest: + type: object + properties: + delivery: + type: boolean + state: + type: string + enum: + - submitted + - uploaded + UpdateBookingRequest: + type: object + required: + - isLocationChecked + properties: + isLocationChecked: + type: boolean + example: true + UpdateInfo: + type: object + required: + - suggestUpdate + properties: + suggestUpdate: + type: boolean + UpdateNotificationPreferencesRequest: + type: object + properties: + data: + type: object + properties: + notices: + type: boolean + example: true + files: + type: boolean + example: true + lectures: + type: boolean + example: true + bookings: + type: boolean + example: true + tickets: + type: boolean + example: true + UpdatePreferencesRequest: + type: object + properties: + language: + type: string + enum: + - it + - en + example: it + ValidateMfaRequest: + type: object + required: + - serial + - nonce + - signature + properties: + serial: + type: string + example: EDUP000123456 + nonce: + type: string + example: 65ba9e0e5aac421a9150991638a9d697 + signature: + type: string + example: 83e08d9fc4be3de046318eb3c2c9ae4ede1374a5423a1487b92febc70d106994 + decline: + type: boolean + example: false + example: + serial: EDUP000123456 + nonce: 65ba9e0e5aac421a9150991638a9d697 + signature: 83e08d9fc4be3de046318eb3c2c9ae4ede1374a5423a1487b92febc70d106994 + decline: false + VideoLecture: + type: object + required: + - id + - title + - teacherId + - abstract + - coverUrl + - videoUrl + - audioUrl + - createdAt + - duration + properties: + id: + type: integer + title: + type: string + teacherId: + type: integer + abstract: + type: string + coverUrl: + type: string + videoUrl: + type: string + audioUrl: + type: string + createdAt: + type: string + format: date-time + duration: + type: string + VirtualClassroom: + type: object + oneOf: + - $ref: '#/components/schemas/VirtualClassroomLive' + - $ref: '#/components/schemas/VirtualClassroomRecording' + discriminator: + propertyName: type + mapping: + live: '#/components/schemas/VirtualClassroomLive' + recording: '#/components/schemas/VirtualClassroomRecording' + VirtualClassroomBase: + type: object + required: + - id + - title + - createdAt + - teacherId + properties: + id: + type: integer + title: + type: string + createdAt: + type: string + format: date-time + teacherId: + type: integer + VirtualClassroomLive: + type: object + required: + - type + properties: + meetingId: + type: string + type: + type: string + enum: + - live + allOf: + - $ref: '#/components/schemas/VirtualClassroomBase' + VirtualClassroomRecording: + type: object + required: + - coverUrl + - videoUrl + - duration + - type + properties: + coverUrl: + type: string + nullable: true + videoUrl: + type: string + duration: + type: string + type: + type: string + enum: + - recording + allOf: + - $ref: '#/components/schemas/VirtualClassroomBase' + YearStatistics: + type: object + required: + - succeeded + - failed + - grades + - averageGrade + properties: + succeeded: + type: integer + failed: + type: integer + grades: + type: array + items: + $ref: '#/components/schemas/GradeCount' + averageGrade: + type: number + nullable: true +servers: + - url: https://app.didattica.polito.it/api + description: Production server + variables: {} + - url: https://app.didattica.polito.it/mock/api + description: Mock server (uses example data) + variables: {} diff --git a/openapi.yaml b/openapi.yaml deleted file mode 100644 index b1dd5c7..0000000 --- a/openapi.yaml +++ /dev/null @@ -1,6410 +0,0 @@ -openapi: 3.0.3 -info: - title: Polito Students API - version: 2.2.3 - license: - name: CC BY-NC 4.0 - url: https://creativecommons.org/licenses/by-nc/4.0/ -servers: - - url: https://app.didattica.polito.it/api - description: Production server (uses live data) - - url: https://app.didattica.polito.it/mock/api - description: Mock server (uses example data) -security: - - bearerAuth: [ ] -paths: - /auth/login: - post: - tags: - - Auth - security: [ ] - summary: Login - operationId: login - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/LoginRequest' - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/Identity' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /auth/switch-career: - post: - tags: - - Auth - summary: Switch career | Cambia carriera - operationId: switchCareer - requestBody: - content: - application/json: - schema: - type: object - properties: - username: - type: string - example: s290683 - client: - $ref: '#/components/schemas/Client' - device: - $ref: '#/components/schemas/Device' - required: [ username ] - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/Identity' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /auth/logout: - delete: - tags: - - Auth - summary: Logout - description: Invalidates the provided token - operationId: logout - responses: - 200: - description: Success - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /auth/client: - patch: - tags: - - Auth - summary: Update client version fields | Aggiorna i campi di versione del client - operationId: appInfo - requestBody: - content: - application/json: - schema: - allOf: - - $ref: '#/components/schemas/ClientVersionRequest' - - $ref: '#/components/schemas/FcmRegistrationRequest' - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/UpdateInfo' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /auth/mfa/enrol: - post: - tags: - - Auth - summary: Enroll a new PUSH token - operationId: enrolMfa - requestBody: - content: - application/json: - schema: - type: object - properties: - description: - type: string - example: "some identifier you chose" - description: User-defined description for the token, pre-populated with the device model - pubkey: - type: string - description: Public key generated by the app - example: "dGhpcyBzaG91bGQgYmUgYW4gZWNkcyBwdWJsaWMga2V5Li4uIHdoYXQgZGlkIHlvdSB0aGluayB0aGlzIHdhcz8hIPCfp5AK" - required: - - description - - pubkey - responses: - 201: - description: Token successfully enrolled - content: - application/json: - schema: - type: object - properties: - data: - type: object - properties: - serial: - type: string - description: Unique identifier for the enrolled token - example: "EDUP000123456" - required: - - serial - required: - - data - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /auth/mfa/validate: - post: - tags: - - Auth - summary: Validate a challenge - operationId: validateMfa - requestBody: - content: - application/json: - schema: - type: object - properties: - serial: - type: string - description: Token serial number - example: "EDUP000123456" - nonce: - type: string - description: Nonce sent by the IdP - example: "65ba9e0e5aac421a9150991638a9d697" - signature: - type: string - description: Signature generated by signing the nonce in the App - example: "83e08d9fc4be3de046318eb3c2c9ae4ede1374a5423a1487b92febc70d106994" - decline: - type: boolean - description: if set to true, decline the authentication request - example: false - required: - - serial - - nonce - - signature - responses: - 200: - description: Challenge validation result - content: - application/json: - schema: - type: object - properties: - data: - type: object - properties: - success: - type: boolean - description: Indicates whether the validation succeeded - example: true - required: - - success - required: - - data - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /auth/mfa/challenge: - get: - tags: - - Auth - summary: Fetch pending challenge - operationId: fetchChallenge - responses: - 200: - description: The most recent of pending challenges - content: - application/json: - schema: - type: object - properties: - data: - type: object - properties: - serial: - type: string - description: Token serial number - example: "EDUP000123456" - challenge: - type: string - description: Challenge data to be signed by the App - example: "dGhpcyBzaG91bGQgYmUgYW4gZWNkcyBwdWJsaWMga2V5Li4uIHdoYXQgZGlkIHlvdSB0aGluayB0aGlzIHdhcz8hIPCfp5AK" - requestTs: - type: string - format: date-time - description: Challenge request - example: '2025-01-01T00:00:00Z' - expirationTs: - type: string - format: date-time - description: Challenge expiration - example: '2025-01-01T01:00:00Z' - required: - - serial - - challenge - - requestTs - - expirationTs - nullable: true - required: - - data - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /auth/mfa/status: - get: - tags: - - Auth - summary: Get MFA status for the current user - operationId: getMfaStatus - responses: - '200': - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/MfaStatusResponse' - required: [ data ] - '400': - $ref: '#/components/responses/BadRequestResponse' - '500': - $ref: '#/components/responses/ErrorResponse' - - /auth/serviceLink/moodle/{course}: - get: - tags: - - Auth - summary: Get authorised service link for Moodle course - operationId: getMoodleLink - parameters: - - name: course - in: path - required: true - schema: - type: integer - description: Moodle course identifier - responses: - '200': - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/LinkToService' - required: [ data ] - '400': - $ref: '#/components/responses/BadRequestResponse' - '500': - $ref: '#/components/responses/ErrorResponse' - - /auth/serviceLink/liveClass/{meetingID}: - get: - tags: - - Auth - summary: Get authorised service link for LiveClass meeting - operationId: getLiveClassLink - parameters: - - name: meetingID - in: path - required: true - schema: - type: string - description: LiveClass meeting identifier - responses: - '200': - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/LinkToService' - required: [ data ] - '400': - $ref: '#/components/responses/BadRequestResponse' - '500': - $ref: '#/components/responses/ErrorResponse' - - /auth/serviceLink/mail: - get: - tags: - - Auth - summary: Get authorised service link for Mail - operationId: getMailLink - responses: - '200': - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/LinkToService' - required: [ data ] - '400': - $ref: '#/components/responses/BadRequestResponse' - '500': - $ref: '#/components/responses/ErrorResponse' - - /me: - get: - tags: - - Student - summary: Retrieve student profile | Recupera il profilo studente - operationId: getStudent - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/Student' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /deadlines: - get: - tags: - - Student - parameters: - - name: fromDate - in: query - description: First day - defaults to 7 days before today - required: false - schema: - type: string - format: date - - name: toDate - in: query - description: Last day - defaults to 7 days after today - required: false - schema: - type: string - format: date - summary: List deadlines | Elenca scadenze - operationId: getDeadlines - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/Deadline' - required: [ data ] - example: - data: - - name: Termine per l'iscrizione e pagamento della prima rata, per gli studenti di anni successivi al primo - type: Iscrizioni e pagamento tasse - date: "2022-10-11" - url: null - - name: Trasferimento da altri Atenei italiani - type: Trasferimenti e valutazioni carriere precedenti - date: "2022-10-14" - url: null - - name: Termine per superare gli esami - type: Sessioni esami di laurea - date: "2022-11-12" - url: null - - name: Termine iscrizione esame finale - type: Sessioni esami di laurea - date: "2022-11-14" - url: null - - name: Periodo per la compilazione del piano carriera / carico didattico - type: Iscrizioni e pagamento tasse - date: "2022-11-25" - url: null - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /grades: - get: - tags: - - Student - summary: Retrieve student grades | Recupera i voti dello studente - operationId: getStudentGrades - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/ExamGrade' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /provisional-grades: - get: - tags: - - Student - summary: Retrieve student provisional grades | Recupera le valutazioni provvisorie dello studente - operationId: getStudentProvisionalGrades - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/ProvisionalGrade' - states: - type: array - items: - $ref: '#/components/schemas/ProvisionalGradeState' - required: [ data, states ] - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /provisional-grades/{provisionalGradeId}/accept: - post: - tags: - - Student - summary: Accept provisional grade | Accetta valutazione provvisoria - operationId: acceptProvisionalGrade - parameters: - - $ref: '#/components/parameters/provisionalGradeIdParam' - responses: - 200: - description: Success - 404: - description: Provisional grade not found - 500: - $ref: '#/components/responses/ErrorResponse' - - /provisional-grades/{provisionalGradeId}/reject: - post: - tags: - - Student - summary: Reject provisional grade | Rifiuta valutazione provvisoria - operationId: rejectProvisionalGrade - parameters: - - $ref: '#/components/parameters/provisionalGradeIdParam' - responses: - 200: - description: Success - 404: - description: Provisional grade not found - 500: - $ref: '#/components/responses/ErrorResponse' - - /unreadEmails: - get: - tags: - - Student - summary: Retrieve student's unread emails number | Recupera il numero di email non lette dello studente - operationId: getUnreadEmailslNumber - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/EmailBadge' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /booking-topics: - get: - tags: - - Bookings - summary: List booking topics | Elenca ambiti di prenotazione - operationId: getBookingTopics - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/BookingTopic' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /booking-topics/{bookingTopicId}/slots: - get: - tags: - - Bookings - summary: Show booking slots | Mostra turni prenotabili - operationId: getBookingSlots - parameters: - - name: bookingTopicId - in: path - required: true - schema: - type: string - - name: fromDate - in: query - description: First day - defaults to monday of current week - required: false - schema: - type: string - format: date - - name: toDate - in: query - description: Last day - defaults to sunday of current week - required: false - schema: - type: string - format: date - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/BookingSlot' - required: [ data ] - 404: - description: Booking topic not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /booking-topics/{bookingTopicId}/slots/{bookingSlotId}/seats: - get: - tags: - - Bookings - summary: Show seats for a booking slots | Mostra posti prenotabili - operationId: getBookingSeats - parameters: - - name: bookingTopicId - in: path - required: true - schema: - type: string - - name: bookingSlotId - in: path - required: true - schema: - type: string - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/BookingSeats' - required: [ data ] - 404: - description: Booking topic|slot not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /bookings: - get: - tags: - - Bookings - summary: List bookings | Elenca prenotazioni - operationId: getBookings - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/Booking' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - post: - tags: - - Bookings - summary: Create booking | Crea prenotazione - operationId: createBooking - requestBody: - content: - application/json: - schema: - type: object - properties: - slotId: - type: integer - example: 226439 - seatId: - type: integer - example: 20018 - required: [ slotId ] - responses: - 200: - description: Success - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /bookings/{bookingId}: - patch: - tags: - - Bookings - summary: Update booking | Aggiorna prenotazione - operationId: updateBooking - parameters: - - name: bookingId - in: path - required: true - schema: - type: integer - requestBody: - content: - application/json: - schema: - type: object - properties: - isLocationChecked: - type: boolean - example: true - required: [ isLocationChecked ] - responses: - 200: - description: Success - 404: - description: Booking not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - delete: - tags: - - Bookings - summary: Delete booking | Cancella prenotazione - operationId: deleteBooking - parameters: - - name: bookingId - in: path - required: true - schema: - type: integer - responses: - 200: - description: Success - 404: - description: Booking not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /v2/courses: - get: - tags: - - Courses - summary: List courses | Elenca corsi - operationId: getCourses - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/CourseOverview' - required: [ data ] - example: - data: - - id: null - name: 'System and device programming' - shortcode: 01NYHOV - cfu: 10 - teachingPeriod: 2-2 - teacherId: 2893 - teacherName: 'Stefano Quer' - previousEditions: [] - isOverBooking: false - isInPersonalStudyPlan: true - year: '2025' - modules: - - id: 251008 - name: 'Programming Module A' - teachingPeriod: 2-2 - teacherId: 3001 - teacherName: 'Mario Rossi' - previousEditions: [{ id: 251005, year: '2024' }] - isOverBooking: false - isInPersonalStudyPlan: true - year: '2025' - - id: 251009 - name: 'Programming Module B' - teachingPeriod: 2-2 - teacherId: 3002 - teacherName: 'Giovanni Verdi' - previousEditions: [{ id: 251006, year: '2024' }] - isOverBooking: false - isInPersonalStudyPlan: true - year: '2025' - - id: 252121 - name: 'Web Applications II' - shortcode: 01TXSOV - cfu: 6 - teachingPeriod: 2-2 - teacherId: 2235 - teacherName: 'Giovanni Malnati' - previousEditions: [] - isOverBooking: false - isInPersonalStudyPlan: true - year: '2025' - modules: null - - id: 252126 - name: 'Security verification and testing' - shortcode: 01TYAOV - cfu: 6 - teachingPeriod: 1-1 - teacherId: 1943 - teacherName: 'Riccardo Sisto' - previousEditions: [] - isOverBooking: false - isInPersonalStudyPlan: true - year: '2025' - modules: null - - id: 252138 - name: 'Information systems security' - shortcode: 01TYMOV - cfu: 6 - teachingPeriod: 1-1 - teacherId: 1847 - teacherName: 'Antonio Lioy' - previousEditions: [] - isOverBooking: false - isInPersonalStudyPlan: true - year: '2025' - modules: null - - id: 252258 - name: 'Cybersecurity' - shortcode: 01UDROV - cfu: 6 - teachingPeriod: 2-2 - teacherId: 1847 - teacherName: 'Antonio Lioy' - previousEditions: [] - isOverBooking: false - isInPersonalStudyPlan: true - year: '2025' - modules: null - - id: 252788 - name: 'Architetture dei sistemi di elaborazione' - shortcode: 02GOLOV - cfu: 10 - teachingPeriod: 1-1 - teacherId: 12684 - teacherName: 'Edgar Ernesto Sanchez Sanchez' - previousEditions: [] - isOverBooking: false - isInPersonalStudyPlan: true - year: '2025' - modules: null - - id: 252842 - name: 'Human Computer Interaction' - shortcode: 02JSKOV - cfu: 6 - teachingPeriod: 1-1 - teacherId: 25734 - teacherName: 'Luigi De Russis' - previousEditions: [] - isOverBooking: false - isInPersonalStudyPlan: true - year: '2025' - modules: null - - id: 253378 - name: 'Cryptography' - shortcode: 03LPYOV - cfu: 6 - teachingPeriod: 2-2 - teacherId: 13461 - teacherName: 'Antonio Josè Di Scala' - previousEditions: [] - isOverBooking: false - isInPersonalStudyPlan: true - year: '2025' - modules: null - - id: null - name: 'Tesi' - shortcode: 29EBHOV - cfu: 30 - teachingPeriod: 1-1 - teacherId: null - teacherName: null - previousEditions: [] - isOverBooking: false - isInPersonalStudyPlan: true - year: '2025' - modules: null - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /courses/{courseId}: - get: - tags: - - Courses - summary: Show course | Mostra corso - operationId: getCourse - parameters: - - name: courseId - in: path - required: true - schema: - type: integer - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/Course' - required: [ data ] - 404: - description: Course not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /courses/{courseId}/files: - get: - tags: - - Courses - summary: List files | Elenca file - operationId: getCourseFiles - parameters: - - name: courseId - in: path - required: true - schema: - type: integer - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/CourseDirectoryContent' - required: [ data ] - example: - data: - - id: "33248655" - name: "videolectures" - type: "directory" - files: - - id: "33248890" - name: "HCI2021-L01 2021-09-28 13-06-26.m4v" - sizeInKiloBytes: 123428 - mimeType: "video/x-m4v" - createdAt: "2021-09-28T16:31:43Z" - type: "file" - - id: "33251708" - name: "HCI2021-L02 2021-09-30 08-34-32.mp4" - sizeInKiloBytes: 248172 - mimeType: "video/mp4" - createdAt: "2021-09-30T10:20:50Z" - type: "file" - - id: "33256476" - name: "HCI2021-L03 2021-10-05 13-06-47.mp4" - sizeInKiloBytes: 243792 - mimeType: "video/mp4" - createdAt: "2021-10-05T15:00:15Z" - type: "file" - - id: "33257988" - name: "HCI2021-L04 2021-10-07 08-35-46.mp4" - sizeInKiloBytes: 244993 - mimeType: "video/mp4" - createdAt: "2021-10-07T11:12:25Z" - type: "file" - - id: "33262287" - name: "HCI2021-L05 2021-10-12 13-05-46.mp4" - sizeInKiloBytes: 298172 - mimeType: "video/mp4" - createdAt: "2021-10-12T16:11:46Z" - type: "file" - - id: "33265387" - name: "HCI2021-L06 2021-10-14 08-35-12.mp4" - sizeInKiloBytes: 285926 - mimeType: "video/mp4" - createdAt: "2021-10-14T11:25:20Z" - type: "file" - - id: "33269079" - name: "HCI2021-L07 2021-10-19 13-10-40.mp4" - sizeInKiloBytes: 234466 - mimeType: "video/mp4" - createdAt: "2021-10-19T15:02:22Z" - type: "file" - - - 404: - description: Course not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /courses/{courseId}/files/{fileId}: - get: - tags: - - Courses - summary: Download file | Scarica file - operationId: getCourseFile - parameters: - - name: courseId - in: path - required: true - schema: - type: integer - - name: fileId - in: path - required: true - schema: - type: string - responses: - 200: - description: Success - 302: - description: Redirect to file download - 404: - description: Course or file not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /courses/{courseId}/assignments: - get: - tags: - - Courses - summary: List assignments | Elenca elaborati - operationId: getCourseAssignments - parameters: - - name: courseId - in: path - required: true - schema: - type: integer - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/CourseAssignment' - required: [ data ] - example: - data: - - id: 1003948 - description: "extrapoints2" - mimeType: "application/x-zip-compressed" - filename: "extrapoints2.zip" - uploadedAt: "2022-01-21T14:38:00Z" - deletedAt: null - url: "https://file.didattica.polito.it/down/ELABORATI_PRE/1003948/S290683/14576f69df588d55b631c3c3c30de3f5/6305eae6" - sizeInKiloBytes: 195 - - id: 993784 - description: "extrapoints1" - mimeType: "application/x-zip-compressed" - filename: "extrapoints1.zip" - uploadedAt: "2022-01-10T18:53:00Z" - deletedAt: null - url: "https://file.didattica.polito.it/down/ELABORATI_PRE/993784/S290683/15c275f7f7682c6acb5acd07d24590a9/6305eae6" - sizeInKiloBytes: 401 - - id: 982517 - description: "lab_09" - mimeType: "application/zip" - filename: "lab_09.zip" - uploadedAt: "2021-12-16T22:48:00Z" - deletedAt: null - url: "https://file.didattica.polito.it/down/ELABORATI_PRE/982517/S290683/29288344d27567de6ddf0fa718b980a5/6305eae6" - sizeInKiloBytes: 126 - - id: 979076 - description: "lab_08" - mimeType: "application/x-zip-compressed" - filename: "lab8.zip" - uploadedAt: "2021-12-10T20:13:00Z" - deletedAt: null - url: "https://file.didattica.polito.it/down/ELABORATI_PRE/979076/S290683/3fecdf972707d6cbc439ed0fbbbe726a/6305eae6" - sizeInKiloBytes: 136 - - id: 970722 - description: "lab_06" - mimeType: "application/x-zip-compressed" - filename: "lab_06.zip" - uploadedAt: "2021-11-26T12:11:00Z" - deletedAt: null - url: "https://file.didattica.polito.it/down/ELABORATI_PRE/970722/S290683/bc51c37cf1368917a24de8d571b069bd/6305eae6" - sizeInKiloBytes: 169 - - id: 948012 - description: "lab_04" - mimeType: "application/zip" - filename: "lab_04.zip" - uploadedAt: "2021-10-30T17:26:00Z" - deletedAt: null - url: "https://file.didattica.polito.it/down/ELABORATI_PRE/948012/S290683/ca52325301df0130d718c7a0525df288/6305eae6" - sizeInKiloBytes: 259 - - id: 947503 - description: "lab_03" - mimeType: "application/x-zip-compressed" - filename: "lab_03.zip" - uploadedAt: "2021-10-29T12:33:00Z" - deletedAt: null - url: "https://file.didattica.polito.it/down/ELABORATI_PRE/947503/S290683/b829dada99af4b2576e551bd852e0a25/6305eae6" - sizeInKiloBytes: 139 - - id: 941444 - description: "lab_02" - mimeType: "application/zip" - filename: "lab_02.zip" - uploadedAt: "2021-10-22T12:12:00Z" - deletedAt: null - url: "https://file.didattica.polito.it/down/ELABORATI_PRE/941444/S290683/08ec123878543394393bd31719863eda/6305eae6" - sizeInKiloBytes: 305 - - id: 934034 - description: "lab_01" - mimeType: "application/x-zip-compressed" - filename: "lab_01.zip" - uploadedAt: "2021-10-13T11:20:00Z" - deletedAt: null - url: "https://file.didattica.polito.it/down/ELABORATI_PRE/934034/S290683/fd675d8a411d0747885b24e473a5d683/6305eae6" - sizeInKiloBytes: 144 - 404: - description: Course not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - post: - tags: - - Courses - summary: Upload assignment | Carica elaborato - operationId: uploadCourseAssignment - parameters: - - name: courseId - in: path - required: true - schema: - type: integer - requestBody: - content: - multipart/form-data: - schema: - $ref: '#/components/schemas/CourseAssignmentUpload' - required: true - responses: - 200: - description: Success - 404: - description: Course not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /courses/{courseId}/assignments/{assignmentId}: - patch: - tags: - - Courses - summary: Update assignment | Aggiorna elaborato - operationId: updateAssignment - parameters: - - $ref: '#/components/parameters/courseIdParam' - - $ref: '#/components/parameters/assignmentIdParam' - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/UpdateAssignmentRequest' - responses: - 200: - description: Assignment successfully updated - 404: - description: Course or assignment not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /courses/{courseId}/guide: - get: - tags: - - Courses - summary: Show guide | Mostra guida - operationId: getCourseGuide - parameters: - - name: courseId - in: path - required: true - schema: - type: integer - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/CourseGuideSection' - required: [ data ] - example: - data: - - title: Presentazione - content: 'Nowadays, computing devices are ubiquitously present and integrated in our daily life. Sensors and actuators are, indeed, embedded in home appliances, lights, or cars; wearable devices like smart watches provide information at glance and act as always-on and personal digital extensions; smartphones and tablets are widely spread. Moreover, most of such devices are Internet-connected and powered by Artificial Intelligence, and people communicate with them by using various interaction paradigms, ranging from "click", to touch, to gestures, speech, or tangible manipulation. As the technology improves, however, we are challenged of how to design suitable interfaces and interactions, so that people can use such technologies with "joy" rather than "frustration".\f\n\f\nThis course would provide a strong foundation to address this challenge. In addition, the course will give students hands-on practice to master this complexity and to develop innovative solutions by adopting a modern human-centered design process while building a web application to serve a set of target users. In the end, students will learn how to design and build technologies usable, useful, and used.' - - title: Risultati attesi - content: 'Knowledge:\f\n- Concepts of Usability, User Experience\f\n- User centered design processes and their application\f\n- Novel Interaction Technologies\f\n\f\nSkills:\f\n- Developing a working prototype according to a human-centered design process\f\n- Mastering some novel interaction technologies\f\n- Experience joint development of a project in a group of engineers' - - title: Prerequisiti - content: '- Programming skills\f\n- Knowledge on web and related technologies/languages (e.g., HTML, JS, client-server architectures, …)\f\n- Attitude towards working in teams\f\n' - - title: Programma - content: 'Course topics will cover three areas: \f\n\f\n - - Introduction to Human-Computer Interaction: history, the human, the computer, vision of the future.\f\n\f\n - - Building interactive applications with a human-centered process. The main tasks and methods to design, develop, and evaluate an interactive application: needfindings strategies, low- and high-fidelity prototypes, mental models and visual design, heuristic evaluation, and basic concepts and methods for controlled experiments (3 credits of lectures and exercises).\f\nThis part will focus, in general, on the design process. Such concepts will be applied to a specific application domain in the development of a group project, which will be carried on during the lab hours (2 credits). \f\n\f\n - - "Beyond WIMP" paradigms: e.g., interaction with AI-powered systems, tangible interaction, voice user interfaces, wearables, gestures, and eye tracking. Selected paradigms will be discussed from different perspectives, ranging from rationale and vision, to contemporary examples and development tools (1 credit). Thematic seminars on emerging topics might also be included, as well as the illustration of specific "case studies".\f\n\f\nMost of the topics will have a theoretical (in-class) foundation plus hands-on (in-lab) experiences by using web technologies. Students projects will follow the proposed human-centered design process and will submit intermediate deliverables. Projects will consist of interactive prototypes as modern web applications, in which a "beyond WIMP" paradigm might be exploited for user interaction.\f\n\f\nDuring the course, communication within teams and with teachers as well as project development will adopt contemporary solutions and tools (e.g., Git and GitHub, Slack/Discord, …).' - - title: Note - content: '' - - title: Organizzazione dell'insegnamento - content: 'The learning method is both project-based (i.e., students learn by doing a project) and problem-based (i.e., the project work starts from real users’ needs), with teams of students working together towards a common goal. \f\n\f\nProject-related activities will start since the beginning of the course and teachers will provide support and guidance for the entire semester. The project will be accompanied by deliverables to be prepared before given deadlines. \f\n\f\nThe course may include live seminars by people from industry or other organizations.' - - title: Bibliografia - content: '* Course slides and related materials (e.g., links, readings, …)\f\n* Selected chapters of:\f\n - - Alan Dix, Janet Finlay, Gregory Abowd, Russell Beale: Human Computer Interaction, 3rd Edition, Prentice Hall, 2004, ISBN 0-13-046109-1\f\n - - Shneiderman, Plaisant, Cohen, Jacobs, Elmqvist & Diakopoulos: Designing the User Interface: Strategies for Effective Human-Computer Interaction, 6th Edition, Pearson, 2016, 013438038X / 9780134380384\f\n' - - title: Regole d'esame - content: 'The exam consists in a written test (in class) and in the evaluation of the group project. The two parts are mandatory and must be taken in the same academic year.\f\n\f\nThe written exam will be closed-note (no books nor notes) and on the topics covered during the lectures (i.e., no code or project-related questions). The duration will be 60 minutes, and will consist of a set of open questions. It will account for 40% of the score, with a minimum threshold.\f\n\f\nThe group project will be evaluated through an oral session, where all group components must be present.\f\nThe evaluation criteria for the group project include: effort invested in the project activity; originality, complexity, and richness of the solution; methodological and technical correctness; completeness and communication quality of the deliverables; presentation and oral discussion; individual contribution. It will account for 60% of the score' - 404: - description: Course not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /courses/{courseId}/notices: - get: - tags: - - Courses - summary: List notices | Elenca avvisi - operationId: getCourseNotices - parameters: - - name: courseId - in: path - required: true - schema: - type: integer - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/CourseNotices' - required: [ data ] - example: - data: - - id: 332559 - publishedAt: '2021-09-22T14:00:00Z' - expiresAt: null - content: '

Dear students,

\r\r

welcome to the 2021 edition of the Human Computer Interaction course (HCI, for short)!

\r\r

Some useful information to get started...

\r\r

The first class will be on Tuesday, September 28, in Room 7T, from 13:00 to 14:30.
\rDon't forget to book a spot in the room, starting from tomorrow, on the Portale della Didattica: the rooms given to this course are currently bigger than the number of enrolled students, so there should be space for everybody!

\r\r

All teaching material, information, and course schedule will be posted on the page: http://bit.ly/polito-hci (we will not use the Portale della Didattica).

\r\r

All messages and communications with the teachers, and among students, will be on Slack. We will completely avoid email communications.
\rPlease, join the HCI Slack workspace at the address:
\r  https://join.slack.com/t/polito-hci-2021/signup
\rPlease note: to have access to the workspace, you must use your @studenti.polito.it email address. You are free to choose your nickname as you prefer. 

\r\r

Finally, all lectures — not labs — will be video-recorded and made available both on YouTube and on the Portale della Didattica. The YouTube playlist is:
\r  https://www.youtube.com/playlist?list=PLs7DWGc_wmwT-1N2vbRkLWrM6LIker9A-

\r\r

See you on Tuesday!

\r\r

Thanks,

\r\r

Luigi and Fulvio

\r' - 404: - description: Course not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /courses/{courseId}/virtual-classrooms: - get: - tags: - - Courses - summary: List virtual classrooms | Elenca virtual classroom - operationId: getCourseVirtualClassrooms - parameters: - - name: courseId - in: path - required: true - schema: - type: integer - - name: live - in: query - description: Filter virtual classrooms by their live status - schema: - type: boolean - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - oneOf: - - $ref: '#/components/schemas/VirtualClassroomLive' - - $ref: '#/components/schemas/VirtualClassroom' - discriminator: - propertyName: type - mapping: - live: '#/components/schemas/VirtualClassroomLive' - recording: '#/components/schemas/VirtualClassroom' - required: [ data ] - example: - data: - - id: 149336 - title: "CYB / lecture 28.09.2021 (TLS, slides 1-40)" - teacherId: 1847 - coverUrl: "https://lucapezzolla.com/cover.jpg" - videoUrl: "https://video.polito.it/dl/BE7C779FC37D50996EE1FF32B6BC7FAE/6305E087/vc2021/252258/64cdcfc29ac1cd827d20ff1fa62c512eade6b3c0-1632832182985.mp4" - createdAt: "2021-09-28T14:29:00Z" - duration: "02h 56m" - type: "recording" - - id: 150397 - title: "CYB / lecture 01.10.2021 (TLS, slides 41-55)" - teacherId: 1847 - coverUrl: "https://lucapezzolla.com/cover.jpg" - videoUrl: "https://video.polito.it/dl/0BC53A27F4776D8A6809D28EB4CB3C9F/6305E087/vc2021/252258/e5e7a53da68cebd5cff1a585659092fcfeca651a-1633074845891.mp4" - createdAt: "2021-10-01T09:54:00Z" - duration: "01h 31m" - type: "recording" - - id: 151650 - title: "CYB / lecture 5.10.2021 (TLS, slides 56-end, + SSH all slides)" - teacherId: 1847 - coverUrl: "https://lucapezzolla.com/cover.jpg" - videoUrl: "https://video.polito.it/dl/56DA5556ECD96ED30EC6F8CBAB704285/6305E087/vc2021/252258/c30092cca256f522f64774e19538d43909ce558b-1633437688385.mp4" - createdAt: "2021-10-05T14:41:00Z" - duration: "02h 43m" - type: "recording" - - id: 152904 - title: "CYB / exercises 8.10.2021 (TLS, SSH, and laboratory introduction)" - teacherId: 12066 - coverUrl: "https://lucapezzolla.com/cover.jpg" - videoUrl: "https://video.polito.it/dl/B738FA2018D0CEDAD999B09E88A0A5BC/6305E087/vc2021/252258/6d7e5ddb4c6accf0ee0ac2f5694ff57b03452a33-1633680044979.mp4" - createdAt: "2021-10-08T10:00:00Z" - duration: "01h 29m" - type: "recording" - - id: 154120 - title: "CYB / lecture 12.10.2021 (X.509-PKI slides 1-37)" - teacherId: 1847 - coverUrl: "https://lucapezzolla.com/cover.jpg" - videoUrl: "https://video.polito.it/dl/59B0F46ACE7A752394D15CFA7ABE1D04/6305E087/vc2021/252258/7ed626fec39372a49de2789c02a30d42e4ed9550-1634041964568.mp4" - createdAt: "2021-10-12T14:32:00Z" - duration: "02h 49m" - type: "recording" - - id: 155289 - title: "CYB / lecture 15.10.2021 (X.509-PKI slides 38-50)" - teacherId: 1847 - coverUrl: "https://lucapezzolla.com/cover.jpg" - videoUrl: "https://video.polito.it/dl/26673F1C1E978DD6EF3A936453977414/6305E087/vc2021/252258/80a41d52d94c236e8d076c959bdd6594df4c640d-1634287717877.mp4" - createdAt: "2021-10-15T10:48:00Z" - duration: "00h 29m" - type: "recording" - - id: 156556 - title: "CYB / lecture 18.10.2021 (X.509-PKI slides 51-87)" - teacherId: 1847 - coverUrl: "https://lucapezzolla.com/cover.jpg" - videoUrl: "https://video.polito.it/dl/683EC58FC3F66A232F871CE9AF6EC41F/6305E087/vc2021/252258/26a670587a538805ca101505347c1f6b95945c7a-1634646791043.mp4" - createdAt: "2021-10-19T14:33:00Z" - duration: "02h 46m" - type: "recording" - - id: 157810 - title: "CYB / lecture 22.10.2021 (X.509-PKI slides 88-113)" - teacherId: 1847 - coverUrl: "https://lucapezzolla.com/cover.jpg" - videoUrl: "https://video.polito.it/dl/E46149A506697BABF2D1F1F7D3BD93C4/6305E087/vc2021/252258/54879788014d7f876efa3e37eb0ab41b28ed5ec7-1634889548847.mp4" - createdAt: "2021-10-22T09:59:00Z" - duration: "01h 14m" - type: "recording" - - id: 159051 - title: "CYB / lecture 26.10.2021 (PKCS#7 and XML dsig/enc, all slides)" - teacherId: 1847 - coverUrl: "https://lucapezzolla.com/cover.jpg" - videoUrl: "https://video.polito.it/dl/C8BC340269DC981A175B5532224C191A/6305E087/vc2021/252258/a3ca5092848ddcfc8e40856f4a7e0d5e806b6612-1635251947471.mp4" - createdAt: "2021-10-26T14:39:00Z" - duration: "02h 23m" - type: "recording" - - id: 161152 - title: "CYB / lecture 2.11.2021 (Raccoon attack + WiFi slides 1-33)" - teacherId: 1847 - coverUrl: "https://lucapezzolla.com/cover.jpg" - videoUrl: "https://video.polito.it/dl/706BF0B4AEA847058A6D1C40FEA13C33/6305E087/vc2021/252258/a450be755938e9117692c396f27df27dfd17d1fc-1635859798379.mp4" - createdAt: "2021-11-02T14:29:00Z" - duration: "02h 58m" - type: "recording" - - id: 162379 - title: "CYB / lecture 05.11.2021 (keypair attack + WiFi slides 34-end + e-identity slides 1-10)" - teacherId: 1847 - coverUrl: "https://lucapezzolla.com/cover.jpg" - videoUrl: "https://video.polito.it/dl/1AB78C6B65D67B72C5CCE0F933225A32/6305E087/vc2021/252258/9e0127b8b6723430d3f984697abc288be39f9422-1636102419696.mp4" - createdAt: "2021-11-05T09:53:00Z" - duration: "01h 20m" - type: "recording" - - id: 163693 - title: "CYB / lecture 09.11.2021 (e-identity slides 11-91)" - teacherId: 1847 - coverUrl: "https://lucapezzolla.com/cover.jpg" - videoUrl: "https://video.polito.it/dl/521B033D824BC6FC0B4D2950CB431960/6305E087/vc2021/252258/548e5779bc1cfd66767c43aa610574c3c3a12dd9-1636464923945.mp4" - createdAt: "2021-11-09T14:35:00Z" - duration: "02h 48m" - type: "recording" - - id: 166121 - title: "CYB / lecture 16.11.2021 (trusted computing - all slides)" - teacherId: 1847 - coverUrl: "https://lucapezzolla.com/cover.jpg" - videoUrl: "https://video.polito.it/dl/360E906166192D9BE6F6155D72E15F1E/6305E087/vc2021/252258/f3018da0ada1e0404dd3b35f5dd4b104bcfee8d3-1637069410236.mp4" - createdAt: "2021-11-16T14:30:00Z" - duration: "02h 46m" - type: "recording" - - id: 168367 - title: "CYB / lecture 23.11.2021 (Intel SGX - all slides)" - teacherId: 37572 - coverUrl: "https://lucapezzolla.com/cover.jpg" - videoUrl: "https://video.polito.it/dl/4FF040DFCF3A479A980291C8C3CCE6CC/6305E087/vc2021/252258/180a6a764703deffc12b2dcee1a424949e325f9d-1637674185628.mp4" - createdAt: "2021-11-23T14:29:00Z" - duration: "02h 58m" - type: "recording" - - id: 170812 - title: "CYB / lecture 30.11.2021 (forensics, slides 1-40)" - teacherId: 12066 - coverUrl: "https://lucapezzolla.com/cover.jpg" - videoUrl: "https://video.polito.it/dl/71B3E9CBDDB642AAA77908985245A885/6305E087/vc2021/252258/87968954515.mp4" - createdAt: "2021-11-30T14:32:00Z" - duration: "02h 45m" - type: "recording" - - id: 172948 - title: "CYB / lecture 7.12.2021 (forensics slides 41-end)" - teacherId: 12066 - coverUrl: "https://lucapezzolla.com/cover.jpg" - videoUrl: "https://video.polito.it/dl/739FC4C2625A96DA19EFB05A3FE043CD/6305E087/vc2021/252258/81581203450.mp4" - createdAt: "2021-12-07T14:34:00Z" - duration: "01h 18m" - type: "recording" - - id: 173056 - title: "CYB / lecture 7.12.2021 (ATT&CK + CRING + privacy slides 1-9)" - teacherId: 1847 - coverUrl: "https://lucapezzolla.com/cover.jpg" - videoUrl: "https://video.polito.it/dl/D039EE5B83A12581050ED2B6B0416F70/6305E087/vc2021/252258/099bf783f435456027c06065201a0eb2d38bd41a-1638889616600.mp4" - createdAt: "2021-12-07T16:06:00Z" - duration: "01h 19m" - type: "recording" - - id: 174893 - title: "CYB / lecture 14.12.2021 (Detract + TPM_Win11 + privacy slides 10-end)" - teacherId: 1847 - coverUrl: "https://lucapezzolla.com/cover.jpg" - videoUrl: "https://video.polito.it/dl/436BD1306E68AFE95AF46B2D0BC1C8DB/6305E087/vc2021/252258/be095df91592bf86178f6bfbf1c9f5bb0d0d0c26-1639488630242.mp4" - createdAt: "2021-12-14T14:30:00Z" - duration: "02h 31m" - type: "recording" - - id: 175951 - title: "CYB / lecture 17.12.2021 (thesis topics and exam example)" - teacherId: 1847 - coverUrl: "https://lucapezzolla.com/cover.jpg" - videoUrl: "https://video.polito.it/dl/1EAD6B130FC26060ABF998EF8CF805BA/6305E087/vc2021/252258/73e45093b2c0bc9c88d542d62c3fbe2639a7bd2b-1639731367509.mp4" - createdAt: "2021-12-17T09:56:00Z" - duration: "00h 50m" - type: "recording" - 404: - description: Course not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /courses/{courseId}/videolectures: - get: - tags: - - Courses - summary: List videolectures | Elenca videolezioni - operationId: getCourseVideolectures - parameters: - - name: courseId - in: path - required: true - schema: - type: integer - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/VideoLecture' - required: [ data ] - 404: - description: Course not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /courses/{courseId}/nextLecture: - get: - tags: - - Courses - summary: Get next lecture | Ottieni prossima lezione - operationId: getNextLecture - parameters: - - name: courseId - in: path - required: true - schema: - type: integer - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/Lecture' - required: [ data ] - example: - data: - id: 12131312 - startsAt: "2021-09-28T14:30:00Z" - endsAt: "2021-09-28T17:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ - { - id: 149336, - title: "CYB / lecture 28.09.2021 (TLS, slides 1-40)" - } - ] - 404: - description: Lecture not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 400: - $ref: '#/components/responses/BadRequestResponse' - - /courses/{courseId}/preferences: - patch: - tags: - - Courses - summary: Update course preferences | Aggiorna preferenze del corso - operationId: updateCoursePreferences - parameters: - - name: courseId - in: path - required: true - schema: - type: integer - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/CoursePreferencesRequest' - required: true - responses: - 200: - description: Success - 404: - description: Course not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /exams: - get: - tags: - - Exams - summary: List exams | Elenca esami - operationId: getExams - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/Exam' - required: [ data ] - example: - data: - - id: 888137 - courseId: 262147 - courseShortcode: 01UDROV - courseName: Cybersecurity (AA-ZZ) - teacherId: 1847 - type: Scritto - status: booked - bookingStartsAt: null - bookingEndsAt: '2022-08-23T14:00:00Z' - examStartsAt: '2022-08-29T08:00:00Z' - examEndsAt: '2022-08-29T10:00:00Z' - bookedCount: 12 - availableCount: 8 - moduleNumber: 1 - notes: null - places: [] - isReschedulable: false - question: null - feedback: Esiste già una prenotazione per l'esame in questione - requestReason: null - requestDetails: null - - id: 887981 - courseId: 262789 - courseShortcode: 01NYHOV - courseName: System and device programming (AA-ZZ) - teacherId: 2893 - type: Esami scritti a risposta aperta o chiusa tramite PC - status: available - bookingStartsAt: null - bookingEndsAt: '2022-09-02T14:00:00Z' - examStartsAt: '2022-09-08T14:00:00Z' - examEndsAt: '2022-09-08T18:00:00Z' - bookedCount: 42 - availableCount: 108 - moduleNumber: 1 - notes: null - places: [] - isReschedulable: false - question: null - feedback: null - requestReason: null - requestDetails: null - - id: 888212 - courseId: 217742 - courseShortcode: 03LPYOV - courseName: Cryptography (AA-ZZ) - teacherId: 13461 - type: Esami scritti a risposta aperta o chiusa tramite PC - status: booked - bookingStartsAt: null - bookingEndsAt: '2022-09-12T14:00:00Z' - examStartsAt: '2022-09-16T11:00:00Z' - examEndsAt: '2022-09-16T13:00:00Z' - bookedCount: 67 - availableCount: 8 - moduleNumber: 1 - notes: null - places: [] - isReschedulable: false - question: null - feedback: Esiste già una prenotazione per l'esame in questione - requestReason: null - requestDetails: null - - id: 888118 - courseId: 217742 - courseShortcode: 01TYAOV - courseName: Security verification and testing (AA-ZZ) - teacherId: 1943 - type: Esami scritti a risposta aperta o chiusa tramite PC - status: booked - bookingStartsAt: null - bookingEndsAt: '2022-09-09T14:00:00Z' - examStartsAt: '2022-09-15T14:00:00Z' - examEndsAt: '2022-09-15T16:00:00Z' - bookedCount: 26 - availableCount: 108 - moduleNumber: 1 - notes: null - places: [] - isReschedulable: false - question: null - feedback: Esiste già una prenotazione per l'esame in questione - requestReason: null - requestDetails: null - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /exams/{examId}/booking: - post: - tags: - - Exams - summary: Book exam | Prenota esame - operationId: bookExam - parameters: - - name: examId - in: path - required: true - schema: - type: integer - requestBody: - content: - application/json: - schema: - type: object - properties: - courseShortcode: - type: string - description: The course shortcode - example: 01UDROV - questionId: - type: integer - description: The id of the question - example: 123456 - questionOption: - type: integer - description: The index of the chosen option (starting at 1) - example: 1 - requestReason: - type: string - description: The reason for the exam booking request - example: "I'm not sure" - required: [ courseShortcode ] - required: true - responses: - 200: - description: Success - 400: - $ref: '#/components/responses/BadRequestResponse' - 404: - description: Exam not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - delete: - tags: - - Exams - summary: Delete exam booking | Annulla prenotazione esame - operationId: deleteExamBookingById - parameters: - - name: examId - in: path - required: true - schema: - type: integer - responses: - 200: - description: Success - 404: - description: Exam or booking not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /exams/{examId}/rescheduleRequest: - post: - tags: - - Exams - summary: Ask to reschedule an exam | Chiedi di spostare un esame - operationId: rescheduleExam - parameters: - - name: examId - in: path - required: true - schema: - type: integer - requestBody: - content: - application/json: - schema: - type: object - properties: - courseShortcode: - type: string - description: The course shortcode - example: 01UDROV - requestReason: - type: string - description: The reason for the exam booking request - example: "Nei giorni dell'appello ho i Campionati Italiani di nuoto" - requestDetails: - type: string - description: The proposed dates for the exam - example: "Io potrei sostenerlo prima del 15 febbraio oppure dopo il 21" - required: [ courseShortcode, requestReason, requestDetails ] - required: true - responses: - 200: - description: Success - 400: - $ref: '#/components/responses/BadRequestResponse' - 404: - description: Exam not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /lectures: - get: - tags: - - Lectures - parameters: - - name: fromDate - in: query - description: First day - defaults to 7 days before today - required: false - schema: - type: string - format: date - - name: toDate - in: query - description: Last day - defaults to 7 days after today - required: false - schema: - type: string - format: date - - name: courseIds[] - in: query - description: Only include lectures belonging to these courses - required: false - schema: - type: array - items: - type: number - summary: List lectures | Elenca lezioni - operationId: getLectures - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/Lecture' - required: [ data ] - example: - data: - - id: 12131312 - startsAt: "2021-09-28T14:30:00Z" - endsAt: "2021-09-28T17:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ - { - id: 149336, - title: "CYB / lecture 28.09.2021 (TLS, slides 1-40)" - } - ] - - id: 12131313 - startsAt: "2021-10-01T10:00:00Z" - endsAt: "2021-10-01T11:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ - { - id: 150397, - title: "CYB / lecture 01.10.2021 (TLS, slides 41-55)" - } - ] - - id: 12131314 - startsAt: "2021-10-05T14:30:00Z" - endsAt: "2021-10-05T17:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131315 - startsAt: "2021-10-08T10:00:00Z" - endsAt: "2021-10-08T11:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Esercitazione aula - description: Demos about TLS and SSH. Introduction to the laboratory. - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131316 - startsAt: "2021-10-12T08:30:00Z" - endsAt: "2021-10-12T10:00:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131317 - startsAt: "2021-10-12T10:00:00Z" - endsAt: "2021-10-12T11:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131318 - startsAt: "2021-10-12T14:30:00Z" - endsAt: "2021-10-12T17:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131319 - startsAt: "2021-10-15T10:00:00Z" - endsAt: "2021-10-15T11:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131320 - startsAt: "2021-10-19T08:30:00Z" - endsAt: "2021-10-19T10:00:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131321 - startsAt: "2021-10-19T10:00:00Z" - endsAt: "2021-10-19T11:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131322 - startsAt: "2021-10-19T14:30:00Z" - endsAt: "2021-10-19T17:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131323 - startsAt: "2021-10-22T10:00:00Z" - endsAt: "2021-10-22T11:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131324 - startsAt: "2021-10-26T08:30:00Z" - endsAt: "2021-10-26T10:00:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131325 - startsAt: "2021-10-26T10:00:00Z" - endsAt: "2021-10-26T11:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131326 - startsAt: "2021-10-26T14:30:00Z" - endsAt: "2021-10-26T17:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131327 - startsAt: "2021-11-02T08:30:00Z" - endsAt: "2021-11-02T10:00:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131328 - startsAt: "2021-11-02T10:00:00Z" - endsAt: "2021-11-02T11:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131329 - startsAt: "2021-11-02T14:30:00Z" - endsAt: "2021-11-02T17:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131330 - startsAt: "2021-11-05T10:00:00Z" - endsAt: "2021-11-05T11:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131331 - startsAt: "2021-11-09T08:30:00Z" - endsAt: "2021-11-09T10:00:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Esercitazione Laboratorio con titolo esageratamente lungo che poi boh - description: "squadra 1" - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131332 - startsAt: "2021-11-09T10:00:00Z" - endsAt: "2021-11-09T11:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Esercitazione Laboratorio - description: "squadra 1" - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131333 - startsAt: "2021-11-09T14:30:00Z" - endsAt: "2021-11-09T17:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131334 - startsAt: "2021-11-16T08:30:00Z" - endsAt: "2021-11-16T10:00:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Esercitazione Laboratorio - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131335 - startsAt: "2021-11-16T10:00:00Z" - endsAt: "2021-11-16T11:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Esercitazione Laboratorio - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131336 - startsAt: "2021-11-16T14:30:00Z" - endsAt: "2021-11-16T17:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131337 - startsAt: "2021-11-23T08:30:00Z" - endsAt: "2021-11-23T10:00:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Esercitazione Laboratorio - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131338 - startsAt: "2021-11-23T10:00:00Z" - endsAt: "2021-11-23T11:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Esercitazione Laboratorio - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131339 - startsAt: "2021-11-23T14:30:00Z" - endsAt: "2021-11-23T17:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131340 - startsAt: "2021-11-30T08:30:00Z" - endsAt: "2021-11-30T10:00:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Esercitazione Laboratorio - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131341 - startsAt: "2021-11-30T10:00:00Z" - endsAt: "2021-11-30T11:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Esercitazione Laboratorio - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131342 - startsAt: "2021-11-30T14:30:00Z" - endsAt: "2021-11-30T17:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Esercitazione aula - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131343 - startsAt: "2021-12-03T10:00:00Z" - endsAt: "2021-12-03T11:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131344 - startsAt: "2021-12-07T08:30:00Z" - endsAt: "2021-12-07T10:00:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131345 - startsAt: "2021-12-07T10:00:00Z" - endsAt: "2021-12-07T11:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131346 - startsAt: "2021-12-07T14:30:00Z" - endsAt: "2021-12-07T17:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131347 - startsAt: "2021-12-10T10:00:00Z" - endsAt: "2021-12-10T11:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131348 - startsAt: "2021-12-14T08:30:00Z" - endsAt: "2021-12-14T10:00:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131349 - startsAt: "2021-12-14T10:00:00Z" - endsAt: "2021-12-14T11:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131350 - startsAt: "2021-12-14T14:30:00Z" - endsAt: "2021-12-14T17:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - - id: 12131351 - startsAt: "2021-12-17T10:00:00Z" - endsAt: "2021-12-17T11:30:00Z" - place: - buildingId: TO_CIT22 - floorId: XPTE - name: Aula 1P - roomId: '036' - siteId: TO_CIT - type: Lezione / Esercitazione - description: - courseId: 252258 - courseName: Human Computer Interaction - teacherId: 1847 - virtualClassrooms: [ ] - 400: - $ref: '#/components/responses/BadRequestResponse' - - /esc: - get: - tags: - - Esc - summary: retreive european student card | recupera la european student card - operationId: escGet - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/EuropeanStudentCard' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - 404: - description: Card not found - 500: - $ref: '#/components/responses/ErrorResponse' - delete: - tags: - - Esc - summary: Delete all Student data on the ESC-Router (and all student's cards) | Cancella tutti i dati dello studente sul Router ESC (e tutte le carte dello studente) - operationId: escDelete - responses: - 204: - description: Success - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorEscResponse' - - /esc/create: - post: - tags: - - Esc - summary: request european student card | richiedi la european student card - operationId: escRequest - responses: - 201: - description: Success - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /news: - get: - tags: - - News - summary: List news | Lista news - operationId: getNews - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/NewsItemOverview' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - - /news/{newsItemId}: - get: - tags: - - News - summary: Show news | Mostra news - operationId: getNewsItem - parameters: - - name: newsItemId - in: path - required: true - schema: - type: number - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/NewsItem' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - - /people: - get: - tags: - - People - summary: Search people | Cerca persone - operationId: getPeople - parameters: - - name: search - in: query - description: Filter people containing 'search' in their full name - required: true - schema: - type: string - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/PersonOverview' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /people/{personId}: - get: - tags: - - People - summary: Show person | Mostra persona - operationId: getPerson - parameters: - - name: personId - in: path - required: true - schema: - type: number - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/Person' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - 404: - description: Person not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /v2/place-categories: - get: - tags: - - Places - summary: List place categories | Elenca categorie luoghi - operationId: getPlaceCategories - parameters: - - $ref: '#/components/parameters/querySiteId' - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/RootPlaceCategory' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /v2/sites: - get: - tags: - - Places - summary: List sites | Elenca sedi - operationId: getSites - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/Site' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /v2/sites/{siteId}/free-rooms: - get: - tags: - - Places - summary: List free rooms | Elenca aule libere - operationId: getFreeRooms - parameters: - - name: date - in: query - description: Date - required: true - schema: - type: string - - name: timeFrom - in: query - description: Start time - required: true - schema: - type: string - - name: timeTo - in: query - description: End time - required: true - schema: - type: string - - $ref: '#/components/parameters/pathSiteId' - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/FreeRoom' - required: [ data ] - 404: - description: Site|Building|Floor not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /v2/sites/{siteId}/buildings: - get: - tags: - - Places - summary: List buildings | Elenca edifici - operationId: getBuildings - parameters: - - $ref: '#/components/parameters/pathSiteId' - - name: search - in: query - description: Filter buildings containing 'search' in their name - schema: - type: string - - $ref: '#/components/parameters/queryPlaceCategoryId' - - $ref: '#/components/parameters/queryPlaceSubCategoryId' - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/Building' - required: [ data ] - 404: - description: Site not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /v2/places: - get: - tags: - - Places - summary: Search places | Cerca luoghi - operationId: getPlaces - parameters: - - name: search - in: query - description: Filter places containing 'search' in their name - schema: - type: string - - $ref: '#/components/parameters/queryPlaceCategoryId' - - $ref: '#/components/parameters/queryPlaceSubCategoryId' - - $ref: '#/components/parameters/querySiteId' - - $ref: '#/components/parameters/queryBuildingId' - - $ref: '#/components/parameters/queryFloorId' - - $ref: '#/components/parameters/queryDepartmentId' - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/PlaceOverview' - required: [ data ] - 404: - description: Site|Building|Floor not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /v2/places/{placeId}: - get: - tags: - - Places - summary: Show place | Mostra luogo - operationId: getPlace - parameters: - - $ref: '#/components/parameters/pathPlaceId' - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/Place' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - - - /departments: - get: - tags: - - Places - summary: List departments | Elenca dipartimenti - operationId: getDepartments - parameters: - - $ref: '#/components/parameters/querySiteId' - - $ref: '#/components/parameters/queryDepartmentType' - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/Department' - required: [ data ] - example: - data: - - id: DAUIN - name: Dipartimento di Automatica e Informatica - type: DIP. - - id: DIMEAS - name: Dipartimento di Ingegneria Meccanica e Aerospaziale - type: DIP. - 404: - description: Site not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /messages: - get: - tags: - - Student - summary: List messages | Elenca messaggi - operationId: getMessages - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/Message' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /messages/{messageId}: - delete: - tags: - - Student - summary: Delete a message | Cancella un messaggio - operationId: deleteMessage - parameters: - - $ref: '#/components/parameters/messageIdParam' - responses: - 200: - description: Success - 404: - description: Message not found - 500: - $ref: '#/components/responses/ErrorResponse' - - /messages/{messageId}/read: - put: - tags: - - Student - summary: Mark a message as read | Segna un messaggio come letto - operationId: markMessageAsRead - parameters: - - $ref: '#/components/parameters/messageIdParam' - responses: - 200: - description: Success - 404: - description: Message not found - 500: - $ref: '#/components/responses/ErrorResponse' - - /notifications: - get: - tags: - - Student - summary: List notifications | Elenca notifiche - operationId: getNotifications - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/Notification' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /notifications/preferences: - get: - tags: - - Student - summary: Get notification preferences | Ottieni preferenze notifiche - operationId: getNotificationPreferences - responses: - 200: - description: Success - content: - application/json: - schema: - $ref: '#/components/schemas/NotificationPreferences' - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - patch: - tags: - - Student - summary: Update notification preferences | Aggiorna preferenze notifiche - operationId: updateNotificationPreferences - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/UpdateNotificationPreferencesRequest' - responses: - 200: - description: Success - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /notifications/{notificationId}: - delete: - tags: - - Student - summary: Delete a notification | Cancella una notifica - operationId: deleteNotification - parameters: - - $ref: '#/components/parameters/notificationIdParam' - responses: - 200: - description: Success - 404: - description: Notification not found - 500: - $ref: '#/components/responses/ErrorResponse' - - /notifications/{notificationId}/read: - put: - tags: - - Student - summary: Mark a notification as read | Segna una notifica come letta - operationId: markNotificationAsRead - parameters: - - $ref: '#/components/parameters/notificationIdParam' - responses: - 200: - description: Success - 404: - description: Notification not found - 500: - $ref: '#/components/responses/ErrorResponse' - - /preferences: - patch: - tags: - - Student - summary: Update device preferences | Aggiorna preferenze del dispositivo - operationId: updateDevicePreferences - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/UpdatePreferencesRequest' - responses: - 200: - description: Success - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /ticket-faqs: - get: - tags: - - Tickets - summary: Search ticket FAQs | Ricerca FAQ ticket - operationId: searchTicketFAQs - parameters: - - $ref: '#/components/parameters/acceptLanguageHeader' - - name: search - in: query - description: Find FAQs containing 'search' in the question - required: true - schema: - type: string - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/TicketFAQ' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /ticket-topics: - get: - tags: - - Tickets - summary: List ticket topics | Elenca ambiti ticket - operationId: getTicketTopics - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/TicketTopic' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /tickets: - get: - tags: - - Tickets - summary: List tickets | Elenca ticket - operationId: getTickets - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/TicketOverview' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - post: - tags: - - Tickets - summary: Create ticket | Crea ticket - operationId: createTicket - requestBody: - content: - multipart/form-data: - schema: - $ref: '#/components/schemas/CreateTicketRequest' - required: true - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/TicketOverview' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - 500: - $ref: '#/components/responses/ErrorResponse' - - /tickets/{ticketId}: - get: - tags: - - Tickets - summary: Show a ticket | Mostra un ticket - operationId: getTicket - parameters: - - $ref: '#/components/parameters/ticketIdParam' - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/Ticket' - required: [ data ] - 404: - description: Ticket not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /tickets/{ticketId}/read: - put: - tags: - - Tickets - summary: Mark a ticket as read | Segna un ticket come letto - operationId: markTicketAsRead - parameters: - - $ref: '#/components/parameters/ticketIdParam' - responses: - 200: - description: Success - 404: - description: Ticket not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /tickets/{ticketId}/close: - put: - tags: - - Tickets - summary: Mark a ticket as closed | Segna un ticket come chiuso - operationId: markTicketAsClosed - parameters: - - $ref: '#/components/parameters/ticketIdParam' - responses: - 200: - description: Success - 404: - description: Ticket not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /tickets/{ticketId}/attachments/{attachmentId}: - get: - tags: - - Tickets - summary: Download ticket attachment | Scarica allegato del ticket - operationId: getTicketAttachment - parameters: - - $ref: '#/components/parameters/ticketIdParam' - - $ref: '#/components/parameters/ticketAttachmentIdParam' - responses: - 200: - description: Attachment - content: - application/octet-stream: - schema: - type: string - format: binary - 302: - description: Redirect to attachment download - 404: - description: Ticket or attachment not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /tickets/{ticketId}/replies: - post: - tags: - - Tickets - summary: Reply to a ticket | Rispondi ad un ticket - operationId: replyToTicket - parameters: - - $ref: '#/components/parameters/ticketIdParam' - requestBody: - content: - multipart/form-data: - schema: - $ref: '#/components/schemas/ReplyTicketRequest' - required: true - responses: - 200: - description: Success - 404: - description: Ticket not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /tickets/{ticketId}/replies/{replyId}/attachments/{attachmentId}: - get: - tags: - - Tickets - summary: Download ticket reply attachment | Scarica allegato di una risposta al ticket - operationId: getTicketReplyAttachment - parameters: - - $ref: '#/components/parameters/ticketIdParam' - - $ref: '#/components/parameters/ticketReplyIdParam' - - $ref: '#/components/parameters/ticketAttachmentIdParam' - responses: - 200: - description: Attachment - content: - application/octet-stream: - schema: - type: string - format: binary - 302: - description: Redirect to attachment download - 404: - description: Ticket or attachment not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /job-offers: - get: - tags: - - Job offers - summary: List job offers | Elenca offerte di lavoro - operationId: getJobOffers - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/JobOfferOverview' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - - /job-offers/{jobOfferId}: - get: - tags: - - Job offers - parameters: - - $ref: '#/components/parameters/jobOfferIdParam' - summary: Show a job offer | Mostra un'offerta di lavoro - operationId: getJobOffer - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/JobOffer' - required: [ data ] - 404: - description: Job offer not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /offering: - get: - tags: - - Offering - summary: Get offering | Mostra offerta formativa - operationId: getOffering - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: object - properties: - bachelor: - type: array - items: - $ref: '#/components/schemas/OfferingClass' - master: - type: array - items: - $ref: '#/components/schemas/OfferingClass' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - - /offering/degrees/{degreeId}: - get: - tags: - - Offering - parameters: - - $ref: '#/components/parameters/degreeIdParam' - - $ref: '#/components/parameters/yearQueryParam' - summary: Show a degree | Mostra un corso di laurea - operationId: getOfferingDegree - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/Degree' - required: [ data ] - 404: - description: Degree not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /offering/courses/{courseShortcode}: - get: - tags: - - Offering - parameters: - - $ref: '#/components/parameters/courseShortcodeParam' - - $ref: '#/components/parameters/yearQueryParam' - summary: Show offering course | Mostra corso dell'offerta formativa - operationId: getOfferingCourse - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/OfferingCourse' - required: [ data ] - 404: - description: Course not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /offering/courses/{courseShortcode}/statistics: - get: - tags: - - Offering - parameters: - - $ref: '#/components/parameters/courseShortcodeParam' - - $ref: '#/components/parameters/yearQueryParam' - - $ref: '#/components/parameters/teacherIdQueryParam' - summary: Retrieve course statistics | Recupera le statistiche dell'insegnamento - operationId: getCourseStatistics - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - $ref: '#/components/schemas/CourseStatistics' - required: [ data ] - 404: - description: Course not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - 500: - $ref: '#/components/responses/ErrorResponse' - - /guides: - get: - tags: - - Student - summary: Get guides | Mostra guide - operationId: getGuides - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/Guide' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - - /surveys: - get: - tags: - - Surveys - summary: Get surveys | Mostra survey - operationId: getSurveys - responses: - 200: - description: Success - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/Survey' - required: [ data ] - 400: - $ref: '#/components/responses/BadRequestResponse' - -components: - parameters: - courseIdParam: - name: courseId - in: path - required: true - schema: - type: integer - assignmentIdParam: - name: assignmentId - in: path - required: true - schema: - type: integer - messageIdParam: - name: messageId - in: path - required: true - schema: - type: integer - notificationIdParam: - name: notificationId - in: path - required: true - schema: - type: integer - pathSiteId: - name: siteId - in: path - required: true - schema: - type: string - provisionalGradeIdParam: - name: provisionalGradeId - in: path - required: true - schema: - type: integer - queryPlaceCategoryId: - name: placeCategoryId - in: query - required: false - schema: - type: string - queryPlaceSubCategoryId: - name: placeSubCategoryId[] - in: query - required: false - schema: - type: array - items: - type: string - querySiteId: - name: siteId - in: query - required: false - schema: - type: string - queryBuildingId: - name: buildingId - in: query - required: false - schema: - type: string - queryFloorId: - name: floorId - in: query - required: false - schema: - type: string - queryDepartmentId: - name: departmentId - in: query - required: false - schema: - type: string - queryDepartmentType: - name: departmentType - in: query - required: false - schema: - type: string - - pathPlaceId: - name: placeId - in: path - required: true - schema: - type: string - ticketIdParam: - name: ticketId - in: path - required: true - schema: - type: integer - ticketReplyIdParam: - name: replyId - in: path - required: true - schema: - type: integer - ticketAttachmentIdParam: - name: attachmentId - in: path - required: true - schema: - type: integer - acceptLanguageHeader: - name: Accept-Language - in: header - schema: - type: string - enum: [ it, en ] - default: it - jobOfferIdParam: - name: jobOfferId - in: path - required: true - schema: - type: integer - degreeIdParam: - name: degreeId - in: path - required: true - schema: - type: string - example: '81-6' - courseShortcodeParam: - name: courseShortcode - in: path - required: true - schema: - type: string - yearQueryParam: - name: year - in: query - required: false - schema: - type: string - example: 2022 - teacherIdQueryParam: - name: teacherId - in: query - required: false - schema: - type: string - example: 1843 - - responses: - ErrorResponse: - description: Server error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - ErrorEscResponse: - description: Server error - content: - application/json: - schema: - allOf: - - $ref: '#/components/schemas/Error' - - type: object - properties: - errors: - type: array - description: Additional error details - items: - $ref: '#/components/schemas/EscError' - example: - - code: 500 - message: "An error occurred" - careerId: "123456" - - BadRequestResponse: - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - securitySchemes: - bearerAuth: - type: http - scheme: bearer - - schemas: - Identity: - type: object - properties: - username: - type: string - example: 's290683' - type: - type: string - example: 'student' - clientId: - type: string - example: '5a54f626-4b7e-488e-a0e3-300f54051510' - token: - type: string - example: c679fa38ff665df6a676acd833194385 - required: [ username, type, clientId, token ] - - Student: - type: object - properties: - username: - type: string - example: 's290683' - firstName: - type: string - example: Luca - lastName: - type: string - example: Pezzolla - status: - type: string - enum: - - active - - closed - - cancelled - - graduated - - career_closed - allCareerIds: - description: All the ids related to this student - type: array - items: - type: string - example: "213956" - example: [ "290683", "213956" ] - degreeId: - type: string - example: '81-6' - degreeCode: - type: string - example: LM-32 - degreeLevel: - type: string - example: Corso di Laurea Magistrale in - degreeName: - type: string - example: INGEGNERIA INFORMATICA (COMPUTER ENGINEERING) - firstEnrollmentYear: - type: integer - example: 2021 - lastEnrollmentYear: - type: integer - example: 2022 - isCurrentlyEnrolled: - type: boolean - example: false - averageGrade: - type: number - nullable: true - example: 18.42 - estimatedFinalGrade: - type: number - nullable: true - example: 99.99 - averageGradePurged: - description: Purged grade is only available for bachelor degree students - type: number - nullable: true - example: null - estimatedFinalGradePurged: - description: Purged grade is only available for bachelor degree students - type: number - nullable: true - example: null - usePurgedAverageFinalGrade: - description: Specify whether to use purgedAverageFinalGrade or averageFinalGrade as the graduation grade shown - type: boolean - nullable: false - example: true - mastersAdmissionAverageGrade: - description: Master's admission grade is only available for bachelor degree students - type: number - nullable: true - example: null - totalOnTimeExamPoints: - description: Total points for "on-time" exams - null if "on-time" exams are not applicable for the student's position (max value = maxOnTimeExamPoints) - type: number - nullable: true - example: 0 - maxOnTimeExamPoints: - description: Maximum points for "on-time" exams - type: number - nullable: false - example: 4 - excludedCreditsNumber: - description: Credits excluded from calculating the purged grade - type: number - nullable: true - example: 16 - totalCredits: - type: integer - example: 126 - totalAttendedCredits: - type: integer - example: 126 - totalAcquiredCredits: - type: integer - example: 68 - enrollmentCredits: - type: integer - example: 86 - enrollmentAttendedCredits: - type: integer - example: 86 - enrollmentAcquiredCredits: - type: integer - example: 28 - smartCardPicture: - type: string - example: https:// - nullable: true - europeanStudentCard: - $ref: '#/components/schemas/EuropeanStudentCard' - required: - - username - - firstName - - lastName - - status - - allCareerIds - - degreeId - - degreeCode - - degreeLevel - - degreeName - - firstEnrollmentYear - - lastEnrollmentYear - - isCurrentlyEnrolled - - averageGrade - - estimatedFinalGrade - - averageGradePurged - - estimatedFinalGradePurged - - usePurgedAverageFinalGrade - - mastersAdmissionAverageGrade - - totalOnTimeExamPoints - - maxOnTimeExamPoints - - excludedCreditsNumber - - totalCredits - - totalAttendedCredits - - totalAcquiredCredits - - enrollmentCredits - - enrollmentAttendedCredits - - enrollmentAcquiredCredits - - smartCardPicture - - europeanStudentCard - - Deadline: - type: object - properties: - id: - type: number - example: 42 - name: - type: string - example: Chiusura del periodo per cambio di ordinamento e/o corso di studi - type: - type: string - example: Trasferimenti e valutazioni carriere precedenti - url: - type: string - nullable: true - example: https://didattica.polito.it/guida/2021/it/passaggi_interni_su_corsi_di_laurea_magistrale?cds=28&sdu=32 - date: - type: string - format: date - example: '2022-08-31' - required: [ name, type, url, date ] - - ExamGrade: - type: object - properties: - courseName: - type: string - example: Human Computer Interaction - credits: - type: number - example: 6 - grade: - type: string - example: "27" - date: - type: string - format: date - example: '2022-05-15' - teacherId: - type: integer - nullable: true - example: 2893 - onTimeExamPoints: - description: Points for "on-time" exams - null the student is not eligible for on-time exams or the exam does not grant on-time points - type: number - nullable: true - example: 0.5 - shortcode: - type: string - example: '02JSKOV' - academicYear: - type: integer - example: 2022 - creditsCountTowardsDegree: - description: Defines whether the credits from the exam count toward the total required for graduation - type: boolean - example: true - required: [ courseName, credits, grade, date, teacherId, onTimeExamPoints, creditsCountTowardsDegree, shortcode, academicYear ] - - ProvisionalGrade: - type: object - properties: - id: - type: number - example: 5817523 - examId: - type: number - example: 903380 - courseShortcode: - type: string - example: 02JSKOV - courseName: - type: string - example: Human Computer Interaction - teacherId: - type: integer - example: 2154 - credits: - type: number - example: 6 - grade: - type: string - example: "27" - date: - type: string - format: date - example: '2022-05-15' - state: - type: string - enum: [ published, confirmed, rejected ] - stateDescription: - type: string - example: Pubblicato - teacherMessage: - type: string - nullable: true - example: sono disponibili aggiornamenti dei risultati relativi all'appello del 26/06/2023 per l'insegnamento Il processo logistico (02TGJRY). Alstom mi ha appena trasmesso la valutazione della parte di formazione svolta in azienda (Flusso fisico e contabile di materiale) e, alla luce dell'ottimo giudizio che avete ricevuto, ho ritenuto opportuno confermare i voti conseguiti durante lo svolgimento del case study in aula e già comunicati al termine del mio corso. La registrazione di questi voti verrà consolidata la prossima settimana. - isWithdrawn: - type: boolean - example: false - isFailure: - type: boolean - example: false - canBeAccepted: - type: boolean - example: true - canBeRejected: - type: boolean - example: true - confirmedAt: - type: string - format: date - nullable: true - rejectedAt: - type: string - format: date-time - nullable: true - rejectingExpiresAt: - type: string - format: date-time - nullable: false - required: [ id, examId, courseShortcode, courseName, teacherId, credits, grade, date, state, stateDescription, teacherMessage, isWithdrawn, isFailure, canBeAccepted, canBeRejected, confirmedAt, rejectedAt, rejectingExpiresAt ] - - ProvisionalGradeState: - type: object - properties: - id: - type: string - example: published - name: - type: string - example: Provvisorio - description: - type: string - example: La valutazione e consolidata. Il docente non ha piu la possibilita di modificarla. Dal momento del consolidamento lo studente ha 48h per esercitare il rifiuto del voto - required: [ id, name, description ] - - EuropeanStudentCard: - type: object - properties: - canBeRequested: - type: boolean - example: false - details: - type: object - properties: - status: - type: string - enum: - - active - - inactive - - expired - example: active - inactiveStatusReason: - description: Reason why the card is inactive (null if the card is active) - type: string - nullable: true - example: 'null' - cardNumber: - type: string - example: 'f74047b0-2108-103d-8ae-001999977754' - expiresAt: - type: string - example: '2024-12-31T22:59:59.000+0000' - qrCode: - type: string - example: 'iVBORw0KGgoAAAANSUhEUgAAADIAAAAyAQAAAAA2RLUcAAAAr0lEQVR4XmP4DwYHGKhGH0hVZATR96OW14Loi87vXcF04k4IHSkLpu/7dILlD4SGgtX/P8kN1n/a6LowiH7/zSUXRN9MK1oMog/OMFcGq4tTzwTR36Y7fQfLSz/bCKI/Hen0BtHHypVeg+hXTU/A5t/hD9EE0X/f6u0E0ZejroiDzbkfexFsf1hsNIi+n/cRzL9YlCILpv3c+MF08aGzYPkg1dtg9dEOYPXo/qYODQD15Rx9h0NUJAAAAABJRU5ErkJggg==' - nullable: true - required: [ status, inactiveStatusReason, cardNumber, expiresAt, qrCode ] - required: [ canBeRequested, details ] - - BookingTopicLeaf: - type: object - properties: - disclaimer: - type: string - example: '' - showCalendar: - type: boolean - slotLength: - type: integer - example: 15 - slotsPerHour: - type: integer - example: 4 - startDate: - type: string - format: date - example: 2022-05-15 - nullable: true - description: Start date of the booking period - startHour: - type: integer - example: 9 - endHour: - type: integer - example: 18 - maxBookingsPerDay: - type: integer - example: 1 - canBeCancelled: - type: boolean - example: true - daysPerWeek: - type: integer - example: 1 - description: Number of days per week the booking is available, starting from startDate weekday, or monday if missing - agendaView: - type: boolean - example: false - description: Specifies if the topic requires the agenda display - required: [ disclaimer, showCalendar, slotLength, slotsPerHour, startDate, startHour, endHour, maxBookingsPerDay, canBeCancelled, daysPerWeek, agendaView ] - - BookingTopic: - allOf: - - $ref: '#/components/schemas/BookingTopicLeaf' - - type: object - properties: - id: - type: string - example: DIDATTICA_ING - title: - type: string - example: Segreteria Didattica Ingegneria - description: - type: string - example: Servizi della Segreteria Didattica Ingegneria - isEnabled: - type: boolean - example: true - subtopics: - type: array - items: - $ref: '#/components/schemas/BookingSubtopic' - required: [ id, title, description, isEnabled, subtopics ] - - BookingSubtopic: - allOf: - - $ref: '#/components/schemas/BookingTopicLeaf' - - type: object - properties: - id: - type: string - example: DID_ING_VC_EN - title: - type: string - example: Aspetti didattici di carriera - Sportello virtuale in inglese - description: - type: string - example: '' - isEnabled: - type: boolean - example: true - requirements: - type: array - items: - type: object - properties: - name: - type: string - example: Informativa Emergenza COVID-19 - url: - type: string - example: https://didattica.polito.it/pdf/informativa_covid.pdf - required: [ id, title, description, isEnabled, requirements ] - - BookingSlot: - type: object - properties: - id: - type: integer - example: 103051 - description: - type: string - example: '' - isBooked: - type: boolean - example: false - canBeBooked: - type: boolean - example: false - hasSeats: - type: boolean - example: false - hasSeatSelection: - type: boolean - example: false - places: - type: integer - example: 2 - bookedPlaces: - type: integer - example: 2 - feedback: - type: string - example: Il turno è pieno - location: - type: object - properties: - name: - type: string - example: Virtual Classroom della Segreteria Generale Studenti - description: - type: string - example: '' - type: - type: string - example: VC - address: - type: string - example: https://didattica.polito.it/pls/portal30/sviluppo.bbb_corsi.queueRoom?id=SEGRETERIA_GENERALE&p_tipo=SEGRETERIA_GENERALE - startsAt: - type: string - format: date-time - example: '2021-10-05T10:00:00Z' - endsAt: - type: string - format: date-time - example: '2021-10-05T10:15:00Z' - bookingStartsAt: - type: string - format: date-time - example: '2021-09-30T00:00:00Z' - bookingEndsAt: - type: string - format: date-time - example: '2021-10-04T16:00:00Z' - required: [ id, description, isBooked, canBeBooked, hasSeats, hasSeatSelection, places, bookedPlaces, feedback, location, startsAt, endsAt, bookingStartsAt, bookingEndsAt ] - - BookingSeats: - type: object - properties: - totalCount: - type: integer - example: 140 - availableCount: - type: integer - example: 42 - rows: - type: array - items: - $ref: '#/components/schemas/BookingSeatsRow' - required: [ totalCount, availableCount, rows ] - - BookingSeatsRow: - type: object - properties: - id: - type: integer - example: 2 - label: - type: string - example: B - seats: - type: array - items: - $ref: '#/components/schemas/BookingSeatCell' - required: [ label, seats ] - - BookingSeatCell: - type: object - properties: - id: - type: integer - example: 42 - status: - type: string - enum: - - available - - booked - - unavailable - label: - type: string - example: B12 - required: [ id, status, label ] - - BookingLocationCheck: - type: object - properties: - enabled: - type: boolean - example: true - checked: - type: boolean - example: false - latitude: - type: string - example: '45.0626340000000000' - nullable: true - longitude: - type: string - example: '7.6605410000000000' - nullable: true - radiusInKm: - type: number - example: 0.1 - nullable: true - required: [ enabled, checked, latitude, longitude, radiusInKm ] - - BookingPlaceRef: - allOf: - - $ref: '#/components/schemas/PlaceRef' - - type: object - properties: - type: - type: string - enum: - - place - description: - type: string - nullable: true - example: 'Description' - required: [ type, description ] - - BookingVirtualPlaceRef: - type: object - properties: - name: - type: string - example: Virtual Classroom della Segreteria Generale Studenti - type: - type: string - enum: - - virtualPlace - url: - type: string - example: https://didattica.polito.it/pls/portal30/sviluppo.bbb_corsi.queueRoom?id=SEGRETERIA_GENERALE&p_tipo=SEGRETERIA_GENERALE - required: [ name, type, url ] - - BookingTopicOverview: - type: object - properties: - id: - type: string - example: DIDATTICA_ING - title: - type: string - example: Segreteria Didattica Ingegneria - description: - type: string - example: Servizi della Segreteria Didattica Ingegneria - required: [ id, title, description ] - - BookingSubtopicOverview: - type: object - properties: - id: - type: string - example: DID_ING_VC_EN - title: - type: string - example: Aspetti didattici di carriera - Sportello virtuale in inglese - description: - type: string - example: '' - nullable: true - example: null - required: [ id, title, description ] - - Booking: - type: object - properties: - id: - type: integer - example: 258674 - description: - type: string - example: "" - topic: - $ref: '#/components/schemas/BookingTopicOverview' - subtopic: - $ref: '#/components/schemas/BookingSubtopicOverview' - startsAt: - type: string - format: date-time - example: '2021-10-05T10:00:00Z' - endsAt: - type: string - format: date-time - example: '2021-10-05T10:15:00Z' - seat: - type: object - nullable: true - properties: - id: - type: integer - example: 20018 - row: - type: string - example: A - column: - type: string - example: 05 - example: null - cancelableUntil: - type: string - format: date-time - example: '2021-10-05T10:00:00Z' - location: - oneOf: - - $ref: '#/components/schemas/BookingPlaceRef' - - $ref: '#/components/schemas/BookingVirtualPlaceRef' - discriminator: - propertyName: type - mapping: - place: '#/components/schemas/BookingPlaceRef' - virtualPlace: '#/components/schemas/BookingVirtualPlaceRef' - locationCheck: - $ref: '#/components/schemas/BookingLocationCheck' - - required: [ id, description, topic, subtopic, startsAt, endsAt, seat, cancelableUntil, location ] - - CourseOverview: - type: object - allOf: - - $ref: '#/components/schemas/CourseModule' - - type: object - properties: - cfu: - type: integer - example: 10 - shortcode: - type: string - example: 01NYHOV - modules: - type: array - items: - $ref: '#/components/schemas/CourseModule' - nullable: true - required: [ shortcode, modules, cfu ] - - CourseModule: - type: object - properties: - id: - type: integer - nullable: true - description: The identifier for the current instance of this course. If null this is not a teaching (such as thesis), it won't have a course page - example: 258674 - name: - type: string - example: System and device programming - teachingPeriod: - type: string - description: The semester(s) this course belongs to - example: 2-2 - teacherId: - type: integer - nullable: true - example: 2893 - teacherName: - type: string - nullable: true - example: Mario Rossi - previousEditions: - description: Previous editions of this course that were part of the student's PSP - type: array - items: - type: object - properties: - year: - type: string - example: '2021' - id: - type: integer - example: 244577 - required: [ year, id ] - isOverBooking: - type: boolean - example: false - isInPersonalStudyPlan: - type: boolean - description: Included in the PSP | Incluso nel carico didattico - example: true - year: - type: string - example: '2022' - required: [ id, name,teachingPeriod, teacherId, teacherName, previousEditions, isOverBooking, isInPersonalStudyPlan, year ] - - CoursePreferencesRequest: - type: object - properties: - notifications: - type: object - properties: - notices: - type: boolean - example: true - files: - type: boolean - example: true - lectures: - type: boolean - example: true - - Course: - type: object - properties: - id: - type: integer - nullable: true - description: The identifier for the current instance of this course. If null this is not a teaching (such as thesis), it won't have a course page - example: 258674 - name: - type: string - example: System and device programming - shortcode: - type: string - example: 01NYHOV - cfu: - type: integer - example: 10 - teachingPeriod: - type: string - description: The semester(s) this course belongs to - example: 2-2 - teacherId: - type: integer - nullable: true - example: 2893 - isOverBooking: - type: boolean - example: false - isInPersonalStudyPlan: - type: boolean - description: Included in the PSP | Incluso nel carico didattico - example: true - year: - type: string - example: '2022' - links: - type: array - items: - type: object - properties: - url: - type: string - example: 'https://docs.google.com/document/d/13hpWEDQxziSkhSU0PuqxMXntqZYp3ffDKZ2-umQ7Ywo/edit?usp=sharing' - description: - type: string - example: 'Calendario settimanale dei contenuti del corso' - required: [ url ] - moodleCourses: - type: array - items: - type: object - properties: - name: - type: string - example: Analisi Matematica I - id: - type: string - example: '645376' - nullable: true - vcPreviousYears: - type: array - items: - type: object - properties: - year: - type: string - example: '2021' - id: - type: integer - example: 244577 - required: [ year, id ] - vcOtherCourses: - description: Other editions/courses to be included in virtual classrooms - type: array - items: - type: object - properties: - year: - type: string - example: '2021' - name: - type: string - example: Fisica II - id: - type: integer - example: 247431 - required: [ year, name, id ] - notifications: - type: object - properties: - notices: - type: boolean - example: true - files: - type: boolean - example: true - lectures: - type: boolean - example: true - required: [ notices, files, lectures ] - staff: - type: array - items: - type: object - properties: - role: - type: string - id: - type: number - example: 244577 - required: [ role, id ] - required: [ id, name, shortcode, cfu, teachingPeriod, teacherId, isOverBooking, isInPersonalStudyPlan, year, links, moodleCourses, vcPreviousYears, vcOtherCourses, notifications, staff ] - - CourseAssignment: - type: object - properties: - id: - type: integer - example: 947503 - description: - type: string - example: laboratorio 3 - mimeType: - type: string - example: application/x-zip-compressed - filename: - type: string - example: lab_03.zip - uploadedAt: - type: string - format: date-time - example: 2022-09-02T14:00:00Z - deletedAt: - type: string - format: date-time - nullable: true - url: - type: string - example: https://file.didattica.polito.it/down/ELABORATI_PRE/1003948/S290683/6791f0016c78599138828211522fa84d/62cebc94 - sizeInKiloBytes: - type: integer - example: 305 - required: [ id, description, mimeType, filename, uploadedAt, deletedAt, url, sizeInKiloBytes ] - - CourseAssignmentUpload: - type: object - properties: - description: - type: string - example: laboratorio 3 - file: - type: string - format: binary - required: [ description, file ] - - UpdateAssignmentRequest: - type: object - properties: - deletedAt: - type: string - format: date-time - nullable: true - example: 2022-07-03T14:00:00Z - required: [ deletedAt ] - - CourseNotices: - type: object - properties: - id: - type: integer - example: 360724 - publishedAt: - type: string - format: date-time - example: 2022-07-03T14:00:00Z - expiresAt: - type: string - format: date-time - nullable: true - example: 2022-08-31T14:00:00Z - content: - type: string - example:

Conferma spostamento orario esame:

Ore 15

- required: [ id, publishedAt, expiresAt, content ] - - CourseGuideSection: - type: object - properties: - title: - type: string - example: Presentazione - content: - type: string - example: The course will cover the design and implementation of server-side - architectures... - required: [ title, content ] - - CourseDirectory: - allOf: - - $ref: '#/components/schemas/CourseDirectoryEntry' - - type: object - properties: - files: - $ref: '#/components/schemas/CourseDirectoryContent' - required: [ files ] - - CourseFileOverview: - allOf: - - $ref: '#/components/schemas/CourseDirectoryEntry' - - type: object - properties: - sizeInKiloBytes: - type: integer - example: 305 - mimeType: - type: string - example: application/x-zip-compressed - createdAt: - type: string - format: date-time - example: 2022-08-31T14:00:00Z - required: [ sizeInKiloBytes, mimeType, createdAt ] - - CourseDirectoryEntry: - type: object - properties: - type: - type: string - enum: - - directory - - file - id: - type: string - example: '33352562' - name: - type: string - example: Laboratori - required: [ id, type, name ] - - CourseDirectoryContent: - type: array - items: - oneOf: - - $ref: '#/components/schemas/CourseDirectory' - - $ref: '#/components/schemas/CourseFileOverview' - discriminator: - propertyName: type - mapping: - directory: '#/components/schemas/CourseDirectory' - file: '#/components/schemas/CourseFileOverview' - - Teacher: - type: object - properties: - id: - type: integer - firstName: - type: string - lastName: - type: string - required: [ id, firstName, lastName ] - - GradeCount: - type: object - properties: - grade: - type: string - enum: [ '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '30L' ] - count: - type: integer - required: [ grade, count ] - - YearStatistics: - type: object - properties: - succeeded: - type: integer - failed: - type: integer - grades: - type: array - items: - $ref: '#/components/schemas/GradeCount' - averageGrade: - type: number - nullable: true - example: 18.01 - required: [ succeeded, failed, grades, averageGrade ] - - PreviousYearsToCompare: - type: object - properties: - year: - type: integer - succeeded: - type: integer - failed: - type: integer - required: [ year, succeeded, failed ] - - CourseStatistics: - type: object - properties: - shortcode: - type: string - year: - type: integer - teacher: - $ref: '#/components/schemas/Teacher' - totalEnrolled: - type: integer - totalSucceeded: - type: integer - totalFailed: - type: integer - firstYear: - $ref: '#/components/schemas/YearStatistics' - otherYears: - $ref: '#/components/schemas/YearStatistics' - previousYearsToCompare: - type: array - items: - $ref: '#/components/schemas/PreviousYearsToCompare' - years: - type: array - items: - type: integer - teachers: - type: array - items: - $ref: '#/components/schemas/Teacher' - required: [ shortcode, year, teacher, totalEnrolled, totalSucceeded, totalFailed, firstYear, otherYears, previousYearsToCompare, years, teachers ] - - Exam: - type: object - properties: - id: - type: integer - example: 888122 - courseId: - type: number - example: 262147 - courseShortcode: - type: string - example: 02JSKOV - courseName: - type: string - example: Human Computer Interaction - teacherId: - type: integer - example: 2154 - type: - type: string - example: Esami scritti a risposta aperta o chiusa tramite PC - places: - type: array - items: - $ref: '#/components/schemas/PlaceRef' - status: - type: string - example: available - enum: - - available - - booked - - requestable - - requested - - requestAccepted - - requestRejected - - unavailable - bookingStartsAt: - type: string - format: date-time - nullable: true - bookingEndsAt: - type: string - format: date-time - example: '2022-08-31T14:00:00Z' - examStartsAt: - type: string - format: date-time - nullable: true - example: '2022-09-02T14:00:00Z' - examEndsAt: - type: string - format: date-time - nullable: true - example: '2022-09-02T17:00:00Z' - bookedCount: - type: integer - example: 42 - availableCount: - type: integer - example: 8 - question: - type: object - nullable: true - properties: - id: - type: integer - example: 1 - statement: - type: string - example: Do you have a laptop to bring at the exam? - options: - type: array - items: - type: string - example: [ Yes, No ] - required: [ id, statement, options ] - example: null - feedback: - type: string - nullable: true - example: null - isReschedulable: - description: If true, the student can ask the professor to reschedule the exam - type: boolean - example: false - notes: - type: string - nullable: true - example: null - moduleNumber: - type: integer - description: The module number, if this is a module - example: 1 - requestReason: - type: string - nullable: true - example: null - requestDetails: - type: string - nullable: true - example: null - required: - - id - - courseId - - courseShortcode - - courseName - - teacherId - - type - - status - - bookingStartsAt - - bookingEndsAt - - examStartsAt - - examEndsAt - - bookedCount - - availableCount - - question - - feedback - - notes - - isReschedulable - - moduleNumber - - requestReason - - requestDetails - - Error: - type: object - properties: - code: - type: integer - example: 2 - message: - type: string - example: Error message - - EscError: - allOf: - - $ref: "#/components/schemas/Error" - - type: object - properties: - careerId: - type: number - example: "290683" - - PersonOverview: - type: object - properties: - id: - type: number - example: 2154 - firstName: - type: string - example: Fulvio - lastName: - type: string - example: Corno - picture: - type: string - nullable: true - example: https://www.swas.polito.it/_library/image_pub.asp?matricola=002154 - role: - type: string - example: Docente - required: [ id, firstName, lastName, picture, role ] - - Person: - allOf: - - $ref: '#/components/schemas/PersonOverview' - - type: object - properties: - email: - type: string - example: fulvio.corno@polito.it - phoneNumbers: - type: array - items: - $ref: '#/components/schemas/PhoneNumber' - facilityShortName: - type: string - nullable: true - example: DAUIN - profileUrl: - type: string - example: https://www.dauin.polito.it/personale/scheda/(matricola)/002154 - courses: - type: array - nullable: true - items: - $ref: "#/components/schemas/PersonCourse" - required: [ email, phoneNumbers, facilityShortName, profileUrl, courses ] - - PersonCourse: - type: object - properties: - id: - type: integer - description: The identifier for this course - example: 258674 - shortcode: - type: string - description: The shortcode for this course - example: 01NYHOV - name: - type: string - description: The name of the course - example: Computer sciences - role: - type: string - description: The role of the person in this course - example: Collaboratore - year: - type: number - description: The year this course was given in - example: 2021 - required: [ id, year, role, name ] - - GeoLocation: - type: object - properties: - latitude: - type: number - example: 45.064254 - longitude: - type: number - example: 7.657823 - required: [ latitude, longitude ] - - RoomOverview: - type: object - properties: - id: - type: string - example: '088' - name: - type: string - example: Aula 1D - required: [ id, name ] - - SiteOverview: - type: object - properties: - id: - type: string - example: TO_CIT - name: - type: string - example: Sede Centrale - Cittadella Politecnica - required: [ id, name ] - - Site: - allOf: - - $ref: '#/components/schemas/SiteOverview' - - type: object - properties: - floors: - type: array - items: - $ref: '#/components/schemas/Floor' - city: - type: object - properties: - id: - type: string - example: 1272 - name: - type: string - example: "Torino" - required: [ id, name ] - extent: - type: number - example: 0.0015 - description: A delta in degrees that applied to the centroid coordinates of the site determines its extent - required: [ floors, extent, city ] - - $ref: '#/components/schemas/GeoLocation' - - BuildingOverview: - type: object - properties: - id: - type: string - example: TO_CIT09 - name: - type: string - example: Aule T - siteId: - type: string - example: TO_CIT - category: - $ref: '#/components/schemas/PlaceCategoryOverview' - geoJson: - $ref: 'https://raw.githubusercontent.com/zit0un/GeoJSON-OAS3/1db6676d3a810b86ec0b9b99a95614f2dbd54b5e/GeoJSON-OAS3.yaml#/components/schemas/Feature' - required: [ id, name, siteId, category ] - - Building: - allOf: - - $ref: '#/components/schemas/BuildingOverview' - - $ref: '#/components/schemas/GeoLocation' - - Floor: - type: object - properties: - id: - type: string - example: XPTE - name: - type: string - example: Piano Terra - level: - type: integer - example: 0 - required: [ id, name, level ] - - Department: - type: object - properties: - id: - type: string - example: 'DAUIN' - name: - type: string - example: 'Dipartimento di Automatica e Informatica' - nullable: true - type: - type: string - example: 'DIP.' - required: [ id, name, type ] - - PlaceCategory: - type: object - properties: - id: - type: string - example: AULA - name: - type: string - example: Aula - showInMenu: - type: boolean - default: false - color: - type: string - example: lightBlue - default: gray - markerUrl: - type: string - format: url - priority: - description: A MapBox style priority number. 0 means most important, larger numbers are less important - type: number - example: 60 - default: 100 - highlighted: - description: If tue, markers of this category should be shown initially on the map - type: boolean - example: true - default: false - required: [ id, name ] - - RootPlaceCategory: - allOf: - - $ref: '#/components/schemas/PlaceCategory' - - type: object - properties: - subCategories: - type: array - items: - $ref: '#/components/schemas/PlaceCategory' - - PlaceCategoryOverview: - allOf: - - $ref: '#/components/schemas/PlaceCategory' - - type: object - properties: - subCategory: - $ref: '#/components/schemas/PlaceCategory' - - PlaceOverview: - allOf: - - type: object - properties: - id: - type: string - example: 'TO_CIT09_XPTE_088' - room: - $ref: '#/components/schemas/RoomOverview' - category: - $ref: '#/components/schemas/PlaceCategoryOverview' - site: - $ref: '#/components/schemas/SiteOverview' - building: - $ref: '#/components/schemas/BuildingOverview' - floor: - $ref: '#/components/schemas/Floor' - department: - $ref: '#/components/schemas/Department' - required: [ id, room, category, site, building, floor, department ] - - $ref: '#/components/schemas/GeoLocation' - - FreeRoom: - allOf: - - $ref: '#/components/schemas/PlaceRef' - - type: object - properties: - id: - type: string - freeFrom: - type: string - format: date-time - freeTo: - type: string - format: date-time - required: [ freeFrom, freeTo ] - - Place: - allOf: - - $ref: '#/components/schemas/PlaceOverview' - - type: object - properties: - geoJson: - $ref: 'https://gist.githubusercontent.com/zit0un/3ac0575eb0f3aabdc645c3faad47ab4a/raw/8db5e3ab89418def3a15474979e494c92b69592e/GeoJSON-OAS3.yaml#/components/schemas/Feature' - capacity: - type: integer - example: 300 - structure: - type: object - nullable: true - properties: - name: - type: string - example: Dipartimento di Ingegneria Strutturale, Edile e Geotecnica - shortName: - type: string - example: DISEG - email: - type: string - nullable: true - example: null - phone: - type: string - nullable: true - example: null - required: [ name, shortName, email, phone ] - resources: - type: array - items: - type: object - properties: - name: - type: string - example: Personal Computer - description: - type: string - example: Computer fisso da tavolo cablato per la proiezione - category: - type: string - example: Technology - required: [ name, description, category ] - required: [ capacity, structure, resources, geoJson ] - - VideoLecture: - type: object - properties: - id: - type: integer - example: 888122 - title: - type: string - example: Lecture 1 - teacherId: - type: integer - example: 888122 - abstract: - type: string - example: Lecture 1 - coverUrl: - type: string - example: https:// - videoUrl: - type: string - example: https:// - audioUrl: - type: string - example: https:// - createdAt: - type: string - format: date-time - example: '2022-08-31T14:00:00Z' - duration: - type: string - example: 00h 46m - required: [ id, title, teacherId, abstract, coverUrl, videoUrl, audioUrl, createdAt, duration ] - - RelatedVirtualClassroom: - type: object - properties: - id: - type: integer - example: 150157 - title: - type: string - example: Lecture 1 - required: [ id, title ] - - VirtualClassroom: - type: object - properties: - id: - type: integer - example: 150157 - title: - type: string - example: Lecture 1 - teacherId: - type: integer - example: 888122 - coverUrl: - type: string - nullable: true - example: https:// - videoUrl: - type: string - example: https:// - createdAt: - type: string - format: date-time - example: '2022-08-31T14:00:00Z' - duration: - type: string - example: 00h 46m - type: - type: string - enum: - - recording - required: [ id, title, teacherId, coverUrl, videoUrl, createdAt, duration, type ] - - VirtualClassroomLive: - type: object - properties: - id: - type: integer - example: 150157 - title: - type: string - example: Lecture 1 - teacherId: - type: integer - example: 888122 - meetingId: - type: string - example: "" - createdAt: - type: string - format: date-time - example: '2022-08-31T14:00:00Z' - type: - type: string - enum: - - live - required: [ id, title, teacherId, createdAt ] - - Lecture: - type: object - properties: - id: - type: number - example: 150157 - startsAt: - type: string - format: date-time - example: 2022-08-31T14:00:00Z - endsAt: - type: string - format: date-time - example: 2022-08-31T14:00:00Z - type: - type: string - example: Lezione / Esercitazione - virtualClassrooms: - type: array - items: - $ref: '#/components/schemas/RelatedVirtualClassroom' - description: - type: string - nullable: true - example: Lezione / Esercitazione - courseId: - type: integer - example: 150157 - courseName: - type: string - example: Human Computer Interaction - teacherId: - type: integer - example: 150157 - place: - $ref: '#/components/schemas/PlaceRef' - required: [ id, startsAt, endsAt, type, virtualClassrooms, description, courseId, courseName, teacherId, place ] - - PlaceRef: - type: object - nullable: true - properties: - buildingId: - type: string - example: TO_CIT22 - floorId: - type: string - example: XPTE - name: - type: string - example: Aula 1P - roomId: - type: string - example: 036 - siteId: - type: string - example: TO_CIT - required: [ buildingId, floorId, name, roomId, siteId ] - - Device: - type: object - properties: - name: - type: string - example: S10+ di Luca - platform: - type: string - example: Android - version: - type: string - example: 12 - model: - type: string - example: S10 - manufacturer: - type: string - example: Samsung - required: [ platform ] - - UpdateInfo: - type: object - properties: - suggestUpdate: - type: boolean - example: true - required: [ suggestUpdate ] - - MfaStatusResponse: - type: object - properties: - status: - type: string - enum: [ active, locked, available, unavailable, needsReauth ] - description: Current MFA status for the user - details: - type: object - nullable: true - description: Additional information about the MFA session. Present only if status is `active` or `locked` - properties: - lastAuth: - type: string - format: date-time - example: '2021-09-30T00:00:00Z' - description: Date and time of the last successful MFA authentication - authCount: - type: integer - example: 1 - serial: - type: string - description: Identifier of the MFA method in use - example: EDUP0000123456 - description: - type: string - description: Custom name or label set by the user to identify the MFA method - example: My phone - required: [ lastAuth, authCount ] - required: [ status, details ] - - ClientVersionRequest: - type: object - properties: - buildNumber: - type: string - example: '1060200' - appVersion: - type: string - example: '1.6.2' - required: [ buildNumber, appVersion ] - - Client: - allOf: - - type: object - properties: - name: - type: string - example: Students app - id: - type: string - example: '5a54f626-4b7e-488e-a0e3-300f54051510' - required: [ name ] - - $ref: '#/components/schemas/ClientVersionRequest' - - $ref: '#/components/schemas/FcmRegistrationRequest' - - PhoneNumber: - type: object - properties: - full: - type: string - example: "0110907053" - internal: - type: string - example: "7053" - required: [ full, internal ] - - MessageType: - type: string - enum: - - emergency - - event - - personal - - teacher - - secretariat - - exams - - mfa - example: secretariat - - Message: - type: object - properties: - id: - type: number - example: 63775600 - title: - type: string - example: Nuovo messaggio dalla Segreteria Studenti - message: - type: string - nullable: true - example: Puoi venire a ritirare la tua smartcard - type: - $ref: '#/components/schemas/MessageType' - senderId: - type: number - example: 150157 - nullable: true - sentAt: - type: string - format: date-time - example: '2021-10-05T10:00:00Z' - isRead: - type: boolean - example: true - required: [ id, title, message, type, senderId, sentAt, isRead ] - - Notification: - type: object - properties: - id: - type: number - example: 63775600 - title: - type: string - example: Nuovo materiale nel corso di Fisica - message: - type: string - nullable: true - example: Nuovo file presentazione.pdf aggiunto al materiale del corso di Fisica - scope: - type: array - description: An array representing the hierarchical path to the object this notification is related to (replicates the navigation/modules structure) - items: - type: string - example: [ "teaching", "courses", "FIS000", "files" ] - sentAt: - type: string - format: date-time - example: '2021-10-05T10:00:00Z' - isRead: - type: boolean - example: true - required: [ id, title, message, sentAt, isRead ] - - TicketSubtopic: - type: object - properties: - id: - type: number - example: 103 - name: - type: string - example: Accesso studenti esterni - required: [ id, name ] - - TicketTopic: - allOf: - - $ref: '#/components/schemas/TicketSubtopic' - - type: object - properties: - subtopics: - type: array - items: - $ref: '#/components/schemas/TicketSubtopic' - example: - id: 61 - name: ACCESSO LAUREE MAGISTRALI - subtopics: - - id: 103 - name: Accesso studenti esterni - required: [ subtopics ] - - TicketFAQ: - type: object - properties: - id: - type: number - example: 3623 - question: - type: string - example: Ho dimenticato il mio nome utente e/o la password e non riesco più ad accedere ad Apply@Polito. Come posso fare? - answer: - type: string - example: Clicca sul link "Codice e/o Password dimenticata?" presente sulla pagina di Log-in e segui le istruzioni. - required: [ id, question, answer ] - - TicketStatus: - type: string - enum: - - new - - pending - - closed - - TicketOverview: - type: object - properties: - id: - type: number - example: 1145890 - subject: - type: string - example: Sostituzione esame in piano carriera - message: - type: string - example: Buongiorno, vi contatto per sostituire A con B - status: - $ref: '#/components/schemas/TicketStatus' - hasAttachments: - type: boolean - example: true - isFromAgent: - type: boolean - description: If true, this ticket was opened by an agent (not by the student) - example: false - agentId: - type: number - example: null - nullable: true - unreadCount: - type: number - example: 2 - createdAt: - type: string - format: date-time - example: 2022-08-31T14:00:00Z - updatedAt: - type: string - format: date-time - example: 2022-08-31T14:00:00Z - required: [ id, subject, message, status, hasAttachments, isFromAgent, agentId, unreadCount, createdAt, updatedAt ] - - Ticket: - allOf: - - $ref: '#/components/schemas/TicketOverview' - - type: object - properties: - replies: - type: array - items: - $ref: '#/components/schemas/TicketReply' - attachments: - type: array - items: - $ref: '#/components/schemas/TicketAttachment' - required: [ replies, attachments ] - - TicketReply: - type: object - properties: - id: - type: number - example: 1145890 - message: - type: string - example: Non si può fare. - isFromAgent: - type: boolean - description: If true, this reply was sent by an agent (not by the student) - example: true - agentId: - type: number - example: 351 - nullable: true - isRead: - type: boolean - example: true - createdAt: - type: string - format: date-time - example: 2022-08-31T14:00:00Z - attachments: - type: array - items: - $ref: '#/components/schemas/TicketAttachment' - required: [ id, message, isFromAgent, agentId, isRead, createdAt, attachments ] - - TicketAttachment: - type: object - properties: - id: - type: number - example: 0 - filename: - type: string - example: screenshot.png - mimeType: - type: string - example: image/png - sizeInKiloBytes: - type: integer - example: 305 - required: [ id, filename, mimeType, sizeInKiloBytes ] - - ReplyTicketRequest: - type: object - properties: - message: - type: string - example: Ok scusa - attachment: - type: string - format: binary - required: [ message ] - - CreateTicketRequest: - type: object - properties: - subject: - type: string - example: Sostituzione esame in piano carriera - message: - type: string - example: Buongiorno, vi contatto per sostituire A con B - subtopicId: - type: number - example: 103 - attachment: - type: string - format: binary - required: [ subject, message, subtopicId ] - - NewsItemOverview: - type: object - properties: - id: - type: number - example: 123 - title: - type: string - example: Partecipazione, co-progettazione e impatto sociale. Sfide e opportunità per l'inclusione sociale - isEvent: - type: boolean - example: false - shortDescription: - type: string - example: Seminario di presentazione del progetto - eventStartTime: - type: string - example: Dal 30 agosto 2023 - nullable: true - eventEndTime: - type: string - example: Al 30 agosto 2023 - nullable: true - createdAt: - type: string - format: date-time - example: 2022-08-31T14:00:00Z - required: [ id, title, isEvent, shortDescription, eventStartTime, eventEndTime, createdAt ] - - NewsItem: - allOf: - - $ref: '#/components/schemas/NewsItemOverview' - - type: object - properties: - location: - type: string - example: Energy Center - Via Paolo Borsellino 38, Torino - htmlContent: - type: string - example: Martedì 18 aprile 2023 - presso l'Auditorium dell'Energy Center del Politecnico... - extras: - type: array - items: - $ref: '#/components/schemas/NewsItemExtra' - required: [ location, htmlContent, extras ] - - NewsItemExtra: - type: object - properties: - url: - type: string - example: https:// - description: - type: string - example: Bando - type: - type: string - enum: - - link - - file - - image - example: image - sizeInKiloBytes: - type: integer - example: 305 - nullable: true - required: [ url, description, type, sizeInKiloBytes ] - - FcmRegistrationRequest: - type: object - properties: - fcmRegistrationToken: - type: string - example: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4 - - UpdatePreferencesRequest: - properties: - language: - type: string - enum: [ it, en ] - example: it - - NotificationPreferences: - type: object - properties: - data: - type: object - properties: - notices: - type: boolean - example: true - files: - type: boolean - example: true - lectures: - type: boolean - example: true - bookings: - type: boolean - example: true - tickets: - type: boolean - example: true - required: [ notices, files, lectures, bookings, tickets ] - required: [ data ] - - UpdateNotificationPreferencesRequest: - type: object - properties: - data: - type: object - properties: - notices: - type: boolean - example: true - files: - type: boolean - example: true - lectures: - type: boolean - example: true - bookings: - type: boolean - example: true - tickets: - type: boolean - example: true - required: [ data ] - - LoginRequestBase: - type: object - properties: - loginType: - type: string - enum: [basic, sso] - client: - $ref: '#/components/schemas/Client' - device: - $ref: '#/components/schemas/Device' - preferences: - $ref: '#/components/schemas/UpdatePreferencesRequest' - required: [loginType, preferences] - - LoginCredentialsBasic: - allOf: - - $ref: '#/components/schemas/LoginRequestBase' - - type: object - properties: - username: - type: string - example: s290683 - password: - type: string - example: moreSecret - additionalProperties: false - required: [username, password] - - LoginCredentialsSSO: - allOf: - - $ref: '#/components/schemas/LoginRequestBase' - - type: object - properties: - uid: - type: string - example: 123456-1234-5678-123456 - key: - type: string - example: abcdef-abcd-efgh-abcdef - additionalProperties: false - required: [uid, key] - - LoginRequest: - oneOf: - - $ref: '#/components/schemas/LoginCredentialsBasic' - - $ref: '#/components/schemas/LoginCredentialsSSO' - discriminator: - propertyName: loginType - mapping: - basic: '#/components/schemas/LoginCredentialsBasic' - sso: '#/components/schemas/LoginCredentialsSSO' - - JobOfferOverview: - type: object - properties: - id: - type: number - example: 43834 - title: - type: string - example: "Progettista" - location: - type: string - example: "BOLLENGO (TO),IVREA (TO)" - companyId: - type: number - example: 3243 - companyName: - type: string - example: "Synergie Italia spa" - createdAtDate: - type: string - format: date - example: 2022-08-31 - endsAtDate: - type: string - format: date - example: 2022-08-31 - required: [ id, title, location, companyId, companyName, createdAtDate, endsAtDate ] - - JobOffer: - allOf: - - $ref: '#/components/schemas/JobOfferOverview' - - type: object - properties: - companyLocation: - type: string - example: "Torino 10152 TORINO (TO)" - companyMission: - type: string - example: "Synergie Agenzia per il lavoro ricerca per importante azienda metalmeccanica produttrice di articoli elettronici" - description: - type: string - example: "Il candidato, in affiancamento al tutor, parteciperà alla progettazione e allo sviluppo di sistemi meccatronici avanzati utilizzando LabVIEW, svolgere attività di test e debug dei sistemi meccatronici progettati." - requirements: - type: string - example: "Preferibile conoscenza di LabVIEW, Matlab, Python e dei motori elettrici in particolare motori step." - contractType: - type: string - example: "Contratto a tempo determinato di 6 mesi\nOrario di lavoro: dal Lunedì al Venerdì dalle 8 alle 17\nSede di lavoro: Ivrea" - salary: - type: string - example: "1200" - contactInformation: - type: string - example: "Pinco Pallo - 0111111111" - nullable: true - url: - type: string - example: "https://..." - nullable: true - email: - type: string - example: "anyone@example.com" - nullable: true - freePositions: - type: number - example: 2 - required: [ companyLocation, companyMission, description, requirements, contractType, salary, contactInformation, url, email, freePositions ] - - DegreeOverview: - type: object - properties: - id: - type: string - example: '81-6' - name: - type: string - example: 'Design e comunicazione' - required: [ id, name ] - - OfferingClass: - type: object - properties: - name: - type: string - example: "Disegno industriale" - code: - type: string - example: 'L-4' - degrees: - type: array - items: - $ref: '#/components/schemas/DegreeOverview' - required: [ name, code, degrees ] - - Degree: - allOf: - - $ref: '#/components/schemas/DegreeOverview' - - type: object - properties: - level: - type: string - example: Corso di laurea di 1°livello - department: - type: object - properties: - name: - type: string - example: Dipartimento di Architettura e Design - required: [ name ] - faculty: - type: object - properties: - id: - type: string - example: 'CL002' - name: - type: string - example: Design e comunicazione - location: - type: string - example: Torino - duration: - type: string - example: 3 anni - class: - type: object - properties: - code: - type: string - example: 'L-4' - name: - type: string - example: Disegno industriale - required: [ code, name ] - year: - type: number - example: 2022 - editions: - description: All the available editions of this degree - type: array - items: - type: string - example: '2021' - notes: - type: array - items: - type: string - example: Corso tenuto in italiano - objectives: - type: object - properties: - title: - type: string - example: Objettivi formativi - content: - type: string - example: 'Il Corso di Laurea in Design e Comunicazione forma un \"designer laureato di primo livello\" ...' - required: [ title, content ] - jobOpportunities: - type: object - properties: - title: - type: string - example: Sbocchi occupazionali e professionali - content: - type: string - example: 'Il Corso di Laurea in Design e Comunicazione forma un \"designer laureato di primo livello\" ...' - required: [ title, content ] - tracks: - type: array - items: - $ref: '#/components/schemas/Track' - - required: [ level, department, faculty, location, duration, class, year, editions, notes, objectives, jobOpportunities, tracks ] - - Track: - type: object - properties: - id: - type: number - example: 2060 - name: - type: string - example: Design per la comunicazione - courses: - type: array - items: - $ref: '#/components/schemas/OfferingCourseOverview' - required: [ id, name, courses ] - - OfferingCourseOverview: - type: object - properties: - name: - type: string - example: System and device programming - shortcode: - type: string - example: 01NYHOV - cfu: - type: integer - example: 10 - teachingYear: - type: integer - description: The year this course belongs to in this degree - example: 1 - language: - type: string - enum: [ it, en ] - group: - type: string - example: Insegnamento a scelta 1 - nullable: true - required: [ name, shortcode, cfu, teachingYear, language, group ] - - CourseHours: - type: object - properties: - lecture: - type: integer - example: 48 - tutoring: - type: integer - example: 12 - classroomExercise: - type: integer - example: 24 - labExercise: - type: integer - example: 24 - - OfferingCourseStaff: - type: object - properties: - role: - type: string - id: - type: number - example: 244577 - courseId: - type: number - example: 262147 - required: [ role, id, courseId ] - - OfferingCourse: - type: object - properties: - name: - type: string - example: System and device programming - shortcode: - type: string - example: 01NYHOV - cfu: - type: integer - example: 10 - teachingPeriod: - type: string - description: The semester(s) this course belongs to - example: 2-2 - languages: - type: array - items: - type: string - enum: [ it, en ] - year: - type: string - example: '2022' - hours: - $ref: '#/components/schemas/CourseHours' - editions: - description: All the available editions of this course - type: array - items: - type: string - example: '2021' - staff: - type: array - items: - $ref: '#/components/schemas/OfferingCourseStaff' - guide: - type: array - items: - $ref: '#/components/schemas/CourseGuideSection' - required: [ name, shortcode, cfu, teachingPeriod, languages, year, hours, editions, staff, guide ] - - GuideField: - type: object - properties: - label: - type: string - example: 'Label' - value: - type: string - example: 'Value' - isCopyEnabled: - type: boolean - example: true - required: [ label, value ] - - GuideSection: - type: object - properties: - title: - type: string - example: 'Title' - content: - type: string - example: "HTML content" - required: [ title, content ] - - Guide: - type: object - properties: - id: - type: string - example: 'dropbox' - listTitle: - type: string - example: 'List title' - title: - type: string - example: 'Title' - intro: - type: string - example: 'Intro' - fields: - type: array - items: - $ref: '#/components/schemas/GuideField' - sections: - type: array - items: - $ref: '#/components/schemas/GuideSection' - required: [ id, listTitle, title, intro, fields, sections ] - - SurveyCourseRef: - type: object - properties: - id: - type: number - example: 1 - name: - type: string - example: 'Course name' - shortcode: - type: string - example: '01NYHOV' - nullable: true - required: [ id, name, shortcode ] - - SurveyTaxonomy: - type: object - properties: - id: - type: string - example: 'CPD' - name: - type: string - example: 'CPD' - required: [ id, name ] - - Survey: - type: object - properties: - id: - type: number - example: 1 - title: - type: string - example: 'Survey title' - subtitle: - type: string - example: 'Survey subtitle' - nullable: true - category: - $ref: '#/components/schemas/SurveyTaxonomy' - type: - $ref: '#/components/schemas/SurveyTaxonomy' - period: - type: number - example: 2 - year: - type: string - example: "2024" - isMandatory: - type: boolean - example: true - isCompiled: - type: boolean - example: false - compileDate: - type: string - format: date-time - example: '2022-08-31T14:00:00Z' - nullable: true - url: - type: string - example: 'https://' - startsAt: - type: string - format: date-time - example: '2022-08-31T14:00:00Z' - endsAt: - type: string - format: date-time - example: '2022-08-31T14:00:00Z' - course: - $ref: '#/components/schemas/SurveyCourseRef' - required: [ id, title, subtitle, category, type, period, year, isMandatory, isCompiled, compileDate, url, startsAt, endsAt ] - - LinkToService: - type: object - properties: - url: - type: string - example: 'https://...' - required: [ url ] - - EmailBadge: - type: object - properties: - unreadEmails: - type: string - example: "99+" - required: [ unreadEmails ] diff --git a/openapitools.json b/openapitools.json new file mode 100644 index 0000000..a7faa21 --- /dev/null +++ b/openapitools.json @@ -0,0 +1,21 @@ +{ + "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "spaces": 2, + "generator-cli": { + "version": "7.17.0", + "generators": { + "typescript-fetch": { + "inputSpec": "./dist/openapi.yaml", + "generatorName": "typescript-fetch", + "output": "./dist/client", + "additionalProperties": { + "npmName": "@polito/api-client", + "npmRepository": "https://github.com/polito/api-spec.git", + "supportsES6": true, + "modelPropertyNaming": "original", + "enumPropertyNaming": "original" + } + } + } + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..cac224e --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3627 @@ +{ + "name": "polito-api-spec", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "polito-api-spec", + "version": "0.0.1", + "devDependencies": { + "@openapitools/openapi-generator-cli": "^2.25.2", + "@typespec/compiler": "^1.7.0", + "@typespec/http": "^1.7.0", + "@typespec/openapi": "^1.7.0", + "@typespec/openapi3": "^1.7.0", + "yaml": "^2.8.2" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@borewit/text-codec": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.1.1.tgz", + "integrity": "sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@inquirer/ansi": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.2.tgz", + "integrity": "sha512-SYLX05PwJVnW+WVegZt1T4Ip1qba1ik+pNJPDiqvk6zS5Y/i8PhRzLpGEtVd7sW0G8cMtkD8t4AZYhQwm8vnww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-5.0.3.tgz", + "integrity": "sha512-xtQP2eXMFlOcAhZ4ReKP2KZvDIBb1AnCfZ81wWXG3DXLVH0f0g4obE0XDPH+ukAEMRcZT0kdX2AS1jrWGXbpxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^2.0.2", + "@inquirer/core": "^11.1.0", + "@inquirer/figures": "^2.0.2", + "@inquirer/type": "^4.0.2" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/confirm": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-6.0.3.tgz", + "integrity": "sha512-lyEvibDFL+NA5R4xl8FUmNhmu81B+LDL9L/MpKkZlQDJZXzG8InxiqYxiAlQYa9cqLLhYqKLQwZqXmSTqCLjyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.0", + "@inquirer/type": "^4.0.2" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-11.1.0.tgz", + "integrity": "sha512-+jD/34T1pK8M5QmZD/ENhOfXdl9Zr+BrQAUc5h2anWgi7gggRq15ZbiBeLoObj0TLbdgW7TAIQRU2boMc9uOKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^2.0.2", + "@inquirer/figures": "^2.0.2", + "@inquirer/type": "^4.0.2", + "cli-width": "^4.1.0", + "mute-stream": "^3.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^9.0.2" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@inquirer/core/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@inquirer/core/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@inquirer/core/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@inquirer/core/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@inquirer/core/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@inquirer/editor": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-5.0.3.tgz", + "integrity": "sha512-wYyQo96TsAqIciP/r5D3cFeV8h4WqKQ/YOvTg5yOfP2sqEbVVpbxPpfV3LM5D0EP4zUI3EZVHyIUIllnoIa8OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.0", + "@inquirer/external-editor": "^2.0.2", + "@inquirer/type": "^4.0.2" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/editor/node_modules/@inquirer/external-editor": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-2.0.2.tgz", + "integrity": "sha512-X/fMXK7vXomRWEex1j8mnj7s1mpnTeP4CO/h2gysJhHLT2WjBnLv4ZQEGpm/kcYI8QfLZ2fgW+9kTKD+jeopLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^2.1.1", + "iconv-lite": "^0.7.0" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/expand": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-5.0.3.tgz", + "integrity": "sha512-2oINvuL27ujjxd95f6K2K909uZOU2x1WiAl7Wb1X/xOtL8CgQ1kSxzykIr7u4xTkXkXOAkCuF45T588/YKee7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.0", + "@inquirer/type": "^4.0.2" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/external-editor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", + "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^2.1.1", + "iconv-lite": "^0.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/figures": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-2.0.2.tgz", + "integrity": "sha512-qXm6EVvQx/FmnSrCWCIGtMHwqeLgxABP8XgcaAoywsL0NFga9gD5kfG0gXiv80GjK9Hsoz4pgGwF/+CjygyV9A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + } + }, + "node_modules/@inquirer/input": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-5.0.3.tgz", + "integrity": "sha512-4R0TdWl53dtp79Vs6Df2OHAtA2FVNqya1hND1f5wjHWxZJxwDMSNB1X5ADZJSsQKYAJ5JHCTO+GpJZ42mK0Otw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.0", + "@inquirer/type": "^4.0.2" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/number": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-4.0.3.tgz", + "integrity": "sha512-TjQLe93GGo5snRlu83JxE38ZPqj5ZVggL+QqqAF2oBA5JOJoxx25GG3EGH/XN/Os5WOmKfO8iLVdCXQxXRZIMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.0", + "@inquirer/type": "^4.0.2" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/password": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-5.0.3.tgz", + "integrity": "sha512-rCozGbUMAHedTeYWEN8sgZH4lRCdgG/WinFkit6ZPsp8JaNg2T0g3QslPBS5XbpORyKP/I+xyBO81kFEvhBmjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^2.0.2", + "@inquirer/core": "^11.1.0", + "@inquirer/type": "^4.0.2" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/prompts": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-8.1.0.tgz", + "integrity": "sha512-LsZMdKcmRNF5LyTRuZE5nWeOjganzmN3zwbtNfcs6GPh3I2TsTtF1UYZlbxVfhxd+EuUqLGs/Lm3Xt4v6Az1wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^5.0.3", + "@inquirer/confirm": "^6.0.3", + "@inquirer/editor": "^5.0.3", + "@inquirer/expand": "^5.0.3", + "@inquirer/input": "^5.0.3", + "@inquirer/number": "^4.0.3", + "@inquirer/password": "^5.0.3", + "@inquirer/rawlist": "^5.1.0", + "@inquirer/search": "^4.0.3", + "@inquirer/select": "^5.0.3" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/rawlist": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-5.1.0.tgz", + "integrity": "sha512-yUCuVh0jW026Gr2tZlG3kHignxcrLKDR3KBp+eUgNz+BAdSeZk0e18yt2gyBr+giYhj/WSIHCmPDOgp1mT2niQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.0", + "@inquirer/type": "^4.0.2" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/search": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-4.0.3.tgz", + "integrity": "sha512-lzqVw0YwuKYetk5VwJ81Ba+dyVlhseHPx9YnRKQgwXdFS0kEavCz2gngnNhnMIxg8+j1N/rUl1t5s1npwa7bqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.0", + "@inquirer/figures": "^2.0.2", + "@inquirer/type": "^4.0.2" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/select": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-5.0.3.tgz", + "integrity": "sha512-M+ynbwS0ecQFDYMFrQrybA0qL8DV0snpc4kKevCCNaTpfghsRowRY7SlQBeIYNzHqXtiiz4RG9vTOeb/udew7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^2.0.2", + "@inquirer/core": "^11.1.0", + "@inquirer/figures": "^2.0.2", + "@inquirer/type": "^4.0.2" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/type": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-4.0.2.tgz", + "integrity": "sha512-cae7mzluplsjSdgFA6ACLygb5jC8alO0UUnFPyu0E7tNRPrL+q/f8VcSXp+cjZQ7l5CMpDpi2G1+IQvkOiL1Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@lukeed/csprng": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz", + "integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@nestjs/axios": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-4.0.1.tgz", + "integrity": "sha512-68pFJgu+/AZbWkGu65Z3r55bTsCPlgyKaV4BSG8yUAD72q1PPuyVRgUwFv6BxdnibTUHlyxm06FmYWNC+bjN7A==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@nestjs/common": "^10.0.0 || ^11.0.0", + "axios": "^1.3.1", + "rxjs": "^7.0.0" + } + }, + "node_modules/@nestjs/common": { + "version": "11.1.9", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-11.1.9.tgz", + "integrity": "sha512-zDntUTReRbAThIfSp3dQZ9kKqI+LjgLp5YZN5c1bgNRDuoeLySAoZg46Bg1a+uV8TMgIRziHocglKGNzr6l+bQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "file-type": "21.1.0", + "iterare": "1.2.1", + "load-esm": "1.0.3", + "tslib": "2.8.1", + "uid": "2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "peerDependencies": { + "class-transformer": ">=0.4.1", + "class-validator": ">=0.13.2", + "reflect-metadata": "^0.1.12 || ^0.2.0", + "rxjs": "^7.1.0" + }, + "peerDependenciesMeta": { + "class-transformer": { + "optional": true + }, + "class-validator": { + "optional": true + } + } + }, + "node_modules/@nestjs/core": { + "version": "11.1.9", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-11.1.9.tgz", + "integrity": "sha512-a00B0BM4X+9z+t3UxJqIZlemIwCQdYoPKrMcM+ky4z3pkqqG1eTWexjs+YXpGObnLnjtMPVKWlcZHp3adDYvUw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@nuxt/opencollective": "0.4.1", + "fast-safe-stringify": "2.1.1", + "iterare": "1.2.1", + "path-to-regexp": "8.3.0", + "tslib": "2.8.1", + "uid": "2.0.2" + }, + "engines": { + "node": ">= 20" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "peerDependencies": { + "@nestjs/common": "^11.0.0", + "@nestjs/microservices": "^11.0.0", + "@nestjs/platform-express": "^11.0.0", + "@nestjs/websockets": "^11.0.0", + "reflect-metadata": "^0.1.12 || ^0.2.0", + "rxjs": "^7.1.0" + }, + "peerDependenciesMeta": { + "@nestjs/microservices": { + "optional": true + }, + "@nestjs/platform-express": { + "optional": true + }, + "@nestjs/websockets": { + "optional": true + } + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nuxt/opencollective": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nuxt/opencollective/-/opencollective-0.4.1.tgz", + "integrity": "sha512-GXD3wy50qYbxCJ652bDrDzgMr3NFEkIS374+IgFQKkCvk9yiYcLvX2XDYr7UyQxf4wK0e+yqDYRubZ0DtOxnmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "consola": "^3.2.3" + }, + "bin": { + "opencollective": "bin/opencollective.js" + }, + "engines": { + "node": "^14.18.0 || >=16.10.0", + "npm": ">=5.10.0" + } + }, + "node_modules/@nuxtjs/opencollective": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@nuxtjs/opencollective/-/opencollective-0.3.2.tgz", + "integrity": "sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "consola": "^2.15.0", + "node-fetch": "^2.6.1" + }, + "bin": { + "opencollective": "bin/opencollective.js" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.0.0" + } + }, + "node_modules/@nuxtjs/opencollective/node_modules/consola": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", + "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@openapitools/openapi-generator-cli": { + "version": "2.25.2", + "resolved": "https://registry.npmjs.org/@openapitools/openapi-generator-cli/-/openapi-generator-cli-2.25.2.tgz", + "integrity": "sha512-TXElbW1NXCy0EECXiO5AD2ZzT1dmaCs41Z8t3pBUGaJf8zgF/Lm0P6GRhVEpw29iHBNjZcy8nrgQ1acUfuCdng==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@nestjs/axios": "4.0.1", + "@nestjs/common": "11.1.9", + "@nestjs/core": "11.1.9", + "@nuxtjs/opencollective": "0.3.2", + "axios": "1.13.2", + "chalk": "4.1.2", + "commander": "8.3.0", + "compare-versions": "6.1.1", + "concurrently": "9.2.1", + "console.table": "0.10.0", + "fs-extra": "11.3.2", + "glob": "13.0.0", + "inquirer": "8.2.7", + "proxy-agent": "6.5.0", + "reflect-metadata": "0.2.2", + "rxjs": "7.8.2", + "tslib": "2.8.1" + }, + "bin": { + "openapi-generator-cli": "main.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/openapi_generator" + } + }, + "node_modules/@scalar/helpers": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@scalar/helpers/-/helpers-0.2.2.tgz", + "integrity": "sha512-oGef7vvtz1KgCy34IaVcbMV99dEXjcGETJtwogT4MU8R7gnYDg6qSTh5200hWAGVO+Ai/6h9rlGVfgeHTzelfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/@scalar/json-magic": { + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/@scalar/json-magic/-/json-magic-0.8.6.tgz", + "integrity": "sha512-alxGHRJXgaefvfv9IISxb11D2y9iVyN+2/1dLBg3jJildkCJCP6yaT5ESC9qB+YOZeuuxIF32gmk+CLwx38YnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@scalar/helpers": "0.2.2", + "yaml": "^2.8.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@scalar/openapi-parser": { + "version": "0.23.7", + "resolved": "https://registry.npmjs.org/@scalar/openapi-parser/-/openapi-parser-0.23.7.tgz", + "integrity": "sha512-OEuP+RM74YT7S11K9yHwuPq7bUnj+8ywCV5few73FY1szr90y39yGreLPcAmZ+SeC0HPhP4ZGKIhBCeSmuSL6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@scalar/json-magic": "0.8.6", + "@scalar/openapi-types": "0.5.3", + "@scalar/openapi-upgrader": "0.1.6", + "ajv": "^8.17.1", + "ajv-draft-04": "^1.0.0", + "ajv-formats": "^3.0.1", + "jsonpointer": "^5.0.1", + "leven": "^4.0.0", + "yaml": "^2.8.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@scalar/openapi-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@scalar/openapi-types/-/openapi-types-0.5.3.tgz", + "integrity": "sha512-m4n/Su3K01d15dmdWO1LlqecdSPKuNjuokrJLdiQ485kW/hRHbXW1QP6tJL75myhw/XhX5YhYAR+jrwnGjXiMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "zod": "^4.1.11" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@scalar/openapi-upgrader": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@scalar/openapi-upgrader/-/openapi-upgrader-0.1.6.tgz", + "integrity": "sha512-XdrNZUr0ASLfR89OS2zP6enbq9f7UGQQxov+a3WF1Wz9DClniAL2ChJ2fbGOrqL5F2kjbV6Fw/iO3bsBTMyLZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@scalar/openapi-types": "0.5.3" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@tokenizer/inflate": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.3.1.tgz", + "integrity": "sha512-4oeoZEBQdLdt5WmP/hx1KZ6D3/Oid/0cUb2nk4F0pTDAWy+KCH3/EnAkZF/bvckWo8I33EqBm01lIPgmgc8rCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.1", + "fflate": "^0.8.2", + "token-types": "^6.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typespec/asset-emitter": { + "version": "0.77.0", + "resolved": "https://registry.npmjs.org/@typespec/asset-emitter/-/asset-emitter-0.77.0.tgz", + "integrity": "sha512-OoeYP3UZ/taf46U6sEcb11VYmBlgpCn02mdHTIAM+suCjBZPBYV02pkeEvKyms4MtHMsg/GdEh7Tpl6cTwwsNg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@typespec/compiler": "^1.7.0" + } + }, + "node_modules/@typespec/compiler": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@typespec/compiler/-/compiler-1.7.0.tgz", + "integrity": "sha512-KE2t5I7u/33M/nsIxdng06FUPrqaGSbMsSEsv51eMwYnj3v1+Z3qTTX/dxHAXRXHcfadNlX/NtyAKju+pkMTFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "~7.27.1", + "@inquirer/prompts": "^8.0.1", + "ajv": "~8.17.1", + "change-case": "~5.4.4", + "env-paths": "^3.0.0", + "globby": "~16.0.0", + "is-unicode-supported": "^2.1.0", + "mustache": "~4.2.0", + "picocolors": "~1.1.1", + "prettier": "~3.6.2", + "semver": "^7.7.1", + "tar": "^7.5.2", + "temporal-polyfill": "^0.3.0", + "vscode-languageserver": "~9.0.1", + "vscode-languageserver-textdocument": "~1.0.12", + "yaml": "~2.8.0", + "yargs": "~18.0.0" + }, + "bin": { + "tsp": "cmd/tsp.js", + "tsp-server": "cmd/tsp-server.js" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@typespec/http": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@typespec/http/-/http-1.7.0.tgz", + "integrity": "sha512-4cGkcMiob3bedWbFkRcq614TDH7WPEI3YMgrg44mBarj903arpEniAESIhNUbLQzQFFc5rOJagexQDl4agVDyA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@typespec/compiler": "^1.7.0", + "@typespec/streams": "^0.77.0" + }, + "peerDependenciesMeta": { + "@typespec/streams": { + "optional": true + } + } + }, + "node_modules/@typespec/openapi": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@typespec/openapi/-/openapi-1.7.0.tgz", + "integrity": "sha512-tEAIgGnjLvOjbGAoCfkBudvpe/tXaOXkzy5nVFXs4921/jAaMTwzcJIt0bTXZpp5cExdlL7w9ZrnehARHiposQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@typespec/compiler": "^1.7.0", + "@typespec/http": "^1.7.0" + } + }, + "node_modules/@typespec/openapi3": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@typespec/openapi3/-/openapi3-1.7.0.tgz", + "integrity": "sha512-HjKM+4FfimQjscnfO7Y1iMGaRO0nlxTfou5+aA82DNuDl+oCsfjtddHAP/CSCVhRdqzkD2HyHdm2SwYPJL/fpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@scalar/json-magic": "^0.8.2", + "@scalar/openapi-parser": "^0.23.3", + "@scalar/openapi-types": "^0.5.0", + "@typespec/asset-emitter": "^0.77.0", + "yaml": "~2.8.0" + }, + "bin": { + "tsp-openapi3": "cmd/tsp-openapi3.js" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@typespec/compiler": "^1.7.0", + "@typespec/events": "^0.77.0", + "@typespec/http": "^1.7.0", + "@typespec/json-schema": "^1.7.0", + "@typespec/openapi": "^1.7.0", + "@typespec/sse": "^0.77.0", + "@typespec/streams": "^0.77.0", + "@typespec/versioning": "^0.77.0" + }, + "peerDependenciesMeta": { + "@typespec/events": { + "optional": true + }, + "@typespec/json-schema": { + "optional": true + }, + "@typespec/sse": { + "optional": true + }, + "@typespec/streams": { + "optional": true + }, + "@typespec/versioning": { + "optional": true + }, + "@typespec/xml": { + "optional": true + } + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-draft-04": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^8.5.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", + "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/change-case": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", + "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/chardet": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", + "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/compare-versions": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", + "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==", + "dev": true, + "license": "MIT" + }, + "node_modules/concurrently": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz", + "integrity": "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "4.1.2", + "rxjs": "7.8.2", + "shell-quote": "1.8.3", + "supports-color": "8.1.1", + "tree-kill": "1.2.2", + "yargs": "17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/concurrently/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/concurrently/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/console.table": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/console.table/-/console.table-0.10.0.tgz", + "integrity": "sha512-dPyZofqggxuvSf7WXvNjuRfnsOk1YazkVP8FdxH4tcH2c37wc79/Yl6Bhr7Lsu00KMgy2ql/qCMuNu8xctZM8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "easy-table": "1.1.0" + }, + "engines": { + "node": "> 0.10" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/easy-table": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.1.0.tgz", + "integrity": "sha512-oq33hWOSSnl2Hoh00tZWaIPi1ievrD9aFG82/IgjlycAnW9hHx5PkJiXpxPsgEE+H7BsbVQXFVFST8TEXS6/pA==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "wcwidth": ">=1.0.1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/env-paths": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", + "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "dev": true, + "license": "MIT" + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/file-type": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.1.0.tgz", + "integrity": "sha512-boU4EHmP3JXkwDo4uhyBhTt5pPstxB6eEXKJBu2yu2l7aAMMm7QQYQEzssJmKReZYrFdFOJS8koVo6bXIBGDqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tokenizer/inflate": "^0.3.1", + "strtok3": "^10.3.1", + "token-types": "^6.0.0", + "uint8array-extras": "^1.4.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs-extra": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz", + "integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/glob": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", + "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-16.0.0.tgz", + "integrity": "sha512-ejy4TJFga99yW6Q0uhM3pFawKWZmtZzZD/v/GwI5+9bCV5Ew+D2pSND6W7fUes5UykqSsJkUfxFVdRh7Q1+P3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^4.0.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.5", + "is-path-inside": "^4.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.4.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", + "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/inquirer": { + "version": "8.2.7", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.7.tgz", + "integrity": "sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/external-editor": "^1.0.0", + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/inquirer/node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/inquirer/node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true, + "license": "ISC" + }, + "node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz", + "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/iterare": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/iterare/-/iterare-1.2.1.tgz", + "integrity": "sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=6" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/leven": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-4.1.0.tgz", + "integrity": "sha512-KZ9W9nWDT7rF7Dazg8xyLHGLrmpgq2nVNFUckhqdW3szVP6YhCpp/RAnpmVExA9JvrMynjwSLVrEj3AepHR6ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/load-esm": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/load-esm/-/load-esm-1.0.3.tgz", + "integrity": "sha512-v5xlu8eHD1+6r8EHTg6hfmO97LN8ugKtiXcy5e6oN72iD2r6u0RPfLl6fxM+7Wnh2ZRq15o0russMst44WauPA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + }, + { + "type": "buymeacoffee", + "url": "https://buymeacoffee.com/borewit" + } + ], + "license": "MIT", + "engines": { + "node": ">=13.2.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "dev": true, + "license": "MIT", + "bin": { + "mustache": "bin/mustache" + } + }, + "node_modules/mute-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-3.0.0.tgz", + "integrity": "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pac-proxy-agent": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "dev": true, + "license": "MIT", + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-to-regexp": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/proxy-agent": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.6", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.1.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true, + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strtok3": { + "version": "10.3.4", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.4.tgz", + "integrity": "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.2.tgz", + "integrity": "sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/temporal-polyfill": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/temporal-polyfill/-/temporal-polyfill-0.3.0.tgz", + "integrity": "sha512-qNsTkX9K8hi+FHDfHmf22e/OGuXmfBm9RqNismxBrnSmZVJKegQ+HYYXT+R7Ha8F/YSm2Y34vmzD4cxMu2u95g==", + "dev": true, + "license": "MIT", + "dependencies": { + "temporal-spec": "0.3.0" + } + }, + "node_modules/temporal-spec": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/temporal-spec/-/temporal-spec-0.3.0.tgz", + "integrity": "sha512-n+noVpIqz4hYgFSMOSiINNOUOMFtV5cZQNCmmszA6GiVFVRt3G7AqVyhXjhCSmowvQn+NsGn+jMDMKJYHd3bSQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/token-types": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.1.tgz", + "integrity": "sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@borewit/text-codec": "^0.1.0", + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/uid": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/uid/-/uid-2.0.2.tgz", + "integrity": "sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@lukeed/csprng": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/uint8array-extras": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", + "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unicorn-magic": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz", + "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", + "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-languageserver-protocol": "3.17.5" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "dev": true, + "license": "MIT" + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/yaml": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/zod": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.11.tgz", + "integrity": "sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..614120f --- /dev/null +++ b/package.json @@ -0,0 +1,27 @@ +{ + "name": "polito-api-spec", + "version": "0.0.1", + "type": "module", + "description": "Polito Students API TypeSpec Definition", + "repository": { + "type": "git", + "url": "https://github.com/polito/api-spec.git" + }, + "packageManager": "npm@10.8.2", + "scripts": { + "watch": "tsp compile src --watch", + "format": "tsp format src/**/*.tsp", + "compile": "tsp compile src", + "generate": "rm -rf dist/client && openapi-generator-cli generate -i ./dist/openapi.yaml -g typescript-fetch -o ./dist/client --git-user-id=polito --git-repo-id=api-spec --additional-properties=npmName=@polito/api-client,npmRepository=https://npm.pkg.github.com/,supportsES6=true,modelPropertyNaming=original,removeOperationIdPrefix=true && cp dist/openapi.yaml dist/client/openapi.yaml && cd dist/client", + "build": "npm run compile && npm run generate", + "copy-local": "rm -rf ../students-app/node_modules/@polito/api-client/* && rsync -av ./dist/client/ ../students-app/node_modules/@polito/api-client/ && cd ../students-app/node_modules/@polito/api-client && npm run build" + }, + "devDependencies": { + "@openapitools/openapi-generator-cli": "^2.25.2", + "@typespec/compiler": "^1.7.0", + "@typespec/http": "^1.7.0", + "@typespec/openapi": "^1.7.0", + "@typespec/openapi3": "^1.7.0", + "yaml": "^2.8.2" + } +} diff --git a/src/common.tsp b/src/common.tsp new file mode 100644 index 0000000..0b7dec4 --- /dev/null +++ b/src/common.tsp @@ -0,0 +1,133 @@ +import "@typespec/http"; + +using Http; + +namespace PolitoAPI; + +/* MODELS */ + +model UpdatePreferencesRequest { + @example("it") + language?: "it" | "en"; +} + +model PlaceRef { + buildingId: string; + floorId: string; + roomId: string; + siteId: string; + name: string; +} + +model EuropeanStudentCard { + canBeRequested: boolean; + details: { + status: "active" | "inactive" | "expired"; + inactiveStatusReason: string | null; + cardNumber: string; + expiresAt: string; + qrCode: string; + } | null; +} + +model RelatedVirtualClassroom { + @example(150157) + id: integer; + + @example("Lecture 1") + title: string; +} + +model Lecture { + id: numeric; + startsAt: utcDateTime; + endsAt: utcDateTime; + type: string; + virtualClassrooms: RelatedVirtualClassroom[]; + description: string | null; + courseId: integer; + courseName: string; + + @example(150157) + teacherId: integer; + + place: PlaceRef; +} + +model GuideSection { + @example("Title") + title: string; + + @example("HTML content") + content: string; +} + +/* UTILS */ + +@error +model ErrorResponse { + code?: integer; + message?: string; +} + +// Reusable response aliases +alias OkResponse = { + @statusCode statusCode: 200; + @body body: T; +}; + +alias CreatedResponse = { + @statusCode statusCode: 201; + @body body: T; +}; + +alias NoContentResponse = { + @statusCode statusCode: 204; +}; + +alias RedirectResponse = { + @statusCode statusCode: 302; +}; + +alias BadRequest = { + @statusCode statusCode: 400; + @body body: ErrorResponse; +}; + +alias NotFound = { + @statusCode statusCode: 404; + @body body: ErrorResponse; +}; + +alias ServerError = { + @statusCode statusCode: 500; + @body body: ErrorResponse; +}; + +alias OkDataResponse = OkResponse<{ + data: T; +}>; + +alias OkDataCreatedResponse = CreatedResponse<{ + data: T; +}>; + +alias BaseErrors = BadRequest | ServerError; + +model EscError { + @example(500) + code?: integer; + + @example("An error occurred") + message?: string; + + @example(123456) + careerId?: integer; +} + +alias EscServerError = { + @statusCode statusCode: 500; + @body body: ErrorResponse & { + errors: EscError[]; + }; +}; diff --git a/src/examples/auth.tsp b/src/examples/auth.tsp new file mode 100644 index 0000000..3a86ba0 --- /dev/null +++ b/src/examples/auth.tsp @@ -0,0 +1,51 @@ +import "@typespec/http"; + +using Http; + +namespace PolitoAPI; + +const _ex_identity = #{ + username: "s290683", + type: "student", + clientId: "5a54f626-4b7e-488e-a0e3-300f54051510", + token: "c679fa38ff665df6a676acd833194385", +}; + +const _ex_switchCareer_req = #{ username: "s290683" }; + +const _ex_enrolMfa_req = #{ + description: "some identifier you chose", + pubkey: "dGhpcyBzaG91bGQgYmUgYW4gZWNkcyBwdWJsaWMga2V5Li4uIHdoYXQgZGlkIHlvdSB0aGluayB0aGlzIHdhcz8hIPCfp5AK", +}; + +const _ex_enrolMfa_resp = #{ + returnType: #{ + statusCode: 201, + body: #{ data: #{ serial: "EDUP000123456" } }, + }, +}; + +const _ex_validateMfa_req = #{ + serial: "EDUP000123456", + nonce: "65ba9e0e5aac421a9150991638a9d697", + signature: "83e08d9fc4be3de046318eb3c2c9ae4ede1374a5423a1487b92febc70d106994", + decline: false, +}; + +const _ex_validateMfa_resp = #{ + returnType: #{ statusCode: 200, body: #{ data: #{ success: true } } }, +}; + +const _ex_fetchChallenge_resp = #{ + returnType: #{ + statusCode: 200, + body: #{ + data: #{ + serial: "EDUP000123456", + challenge: "dGhpcyBzaG91bGQgYmUgYW4gZWNkcyBwdWJsaWMga2V5Li4uIHdoYXQgZGlkIHlvdSB0aGluayB0aGlzIHdhcz8hIPCfp5AK", + requestTs: utcDateTime.fromISO("2025-01-01T00:00:00Z"), + expirationTs: utcDateTime.fromISO("2025-01-01T01:00:00Z"), + }, + }, + }, +}; diff --git a/src/examples/bookings.tsp b/src/examples/bookings.tsp new file mode 100644 index 0000000..2fdda26 --- /dev/null +++ b/src/examples/bookings.tsp @@ -0,0 +1,89 @@ +import "@typespec/http"; + +using Http; + +namespace PolitoAPI; + +const _ex_booking_topic = #{ + id: "DIDATTICA_ING", + title: "Segreteria Didattica Ingegneria", + description: "Servizi della Segreteria Didattica Ingegneria", + isEnabled: true, + disclaimer: "", + showCalendar: true, + slotLength: 15, + slotsPerHour: 4, + startDate: null, + startHour: 8, + endHour: 18, + maxBookingsPerDay: 2, + canBeCancelled: true, + daysPerWeek: 5, + agendaView: false, + subtopics: #[ + #{ + id: "DID_ING_VC_EN", + title: "Aspetti didattici di carriera - Sportello virtuale in inglese", + description: "", + isEnabled: true, + disclaimer: "", + showCalendar: true, + slotLength: 15, + slotsPerHour: 4, + startDate: null, + startHour: 8, + endHour: 18, + maxBookingsPerDay: 2, + canBeCancelled: true, + daysPerWeek: 5, + agendaView: false, + requirements: #[], + } + ], +}; + +const _ex_booking_slot = #{ + id: 103051, + description: "", + isBooked: false, + canBeBooked: false, + hasSeats: false, + hasSeatSelection: false, + places: 2, + bookedPlaces: 2, + feedback: "Il turno è pieno", + location: #{ + name: "Virtual Classroom della Segreteria Generale Studenti", + description: "", + type: "VC", + address: "https://didattica.polito.it/pls/portal30/sviluppo.bbb_corsi.queueRoom?id=SEGRETERIA_GENERALE&p_tipo=SEGRETERIA_GENERALE", + }, + startsAt: utcDateTime.fromISO("2021-10-05T10:00:00Z"), + endsAt: utcDateTime.fromISO("2021-10-05T10:15:00Z"), + bookingStartsAt: utcDateTime.fromISO("2021-10-01T00:00:00Z"), + bookingEndsAt: utcDateTime.fromISO("2021-10-05T09:00:00Z"), +}; + +const _ex_booking = #{ + id: 258674, + description: "", + topic: #{ + id: "DIDATTICA_ING", + title: "Segreteria Didattica Ingegneria", + description: "Servizi della Segreteria Didattica Ingegneria", + }, + subtopic: null, + startsAt: utcDateTime.fromISO("2021-10-05T10:00:00Z"), + endsAt: utcDateTime.fromISO("2021-10-05T10:15:00Z"), + seat: #{ id: 20018, row: "A", column: "5" }, + cancelableUntil: utcDateTime.fromISO("2021-10-05T09:00:00Z"), + location: #{ + siteId: "TO_CIT", + buildingId: "TO_CIT11", + floorId: "XPTE", + roomId: "001", + name: "Aula 1", + description: "Virtual Classroom della Segreteria Generale Studenti", + type: "place", + }, +}; diff --git a/src/examples/courses.tsp b/src/examples/courses.tsp new file mode 100644 index 0000000..74bc9f1 --- /dev/null +++ b/src/examples/courses.tsp @@ -0,0 +1,1330 @@ +const _ex_getCourseFiles_resp = #{ + returnType: #{ + statusCode: 200, + body: #{ + data: #[ + #{ + id: "33248655", + name: "videolectures", + type: "directory", + files: #[ + #{ + id: "33248890", + name: "HCI2021-L01 2021-09-28 13-06-26.m4v", + sizeInKiloBytes: 123428, + mimeType: "video/x-m4v", + createdAt: utcDateTime.fromISO("2021-09-28T16:31:43Z"), + type: "file", + checksum: "deadbeefcafebabe0000000000000000", + }, + #{ + id: "33251708", + name: "HCI2021-L02 2021-09-30 08-34-32.mp4", + sizeInKiloBytes: 248172, + mimeType: "video/mp4", + createdAt: utcDateTime.fromISO("2021-09-30T10:20:50Z"), + type: "file", + checksum: "deadbeefcafebabe0000000000000001", + }, + #{ + id: "33256476", + name: "HCI2021-L03 2021-10-05 13-06-47.mp4", + sizeInKiloBytes: 243792, + mimeType: "video/mp4", + createdAt: utcDateTime.fromISO("2021-10-05T15:00:15Z"), + type: "file", + checksum: "deadbeefcafebabe0000000000000002", + }, + #{ + id: "33257988", + name: "HCI2021-L04 2021-10-07 08-35-46.mp4", + sizeInKiloBytes: 244993, + mimeType: "video/mp4", + createdAt: utcDateTime.fromISO("2021-10-07T11:12:25Z"), + type: "file", + checksum: "deadbeefcafebabe0000000000000003", + }, + #{ + id: "33262287", + name: "HCI2021-L05 2021-10-12 13-05-46.mp4", + sizeInKiloBytes: 298172, + mimeType: "video/mp4", + createdAt: utcDateTime.fromISO("2021-10-12T16:11:46Z"), + type: "file", + checksum: "deadbeefcafebabe0000000000000004", + }, + #{ + id: "33265387", + name: "HCI2021-L06 2021-10-14 08-35-12.mp4", + sizeInKiloBytes: 285926, + mimeType: "video/mp4", + createdAt: utcDateTime.fromISO("2021-10-14T11:25:20Z"), + type: "file", + checksum: "deadbeefcafebabe0000000000000005", + }, + #{ + id: "33269079", + name: "HCI2021-L07 2021-10-19 13-10-40.mp4", + sizeInKiloBytes: 234466, + mimeType: "video/mp4", + createdAt: utcDateTime.fromISO("2021-10-19T15:02:22Z"), + type: "file", + checksum: "deadbeefcafebabe0000000000000006", + } + ], + } + ], + }, + }, +}; + +const _ex_course_file_overview = #{ + type: "file", + id: "2", + name: "Lecture1.pdf", + sizeInKiloBytes: 2048, + mimeType: "application/pdf", + createdAt: utcDateTime.fromISO("2024-06-01T10:00:00Z"), + checksum: "deadbeefcafebabe0000000000000000", +}; + +const _ex_courses_list = #{ + returnType: #{ + statusCode: 200, + body: #{ + data: #[ + #{ + id: null, + name: "System and device programming", + shortcode: "01NYHOV", + cfu: 10, + teachingPeriod: "2-2", + teacherId: 2893, + teacherName: "Stefano Quer", + previousEditions: #[], + isOverBooking: false, + isInPersonalStudyPlan: true, + year: "2025", + modules: #[ + #{ + id: 251008, + name: "Programming Module A", + teachingPeriod: "2-2", + teacherId: 3001, + teacherName: "Mario Rossi", + previousEditions: #[#{ id: 251005, year: "2024" }], + isOverBooking: false, + isInPersonalStudyPlan: true, + year: "2025", + }, + #{ + id: 251009, + name: "Programming Module B", + teachingPeriod: "2-2", + teacherId: 3002, + teacherName: "Giovanni Verdi", + previousEditions: #[#{ id: 251006, year: "2024" }], + isOverBooking: false, + isInPersonalStudyPlan: true, + year: "2025", + } + ], + }, + #{ + id: 252121, + name: "Web Applications II", + shortcode: "01TXSOV", + cfu: 6, + teachingPeriod: "2-2", + teacherId: 2235, + teacherName: "Giovanni Malnati", + previousEditions: #[], + isOverBooking: false, + isInPersonalStudyPlan: true, + year: "2025", + modules: null, + }, + #{ + id: 252126, + name: "Security verification and testing", + shortcode: "01TYAOV", + cfu: 6, + teachingPeriod: "1-1", + teacherId: 1943, + teacherName: "Riccardo Sisto", + previousEditions: #[], + isOverBooking: false, + isInPersonalStudyPlan: true, + year: "2025", + modules: null, + }, + #{ + id: 252138, + name: "Information systems security", + shortcode: "01TYMOV", + cfu: 6, + teachingPeriod: "1-1", + teacherId: 1847, + teacherName: "Antonio Lioy", + previousEditions: #[], + isOverBooking: false, + isInPersonalStudyPlan: true, + year: "2025", + modules: null, + }, + #{ + id: 252258, + name: "Cybersecurity", + shortcode: "01UDROV", + cfu: 6, + teachingPeriod: "2-2", + teacherId: 1847, + teacherName: "Antonio Lioy", + previousEditions: #[], + isOverBooking: false, + isInPersonalStudyPlan: true, + year: "2025", + modules: null, + }, + #{ + id: 252788, + name: "Architetture dei sistemi di elaborazione", + shortcode: "02GOLOV", + cfu: 10, + teachingPeriod: "1-1", + teacherId: 12684, + teacherName: "Edgar Ernesto Sanchez Sanchez", + previousEditions: #[], + isOverBooking: false, + isInPersonalStudyPlan: true, + year: "2025", + modules: null, + }, + #{ + id: 252842, + name: "Human Computer Interaction", + shortcode: "02JSKOV", + cfu: 6, + teachingPeriod: "1-1", + teacherId: 25734, + teacherName: "Luigi De Russis", + previousEditions: #[], + isOverBooking: false, + isInPersonalStudyPlan: true, + year: "2025", + modules: null, + }, + #{ + id: 253378, + name: "Cryptography", + shortcode: "03LPYOV", + cfu: 6, + teachingPeriod: "2-2", + teacherId: 13461, + teacherName: "Antonio Jose Di Scala", + previousEditions: #[], + isOverBooking: false, + isInPersonalStudyPlan: true, + year: "2025", + modules: null, + }, + #{ + id: null, + name: "Tesi", + shortcode: "29EBHOV", + cfu: 30, + teachingPeriod: "1-1", + teacherId: null, + teacherName: null, + previousEditions: #[], + isOverBooking: false, + isInPersonalStudyPlan: true, + year: "2025", + modules: null, + } + ], + }, + }, +}; + +const _ex_getCourseAssignments_resp = #{ + returnType: #{ + statusCode: 200, + body: #{ + data: #[ + #{ + id: 1003948, + description: "extrapoints2", + mimeType: "application/x-zip-compressed", + filename: "extrapoints2.zip", + uploadedAt: utcDateTime.fromISO("2022-01-21T14:38:00Z"), + deletedAt: null, + url: "https://file.didattica.polito.it/down/ELABORATI_PRE/1003948/S290683/14576f69df588d55b631c3c3c30de3f5/6305eae6", + sizeInKiloBytes: 195, + }, + #{ + id: 993784, + description: "extrapoints1", + mimeType: "application/x-zip-compressed", + filename: "extrapoints1.zip", + uploadedAt: utcDateTime.fromISO("2022-01-10T18:53:00Z"), + deletedAt: null, + url: "https://file.didattica.polito.it/down/ELABORATI_PRE/993784/S290683/15c275f7f7682c6acb5acd07d24590a9/6305eae6", + sizeInKiloBytes: 401, + }, + #{ + id: 982517, + description: "lab_09", + mimeType: "application/zip", + filename: "lab_09.zip", + uploadedAt: utcDateTime.fromISO("2021-12-16T22:48:00Z"), + deletedAt: null, + url: "https://file.didattica.polito.it/down/ELABORATI_PRE/982517/S290683/29288344d27567de6ddf0fa718b980a5/6305eae6", + sizeInKiloBytes: 126, + }, + #{ + id: 934034, + description: "lab_01", + mimeType: "application/x-zip-compressed", + filename: "lab_01.zip", + uploadedAt: utcDateTime.fromISO("2021-10-13T11:20:00Z"), + deletedAt: null, + url: "https://file.didattica.polito.it/down/ELABORATI_PRE/934034/S290683/fd675d8a411d0747885b24e473a5d683/6305eae6", + sizeInKiloBytes: 144, + } + ], + }, + }, +}; + +const _ex_getLectures_resp = #{ + returnType: #{ + statusCode: 200, + body: #{ + data: #[ + #{ + id: 12131312, + startsAt: utcDateTime.fromISO("2021-09-28T14:30:00Z"), + endsAt: utcDateTime.fromISO("2021-09-28T17:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[ + #{ + id: 149336, + title: "CYB / lecture 28.09.2021 (TLS, slides 1-40)", + } + ], + }, + #{ + id: 12131313, + startsAt: utcDateTime.fromISO("2021-10-01T10:00:00Z"), + endsAt: utcDateTime.fromISO("2021-10-01T11:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[ + #{ + id: 150397, + title: "CYB / lecture 01.10.2021 (TLS, slides 41-55)", + } + ], + }, + #{ + id: 12131314, + startsAt: utcDateTime.fromISO("2021-10-05T14:30:00Z"), + endsAt: utcDateTime.fromISO("2021-10-05T17:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131315, + startsAt: utcDateTime.fromISO("2021-10-08T10:00:00Z"), + endsAt: utcDateTime.fromISO("2021-10-08T11:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Esercitazione aula", + description: "Demos about TLS and SSH. Introduction to the laboratory.", + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131316, + startsAt: utcDateTime.fromISO("2021-10-12T08:30:00Z"), + endsAt: utcDateTime.fromISO("2021-10-12T10:00:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131317, + startsAt: utcDateTime.fromISO("2021-10-12T10:00:00Z"), + endsAt: utcDateTime.fromISO("2021-10-12T11:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131318, + startsAt: utcDateTime.fromISO("2021-10-12T14:30:00Z"), + endsAt: utcDateTime.fromISO("2021-10-12T17:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131319, + startsAt: utcDateTime.fromISO("2021-10-15T10:00:00Z"), + endsAt: utcDateTime.fromISO("2021-10-15T11:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131320, + startsAt: utcDateTime.fromISO("2021-10-19T08:30:00Z"), + endsAt: utcDateTime.fromISO("2021-10-19T10:00:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131321, + startsAt: utcDateTime.fromISO("2021-10-19T10:00:00Z"), + endsAt: utcDateTime.fromISO("2021-10-19T11:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131322, + startsAt: utcDateTime.fromISO("2021-10-19T14:30:00Z"), + endsAt: utcDateTime.fromISO("2021-10-19T17:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131323, + startsAt: utcDateTime.fromISO("2021-10-22T10:00:00Z"), + endsAt: utcDateTime.fromISO("2021-10-22T11:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131324, + startsAt: utcDateTime.fromISO("2021-10-26T08:30:00Z"), + endsAt: utcDateTime.fromISO("2021-10-26T10:00:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131325, + startsAt: utcDateTime.fromISO("2021-10-26T10:00:00Z"), + endsAt: utcDateTime.fromISO("2021-10-26T11:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131326, + startsAt: utcDateTime.fromISO("2021-10-26T14:30:00Z"), + endsAt: utcDateTime.fromISO("2021-10-26T17:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131327, + startsAt: utcDateTime.fromISO("2021-11-02T08:30:00Z"), + endsAt: utcDateTime.fromISO("2021-11-02T10:00:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131328, + startsAt: utcDateTime.fromISO("2021-11-02T10:00:00Z"), + endsAt: utcDateTime.fromISO("2021-11-02T11:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131329, + startsAt: utcDateTime.fromISO("2021-11-02T14:30:00Z"), + endsAt: utcDateTime.fromISO("2021-11-02T17:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131330, + startsAt: utcDateTime.fromISO("2021-11-05T10:00:00Z"), + endsAt: utcDateTime.fromISO("2021-11-05T11:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131331, + startsAt: utcDateTime.fromISO("2021-11-09T08:30:00Z"), + endsAt: utcDateTime.fromISO("2021-11-09T10:00:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Esercitazione Laboratorio con titolo esageratamente lungo che poi boh", + description: "squadra 1", + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131332, + startsAt: utcDateTime.fromISO("2021-11-09T10:00:00Z"), + endsAt: utcDateTime.fromISO("2021-11-09T11:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Esercitazione Laboratorio", + description: "squadra 1", + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131333, + startsAt: utcDateTime.fromISO("2021-11-09T14:30:00Z"), + endsAt: utcDateTime.fromISO("2021-11-09T17:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131334, + startsAt: utcDateTime.fromISO("2021-11-16T08:30:00Z"), + endsAt: utcDateTime.fromISO("2021-11-16T10:00:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Esercitazione Laboratorio", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131335, + startsAt: utcDateTime.fromISO("2021-11-16T10:00:00Z"), + endsAt: utcDateTime.fromISO("2021-11-16T11:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Esercitazione Laboratorio", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131336, + startsAt: utcDateTime.fromISO("2021-11-16T14:30:00Z"), + endsAt: utcDateTime.fromISO("2021-11-16T17:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131337, + startsAt: utcDateTime.fromISO("2021-11-23T08:30:00Z"), + endsAt: utcDateTime.fromISO("2021-11-23T10:00:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Esercitazione Laboratorio", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131338, + startsAt: utcDateTime.fromISO("2021-11-23T10:00:00Z"), + endsAt: utcDateTime.fromISO("2021-11-23T11:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Esercitazione Laboratorio", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131339, + startsAt: utcDateTime.fromISO("2021-11-23T14:30:00Z"), + endsAt: utcDateTime.fromISO("2021-11-23T17:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131340, + startsAt: utcDateTime.fromISO("2021-11-30T08:30:00Z"), + endsAt: utcDateTime.fromISO("2021-11-30T10:00:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Esercitazione Laboratorio", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131341, + startsAt: utcDateTime.fromISO("2021-11-30T10:00:00Z"), + endsAt: utcDateTime.fromISO("2021-11-30T11:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Esercitazione Laboratorio", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131342, + startsAt: utcDateTime.fromISO("2021-11-30T14:30:00Z"), + endsAt: utcDateTime.fromISO("2021-11-30T17:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Esercitazione aula", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131343, + startsAt: utcDateTime.fromISO("2021-12-03T10:00:00Z"), + endsAt: utcDateTime.fromISO("2021-12-03T11:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131344, + startsAt: utcDateTime.fromISO("2021-12-07T08:30:00Z"), + endsAt: utcDateTime.fromISO("2021-12-07T10:00:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131345, + startsAt: utcDateTime.fromISO("2021-12-07T10:00:00Z"), + endsAt: utcDateTime.fromISO("2021-12-07T11:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131346, + startsAt: utcDateTime.fromISO("2021-12-07T14:30:00Z"), + endsAt: utcDateTime.fromISO("2021-12-07T17:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131347, + startsAt: utcDateTime.fromISO("2021-12-10T10:00:00Z"), + endsAt: utcDateTime.fromISO("2021-12-10T11:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131348, + startsAt: utcDateTime.fromISO("2021-12-14T08:30:00Z"), + endsAt: utcDateTime.fromISO("2021-12-14T10:00:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131349, + startsAt: utcDateTime.fromISO("2021-12-14T10:00:00Z"), + endsAt: utcDateTime.fromISO("2021-12-14T11:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131350, + startsAt: utcDateTime.fromISO("2021-12-14T14:30:00Z"), + endsAt: utcDateTime.fromISO("2021-12-14T17:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + }, + #{ + id: 12131351, + startsAt: utcDateTime.fromISO("2021-12-17T10:00:00Z"), + endsAt: utcDateTime.fromISO("2021-12-17T11:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione / Esercitazione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[], + } + ], + }, + }, +}; + +const _ex_course_directory_content = #{ + data: #[ + #{ + id: "33248655", + name: "videolectures", + type: "directory", + files: #[ + #{ + id: "33248890", + name: "HCI2021-L01 2021-09-28 13-06-26.m4v", + sizeInKiloBytes: 123428, + mimeType: "video/x-m4v", + createdAt: utcDateTime.fromISO("2021-09-28T16:31:43Z"), + type: "file", + checksum: "deadbeefcafebabe0000000000000000", + }, + #{ + id: "33251708", + name: "HCI2021-L02 2021-09-30 08-34-32.mp4", + sizeInKiloBytes: 248172, + mimeType: "video/mp4", + createdAt: utcDateTime.fromISO("2021-09-30T10:20:50Z"), + type: "file", + checksum: "deadbeefcafebabe0000000000000000", + }, + #{ + id: "33256476", + name: "HCI2021-L03 2021-10-05 13-06-47.mp4", + sizeInKiloBytes: 243792, + mimeType: "video/mp4", + createdAt: utcDateTime.fromISO("2021-10-05T15:00:15Z"), + type: "file", + checksum: "deadbeefcafebabe0000000000000000", + }, + #{ + id: "33257988", + name: "HCI2021-L04 2021-10-07 08-35-46.mp4", + sizeInKiloBytes: 244993, + mimeType: "video/mp4", + createdAt: utcDateTime.fromISO("2021-10-07T11:12:25Z"), + type: "file", + checksum: "deadbeefcafebabe0000000000000000", + }, + #{ + id: "33262287", + name: "HCI2021-L05 2021-10-12 13-05-46.mp4", + sizeInKiloBytes: 298172, + mimeType: "video/mp4", + createdAt: utcDateTime.fromISO("2021-10-12T16:11:46Z"), + type: "file", + checksum: "deadbeefcafebabe0000000000000000", + }, + #{ + id: "33265387", + name: "HCI2021-L06 2021-10-14 08-35-12.mp4", + sizeInKiloBytes: 285926, + mimeType: "video/mp4", + createdAt: utcDateTime.fromISO("2021-10-14T11:25:20Z"), + type: "file", + checksum: "deadbeefcafebabe0000000000000000", + }, + #{ + id: "33269079", + name: "HCI2021-L07 2021-10-19 13-10-40.mp4", + sizeInKiloBytes: 234466, + mimeType: "video/mp4", + createdAt: utcDateTime.fromISO("2021-10-19T15:02:22Z"), + type: "file", + checksum: "deadbeefcafebabe0000000000000000", + } + ], + } + ], +}; + +const _ex_course_assignments = #{ + data: #[ + #{ + id: 1003948, + description: "extrapoints2", + mimeType: "application/x-zip-compressed", + filename: "extrapoints2.zip", + uploadedAt: utcDateTime.fromISO("2022-01-21T14:38:00Z"), + deletedAt: null, + url: "https://file.didattica.polito.it/down/ELABORATI_PRE/1003948/S290683/14576f69df588d55b631c3c3c30de3f5/6305eae6", + sizeInKiloBytes: 195, + }, + #{ + id: 993784, + description: "extrapoints1", + mimeType: "application/x-zip-compressed", + filename: "extrapoints1.zip", + uploadedAt: utcDateTime.fromISO("2022-01-10T18:53:00Z"), + deletedAt: null, + url: "https://file.didattica.polito.it/down/ELABORATI_PRE/993784/S290683/15c275f7f7682c6acb5acd07d24590a9/6305eae6", + sizeInKiloBytes: 401, + }, + #{ + id: 982517, + description: "lab_09", + mimeType: "application/zip", + filename: "lab_09.zip", + uploadedAt: utcDateTime.fromISO("2021-12-16T22:48:00Z"), + deletedAt: null, + url: "https://file.didattica.polito.it/down/ELABORATI_PRE/982517/S290683/29288344d27567de6ddf0fa718b980a5/6305eae6", + sizeInKiloBytes: 126, + }, + #{ + id: 979076, + description: "lab_08", + mimeType: "application/x-zip-compressed", + filename: "lab8.zip", + uploadedAt: utcDateTime.fromISO("2021-12-10T20:13:00Z"), + deletedAt: null, + url: "https://file.didattica.polito.it/down/ELABORATI_PRE/979076/S290683/3fecdf972707d6cbc439ed0fbbbe726a/6305eae6", + sizeInKiloBytes: 136, + }, + #{ + id: 970722, + description: "lab_06", + mimeType: "application/x-zip-compressed", + filename: "lab_06.zip", + uploadedAt: utcDateTime.fromISO("2021-11-26T12:11:00Z"), + deletedAt: null, + url: "https://file.didattica.polito.it/down/ELABORATI_PRE/970722/S290683/bc51c37cf1368917a24de8d571b069bd/6305eae6", + sizeInKiloBytes: 169, + }, + #{ + id: 948012, + description: "lab_04", + mimeType: "application/zip", + filename: "lab_04.zip", + uploadedAt: utcDateTime.fromISO("2021-10-30T17:26:00Z"), + deletedAt: null, + url: "https://file.didattica.polito.it/down/ELABORATI_PRE/948012/S290683/ca52325301df0130d718c7a0525df288/6305eae6", + sizeInKiloBytes: 259, + }, + #{ + id: 947503, + description: "lab_03", + mimeType: "application/x-zip-compressed", + filename: "lab_03.zip", + uploadedAt: utcDateTime.fromISO("2021-10-29T10:59:00Z"), + deletedAt: null, + url: "https://file.didattica.polito.it/down/ELABORATI_PRE/947503/S290683/050d6985107364d73d9ea3a387813882/6305eae6", + sizeInKiloBytes: 305, + } + ], +}; + +const _ex_course_module = #{ + id: 251008, + name: "Programming Module A", + teachingPeriod: "2-2", + teacherId: 3001, + teacherName: "Mario Rossi", + previousEditions: #[#{ id: 251005, year: "2024" }], + isOverBooking: false, + isInPersonalStudyPlan: true, + year: "2025", +}; + +const _ex_getCourseGuide_resp = #{ + returnType: #{ + statusCode: 200, + body: #{ + data: #[ + #{ + title: "Presentazione", + content: "Nowadays, computing devices are ubiquitously present and integrated in our daily life. Sensors and actuators are embedded in home appliances, lights, or cars. This course provides a strong foundation in human-centered design principles.", + }, + #{ + title: "Risultati attesi", + content: "Knowledge: Concepts of Usability, User Experience, User centered design processes. Skills: Developing a working prototype, mastering novel interaction technologies, joint development in teams.", + }, + #{ + title: "Prerequisiti", + content: "Programming skills, knowledge on web technologies (HTML, JS, client-server architectures), attitude towards working in teams.", + }, + #{ + title: "Programma", + content: "Introduction to Human-Computer Interaction, building interactive applications with human-centered design process, beyond WIMP paradigms (AI-powered systems, tangible interaction, voice, wearables).", + }, + #{ title: "Note", content: "" }, + #{ + title: "Organizzazione dell'insegnamento", + content: "Project-based and problem-based learning with teams working towards a common goal. Project-related activities start since the beginning with deliverables before given deadlines.", + }, + #{ + title: "Bibliografia", + content: "Course slides and related materials. Selected chapters from Human Computer Interaction texts by Dix et al., and Shneiderman et al.", + }, + #{ + title: "Regole d'esame", + content: "Exam consists of written test (40% of score) and group project evaluation (60% of score). Both parts are mandatory and must be taken in the same academic year.", + } + ], + }, + }, +}; + +const _ex_course_directory = #{ + name: "Root", + id: "1234", + type: "directory", + files: #[#{ type: "directory", id: "1", name: "Week 1", files: #[] }], +}; + +const _ex_getCourseNotices_resp = #{ + returnType: #{ + statusCode: 200, + body: #{ + data: #[ + #{ + id: 332559, + publishedAt: utcDateTime.fromISO("2021-09-22T14:00:00Z"), + expiresAt: null, + content: "

Dear students,

\r\r

welcome to the 2021 edition of the Human Computer Interaction course (HCI, for short)!

\r\r

Some useful information to get started...

\r\r

The first class will be on Tuesday, September 28, in Room 7T, from 13:00 to 14:30.
\rDon't forget to book a spot in the room, starting from tomorrow, on the Portale della Didattica: the rooms given to this course are currently bigger than the number of enrolled students, so there should be space for everybody!

\r\r

All teaching material, information, and course schedule will be posted on the page: http://bit.ly/polito-hci (we will not use the Portale della Didattica).

\r\r

All messages and communications with the teachers, and among students, will be on Slack. We will completely avoid email communications.
\rPlease, join the HCI Slack workspace at the address:
\r  https://join.slack.com/t/polito-hci-2021/signup
\rPlease note: to have access to the workspace, you must use your @studenti.polito.it email address. You are free to choose your nickname as you prefer. 

\r\r

Finally, all lectures — not labs — will be video-recorded and made available both on YouTube and on the Portale della Didattica. The YouTube playlist is:
\r  https://www.youtube.com/playlist?list=PLs7DWGc_wmwT-1N2vbRkLWrM6LIker9A-

\r\r

See you on Tuesday!

\r\r

Thanks,

\r\r

Luigi and Fulvio

\r", + } + ], + }, + }, +}; + +const _ex_getCourseVirtualClassrooms_resp = #{ + returnType: #{ + statusCode: 200, + body: #{ + data: #[ + #{ + id: 149336, + title: "CYB / lecture 28.09.2021 (TLS, slides 1-40)", + teacherId: 1847, + coverUrl: "https://lucapezzolla.com/cover.jpg", + videoUrl: "https://video.polito.it/dl/BE7C779FC37D50996EE1FF32B6BC7FAE/6305E087/vc2021/252258/64cdcfc29ac1cd827d20ff1fa62c512eade6b3c0-1632832182985.mp4", + createdAt: utcDateTime.fromISO("2021-09-28T14:29:00Z"), + duration: "02h 56m", + type: "recording", + }, + #{ + id: 150397, + title: "CYB / lecture 01.10.2021 (TLS, slides 41-55)", + teacherId: 1847, + coverUrl: "https://lucapezzolla.com/cover.jpg", + videoUrl: "https://video.polito.it/dl/0BC53A27F4776D8A6809D28EB4CB3C9F/6305E087/vc2021/252258/e5e7a53da68cebd5cff1a585659092fcfeca651a-1633074845891.mp4", + createdAt: utcDateTime.fromISO("2021-10-01T09:54:00Z"), + duration: "01h 31m", + type: "recording", + }, + #{ + id: 151650, + title: "CYB / lecture 5.10.2021 (TLS, slides 56-end, + SSH all slides)", + teacherId: 1847, + coverUrl: "https://lucapezzolla.com/cover.jpg", + videoUrl: "https://video.polito.it/dl/56DA5556ECD96ED30EC6F8CBAB704285/6305E087/vc2021/252258/c30092cca256f522f64774e19538d43909ce558b-1633437688385.mp4", + createdAt: utcDateTime.fromISO("2021-10-05T14:41:00Z"), + duration: "02h 43m", + type: "recording", + } + ], + }, + }, +}; + +const _ex_getNextLecture_resp = #{ + returnType: #{ + statusCode: 200, + body: #{ + data: #{ + id: 12131312, + startsAt: utcDateTime.fromISO("2021-09-28T14:30:00Z"), + endsAt: utcDateTime.fromISO("2021-09-28T17:30:00Z"), + place: #{ + buildingId: "TO_CIT22", + floorId: "XPTE", + name: "Aula 1P", + roomId: "036", + siteId: "TO_CIT", + }, + type: "Lezione", + description: null, + courseId: 252258, + courseName: "Human Computer Interaction", + teacherId: 1847, + virtualClassrooms: #[ + #{ id: 149336, title: "CYB / lecture 28.09.2021 (TLS, slides 1-40)" } + ], + }, + }, + }, +}; diff --git a/src/examples/esc.tsp b/src/examples/esc.tsp new file mode 100644 index 0000000..8e4ac6b --- /dev/null +++ b/src/examples/esc.tsp @@ -0,0 +1,16 @@ +import "@typespec/http"; + +using Http; + +namespace PolitoAPI; + +const _ex_esc_delete_err = #{ + returnType: #{ + statusCode: 500, + body: #{ + code: 500, + message: "An error occurred", + errors: #[#{ code: 500, message: "An error occurred", careerId: 123456 }], + }, + }, +}; diff --git a/src/examples/exams.tsp b/src/examples/exams.tsp new file mode 100644 index 0000000..42db9a2 --- /dev/null +++ b/src/examples/exams.tsp @@ -0,0 +1,62 @@ +import "@typespec/http"; + +using Http; + +namespace PolitoAPI; + +// Exams list example +const _ex_getExams_resp = #{ + returnType: #{ + statusCode: 200, + body: #{ + data: #[ + #{ + id: 888137, + courseId: 262147, + courseShortcode: "01UDROV", + courseName: "Cybersecurity (AA-ZZ)", + teacherId: 1847, + type: "Scritto", + status: "booked", + bookingStartsAt: null, + bookingEndsAt: utcDateTime.fromISO("2022-08-23T14:00:00Z"), + examStartsAt: utcDateTime.fromISO("2022-08-29T08:00:00Z"), + examEndsAt: utcDateTime.fromISO("2022-08-29T10:00:00Z"), + bookedCount: 12, + availableCount: 8, + moduleNumber: 1, + notes: null, + places: #[], + isReschedulable: false, + question: null, + feedback: "Esiste già una prenotazione per l'esame in questione", + requestReason: null, + requestDetails: null, + }, + #{ + id: 887981, + courseId: 262789, + courseShortcode: "01NYHOV", + courseName: "System and device programming (AA-ZZ)", + teacherId: 2893, + type: "Esami scritti a risposta aperta o chiusa tramite PC", + status: "available", + bookingStartsAt: null, + bookingEndsAt: utcDateTime.fromISO("2022-09-02T14:00:00Z"), + examStartsAt: utcDateTime.fromISO("2022-09-08T14:00:00Z"), + examEndsAt: utcDateTime.fromISO("2022-09-08T18:00:00Z"), + bookedCount: 42, + availableCount: 108, + moduleNumber: 1, + notes: null, + places: #[], + isReschedulable: false, + question: null, + feedback: null, + requestReason: null, + requestDetails: null, + } + ], + }, + }, +}; diff --git a/src/examples/news.tsp b/src/examples/news.tsp new file mode 100644 index 0000000..5e5986e --- /dev/null +++ b/src/examples/news.tsp @@ -0,0 +1,42 @@ +import "@typespec/http"; + +using Http; + +namespace PolitoAPI; + +const _ex_news_item_overview = #{ + id: 123, + title: "Partecipazione, co-progettazione e impatto sociale. Sfide e opportunità per l'inclusione sociale", + isEvent: false, + shortDescription: "Seminario di presentazione del progetto", + eventStartTime: "Dal 30 agosto 2023", + eventEndTime: "Al 30 agosto 2023", + createdAt: utcDateTime.fromISO("2022-08-31T14:00:00Z"), +}; + +const _ex_news_item = #{ + id: 123, + title: "Partecipazione, co-progettazione e impatto sociale. Sfide e opportunità per l'inclusione sociale", + isEvent: false, + shortDescription: "Seminario di presentazione del progetto", + eventStartTime: "Dal 30 agosto 2023", + eventEndTime: "Al 30 agosto 2023", + createdAt: utcDateTime.fromISO("2022-08-31T14:00:00Z"), + location: "Energy Center - Via Paolo Borsellino 38, Torino", + htmlContent: "Martedì 18 aprile 2023 - presso l'Auditorium dell'Energy Center del Politecnico...", + extras: #[ + #{ + url: "https://", + description: "Bando", + type: "image", + sizeInKiloBytes: 305, + } + ], +}; + +const _ex_news_item_extra = #{ + url: "https://", + description: "Bando", + type: "image", + sizeInKiloBytes: 305, +}; diff --git a/src/examples/offering.tsp b/src/examples/offering.tsp new file mode 100644 index 0000000..09144a9 --- /dev/null +++ b/src/examples/offering.tsp @@ -0,0 +1,37 @@ +import "@typespec/http"; + +using Http; + +namespace PolitoAPI; + +const _ex_degree_overview = #{ id: "81-6", name: "Design e comunicazione" }; + +const _ex_offering_class = #{ + name: "Disegno industriale", + code: "L-4", + degrees: #[#{ id: "81-6", name: "Design e comunicazione" }], +}; + +const _ex_offering_course_overview = #{ + name: "System and device programming", + shortcode: "01NYHOV", + cfu: 10, + teachingYear: 1, + language: "en", + group: "Insegnamento a scelta 1", +}; + +const _ex_track = #{ + id: 2060, + name: "Design per la comunicazione", + courses: #[ + #{ + name: "System and device programming", + shortcode: "01NYHOV", + cfu: 10, + teachingYear: 1, + language: "en", + group: "Insegnamento a scelta 1", + } + ], +}; diff --git a/src/examples/people.tsp b/src/examples/people.tsp new file mode 100644 index 0000000..6488099 --- /dev/null +++ b/src/examples/people.tsp @@ -0,0 +1,44 @@ +import "@typespec/http"; + +using Http; + +namespace PolitoAPI; + +const _ex_person_overview = #{ + id: 2154, + firstName: "Fulvio", + lastName: "Corno", + picture: "https://www.swas.polito.it/_library/image_pub.asp?matricola=002154", + role: "Docente", +}; + +const _ex_phone_number = #{ full: "0110907053", internal: "7053" }; + +const _ex_person_course = #{ + id: 258674, + shortcode: "01NYHOV", + name: "Computer sciences", + role: "Collaboratore", + year: 2021, +}; + +const _ex_person = #{ + id: 2154, + firstName: "Fulvio", + lastName: "Corno", + picture: "https://www.swas.polito.it/_library/image_pub.asp?matricola=002154", + role: "Docente", + email: "fulvio.corno@polito.it", + phoneNumbers: #[#{ full: "0110907053", internal: "7053" }], + facilityShortName: "DAUIN", + profileUrl: "https://www.dauin.polito.it/personale/scheda/(matricola)/002154", + courses: #[ + #{ + id: 258674, + shortcode: "01NYHOV", + name: "Computer sciences", + role: "Collaboratore", + year: 2021, + } + ], +}; diff --git a/src/examples/places.tsp b/src/examples/places.tsp new file mode 100644 index 0000000..5960a39 --- /dev/null +++ b/src/examples/places.tsp @@ -0,0 +1,38 @@ +import "@typespec/http"; + +using Http; + +namespace PolitoAPI; + +const _ex_geo_location = #{ latitude: 45.064254, longitude: 7.657823 }; + +const _ex_place_category = #{ + id: "AULA", + name: "Aula", + showInMenu: false, + color: "lightBlue", + priority: 60, + highlighted: false, +}; + +const _ex_place = #{ id: "TO_CIT09_XPTE_088", capacity: 300 }; + +const _ex_getDepartments_resp = #{ + returnType: #{ + statusCode: 200, + body: #{ + data: #[ + #{ + id: "DAUIN", + name: "Dipartimento di Automatica e Informatica", + type: "DIP.", + }, + #{ + id: "DIMEAS", + name: "Dipartimento di Ingegneria Meccanica e Aerospaziale", + type: "DIP.", + } + ], + }, + }, +}; diff --git a/src/examples/student.tsp b/src/examples/student.tsp new file mode 100644 index 0000000..0b9a185 --- /dev/null +++ b/src/examples/student.tsp @@ -0,0 +1,46 @@ +import "@typespec/http"; + +using Http; + +namespace PolitoAPI; + +// Deadline examples for getDeadlines +const _ex_getDeadlines_resp = #{ + returnType: #{ + statusCode: 200, + body: #{ + data: #[ + #{ + name: "Termine per l'iscrizione e pagamento della prima rata, per gli studenti di anni successivi al primo", + type: "Iscrizioni e pagamento tasse", + date: plainDate.fromISO("2022-10-11"), + url: null, + }, + #{ + name: "Trasferimento da altri Atenei italiani", + type: "Trasferimenti e valutazioni carriere precedenti", + date: plainDate.fromISO("2022-10-14"), + url: null, + }, + #{ + name: "Termine per superare gli esami", + type: "Sessioni esami di laurea", + date: plainDate.fromISO("2022-11-12"), + url: null, + }, + #{ + name: "Termine iscrizione esame finale", + type: "Sessioni esami di laurea", + date: plainDate.fromISO("2022-11-14"), + url: null, + }, + #{ + name: "Periodo per la compilazione del piano carriera / carico didattico", + type: "Iscrizioni e pagamento tasse", + date: plainDate.fromISO("2022-11-25"), + url: null, + } + ], + }, + }, +}; diff --git a/src/examples/surveys.tsp b/src/examples/surveys.tsp new file mode 100644 index 0000000..d13e239 --- /dev/null +++ b/src/examples/surveys.tsp @@ -0,0 +1,30 @@ +import "@typespec/http"; + +using Http; + +namespace PolitoAPI; + +const _ex_survey_course_ref = #{ + id: 1, + name: "Course name", + shortcode: "01NYHOV", +}; + +const _ex_survey_taxonomy = #{ id: "CPD", name: "CPD" }; + +const _ex_survey = #{ + id: 1, + title: "Survey title", + subtitle: "Survey subtitle", + category: #{ id: "CPD", name: "CPD" }, + type: #{ id: "CPD", name: "CPD" }, + period: 2, + year: "2024", + isMandatory: true, + isCompiled: false, + compileDate: utcDateTime.fromISO("2022-08-31T14:00:00Z"), + url: "https://", + startsAt: utcDateTime.fromISO("2022-08-31T14:00:00Z"), + endsAt: utcDateTime.fromISO("2022-08-31T14:00:00Z"), + course: #{ id: 1, name: "Course name", shortcode: "01NYHOV" }, +}; diff --git a/src/examples/tickets.tsp b/src/examples/tickets.tsp new file mode 100644 index 0000000..13f2ca8 --- /dev/null +++ b/src/examples/tickets.tsp @@ -0,0 +1,49 @@ +import "@typespec/http"; + +using Http; + +namespace PolitoAPI; + +const _ex_ticket_faq = #{ + id: 3623, + question: "Ho dimenticato il mio nome utente e/o la password e non riesco più ad accedere ad Apply@Polito. Come posso fare?", + answer: "Clicca sul link "Codice e/o Password dimenticata?" presente sulla pagina di Log-in e segui le istruzioni.", +}; + +const _ex_ticket_subtopic = #{ id: 103, name: "Accesso studenti esterni" }; + +const _ex_ticket_topic = #{ + id: 61, + name: "ACCESSO LAUREE MAGISTRALI", + subtopics: #[#{ id: 103, name: "Accesso studenti esterni" }], +}; + +const _ex_ticket_attachment = #{ + id: 0, + filename: "screenshot.png", + mimeType: "image/png", + sizeInKiloBytes: 305, +}; + +const _ex_ticket_overview = #{ + id: 1145890, + subject: "Sostituzione esame in piano carriera", + message: "Buongiorno, vi contatto per sostituire A con B", + status: TicketStatus.new, + hasAttachments: true, + isFromAgent: false, + agentId: null, + unreadCount: 2, + createdAt: utcDateTime.fromISO("2022-08-31T14:00:00Z"), + updatedAt: utcDateTime.fromISO("2022-08-31T14:00:00Z"), +}; + +const _ex_ticket_reply = #{ + id: 1145890, + message: "Non si può fare.", + isFromAgent: true, + agentId: 351, + isRead: true, + createdAt: utcDateTime.fromISO("2022-08-31T14:00:00Z"), + attachments: #[], +}; diff --git a/src/main.tsp b/src/main.tsp new file mode 100644 index 0000000..b02b37b --- /dev/null +++ b/src/main.tsp @@ -0,0 +1,43 @@ +import "@typespec/http"; +import "@typespec/openapi"; +import "@typespec/openapi3"; + +import "./common.tsp"; + +import "./routes/auth.tsp"; +import "./routes/student.tsp"; +import "./routes/bookings.tsp"; +import "./routes/courses.tsp"; +import "./routes/exams.tsp"; +import "./routes/esc.tsp"; +import "./routes/news.tsp"; +import "./routes/people.tsp"; +import "./routes/places.tsp"; +import "./routes/tickets.tsp"; +import "./routes/job-offers.tsp"; +import "./routes/offering.tsp"; +import "./routes/surveys.tsp"; + +import "./version.tsp"; + +using Http; +using OpenAPI; + +@service(#{ title: "Polito Students API" }) +@info(#{ + version: version, + license: #{ + name: "CC BY-NC 4.0", + url: "https://creativecommons.org/licenses/by-nc/4.0/", + }, +}) +@server( + "https://app.didattica.polito.it/mock/api", + "Mock server (uses example data)" +) +@server( + // Decorators are processed in reverse order, so this is the default + "https://app.didattica.polito.it/api", + "Production server" +) +namespace PolitoAPI; diff --git a/src/routes/auth.tsp b/src/routes/auth.tsp new file mode 100644 index 0000000..6c8fa6f --- /dev/null +++ b/src/routes/auth.tsp @@ -0,0 +1,256 @@ +import "@typespec/http"; +import "@typespec/openapi3"; + +import "../common.tsp"; +import "../examples/auth.tsp"; + +using Http; +using OpenAPI; + +namespace PolitoAPI; + +@example(_ex_identity) +model Identity { + @example("s290683") + username: string; + + @example("student") + type: string; + + @example("5a54f626-4b7e-488e-a0e3-300f54051510") + clientId: string; + + @example("c679fa38ff665df6a676acd833194385") + token: string; +} + +model Device { + name?: string; + platform: string; + version?: string; + `model`?: string; + manufacturer?: string; +} + +model UpdateInfo { + suggestUpdate: boolean; +} + +model ClientVersionRequest { + @example("1060200") + buildNumber: string; + + @example("1.6.2") + appVersion: string; +} + +model FcmRegistrationRequest { + @example("a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4") + fcmRegistrationToken?: string; +} + +model Client { + ...ClientVersionRequest; + ...FcmRegistrationRequest; + + @example("Students app") + name: string; + + @example("5a54f626-4b7e-488e-a0e3-300f54051510") + id?: string; +} + +model LoginRequestBase { + client?: Client; + device?: Device; + preferences: UpdatePreferencesRequest; +} + +model LoginCredentialsBasic extends LoginRequestBase { + @example("s290683") + username: string; + + @example("moreSecret") + password: string; + + loginType: "basic"; +} + +model LoginCredentialsSSO extends LoginRequestBase { + @example("123456-1234-5678-123456") + uid: string; + + @example("abcdef-abcd-efgh-abcdef") + key: string; + + loginType: "sso"; +} + +@oneOf +@discriminated(#{ envelope: "none", discriminatorPropertyName: "loginType" }) +union LoginRequest { + basic: LoginCredentialsBasic, + sso: LoginCredentialsSSO, +} + +@example(_ex_switchCareer_req) +model SwitchCareerRequest { + @example("s290683") + username: string; + + client?: Client; + device?: Device; +} + +@example(_ex_validateMfa_req) +model ValidateMfaRequest { + @example("EDUP000123456") + serial: string; + + @example("65ba9e0e5aac421a9150991638a9d697") + nonce: string; + + @example("83e08d9fc4be3de046318eb3c2c9ae4ede1374a5423a1487b92febc70d106994") + signature: string; + + @example(false) + decline?: boolean; +} + +model MfaChallenge { + @example("EDUP000123456") + serial: string; + + @example("dGhpcyBzaG91bGQgYmUgYW4gZWNkcyBwdWJsaWMga2V5Li4uIHdoYXQgZGlkIHlvdSB0aGluayB0aGlzIHdhcz8hIPCfp5AK") + challenge: string; + + @example(utcDateTime.fromISO("2025-01-01T00:00:00Z")) + requestTs: utcDateTime; + + @example(utcDateTime.fromISO("2025-01-01T01:00:00Z")) + expirationTs: utcDateTime; +} + +model MfaStatusResponse { + /** Current MFA status for the user */ + status: "active" | "locked" | "available" | "unavailable" | "needsReauth"; + + /** Additional information about the MFA session. + * Present only if status is `active` or `locked` */ + details: { + @example(utcDateTime.fromISO("2021-09-30T00:00:00Z")) + lastAuth: utcDateTime; + + @example(1) + authCount: integer; + + @example("EDUP0000123456") + serial?: string; + + @example("My phone") + description?: string; + } | null; +} + +model LinkToService { + url: string; +} + +model AppInfoRequest { + ...ClientVersionRequest; + ...FcmRegistrationRequest; +} + +@tag("Auth") +@route("/auth") +interface Auth { + @post + @route("/login") + @summary("Login") + login(@body body: LoginRequest): OkDataResponse | BaseErrors; + + @post + @route("/switch-career") + @summary("Switch career | Cambia carriera") + switchCareer( + @body body: SwitchCareerRequest, + ): OkDataResponse | BaseErrors; + + /** Invalidates the provided token */ + @delete + @route("/logout") + @summary("Logout") + logout(): NoContentResponse | BaseErrors; + + @patch(#{ implicitOptionality: true }) + @route("/client") + @summary("Update client version fields | Aggiorna i campi di versione del client") + appInfo(@body body: AppInfoRequest): OkDataResponse | BaseErrors; +} + +@example(_ex_enrolMfa_req) +model EnrolMfaRequest { + @example("some identifier you chose") + description: string; + + @example("dGhpcyBzaG91bGQgYmUgYW4gZWNkcyBwdWJsaWMga2V5Li4uIHdoYXQgZGlkIHlvdSB0aGluayB0aGlzIHdhcz8hIPCfp5AK") + pubkey: string; +} + +@tag("Auth") +@route("/auth/mfa") +interface Mfa { + @post + @route("/enrol") + @summary("Enroll a new PUSH token") + @opExample(_ex_enrolMfa_resp) + enrolMfa(@body body: EnrolMfaRequest): OkDataCreatedResponse<{ + @example("EDUP000123456") + serial: string; + }> | BaseErrors; + + @post + @route("/validate") + @summary("Validate a challenge") + @opExample(_ex_validateMfa_resp) + validateMfa(@body body: ValidateMfaRequest): OkDataResponse<{ + @example(true) + success: boolean; + }> | BaseErrors; + + @get + @route("/challenge") + @summary("Fetch pending challenge") + @opExample(_ex_fetchChallenge_resp) + fetchChallenge(): OkDataResponse | BaseErrors; + + @route("/status") + @get + @summary("Get MFA status for the current user") + getMfaStatus(): OkDataResponse | BaseErrors; +} + +@tag("Auth") +@route("/auth/serviceLink") +interface ServiceLink { + @get + @route("/moodle/{course}") + @summary("Get authorised service link for Moodle course") + getMoodleLink( + /** Moodle course identifier */ + @path course: integer, + ): OkDataResponse | BaseErrors; + + @get + @route("/liveClass/{meetingID}") + @summary("Get authorised service link for LiveClass meeting") + getLiveClassLink( + /** LiveClass meeting identifier */ + @path meetingID: string, + ): OkDataResponse | BaseErrors; + + @get + @route("/mail") + @summary("Get authorised service link for Mail") + getMailLink(): OkDataResponse | BaseErrors; +} diff --git a/src/routes/bookings.tsp b/src/routes/bookings.tsp new file mode 100644 index 0000000..e46636b --- /dev/null +++ b/src/routes/bookings.tsp @@ -0,0 +1,262 @@ +import "@typespec/http"; +import "@typespec/openapi3"; + +import "../common.tsp"; +import "../examples/bookings.tsp"; + +using Http; + +namespace PolitoAPI; +model BookingTopicOverview { + @example("DIDATTICA_ING") + id: string; + + @example("Segreteria Didattica Ingegneria") + title: string; + + @example("Servizi della Segreteria Didattica Ingegneria") + description: string; +} + +model BookingTopicLeaf extends BookingTopicOverview { + @example(true) + isEnabled: boolean; + + @example("") + disclaimer: string; + + @example(true) + showCalendar: boolean; + + @example(15) + slotLength: integer; + + @example(4) + slotsPerHour: integer; + + /** Start date of the booking period */ + startDate: plainDate | null; + + @example(8) + startHour: integer; + + @example(18) + endHour: integer; + + @example(2) + maxBookingsPerDay: integer; + + @example(true) + canBeCancelled: boolean; + + /** Number of days per week the booking is available, starting from startDate weekday, or monday if missing */ + @example(5) + daysPerWeek: integer; + + /** Specifies if the topic requires the agenda display */ + @example(false) + agendaView: boolean; +} + +model BookingSubtopic extends BookingTopicLeaf { + requirements: { + name?: string; + url?: string; + }[]; +} + +@example(_ex_booking_topic) +model BookingTopic extends BookingTopicLeaf { + subtopics: BookingSubtopic[]; +} + +@example(_ex_booking_slot) +model BookingSlot { + @example(103051) + id: integer; + + @example("") + description: string; + + @example(false) + isBooked: boolean; + + @example(false) + canBeBooked: boolean; + + @example(false) + hasSeats: boolean; + + @example(false) + hasSeatSelection: boolean; + + @example(2) + places: integer; + + @example(2) + bookedPlaces: integer; + + @example("Il turno è pieno") + feedback: string; + + location: { + name?: string; + description?: string; + type?: string; + address?: string; + }; + + @example(utcDateTime.fromISO("2021-10-05T10:00:00Z")) + startsAt: utcDateTime; + + @example(utcDateTime.fromISO("2021-10-05T10:15:00Z")) + endsAt: utcDateTime; + + @example(utcDateTime.fromISO("2021-10-01T00:00:00Z")) + bookingStartsAt: utcDateTime; + + @example(utcDateTime.fromISO("2021-10-05T09:00:00Z")) + bookingEndsAt: utcDateTime; +} + +model BookingSeatCell { + @example(20018) + id: integer; + + @example("available") + status: "available" | "booked" | "unavailable"; + + @example("A5") + label: string; +} +model BookingSeatsRow { + id?: integer; + label: string; + seats: BookingSeatCell[]; +} +model BookingSeats { + totalCount: integer; + availableCount: integer; + rows: BookingSeatsRow[]; +} + +@tag("Bookings") +@route("/booking-topics") +interface BookingTopics { + @get + @summary("List booking topics | Elenca ambiti di prenotazione") + getBookingTopics(): OkDataResponse | BaseErrors; + + @route("/{bookingTopicId}/slots") + @get + @summary("Show booking slots | Mostra turni prenotabili") + getBookingSlots( + @path bookingTopicId: string, + + /** First day - defaults to monday of current week */ + @query fromDate?: plainDate, + + /** Last day - defaults to sunday of current week */ + @query toDate?: plainDate, + ): OkDataResponse | BaseErrors; + + @route("/{bookingTopicId}/slots/{bookingSlotId}/seats") + @get + @summary("Show seats for a booking slots | Mostra posti prenotabili") + getBookingSeats( + @path bookingTopicId: string, + @path bookingSlotId: string, + ): OkDataResponse | BaseErrors; +} + +model BookingLocationCheck { + enabled: boolean; + checked: boolean; + latitude: string | null; + longitude: string | null; + radiusInKm: numeric | null; +} + +model BookingPhysicalPlaceRef extends PlaceRef { + description: string; +} + +model BookingVirtualPlaceRef { + name: string; + url: string; +} + +@discriminated(#{ envelope: "none", discriminatorPropertyName: "type" }) +union BookingPlaceRef { + place: BookingPhysicalPlaceRef, + virtualPlace: BookingVirtualPlaceRef, +} + +model Booking { + @example(258674) + id: integer; + + @example("") + description: string; + + topic: BookingTopicOverview; + subtopic: BookingTopicOverview | null; + + @example(utcDateTime.fromISO("2021-10-05T10:00:00Z")) + startsAt: utcDateTime; + + @example(utcDateTime.fromISO("2021-10-05T10:15:00Z")) + endsAt: utcDateTime; + + seat: { + id?: integer; + row?: string; + column?: string; + } | null; + + @example(utcDateTime.fromISO("2021-10-05T09:00:00Z")) + cancelableUntil: utcDateTime; + + location: BookingPlaceRef; + locationCheck?: BookingLocationCheck; +} + +model UpdateBookingRequest { + @example(true) + isLocationChecked: boolean; +} + +model CreateBookingRequest { + @example(103051) + slotId: integer; + + @example(20018) + seatId?: integer; +} + +@tag("Bookings") +@route("/bookings") +interface BookingsManagement { + @get + @summary("List bookings | Elenca prenotazioni") + getBookings(): OkDataResponse | BaseErrors; + + @post + @summary("Create booking | Crea prenotazione") + createBooking( + @body body: CreateBookingRequest, + ): NoContentResponse | BaseErrors; + + @route("/{bookingId}") + @delete + @summary("Delete booking | Cancella prenotazione") + deleteBooking(@path bookingId: integer): NoContentResponse | BaseErrors; + + @route("/{bookingId}") + @patch(#{ implicitOptionality: false }) + @summary("Update booking | Aggiorna prenotazione") + updateBooking( + @path bookingId: integer, + @body body: UpdateBookingRequest, + ): NoContentResponse | BaseErrors; +} diff --git a/src/routes/courses.tsp b/src/routes/courses.tsp new file mode 100644 index 0000000..ff42ed2 --- /dev/null +++ b/src/routes/courses.tsp @@ -0,0 +1,404 @@ +import "@typespec/http"; +import "@typespec/openapi3"; + +import "../common.tsp"; + +import "../examples/courses.tsp"; + +using Http; +using OpenAPI; + +namespace PolitoAPI; + +model CourseModuleEdition { + @example("2021") + year: string; + + @example(244577) + id: integer; +} + +@example(_ex_course_module) +model CourseModule { + /** The identifier for the current instance of this course. + * If null this is not a teaching (such as thesis), it won't have a course page */ + @example(258674) + id: integer | null; + + @example("System and device programming") + name: string; + + /** The semester(s) this course belongs to */ + @example("2-2") + teachingPeriod: string; + + @example(2893) + teacherId: integer | null; + + @example("Mario Rossi") + teacherName: string | null; + + /** Previous editions of this course that were part of the student's PSP */ + @example(#[#{ id: 244577, year: "2021" }]) + previousEditions: CourseModuleEdition[]; + + @example(false) + isOverBooking: boolean; + + /** Included in the PSP | Incluso nel carico didattico */ + @example(true) + isInPersonalStudyPlan: boolean; + + @example("2022") + year: string; +} + +model CourseOverview extends CourseModule { + @example(10) + cfu: integer; + + @example("01NYHOV") + shortcode: string; + + modules: CourseModule[] | null; +} + +model Course { + /** The identifier for the current instance of this course. If null this is not a teaching (such as thesis), it won't have a course page */ + @example(258674) + id: integer | null; + + @example("System and device programming") + name: string; + + @example("01NYHOV") + shortcode: string; + + @example(10) + cfu: integer; + + /** The semester(s) this course belongs to */ + @example("2-2") + teachingPeriod: string; + + @example(2893) + teacherId: integer | null; + + @example(false) + isOverBooking: boolean; + + /** Included in the PSP | Incluso nel carico didattico */ + @example(true) + isInPersonalStudyPlan: boolean; + + @example("2022") + year: string; + + links: { + @example("https://docs.google.com/document/d/13hpWEDQxziSkhSU0PuqxMXntqZYp3ffDKZ2-umQ7Ywo/edit?usp=sharing") + url: string; + + @example("Calendario settimanale dei contenuti del corso") + description?: string; + }[]; + moodleCourses: { + @example("Analisi Matematica I") + name?: string; + + @example("645376") + id?: string; + }[] | null; + + @example(#[#{ id: 244577, year: "2021" }]) + vcPreviousYears: CourseModuleEdition[]; + + /** Other editions/courses to be included in virtual classrooms */ + vcOtherCourses: { + ...CourseModuleEdition; + + @example("Fisica II") + name: string; + }[]; + + notifications: { + @example(true) + notices: boolean; + + @example(true) + files: boolean; + + @example(true) + lectures: boolean; + }; + staff: { + role: string; + + @example(244577) + id: numeric; + }[]; +} + +@example(_ex_course_directory) +model CourseDirectory { + id: string; + name: string; + files: CourseDirectoryContent; + type: "directory"; +} + +@example(_ex_course_file_overview) +model CourseFileOverview { + @example("33352562") + id: string; + + @example("Laboratori") + name: string; + + @example(305) + sizeInKiloBytes: integer; + + @example("application/x-zip-compressed") + mimeType: string; + + @example(utcDateTime.fromISO("2022-08-31T14:00:00Z")) + createdAt: utcDateTime; + + type: "file"; + + @example("deadbeefcafebabe0000000000000000") + checksum: string; +} + +@oneOf +@discriminated(#{ envelope: "none", discriminatorPropertyName: "type" }) +union CourseDirectoryEntry { + directory: CourseDirectory, + file: CourseFileOverview, +} + +model CourseDirectoryContent is CourseDirectoryEntry[]; + +model VideoLecture { + id: integer; + title: string; + teacherId: integer; + abstract: string; + coverUrl: string; + videoUrl: string; + audioUrl: string; + createdAt: utcDateTime; + duration: string; +} + +model VirtualClassroomBase { + id: integer; + title: string; + createdAt: utcDateTime; + teacherId: integer; +} + +model VirtualClassroomRecording extends VirtualClassroomBase { + coverUrl: string | null; + videoUrl: string; + duration: string; + type: "recording"; +} + +model VirtualClassroomLive extends VirtualClassroomBase { + meetingId?: string; + type: "live"; +} + +@discriminated(#{ envelope: "none", discriminatorPropertyName: "type" }) +union VirtualClassroom { + live: VirtualClassroomLive, + recording: VirtualClassroomRecording, +} + +@route("/v2/courses") +@tag("Courses") +interface CoursesV2 { + @get + @summary("List courses | Elenca corsi") + @opExample(_ex_courses_list) + getCourses(): OkDataResponse | BaseErrors; +} + +model CourseAssignmentUpload { + description: HttpPart; + file: HttpPart; +} + +model CourseAssignment { + @example(947503) + id: integer; + + @example("laboratorio 3") + description: string; + + @example("application/x-zip-compressed") + mimeType: string; + + @example("lab_03.zip") + filename: string; + + @example(utcDateTime.fromISO("2022-09-02T14:00:00Z")) + uploadedAt: utcDateTime; + + deletedAt: utcDateTime | null; + + @example("https://file.didattica.polito.it/down/ELABORATI_PRE/1003948/S290683/6791f0016c78599138828211522fa84d/62cebc94") + url: string; + + @example(305) + sizeInKiloBytes: integer; +} + +model CourseNotices { + @example(360724) + id: integer; + + @example(utcDateTime.fromISO("2022-07-03T14:00:00Z")) + publishedAt: utcDateTime; + + expiresAt: utcDateTime | null; + + @example("

Conferma spostamento orario esame:

Ore 15

") + content: string; +} + +model CoursePreferencesRequest { + notifications?: { + @example(true) + notices?: boolean; + + @example(true) + files?: boolean; + + @example(true) + lectures?: boolean; + }; +} + +model UpdateAssignmentRequest { + delivery?: boolean; + state?: "submitted" | "uploaded"; +} + +@tag("Courses") +@route("/courses") +interface Courses { + @route("/{courseId}") + @get + @summary("Show course | Mostra corso") + getCourse(@path courseId: integer): OkDataResponse | BaseErrors; + + @route("/{courseId}/files") + @get + @summary("List files | Elenca file") + @opExample(_ex_getCourseFiles_resp) + getCourseFiles( + @path courseId: integer, + ): OkDataResponse | BaseErrors; + + @route("/{courseId}/files/{fileId}") + @get + @summary("Download file | Scarica file") + getCourseFile(@path courseId: integer, @path fileId: string): + | OkResponse + | RedirectResponse + | NotFoundResponse + | BaseErrors; + + @route("/{courseId}/assignments") + @get + @summary("List assignments | Elenca elaborati") + @opExample(_ex_getCourseAssignments_resp) + getCourseAssignments( + @path courseId: integer, + ): OkDataResponse | BaseErrors; + + @route("/{courseId}/assignments") + @post + @summary("Upload assignment | Carica elaborato") + uploadCourseAssignment( + @path courseId: integer, + @header contentType: "multipart/form-data", + @multipartBody body: CourseAssignmentUpload, + ): NoContentResponse | BaseErrors; + + @route("/{courseId}/assignments/{assignmentId}") + @patch(#{ implicitOptionality: false }) + @summary("Update assignment | Aggiorna elaborato") + updateAssignment( + @path courseId: integer, + @path assignmentId: integer, + @body body: UpdateAssignmentRequest, + ): NoContentResponse | BaseErrors; + + @route("/{courseId}/guide") + @get + @summary("Show guide | Mostra guida") + @opExample(_ex_getCourseGuide_resp) + getCourseGuide( + @path courseId: integer, + ): OkDataResponse | BaseErrors; + + @route("/{courseId}/notices") + @get + @summary("List notices | Elenca avvisi") + @opExample(_ex_getCourseNotices_resp) + getCourseNotices( + @path courseId: integer, + ): OkDataResponse | BaseErrors; + + @route("/{courseId}/virtual-classrooms") + @get + @summary("List virtual classrooms | Elenca virtual classroom") + @opExample(_ex_getCourseVirtualClassrooms_resp) + getCourseVirtualClassrooms( + @path courseId: integer, + + /** Filter virtual classrooms by their live status */ + @query live?: boolean, + ): OkDataResponse | BaseErrors; + + @route("/{courseId}/videolectures") + @get + @summary("List videolectures | Elenca videolezioni") + getCourseVideolectures( + @path courseId: integer, + ): OkDataResponse | BaseErrors; + + @route("/{courseId}/nextLecture") + @get + @summary("Get next lecture | Ottieni prossima lezione") + @opExample(_ex_getNextLecture_resp) + getNextLecture(@path courseId: integer): OkDataResponse | BaseErrors; + + @route("/{courseId}/preferences") + @patch(#{ implicitOptionality: false }) + @summary("Update course preferences | Aggiorna preferenze del corso") + updateCoursePreferences( + @path courseId: integer, + @body body: CoursePreferencesRequest, + ): NoContentResponse | BaseErrors; +} + +@tag("Lectures") +@route("/lectures") +interface Lectures { + @get + @summary("List lectures | Elenca lezioni") + @opExample(_ex_getLectures_resp) + getLectures( + /** First day - defaults to 7 days before today */ + @query fromDate?: plainDate, + + /** Last day - defaults to 7 days after today */ + @query toDate?: plainDate, + + /** Only include lectures belonging to these courses */ + @query(#{ explode: true }) `courseIds[]`?: numeric[], + ): OkDataResponse | BaseErrors; +} diff --git a/src/routes/esc.tsp b/src/routes/esc.tsp new file mode 100644 index 0000000..381f00c --- /dev/null +++ b/src/routes/esc.tsp @@ -0,0 +1,26 @@ +import "@typespec/http"; +import "@typespec/openapi3"; + +import "../common.tsp"; +import "../examples/esc.tsp"; + +namespace PolitoAPI; + +using Http; + +@tag("Esc") +@route("/esc") +interface Esc { + @delete + @summary("Delete all Student data on the ESC-Router (and all student's cards) | Cancella tutti i dati dello studente sul Router ESC (e tutte le carte dello studente)") + @opExample(_ex_esc_delete_err) + escDelete(): NoContentResponse | BaseErrors | EscServerError; + + @get + @summary("retrieve european student card | recupera la european student card") + escGet(): OkDataResponse | BaseErrors; + @route("/create") + @post + @summary("request european student card | richiedi la european student card") + escRequest(): CreatedResponse | BaseErrors; +} diff --git a/src/routes/exams.tsp b/src/routes/exams.tsp new file mode 100644 index 0000000..8cbc3fe --- /dev/null +++ b/src/routes/exams.tsp @@ -0,0 +1,97 @@ +import "@typespec/http"; +import "@typespec/openapi3"; + +import "../common.tsp"; +import "../examples/exams.tsp"; + +using Http; + +namespace PolitoAPI; + +model Exam { + id: integer; + courseId: numeric; + courseShortcode: string; + courseName: string; + teacherId: integer; + type: string; + places?: PlaceRef[]; + status: + | "available" + | "booked" + | "requestable" + | "requested" + | "requestAccepted" + | "requestRejected" + | "unavailable"; + bookingStartsAt: utcDateTime | null; + bookingEndsAt: utcDateTime; + examStartsAt: utcDateTime | null; + examEndsAt: utcDateTime | null; + bookedCount: integer; + availableCount: integer; + question: { + id: integer; + statement: string; + options: string[]; + } | null; + feedback: string | null; + + /** If true, the student can ask the professor to reschedule the exam */ + isReschedulable: boolean; + + notes: string | null; + + /** The module number, if this is a module */ + moduleNumber: integer; + + requestReason: string | null; + requestDetails: string | null; +} + +model RescheduleExamRequest { + @example("01UDROV") + courseShortcode: string; + + requestReason: string; + requestDetails: string; +} + +model BookExamRequest { + @example("01UDROV") + courseShortcode: string; + + questionId?: integer; + questionOption?: integer; + requestReason?: string; +} + +@tag("Exams") +@route("/exams") +interface Exams { + @get + @summary("List exams | Elenca esami") + @opExample(_ex_getExams_resp) + getExams(): OkDataResponse | BaseErrors; + + @route("/{examId}/booking") + @delete + @summary("Delete exam booking | Annulla prenotazione esame") + deleteExamBookingById(@path examId: integer): NoContentResponse | BaseErrors; + + @route("/{examId}/booking") + @post + @summary("Book exam | Prenota esame") + bookExam( + @path examId: integer, + @body body: BookExamRequest, + ): NoContentResponse | BaseErrors; + + @route("/{examId}/rescheduleRequest") + @post + @summary("Ask to reschedule an exam | Chiedi di spostare un esame") + rescheduleExam( + @path examId: integer, + @body body: RescheduleExamRequest, + ): NoContentResponse | BaseErrors; +} diff --git a/src/routes/job-offers.tsp b/src/routes/job-offers.tsp new file mode 100644 index 0000000..3b382aa --- /dev/null +++ b/src/routes/job-offers.tsp @@ -0,0 +1,46 @@ +import "@typespec/http"; +import "@typespec/openapi3"; + +import "../common.tsp"; + +namespace PolitoAPI; + +using Http; + +model JobOfferOverview { + id: numeric; + title: string; + location: string; + companyId: numeric; + companyName: string; + createdAtDate: plainDate; + endsAtDate: plainDate; +} + +model JobOffer extends JobOfferOverview { + companyLocation: string; + companyMission: string; + description: string; + requirements: string; + contractType: string; + salary: string; + contactInformation: string | null; + url: string | null; + email: string | null; + + @example(2) + freePositions: numeric; +} + +@tag("Job offers") +@route("/job-offers") +interface JobOffers { + @get + @summary("List job offers | Elenca offerte di lavoro") + getJobOffers(): OkDataResponse | BaseErrors; + + @route("/{jobOfferId}") + @get + @summary("Show a job offer | Mostra un'offerta di lavoro") + getJobOffer(@path jobOfferId: integer): OkDataResponse | BaseErrors; +} diff --git a/src/routes/news.tsp b/src/routes/news.tsp new file mode 100644 index 0000000..306c116 --- /dev/null +++ b/src/routes/news.tsp @@ -0,0 +1,72 @@ +import "@typespec/http"; +import "@typespec/openapi3"; + +import "../common.tsp"; +import "../examples/news.tsp"; + +namespace PolitoAPI; + +using Http; + +@example(_ex_news_item_overview) +model NewsItemOverview { + @example(123) + id: numeric; + + @example("Partecipazione, co-progettazione e impatto sociale. Sfide e opportunità per l'inclusione sociale") + title: string; + + @example(false) + isEvent: boolean; + + @example("Seminario di presentazione del progetto") + shortDescription: string; + + @example("Dal 30 agosto 2023") + eventStartTime: string | null; + + @example("Al 30 agosto 2023") + eventEndTime: string | null; + + @example(utcDateTime.fromISO("2022-08-31T14:00:00Z")) + createdAt: utcDateTime; +} + +@example(_ex_news_item_extra) +model NewsItemExtra { + @example("https://") + url: string; + + @example("Bando") + description: string; + + @example("image") + type: "link" | "file" | "image"; + + @example(305) + sizeInKiloBytes: integer | null; +} + +@example(_ex_news_item) +model NewsItem extends NewsItemOverview { + @example("Energy Center - Via Paolo Borsellino 38, Torino") + location: string; + + @example("Martedì 18 aprile 2023 - presso l'Auditorium dell'Energy Center del Politecnico...") + htmlContent: string; + + extras: NewsItemExtra[]; +} + +@tag("News") +@route("/news") +interface News { + @get + @summary("List news | Lista news") + getNews(): OkDataResponse | BaseErrors; + + @route("/{newsItemId}") + @get + @summary("Show news | Mostra news") + getNewsItem(@path newsItemId: numeric): OkDataResponse | BaseErrors; +} diff --git a/src/routes/offering.tsp b/src/routes/offering.tsp new file mode 100644 index 0000000..44e7aa2 --- /dev/null +++ b/src/routes/offering.tsp @@ -0,0 +1,221 @@ +import "@typespec/http"; +import "@typespec/openapi3"; + +import "../common.tsp"; +import "../examples/offering.tsp"; + +namespace PolitoAPI; + +using Http; + +@example(_ex_degree_overview) +model DegreeOverview { + @example("81-6") + id: string; + + @example("Design e comunicazione") + name: string; +} + +@example(_ex_offering_class) +model OfferingClass { + @example("Disegno industriale") + name: string; + + @example("L-4") + code: string; + + degrees: DegreeOverview[]; +} + +@example(_ex_track) +model Track { + @example(2060) + id: numeric; + + @example("Design per la comunicazione") + name: string; + + courses: OfferingCourseOverview[]; +} + +model Degree { + ...DegreeOverview; + level: string; + department: { + name: string; + }; + faculty: { + id?: string; + name?: string; + }; + location: string; + duration: string; + class: { + code: string; + name: string; + }; + year: numeric; + + /** All the available editions of this degree */ + editions: string[]; + + @example(#["Corso tenuto in italiano"]) + notes: string[]; + + objectives: { + @example("Obiettivi formativi") + title: string; + + content: string; + }; + jobOpportunities: { + title: string; + content: string; + }; + tracks: Track[]; +} + +@example(_ex_offering_course_overview) +model OfferingCourseOverview { + @example("System and device programming") + name: string; + + @example("01NYHOV") + shortcode: string; + + @example(10) + cfu: integer; + + /** The year this course belongs to in this degree */ + @example(1) + teachingYear: integer; + + @example("en") + language: "it" | "en"; + + @example("Insegnamento a scelta 1") + group: string | null; +} + +model OfferingCourseStaff { + role: string; + id: numeric; + courseId: numeric; +} + +model CourseHours { + lecture?: integer; + tutoring?: integer; + classroomExercise?: integer; + labExercise?: integer; +} + +model OfferingCourse { + name: string; + shortcode: string; + cfu: integer; + + /** The semester(s) this course belongs to */ + teachingPeriod: string; + + languages: ("it" | "en")[]; + year: string; + hours: CourseHours; + + /** All the available editions of this course */ + editions: string[]; + + staff: OfferingCourseStaff[]; + guide: GuideSection[]; +} + +model Teacher { + id: integer; + firstName: string; + lastName: string; +} + +model GradeCount { + grade: + | "18" + | "19" + | "20" + | "21" + | "22" + | "23" + | "24" + | "25" + | "26" + | "27" + | "28" + | "29" + | "30" + | "30L"; + count: integer; +} + +model YearStatistics { + succeeded: integer; + failed: integer; + grades: GradeCount[]; + averageGrade: numeric | null; +} + +model PreviousYearsToCompare { + year: integer; + succeeded: integer; + failed: integer; +} + +model CourseStatistics { + shortcode: string; + year: integer; + teacher: Teacher; + totalEnrolled: integer; + totalSucceeded: integer; + totalFailed: integer; + firstYear: YearStatistics; + otherYears: YearStatistics; + previousYearsToCompare: PreviousYearsToCompare[]; + years: integer[]; + teachers: Teacher[]; +} + +model OfferingResponse { + bachelor?: OfferingClass[]; + master?: OfferingClass[]; +} + +@tag("Offering") +@route("/offering") +interface Offering { + @get + @summary("Get offering | Mostra offerta formativa") + getOffering(): OkDataResponse | BaseErrors; + + @route("/degrees/{degreeId}") + @get + @summary("Show a degree | Mostra un corso di laurea") + getOfferingDegree( + @path degreeId: string, + @query year?: string, + ): OkDataResponse | BaseErrors; + + @route("/courses/{courseShortcode}") + @get + @summary("Show offering course | Mostra corso dell'offerta formativa") + getOfferingCourse( + @path courseShortcode: string, + @query year?: string, + ): OkDataResponse | BaseErrors; + + @route("/courses/{courseShortcode}/statistics") + @get + @summary("Retrieve course statistics | Recupera le statistiche dell'insegnamento") + getCourseStatistics( + @path courseShortcode: string, + @query year?: string, + @query teacherId?: string, + ): OkDataResponse | BaseErrors; +} diff --git a/src/routes/people.tsp b/src/routes/people.tsp new file mode 100644 index 0000000..368802c --- /dev/null +++ b/src/routes/people.tsp @@ -0,0 +1,91 @@ +import "@typespec/http"; +import "@typespec/openapi3"; + +import "../common.tsp"; +import "../examples/people.tsp"; + +namespace PolitoAPI; + +using Http; + +@example(_ex_person_course) +model PersonCourse { + /** The identifier for this course */ + @example(258674) + id: integer; + + /** The shortcode for this course */ + @example("01NYHOV") + shortcode?: string; + + /** The name of the course */ + @example("Computer sciences") + name: string; + + /** The role of the person in this course */ + @example("Collaboratore") + role: string; + + /** The year this course was given in */ + @example(2021) + year: numeric; +} + +@example(_ex_person_overview) +model PersonOverview { + @example(2154) + id: numeric; + + @example("Fulvio") + firstName: string; + + @example("Corno") + lastName: string; + + @example("https://www.swas.polito.it/_library/image_pub.asp?matricola=002154") + picture: string | null; + + @example("Docente") + role: string; +} + +@example(_ex_phone_number) +model PhoneNumber { + @example("0110907053") + full: string; + + @example("7053") + internal: string; +} + +@example(_ex_person) +model Person extends PersonOverview { + @example("fulvio.corno@polito.it") + email: string; + + phoneNumbers: PhoneNumber[]; + + @example("DAUIN") + facilityShortName: string | null; + + @example("https://www.dauin.polito.it/personale/scheda/(matricola)/002154") + profileUrl: string; + + courses: PersonCourse[] | null; +} + +@tag("People") +@route("/people") +interface People { + @get + @summary("Search people | Cerca persone") + getPeople( + /** Filter people containing 'search' in their full name */ + @query search: string, + ): OkDataResponse | BaseErrors; + + @get + @route("/{personId}") + @summary("Show person | Mostra persona") + getPerson(@path personId: numeric): OkDataResponse | BaseErrors; +} diff --git a/src/routes/places.tsp b/src/routes/places.tsp new file mode 100644 index 0000000..a931cf7 --- /dev/null +++ b/src/routes/places.tsp @@ -0,0 +1,224 @@ +import "@typespec/http"; +import "@typespec/openapi3"; + +import "../common.tsp"; +import "../examples/places.tsp"; + +namespace PolitoAPI; + +using Http; + +@example(_ex_place_category) +model PlaceCategory { + @example("AULA") + id: string; + + @example("Aula") + name: string; + + showInMenu?: boolean; + + @example("lightBlue") + color?: string = "gray"; + + @format("url") markerUrl?: string; + + /** A MapBox style priority number. 0 means most important, larger numbers are less important */ + @example(60) + priority?: numeric = 100; + + /** If true, markers of this category should be shown initially on the map */ + @example(false) + highlighted?: boolean; +} + +model RootPlaceCategory { + ...PlaceCategory; + subCategories?: PlaceCategory[]; +} + +model PlaceCategoryOverview { + ...PlaceCategory; + subCategory?: PlaceCategory; +} + +model GeoJsonPolygon { + type: "Feature"; + geometry: { + type: "Polygon"; + coordinates: numeric[][][]; + }; +} + +@example(_ex_geo_location) +model GeoLocation { + @example(45.064254) + latitude: numeric; + + @example(7.657823) + longitude: numeric; +} + +model Building { + ...BuildingOverview; + ...GeoLocation; +} +model BuildingOverview { + id: string; + name: string; + siteId: string; + category: PlaceCategoryOverview; + geoJson?: GeoJsonPolygon; +} + +model Department { + id: string; + name: string | null; + type: string; +} +model Floor { + id: string; + name: string; + level: numeric; +} + +model PlaceOverview { + ...GeoLocation; + id: string; + room: { + id: string; + name: string; + }; + category: PlaceCategoryOverview; + site: { + id: string; + name: string; + }; + building: BuildingOverview; + floor: Floor; + department: Department; +} + +model Site { + id: string; + name: string; + ...GeoLocation; + floors: Floor[]; + city: { + id: string; + name: string; + }; + + /** A delta in degrees that applied to the centroid + * coordinates of the site determines its extent */ + extent: numeric; +} + +model FreeRoom { + ...PlaceRef; + id?: string; + freeFrom: utcDateTime; + freeTo: utcDateTime; +} + +model Place { + ...PlaceOverview; + geoJson: GeoJsonPolygon; + + @example(300) + capacity: integer; + + structure: { + name: string; + shortName: string; + email: string | null; + phone: string | null; + } | null; + resources: { + name: string; + description: string; + category: string; + }[]; +} + +@tag("Places") +@route("/v2/place-categories") +interface PlaceCategories { + @get + @summary("List place categories | Elenca categorie luoghi") + getPlaceCategories( + @query siteId?: string, + ): OkDataResponse | BaseErrors; +} + +@tag("Places") +@route("/v2/sites") +interface Sites { + @get + @summary("List sites | Elenca sedi") + getSites(): OkDataResponse | BaseErrors; + + @route("/{siteId}/free-rooms") + @get + @summary("List free rooms | Elenca aule libere") + getFreeRooms( + /** Date */ + @query date: string, + + /** Start time */ + @query timeFrom: string, + + /** End time */ + @query timeTo: string, + + @path siteId: string, + ): OkDataResponse | BaseErrors; + + @route("/{siteId}/buildings") + @get + @summary("List buildings | Elenca edifici") + getBuildings( + @path siteId: string, + + /** Filter buildings containing 'search' in their name */ + @query search?: string, + + @query placeCategoryId?: string, + @query(#{ explode: true }) `placeSubCategoryId[]`?: string[], + ): OkDataResponse | BaseErrors; +} + +@tag("Places") +@route("/v2/places") +interface Places { + @get + @summary("Search places | Cerca luoghi") + getPlaces( + /** Filter places containing 'search' in their name */ + @query search?: string, + + @query placeCategoryId?: string, + @query(#{ explode: true }) `placeSubCategoryId[]`?: string[], + @query siteId?: string, + @query buildingId?: string, + @query floorId?: string, + @query departmentId?: string, + ): OkDataResponse | BaseErrors; + + @get + @route("/{placeId}") + @summary("Show place | Mostra luogo") + getPlace(@path placeId: string): OkDataResponse | BaseErrors; +} + +@tag("Places") +@route("/departments") +interface Departments { + @get + @summary("List departments | Elenca dipartimenti") + @opExample(_ex_getDepartments_resp) + getDepartments( + @query siteId?: string, + @query departmentType?: string, + ): OkDataResponse | BaseErrors; +} diff --git a/src/routes/student.tsp b/src/routes/student.tsp new file mode 100644 index 0000000..d264433 --- /dev/null +++ b/src/routes/student.tsp @@ -0,0 +1,489 @@ +import "@typespec/http"; +import "@typespec/openapi3"; + +import "../common.tsp"; +import "../examples/student.tsp"; + +using Http; + +namespace PolitoAPI; + +model Deadline { + id?: numeric; + + @example("Termine per l'iscrizione e pagamento della prima rata") + name: string; + + @example("Iscrizioni e pagamento tasse") + type: string; + + url: string | null; + + @example(plainDate.fromISO("2022-10-11")) + date: plainDate; +} + +model ProvisionalGrade { + @example(654632) + id: numeric; + + @example(887981) + examId: numeric; + + @example("01NYHOV") + courseShortcode: string; + + @example("System and device programming") + courseName: string; + + @example(2893) + teacherId: integer; + + @example(10) + credits: numeric; + + @example("30") + grade: string; + + @example(plainDate.fromISO("2022-07-15")) + date: plainDate; + + @example("published") + state: "published" | "confirmed" | "rejected"; + + @example("Pubblicata") + stateDescription: string; + + teacherMessage: string | null; + + @example(false) + isWithdrawn: boolean; + + @example(false) + isFailure: boolean; + + @example(true) + canBeAccepted: boolean; + + @example(true) + canBeRejected: boolean; + + confirmedAt: plainDate | null; + rejectedAt: utcDateTime | null; + + @example(utcDateTime.fromISO("2022-07-31T23:59:59Z")) + rejectingExpiresAt: utcDateTime; +} + +model ProvisionalGradeState { + @example("published") + id: string; + + @example("Pubblicata") + name: string; + + @example("La valutazione è stata pubblicata dal docente") + description: string; +} + +model ExamGrade { + @example("System and device programming") + courseName: string; + + @example(10) + credits: numeric; + + @example("30L") + grade: string; + + @example(plainDate.fromISO("2022-07-15")) + date: plainDate; + + @example(2893) + teacherId: integer | null; + + /** Points for "on-time" exams - null the student is not eligible for on-time exams or the exam does not grant on-time points */ + @example(2) + onTimeExamPoints: numeric | null; + + @example("01NYHOV") + shortcode: string; + + @example(2021) + academicYear: integer; + + /** Defines whether the credits from the exam count toward the total required for graduation */ + @example(true) + creditsCountTowardsDegree: boolean; +} + +model EmailBadge { + @example("99+") + unreadEmails: string; +} + +@example(MessageType.secretariat) +enum MessageType { + emergency, + event, + personal, + teacher, + secretariat, + exams, + mfa, +} + +model Message { + @example(123) + id: numeric; + + @example("Nuovo avviso da System and device programming") + title: string; + + @example("Ricordati di...") + message: string | null; + + @example(MessageType.teacher) + type: MessageType; + + @example(2893) + senderId: numeric | null; + + @example(utcDateTime.fromISO("2022-08-31T14:00:00Z")) + sentAt: utcDateTime; + + @example(false) + isRead: boolean; +} + +model Notification { + @example(123) + id: numeric; + + @example("Nuovo avviso da System and device programming") + title: string; + + @example("Ricordati di...") + message: string | null; + + /** An array representing the hierarchical path to the object this notification is related to (replicates the navigation/modules structure) */ + @example(#["courses", "258674", "notices"]) + scope?: string[]; + + @example(utcDateTime.fromISO("2022-08-31T14:00:00Z")) + sentAt: utcDateTime; + + @example(false) + isRead: boolean; +} + +model NotificationPreferences { + @example(true) + notices: boolean; + + @example(true) + files: boolean; + + @example(true) + lectures: boolean; + + @example(true) + bookings: boolean; + + @example(true) + tickets: boolean; +} + +model UpdateNotificationPreferencesRequest { + data: { + @example(true) + notices?: boolean; + + @example(true) + files?: boolean; + + @example(true) + lectures?: boolean; + + @example(true) + bookings?: boolean; + + @example(true) + tickets?: boolean; + }; +} + +model GuideField { + label: string; + value: string; + isCopyEnabled?: boolean; +} + +model Guide { + id: string; + listTitle: string; + title: string; + intro: string; + fields: GuideField[]; + sections: GuideSection[]; +} + +model EmergencyHour { + @example("Monday") + day: string; + + @example("09:00") + open: string; + + @example("18:00") + close: string; +} + +model EmergencySite { + places: PlaceRef[]; + + @example("+39 011 090 1234") + phoneNumber: string; + + hours: EmergencyHour[]; + + @example(true) + backup: boolean; +} + +model EmergencyCta { + @example("Emergenza 112") + text: string; + + action: EmergencySite; + + @example("fa-phone") + icon?: string; + + @example("#E11D48") + color: string; + + @example(true) + primary: boolean; +} + +model EmergencyContent { + @example("Emergency Title") + title?: string; + + @example("Important information regarding the emergency.") + content: string; + + cta: EmergencyCta; +} + +model EmergencyResponse { + @example("fa-warning") + icon: string; + + @example("Emergency Name") + name: string; + + content: EmergencyContent[]; + cta: EmergencyCta[]; +} + +model Student { + @example("s290683") + username: string; + + @example("Luca") + firstName: string; + + @example("Pezzolla") + lastName: string; + + @example("active") + status: "active" | "closed" | "cancelled" | "graduated" | "career_closed"; + + /** All the ids related to this student */ + @example(#["290683", "213956"]) + allCareerIds: string[]; + + @example("81-6") + degreeId: string; + + @example("LM-32") + degreeCode: string; + + @example("Corso di Laurea Magistrale in") + degreeLevel: string; + + @example("INGEGNERIA INFORMATICA (COMPUTER ENGINEERING)") + degreeName: string; + + @example(2021) + firstEnrollmentYear: integer; + + @example(2022) + lastEnrollmentYear: integer; + + @example(false) + isCurrentlyEnrolled: boolean; + + @example(27.5) + averageGrade: numeric | null; + + @example(105) + estimatedFinalGrade: numeric | null; + + /** Purged grade is only available for bachelor degree students */ + averageGradePurged: numeric | null; + + /** Purged grade is only available for bachelor degree students */ + estimatedFinalGradePurged: numeric | null; + + /** Specify whether to use purgedAverageFinalGrade or averageFinalGrade as the graduation grade shown */ + usePurgedAverageFinalGrade: boolean; + + /** Master's admission grade is only available for bachelor degree students */ + mastersAdmissionAverageGrade: numeric | null; + + /** Total points for "on-time" exams - null if "on-time" exams are not applicable for the student's position (max value = maxOnTimeExamPoints) */ + totalOnTimeExamPoints: numeric | null; + + /** Maximum points for "on-time" exams */ + maxOnTimeExamPoints: numeric; + + /** Credits excluded from calculating the purged grade */ + excludedCreditsNumber: numeric | null; + + totalCredits: integer; + totalAttendedCredits: integer; + totalAcquiredCredits: integer; + enrollmentCredits: integer; + enrollmentAttendedCredits: integer; + enrollmentAcquiredCredits: integer; + smartCardPicture: string | null; + europeanStudentCard: EuropeanStudentCard; +} + +@tag("Student") +interface StudentNs { + @route("/me") + @get + @summary("Retrieve student profile | Recupera il profilo studente") + getStudent(): OkDataResponse | BaseErrors; + + @route("/deadlines") + @get + @summary("List deadlines | Elenca scadenze") + @opExample(_ex_getDeadlines_resp) + getDeadlines( + /** First day - defaults to 7 days before today */ + @query fromDate?: plainDate, + + /** Last day - defaults to 7 days after today */ + @query toDate?: plainDate, + ): OkDataResponse | BaseErrors; + + @route("/grades") + @get + @summary("Retrieve student grades | Recupera i voti dello studente") + getStudentGrades(): OkDataResponse | BaseErrors; + + @route("/unreadEmails") + @get + @summary("Retrieve student's unread emails number | Recupera il numero di email non lette dello studente") + getUnreadEmailsNumber(): OkDataResponse | BaseErrors; + + @route("/preferences") + @patch(#{ implicitOptionality: true }) + @summary("Update device preferences | Aggiorna preferenze del dispositivo") + updateDevicePreferences( + @body body: UpdatePreferencesRequest, + ): NoContentResponse | BaseErrors; + + @route("/guides") + @get + @summary("Get guides | Mostra guide") + getGuides(): OkDataResponse | BaseErrors; + + @route("/emergencecies") + @get + @summary("Show emergencecies text and number | Mostra testi e numeri di emergenza") + getEmergencies(): EmergencyResponse | BaseErrors; +} + +@tag("Student") +@route("/messages") +interface Messages { + @get + @summary("List messages | Elenca messaggi") + getMessages(): OkDataResponse | BaseErrors; + + @route("/{messageId}") + @delete + @summary("Delete a message | Cancella un messaggio") + deleteMessage(@path messageId: integer): NoContentResponse | BaseErrors; + + @route("/{messageId}/read") + @put + @summary("Mark a message as read | Segna un messaggio come letto") + markMessageAsRead(@path messageId: integer): NoContentResponse | BaseErrors; +} + +@tag("Student") +@route("/notifications") +interface Notifications { + @get + @summary("List notifications | Elenca notifiche") + getNotifications(): OkDataResponse | BaseErrors; + + @route("/preferences") + @get + @summary("Get notification preferences | Ottieni preferenze notifiche") + getNotificationPreferences( + ): OkDataResponse | BaseErrors; + + @route("/preferences") + @patch(#{ implicitOptionality: true }) + @summary("Update notification preferences | Aggiorna preferenze notifiche") + updateNotificationPreferences( + @body body: UpdateNotificationPreferencesRequest, + ): NoContentResponse | BaseErrors; + + @route("/{notificationId}") + @delete + @summary("Delete a notification | Cancella una notifica") + deleteNotification( + @path notificationId: integer, + ): NoContentResponse | BaseErrors; + + @route("/{notificationId}/read") + @put + @summary("Mark a notification as read | Segna una notifica come letta") + markNotificationAsRead( + @path notificationId: integer, + ): NoContentResponse | BaseErrors; +} + +@tag("Student") +@route("/provisional-grades") +interface ProvisionalGrades { + @get + @summary("Retrieve student provisional grades | Recupera le valutazioni provvisorie dello studente") + getStudentProvisionalGrades(): OkResponse<{ + data: ProvisionalGrade[]; + states: ProvisionalGradeState[]; + }> | BaseErrors; + + @route("/{provisionalGradeId}/accept") + @post + @summary("Accept provisional grade | Accetta valutazione provvisoria") + acceptProvisionalGrade( + @path provisionalGradeId: integer, + ): NoContentResponse | BaseErrors; + + @route("/{provisionalGradeId}/reject") + @post + @summary("Reject provisional grade | Rifiuta valutazione provvisoria") + rejectProvisionalGrade( + @path provisionalGradeId: integer, + ): NoContentResponse | BaseErrors; +} diff --git a/src/routes/surveys.tsp b/src/routes/surveys.tsp new file mode 100644 index 0000000..7783fac --- /dev/null +++ b/src/routes/surveys.tsp @@ -0,0 +1,79 @@ +import "@typespec/http"; +import "@typespec/openapi3"; + +import "../common.tsp"; +import "../examples/surveys.tsp"; + +namespace PolitoAPI; + +using Http; + +@example(_ex_survey_course_ref) +model SurveyCourseRef { + @example(1) + id: numeric; + + @example("Course name") + name: string; + + @example("01NYHOV") + shortcode: string; +} + +@example(_ex_survey_taxonomy) +model SurveyTaxonomy { + @example("CPD") + id: string; + + @example("CPD") + name: string; +} + +@example(_ex_survey) +model Survey { + @example(1) + id: numeric; + + @example("Survey title") + title: string; + + @example("Survey subtitle") + subtitle: string | null; + + category: SurveyTaxonomy; + type: SurveyTaxonomy; + + @example(2) + period: numeric; + + @example("2024") + year: string; + + @example(true) + isMandatory: boolean; + + @example(false) + isCompiled: boolean; + + @example(utcDateTime.fromISO("2022-08-31T14:00:00Z")) + compileDate: utcDateTime | null; + + @example("https://") + url: string; + + @example(utcDateTime.fromISO("2022-08-31T14:00:00Z")) + startsAt: utcDateTime; + + @example(utcDateTime.fromISO("2022-08-31T14:00:00Z")) + endsAt: utcDateTime; + + course?: SurveyCourseRef | null; +} + +@tag("Surveys") +@route("/surveys") +interface Surveys { + @get + @summary("Get surveys | Mostra survey") + getSurveys(): OkDataResponse | BaseErrors; +} diff --git a/src/routes/tickets.tsp b/src/routes/tickets.tsp new file mode 100644 index 0000000..7bb1192 --- /dev/null +++ b/src/routes/tickets.tsp @@ -0,0 +1,219 @@ +import "@typespec/http"; +import "@typespec/openapi3"; + +import "../common.tsp"; +import "../examples/tickets.tsp"; + +namespace PolitoAPI; + +using Http; + +@example(_ex_ticket_faq) +model TicketFAQ { + @example(3623) + id: numeric; + + @example("Ho dimenticato il mio nome utente e/o la password e non riesco più ad accedere ad Apply@Polito. Come posso fare?") + question: string; + + @example("Clicca sul link "Codice e/o Password dimenticata?" presente sulla pagina di Log-in e segui le istruzioni.") + answer: string; +} + +@example(_ex_ticket_subtopic) +model TicketSubtopic { + @example(103) + id: numeric; + + @example("Accesso studenti esterni") + name: string; +} + +@example(_ex_ticket_topic) +model TicketTopic { + ...TicketSubtopic; + subtopics: TicketSubtopic[]; +} + +enum TicketStatus { + new, + pending, + closed, +} + +@example(_ex_ticket_attachment) +model TicketAttachment { + @example(0) + id: numeric; + + @example("screenshot.png") + filename: string; + + @example("image/png") + mimeType: string; + + @example(305) + sizeInKiloBytes: integer; +} + +@example(_ex_ticket_overview) +model TicketOverview { + @example(1145890) + id: numeric; + + @example("Sostituzione esame in piano carriera") + subject: string; + + @example("Buongiorno, vi contatto per sostituire A con B") + message: string; + + status: TicketStatus; + + @example(true) + hasAttachments: boolean; + + /** If true, this ticket was opened by an agent (not by the student) */ + @example(false) + isFromAgent: boolean; + + agentId: numeric | null; + + @example(2) + unreadCount: numeric; + + @example(utcDateTime.fromISO("2022-08-31T14:00:00Z")) + createdAt: utcDateTime; + + @example(utcDateTime.fromISO("2022-08-31T14:00:00Z")) + updatedAt: utcDateTime; +} + +@example(_ex_ticket_reply) +model TicketReply { + @example(1145890) + id: numeric; + + @example("Non si può fare.") + message: string; + + /** If true, this reply was sent by an agent (not by the student) */ + @example(true) + isFromAgent: boolean; + + @example(351) + agentId: numeric | null; + + @example(true) + isRead: boolean; + + @example(utcDateTime.fromISO("2022-08-31T14:00:00Z")) + createdAt: utcDateTime; + + attachments: TicketAttachment[]; +} + +model Ticket { + ...TicketOverview; + replies: TicketReply[]; + attachments: TicketAttachment[]; +} + +model CreateTicketRequest { + subject: HttpPart; + message: HttpPart; + subtopicId: HttpPart; + attachment?: HttpPart; +} + +model ReplyTicketRequest { + message: HttpPart; + attachment?: HttpPart; +} + +@tag("Tickets") +@route("/ticket-faqs") +interface TicketFAQs { + @get + @summary("Search ticket FAQs | Ricerca FAQ ticket") + searchTicketFAQs( + @header `Accept-Language`?: "it" | "en" = "it", + + /** Find FAQs containing 'search' in the question */ + @query search: string, + ): OkDataResponse | BaseErrors; +} + +@tag("Tickets") +@route("/ticket-topics") +interface TicketTopics { + @get + @summary("List ticket topics | Elenca ambiti ticket") + getTicketTopics(): OkDataResponse | BaseErrors; +} + +@tag("Tickets") +@route("/tickets") +interface Tickets { + @get + @summary("List tickets | Elenca ticket") + getTickets(): OkDataResponse | BaseErrors; + + @post + @summary("Create ticket | Crea ticket") + createTicket( + @header contentType: "multipart/form-data", + @multipartBody body: CreateTicketRequest, + ): OkDataResponse | BaseErrors; + + @route("/{ticketId}") + @get + @summary("Show a ticket | Mostra un ticket") + getTicket(@path ticketId: integer): OkDataResponse | BaseErrors; + + @route("/{ticketId}/read") + @put + @summary("Mark a ticket as read | Segna un ticket come letto") + markTicketAsRead(@path ticketId: integer): NoContentResponse | BaseErrors; + + @route("/{ticketId}/close") + @put + @summary("Mark a ticket as closed | Segna un ticket come chiuso") + markTicketAsClosed(@path ticketId: integer): NoContentResponse | BaseErrors; + + @route("/{ticketId}/attachments/{attachmentId}") + @get + @summary("Download ticket attachment | Scarica allegato del ticket") + getTicketAttachment(@path ticketId: integer, @path attachmentId: integer): + | { + @header contentType: "application/octet-stream"; + @body body: bytes; + } + | RedirectResponse + | NotFoundResponse + | BaseErrors; + + @route("/{ticketId}/replies") + @post + @summary("Reply to a ticket | Rispondi ad un ticket") + replyToTicket( + @path ticketId: integer, + @header contentType: "multipart/form-data", + @multipartBody body: ReplyTicketRequest, + ): NoContentResponse | BaseErrors; + + @route("/{ticketId}/replies/{replyId}/attachments/{attachmentId}") + @get + @summary("Download ticket reply attachment | Scarica allegato di una risposta al ticket") + getTicketReplyAttachment( + @path ticketId: integer, + @path replyId: integer, + @path attachmentId: integer, + ): + | { + @header contentType: "application/octet-stream"; + @body body: bytes; + } + | RedirectResponse + | NotFoundResponse + | BaseErrors; +} diff --git a/src/version.tsp b/src/version.tsp new file mode 100644 index 0000000..2c02524 --- /dev/null +++ b/src/version.tsp @@ -0,0 +1,3 @@ +// Placeholder file for versioning purposes; +// do not delete or alter this file. +const version = "0.0.1"; diff --git a/tspconfig.yaml b/tspconfig.yaml new file mode 100644 index 0000000..2f04161 --- /dev/null +++ b/tspconfig.yaml @@ -0,0 +1,5 @@ +emit: + - "@typespec/openapi3" +options: + "@typespec/openapi3": + emitter-output-dir: "{project-root}/dist"