{
  "openapi": "3.0.1",
  "info": {
    "title": "SoftLanding.ApiService | customer",
    "version": "1.0.0"
  },
  "paths": {
    "/customer/dashboard": {
      "get": {
        "tags": [
          "Dashboard (Customer)"
        ],
        "summary": "Get the customer dashboard aggregate.",
        "description": "Returns a single read-only snapshot object for the signed-in customer's home screen, assembled in\none call instead of from the individual customer endpoints.\n\nIt is scoped to the signed-in customer and aggregates across all of that customer's own students:\n- counters (remaining prepaid credit in CHF, outstanding unpaid invoices, upcoming lessons, unread\n  notifications),\n- upcoming lessons across the customer's students,\n- course invites awaiting the customer's response,\n- recently issued invoices and recent notifications.\n\nThe figures are point-in-time and computed on each request. No other customer's data is included.",
        "operationId": "GetCustomerDashboard",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerDashboardGet"
                }
              }
            }
          }
        }
      }
    },
    "/customer/customers": {
      "get": {
        "tags": [
          "Customer (Customer)"
        ],
        "summary": "List customers (customer portal).",
        "description": "Returns the customer account(s) the signed-in user can see in the self-service portal — normally\nonly their own record — each as a `CustomerGet` with the customer type (Company or Private Person),\ncompany name, correspondence language, contact person, billing address and the list of the\ncustomer's students. Office-internal fields (VAT number, notes, activity flag) are not exposed.\nRecords belonging to other customers are never returned. Soft-deleted records are excluded by\ndefault. Filter with `searchTerm` (matches company name, contact first/last name, email and phone),\n`customerTypeId`, `city` and `postalCode`.\n\nSupports pagination and sorting: send an optional `Range` request header (`0-49` = first 50,\n`-50` = last 50, `50` = from index 50; 0-based, end inclusive) plus the `orderBy` (a property\nname of the returned object, case-insensitive) and `desc` query parameters. The body is a plain\nJSON array; the total count is returned in the `Content-Range` response header\n(`items {start}-{end}/{total}`). Status is `206` when a `Range` is sent, `416` if the range is invalid.",
        "operationId": "GetCustomersCustomer",
        "parameters": [
          {
            "name": "SearchTerm",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ShowRemoved",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "CustomerTypeId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "City",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "PostalCode",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "description": "Pagination window (zero-based, end inclusive): `{start}-{end}` e.g. `0-49`; `-{n}` = last n; `{n}` = first n. When set, the response is 206 with a `Content-Range` header.",
            "schema": {
              "type": "string",
              "example": "0-49"
            }
          },
          {
            "name": "orderBy",
            "in": "query",
            "description": "Sort by this result property name (case-insensitive). Unknown property → 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "desc",
            "in": "query",
            "description": "Sort descending when true (default false). Applied before pagination.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CustomerGet"
                  }
                }
              }
            }
          },
          "206": {
            "description": "Partial Content — returned when a `Range` header is present. Body is the requested window.",
            "headers": {
              "Content-Range": {
                "description": "`items {start}-{end}/{total}` (empty page → `items */{total}`).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CustomerGet"
                  }
                }
              }
            }
          },
          "416": {
            "description": "Range Not Satisfiable — the `Range` header is malformed or starts beyond the last item."
          }
        }
      },
      "post": {
        "tags": [
          "Customer (Customer)"
        ],
        "summary": "Register a customer (private person self-registration).",
        "description": "Self-registers a new private-person customer account from the `CustomerPost` body and returns the\ncreated `CustomerGet` (with its generated id). The new account starts with `ProfileConfirmed`\nset to false so the portal can prompt for a first-login profile review. Returns `400` with\nvalidation details if the body is invalid.",
        "operationId": "CreateCustomerCustomer",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomerPost"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerGet"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/customers/{id}": {
      "get": {
        "tags": [
          "Customer (Customer)"
        ],
        "summary": "Get a single customer by id.",
        "description": "Returns a single customer account by its id as a `CustomerGet` (self-view; office-internal fields\nexcluded). Returns `404` if no such customer exists or if it does not belong to the signed-in user.",
        "operationId": "GetCustomerCustomerById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Customer (Customer)"
        ],
        "summary": "Partially update a customer.",
        "description": "Partially updates an existing customer account: only the fields present in the `CustomerPatch`\nbody are changed, the rest stay as they are. Returns the updated `CustomerGet`. Returns `404` if\nno such customer exists or it does not belong to the signed-in user; `400` on validation errors.",
        "operationId": "UpdateCustomerCustomer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomerPatch"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Customer (Customer)"
        ],
        "summary": "Delete a customer (soft by default; ?hard=true to hard-delete).",
        "description": "Deletes a customer account. By default this is a soft delete — the account is hidden from normal\nlistings but can be restored; pass `?hard=true` to remove it permanently. Returns `204`, or `404`\nif no such customer exists or it does not belong to the signed-in user.",
        "operationId": "DeleteCustomerCustomer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "hard",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/customers/{id}/restore": {
      "post": {
        "tags": [
          "Customer (Customer)"
        ],
        "summary": "Restore a soft-deleted customer.",
        "description": "Restores a previously soft-deleted customer account so it appears in normal listings again.\nReturns `204`, or `404` if no such customer exists or it does not belong to the signed-in user.",
        "operationId": "RestoreCustomerCustomer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/students": {
      "get": {
        "tags": [
          "Student (Customer)"
        ],
        "summary": "List the current customer's students.",
        "description": "Returns the students that belong to the signed-in customer â€” each a `StudentGet` with identity\n(name, birthdate, native language), contact details, subjects (language/level pairs), lifecycle\nstatus and the student's related courses and lessons. Office-internal fields (teacher notes,\ninternal exam records) are excluded. Students of other customers are never returned. Soft-deleted\nstudents are excluded by default. Filter with `searchTerm` (matches first name, last name and\nemail), `nativeLanguageId`, `subjectLanguageId` (resolvable via `/lookups/â€¦`), `isChild` and\n`status`.\n\nSupports pagination and sorting: send an optional `Range` request header (`0-49` = first 50,\n`-50` = last 50, `50` = from index 50; 0-based, end inclusive) plus the `orderBy` (a property\nname of the returned object, case-insensitive) and `desc` query parameters. The body is a plain\nJSON array; the total count is returned in the `Content-Range` response header\n(`items {start}-{end}/{total}`). Status is `206` when a `Range` is sent, `416` if the range is invalid.",
        "operationId": "GetStudentsCustomer",
        "parameters": [
          {
            "name": "SearchTerm",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ShowRemoved",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "NativeLanguageId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "IsChild",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "SubjectLanguageId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Status",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/NullableOfEStudentStatus"
            }
          },
          {
            "name": "AccountStatus",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/NullableOfEAccountStatus"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "description": "Pagination window (zero-based, end inclusive): `{start}-{end}` e.g. `0-49`; `-{n}` = last n; `{n}` = first n. When set, the response is 206 with a `Content-Range` header.",
            "schema": {
              "type": "string",
              "example": "0-49"
            }
          },
          {
            "name": "orderBy",
            "in": "query",
            "description": "Sort by this result property name (case-insensitive). Unknown property → 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "desc",
            "in": "query",
            "description": "Sort descending when true (default false). Applied before pagination.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/StudentGet"
                  }
                }
              }
            }
          },
          "206": {
            "description": "Partial Content — returned when a `Range` header is present. Body is the requested window.",
            "headers": {
              "Content-Range": {
                "description": "`items {start}-{end}/{total}` (empty page → `items */{total}`).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/StudentGet"
                  }
                }
              }
            }
          },
          "416": {
            "description": "Range Not Satisfiable — the `Range` header is malformed or starts beyond the last item."
          }
        }
      },
      "post": {
        "tags": [
          "Student (Customer)"
        ],
        "summary": "Add a student to the current customer's account.",
        "description": "Adds a new student to the signed-in customer's account from the `StudentPost` body and returns\nthe created `StudentGet` (with its generated id). The new student is automatically linked to the\nsigned-in customer. Returns `400` with validation details if the body is invalid.",
        "operationId": "CreateStudentCustomer",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StudentPost"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StudentGet"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/students/{id}": {
      "get": {
        "tags": [
          "Student (Customer)"
        ],
        "summary": "Get a single student by id (customer).",
        "description": "Returns a single student by its id as a `StudentGet` (office-internal fields excluded). Returns\n`404` if no such student exists or if it does not belong to the signed-in customer.",
        "operationId": "GetStudentCustomerById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StudentGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Student (Customer)"
        ],
        "summary": "Partially update one of the customer's students.",
        "description": "Partially updates one of the customer's students: only the fields present in the `StudentPatch`\nbody are changed, the rest stay as they are. Returns the updated `StudentGet`. Returns `404` if\nno such student exists or it does not belong to the signed-in customer; `400` on validation errors.",
        "operationId": "UpdateStudentCustomer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StudentPatch"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StudentGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Student (Customer)"
        ],
        "summary": "Delete one of the customer's students (soft by default; ?hard=true to hard-delete).",
        "description": "Deletes one of the customer's students. By default this is a soft delete â€” the student is hidden\nfrom normal listings but can be restored; pass `?hard=true` to remove it permanently. Returns\n`204`, or `404` if no such student exists or it does not belong to the signed-in customer.",
        "operationId": "DeleteStudentCustomer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "hard",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/students/{id}/resend-invitation": {
      "post": {
        "tags": [
          "Student (Customer)"
        ],
        "summary": "Re-send one of my students' password-setup mail.",
        "description": "Triggers the onboarding (\"magic link\") mail again for one of the signed-in customer's own students â€”\nthe one added through \"Add new student\" who has not followed the first mail. It also repairs a\nprovisioning run that did not finish, which is how a student whose `accountStatus` reads `Failed` is\nfixed. The mail is rendered in the student's correspondence language.\n\nOnly the customer's OWN students are reachable: another customer's student is `404`, never `403`.\nReturns `204` on success, `400` if the student has no email address, `409` if the account already\ncompleted onboarding (a forgotten password is reset by the student through the sign-in page, not\nfrom here), and `503` when no identity provider is configured for this environment.",
        "operationId": "ResendStudentInvitationCustomer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/students/{id}/set-password": {
      "post": {
        "tags": [
          "Student (Customer)"
        ],
        "summary": "Set a one-time password for one of my students' logins.",
        "description": "Sets a one-time password on one of the signed-in customer's own students and forces the student to\nchoose their own at the next sign-in. This is how a student **without an email address** gets in\nat all — no magic link can reach them, so they sign in with their `loginNumber` plus this\npassword — and it is also the password reset, because the identity provider's self-service reset\nneeds a mailbox the student does not have.\n\nType the password and tell the student directly; nothing is mailed. Works for every one of your\nstudents, not only those without an address.\n\nOnly the customer's OWN students are reachable: another customer's student is `404`, never `403`.\nReturns `204` on success, `400` if the password is missing or shorter than 8 characters, `409` if\nthe student has no login account yet, and `502` if the identity provider could not be reached.",
        "operationId": "SetStudentPasswordCustomer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetPasswordPost"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "Bad Gateway",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/students/{id}/restore": {
      "post": {
        "tags": [
          "Student (Customer)"
        ],
        "summary": "Restore a soft-deleted student (customer).",
        "description": "Restores a previously soft-deleted student so it appears in normal listings again. Returns `204`,\nor `404` if no such student exists or it does not belong to the signed-in customer.",
        "operationId": "RestoreStudentCustomer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/courses": {
      "get": {
        "tags": [
          "Course (Customer)"
        ],
        "summary": "List every course relevant to the customer (catalog + enrolled + requested).",
        "description": "Returns the SUPERSET of courses relevant to the signed-in customer: the union of the open\ncatalog (group courses available for enrollment), courses the customer's own students are\nenrolled in, and courses the customer has an enrollment request for. Each `CourseGet` carries\nthree server-computed membership flags so the FE can tell the categories apart (they overlap):\n`IsAvailable` (in the open catalog), `IsEnrolled` (has one of your students) and `IsRequested`\n(you have a request for it). The customer-contextual data (`EnrolledStudents`,\n`EnrollmentRequests`, `EnrollmentStatus`, `Capacity`) is scoped to the signed-in customer; no\ninternal pricing or teacher-internal data is included. Each course also carries its `Lessons`\n(schedule: date/time, teacher, room, status, homework) — the enrolled students are NOT repeated\nper lesson, read them once from the course's `EnrolledStudents`. Use `/customer/courses/available` and\n`/customer/courses/my` for the pre-filtered subsets. Filter here with `searchTerm` (name and\ndescription), `courseTypeId`, `subjectId`, `levelId`, `statusId` (resolvable via `/lookups/…`)\nand the flag filters `isAvailable` / `isEnrolled` / `isRequested`.\n\nSupports pagination and sorting: send an optional `Range` request header (`0-49` = first 50,\n`-50` = last 50, `50` = from index 50; 0-based, end inclusive) plus the `orderBy` (a property\nname of the returned object, case-insensitive) and `desc` query parameters. The body is a plain\nJSON array; the total count is returned in the `Content-Range` response header\n(`items {start}-{end}/{total}`). Status is `206` when a `Range` is sent, `416` if the range is invalid.",
        "operationId": "GetCoursesCustomer",
        "parameters": [
          {
            "name": "SearchTerm",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ShowRemoved",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "CourseTypeId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "SubjectId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "LevelId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "StatusId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "IsAvailable",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "IsEnrolled",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "IsRequested",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "description": "Pagination window (zero-based, end inclusive): `{start}-{end}` e.g. `0-49`; `-{n}` = last n; `{n}` = first n. When set, the response is 206 with a `Content-Range` header.",
            "schema": {
              "type": "string",
              "example": "0-49"
            }
          },
          {
            "name": "orderBy",
            "in": "query",
            "description": "Sort by this result property name (case-insensitive). Unknown property → 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "desc",
            "in": "query",
            "description": "Sort descending when true (default false). Applied before pagination.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CourseGet"
                  }
                }
              }
            }
          },
          "206": {
            "description": "Partial Content — returned when a `Range` header is present. Body is the requested window.",
            "headers": {
              "Content-Range": {
                "description": "`items {start}-{end}/{total}` (empty page → `items */{total}`).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CourseGet"
                  }
                }
              }
            }
          },
          "416": {
            "description": "Range Not Satisfiable — the `Range` header is malformed or starts beyond the last item."
          }
        }
      }
    },
    "/customer/courses/available": {
      "get": {
        "tags": [
          "Course (Customer)"
        ],
        "summary": "List the public catalog of open group courses available for enrollment.",
        "description": "The catalog subset of `/customer/courses`: publicly-open group courses (status Created /\nPlanned / Started), shown regardless of whether the customer already has students enrolled or\nrequests pending. Full courses are not filtered out — read each `CourseGet`'s `Capacity`. Narrow\nwith `searchTerm`, `courseTypeId`, `subjectId`, `levelId`, `statusId` (resolvable via `/lookups/…`).\nPaginated/sortable via `Range` + `orderBy`/`desc` (see `/customer/courses`).",
        "operationId": "GetAvailableCoursesCustomer",
        "parameters": [
          {
            "name": "SearchTerm",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ShowRemoved",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "CourseTypeId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "SubjectId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "LevelId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "StatusId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "description": "Pagination window (zero-based, end inclusive): `{start}-{end}` e.g. `0-49`; `-{n}` = last n; `{n}` = first n. When set, the response is 206 with a `Content-Range` header.",
            "schema": {
              "type": "string",
              "example": "0-49"
            }
          },
          {
            "name": "orderBy",
            "in": "query",
            "description": "Sort by this result property name (case-insensitive). Unknown property → 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "desc",
            "in": "query",
            "description": "Sort descending when true (default false). Applied before pagination.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CourseGet"
                  }
                }
              }
            }
          },
          "206": {
            "description": "Partial Content — returned when a `Range` header is present. Body is the requested window.",
            "headers": {
              "Content-Range": {
                "description": "`items {start}-{end}/{total}` (empty page → `items */{total}`).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CourseGet"
                  }
                }
              }
            }
          },
          "416": {
            "description": "Range Not Satisfiable — the `Range` header is malformed or starts beyond the last item."
          }
        }
      }
    },
    "/customer/courses/my": {
      "get": {
        "tags": [
          "Course (Customer)"
        ],
        "summary": "List courses the customer's own students are enrolled in (\"my courses\").",
        "description": "The enrolment subset of `/customer/courses`: courses in which the signed-in customer has\nenrolled students. Can include non-catalog courses the customer's students are in (e.g.\nprivate/duo). Only the customer's own students/requests are shown within each course. Filter with\n`searchTerm`, `courseTypeId`, `subjectId`, `statusId` and `studentId` to narrow to a specific one\nof your own students. Paginated/sortable via `Range` + `orderBy`/`desc` (see `/customer/courses`).",
        "operationId": "GetMyCoursesCustomer",
        "parameters": [
          {
            "name": "SearchTerm",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ShowRemoved",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "CourseTypeId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "SubjectId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "StatusId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "StudentId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "description": "Pagination window (zero-based, end inclusive): `{start}-{end}` e.g. `0-49`; `-{n}` = last n; `{n}` = first n. When set, the response is 206 with a `Content-Range` header.",
            "schema": {
              "type": "string",
              "example": "0-49"
            }
          },
          {
            "name": "orderBy",
            "in": "query",
            "description": "Sort by this result property name (case-insensitive). Unknown property → 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "desc",
            "in": "query",
            "description": "Sort descending when true (default false). Applied before pagination.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CourseGet"
                  }
                }
              }
            }
          },
          "206": {
            "description": "Partial Content — returned when a `Range` header is present. Body is the requested window.",
            "headers": {
              "Content-Range": {
                "description": "`items {start}-{end}/{total}` (empty page → `items */{total}`).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CourseGet"
                  }
                }
              }
            }
          },
          "416": {
            "description": "Range Not Satisfiable — the `Range` header is malformed or starts beyond the last item."
          }
        }
      }
    },
    "/customer/courses/{id}": {
      "get": {
        "tags": [
          "Course (Customer)"
        ],
        "summary": "Get a single course by id (any course in the customer's superset).",
        "description": "Returns a single course by its id as a `CourseGet`, resolvable for any course in the customer's\nsuperset — the open catalog, one their students are enrolled in, OR one they have a request for —\nso every list (`/`, `/available`, `/my`) can open a detail view with the same id. Only the\ncustomer's own enrolled students and enrollment requests are shown within the course; the course's\n`Lessons` (schedule) are included without repeating the students per lesson; no internal pricing\nor teacher-internal data is included. Returns `404` if no such course exists or if it is not in\nthe signed-in customer's superset.",
        "operationId": "GetCourseCustomerById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CourseGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/interests": {
      "get": {
        "tags": [
          "Interest (Customer)"
        ],
        "summary": "List interests (customer portal).",
        "description": "Returns the interests (tuition requests) the signed-in customer has raised for their own\nstudents — each an `InterestGet` with the language, level, interest type (Private, Group,\nNaturalizationPrep, ExamPrep, Fide), status (Open, Done, Declined), desired schedule, requested\nstudents and an estimated price. Teacher applications against these interests are not visible to\nthe customer; the office matches teachers internally. Interests raised by other customers are\nnever returned. Soft-deleted interests are excluded by default. Filter with `searchTerm` (matches\nstudent, language and level), `studentId`, `languageId`, `levelId`, `interestTypeId`, `statusId`\n(resolvable via `/lookups/…`) and a `dateFrom` / `dateTo` overlap range.\n\nSupports pagination and sorting: send an optional `Range` request header (`0-49` = first 50,\n`-50` = last 50, `50` = from index 50; 0-based, end inclusive) plus the `orderBy` (a property\nname of the returned object, case-insensitive) and `desc` query parameters. The body is a plain\nJSON array; the total count is returned in the `Content-Range` response header\n(`items {start}-{end}/{total}`). Status is `206` when a `Range` is sent, `416` if the range is invalid.",
        "operationId": "GetInterestsCustomer",
        "parameters": [
          {
            "name": "SearchTerm",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ShowRemoved",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "StudentId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "LanguageId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "LevelId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "InterestTypeId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "StatusId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "DateFrom",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "DateTo",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "description": "Pagination window (zero-based, end inclusive): `{start}-{end}` e.g. `0-49`; `-{n}` = last n; `{n}` = first n. When set, the response is 206 with a `Content-Range` header.",
            "schema": {
              "type": "string",
              "example": "0-49"
            }
          },
          {
            "name": "orderBy",
            "in": "query",
            "description": "Sort by this result property name (case-insensitive). Unknown property → 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "desc",
            "in": "query",
            "description": "Sort descending when true (default false). Applied before pagination.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/InterestGet"
                  }
                }
              }
            }
          },
          "206": {
            "description": "Partial Content — returned when a `Range` header is present. Body is the requested window.",
            "headers": {
              "Content-Range": {
                "description": "`items {start}-{end}/{total}` (empty page → `items */{total}`).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/InterestGet"
                  }
                }
              }
            }
          },
          "416": {
            "description": "Range Not Satisfiable — the `Range` header is malformed or starts beyond the last item."
          }
        }
      },
      "post": {
        "tags": [
          "Interest (Customer)"
        ],
        "summary": "Raise a new interest for one of the customer's students.",
        "description": "Raises a new interest (tuition request) for one or more of the customer's own students from the\n`InterestPost` body and returns the created `InterestGet` (with its generated id and an Open\nstatus). The office then reviews it and matches a teacher. Returns `400` with validation details\nif the body is invalid or if a referenced student does not belong to the signed-in customer.",
        "operationId": "CreateInterestCustomer",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InterestPost"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InterestGet"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/interests/{id}": {
      "get": {
        "tags": [
          "Interest (Customer)"
        ],
        "summary": "Get a single interest by id.",
        "description": "Returns a single interest by its id as an `InterestGet`. Returns `404` if no such interest exists\nor if it was not raised by the signed-in customer.",
        "operationId": "GetInterestCustomerById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InterestGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Interest (Customer)"
        ],
        "summary": "Partially update an open interest (or withdraw it).",
        "description": "Partially updates an existing interest (e.g. adjusting the desired schedule or notes, or\nwithdrawing it): only the fields present in the `InterestPatch` body are changed, the rest stay\nas they are. Returns the updated `InterestGet`. Returns `404` if no such interest exists or it\nwas not raised by the signed-in customer; `400` on validation errors.",
        "operationId": "UpdateInterestCustomer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InterestPatch"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InterestGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Interest (Customer)"
        ],
        "summary": "Delete an interest (soft by default; ?hard=true to hard-delete).",
        "description": "Deletes an interest. By default this is a soft delete — the interest is hidden from normal\nlistings but can be restored; pass `?hard=true` to remove it permanently. Returns `204`, or `404`\nif no such interest exists or it was not raised by the signed-in customer.",
        "operationId": "DeleteInterestCustomer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "hard",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/interests/{id}/restore": {
      "post": {
        "tags": [
          "Interest (Customer)"
        ],
        "summary": "Restore a soft-deleted interest.",
        "description": "Restores a previously soft-deleted interest so it appears in normal listings again. Returns `204`,\nor `404` if no such interest exists or it was not raised by the signed-in customer.",
        "operationId": "RestoreInterestCustomer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/lessons": {
      "get": {
        "tags": [
          "Lesson (Customer)"
        ],
        "summary": "List lessons (customer).",
        "description": "Returns the lessons attached to courses the signed-in customer's students are enrolled in — each\na `LessonGet` with date and time, course reference, teacher (name only) and room, computed status,\nhomework assignments, attendance records and `enrolledStudents` (the customer's OWN students in\nthe lesson's course, mirroring the `enrolledStudents` on the course view). Only the customer's own\ndata is shown: attendance records and enrolled students are limited to the customer's own students,\nand no salary, invoicing or teacher-internal fields are included. Lessons unrelated to the\ncustomer's students are never returned. Soft-deleted lessons are excluded by default. Filter with\n`searchTerm` (matches homework text and course name), `courseId`, a `dateFrom` / `dateTo` range\nand `isCancelled`.\n\nSupports pagination and sorting: send an optional `Range` request header (`0-49` = first 50,\n`-50` = last 50, `50` = from index 50; 0-based, end inclusive) plus the `orderBy` (a property\nname of the returned object, case-insensitive) and `desc` query parameters. The body is a plain\nJSON array; the total count is returned in the `Content-Range` response header\n(`items {start}-{end}/{total}`). Status is `206` when a `Range` is sent, `416` if the range is invalid.",
        "operationId": "GetLessonsCustomer",
        "parameters": [
          {
            "name": "SearchTerm",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ShowRemoved",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "CourseId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "DateFrom",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "DateTo",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "IsCancelled",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "description": "Pagination window (zero-based, end inclusive): `{start}-{end}` e.g. `0-49`; `-{n}` = last n; `{n}` = first n. When set, the response is 206 with a `Content-Range` header.",
            "schema": {
              "type": "string",
              "example": "0-49"
            }
          },
          {
            "name": "orderBy",
            "in": "query",
            "description": "Sort by this result property name (case-insensitive). Unknown property → 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "desc",
            "in": "query",
            "description": "Sort descending when true (default false). Applied before pagination.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LessonGet"
                  }
                }
              }
            }
          },
          "206": {
            "description": "Partial Content — returned when a `Range` header is present. Body is the requested window.",
            "headers": {
              "Content-Range": {
                "description": "`items {start}-{end}/{total}` (empty page → `items */{total}`).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LessonGet"
                  }
                }
              }
            }
          },
          "416": {
            "description": "Range Not Satisfiable — the `Range` header is malformed or starts beyond the last item."
          }
        }
      }
    },
    "/customer/lessons/{id}": {
      "get": {
        "tags": [
          "Lesson (Customer)"
        ],
        "summary": "Get a single lesson by id.",
        "description": "Returns a single lesson by its id as a `LessonGet`, with attendance and `enrolledStudents` limited\nto the customer's own students and no salary / teacher-internal fields. Returns `404` if no such\nlesson exists or if it does not belong to a course the signed-in customer's students are enrolled in.",
        "operationId": "GetLessonCustomerById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LessonGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/invoices": {
      "get": {
        "tags": [
          "Invoice (Customer)"
        ],
        "summary": "List invoices (customer).",
        "description": "Returns the invoices addressed to the signed-in customer — each an `InvoiceGet` with title,\ninvoice number, issue and due date, payment status, total amount, line items and, when available,\na download link (`FileUrl`) for the invoice PDF. This is a read-only view; invoices belonging to\nother customers are never returned. Soft-deleted invoices are excluded by default. Filter with\n`searchTerm` (matches title and invoice number), `statusId` (resolvable via `/lookups/…`),\nthe billing period via `periodYear` and/or `periodMonth` (each independent),\n`invoiceDateFrom` / `invoiceDateTo`, `dueDateFrom` / `dueDateTo` and a `minTotalAmount` /\n`maxTotalAmount` range.\n\nSupports pagination and sorting: send an optional `Range` request header (`0-49` = first 50,\n`-50` = last 50, `50` = from index 50; 0-based, end inclusive) plus the `orderBy` (a property\nname of the returned object, case-insensitive) and `desc` query parameters. The body is a plain\nJSON array; the total count is returned in the `Content-Range` response header\n(`items {start}-{end}/{total}`). Status is `206` when a `Range` is sent, `416` if the range is invalid.",
        "operationId": "GetInvoicesCustomer",
        "parameters": [
          {
            "name": "SearchTerm",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ShowRemoved",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "StatusId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "InvoiceDateFrom",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "InvoiceDateTo",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "DueDateFrom",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "DueDateTo",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "PeriodYear",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "PeriodMonth",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "MinTotalAmount",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "MaxTotalAmount",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "description": "Pagination window (zero-based, end inclusive): `{start}-{end}` e.g. `0-49`; `-{n}` = last n; `{n}` = first n. When set, the response is 206 with a `Content-Range` header.",
            "schema": {
              "type": "string",
              "example": "0-49"
            }
          },
          {
            "name": "orderBy",
            "in": "query",
            "description": "Sort by this result property name (case-insensitive). Unknown property → 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "desc",
            "in": "query",
            "description": "Sort descending when true (default false). Applied before pagination.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/InvoiceGet"
                  }
                }
              }
            }
          },
          "206": {
            "description": "Partial Content — returned when a `Range` header is present. Body is the requested window.",
            "headers": {
              "Content-Range": {
                "description": "`items {start}-{end}/{total}` (empty page → `items */{total}`).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/InvoiceGet"
                  }
                }
              }
            }
          },
          "416": {
            "description": "Range Not Satisfiable — the `Range` header is malformed or starts beyond the last item."
          }
        }
      }
    },
    "/customer/invoices/{id}": {
      "get": {
        "tags": [
          "Invoice (Customer)"
        ],
        "summary": "Get a single invoice by id.",
        "description": "Returns a single invoice by its id as an `InvoiceGet`, including its line items and download link.\nReturns `404` if no such invoice exists or if it is not addressed to the signed-in customer.",
        "operationId": "GetInvoiceCustomerById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/invoices/annual-overview": {
      "get": {
        "tags": [
          "Invoice (Customer)"
        ],
        "summary": "Annual invoice overview (customer).",
        "description": "Returns an aggregated yearly roll-up over the signed-in customer's own invoices for a single\nbilling-period year, as an `AnnualOverviewGet`: the year, the overall total amount and invoice\ncount, a per-month breakdown (`Months`), a per-status breakdown (`ByStatus`), and the underlying\ninvoices (`Invoices`). Like every customer invoice view it is read-only and identity-scoped —\nanother customer's invoices are never included.\n\nThe optional `year` query parameter selects the billing-period year; when omitted it defaults to\nthe current (UTC) year. A `year` outside the supported range (2000–2100) returns `400`.",
        "operationId": "GetInvoiceCustomerAnnualOverview",
        "parameters": [
          {
            "name": "year",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnnualOverviewGet"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/invoices/annual-overview.pdf": {
      "get": {
        "tags": [
          "Invoice (Customer)"
        ],
        "summary": "Annual invoice overview as PDF (customer).",
        "description": "Downloads the customer's annual invoice overview for a billing-period year as a PDF\n(`application/pdf`, filename `annual-overview-{year}.pdf`). The optional `year` query parameter\nselects the year and defaults to the current (UTC) year; a `year` outside 2000–2100 returns `400`.\n\nNOTE: PDF generation is not implemented yet — this currently returns an EMPTY placeholder file.\nThe real document (rendered from the same data as `GET /customer/invoices/annual-overview`) is a\nfollow-up. See the `annual-overview-pdf-todo` note.",
        "operationId": "GetInvoiceCustomerAnnualOverviewPdf",
        "parameters": [
          {
            "name": "year",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/budgets": {
      "get": {
        "tags": [
          "Budget (Customer)"
        ],
        "summary": "List budgets (customer).",
        "description": "Returns the budgets that involve the signed-in customer — i.e. budgets the customer funds\n(as sponsor) or receives and spends (as beneficiary) — each as a `BudgetGet` with its status\n(Active, Exhausted, Expired, Closed), total / consumed / remaining amount, item count and the\nsponsor and beneficiary references. Budgets belonging only to other parties are never returned.\nSoft-deleted budgets are excluded by default. Filter with `searchTerm` (matches the description\nand the sponsor / beneficiary display name), `sponsorCustomerId`, `beneficiaryCustomerId` and a\n`minTotalAmount` / `maxTotalAmount` range.\n\nSupports pagination and sorting: send an optional `Range` request header (`0-49` = first 50,\n`-50` = last 50, `50` = from index 50; 0-based, end inclusive) plus the `orderBy` (a property\nname of the returned object, case-insensitive) and `desc` query parameters. The body is a plain\nJSON array; the total count is returned in the `Content-Range` response header\n(`items {start}-{end}/{total}`). Status is `206` when a `Range` is sent, `416` if the range is invalid.",
        "operationId": "GetBudgetsCustomer",
        "parameters": [
          {
            "name": "SearchTerm",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ShowRemoved",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "SponsorCustomerId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "BeneficiaryCustomerId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "MinTotalAmount",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "MaxTotalAmount",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "description": "Pagination window (zero-based, end inclusive): `{start}-{end}` e.g. `0-49`; `-{n}` = last n; `{n}` = first n. When set, the response is 206 with a `Content-Range` header.",
            "schema": {
              "type": "string",
              "example": "0-49"
            }
          },
          {
            "name": "orderBy",
            "in": "query",
            "description": "Sort by this result property name (case-insensitive). Unknown property → 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "desc",
            "in": "query",
            "description": "Sort descending when true (default false). Applied before pagination.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/BudgetGet"
                  }
                }
              }
            }
          },
          "206": {
            "description": "Partial Content — returned when a `Range` header is present. Body is the requested window.",
            "headers": {
              "Content-Range": {
                "description": "`items {start}-{end}/{total}` (empty page → `items */{total}`).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/BudgetGet"
                  }
                }
              }
            }
          },
          "416": {
            "description": "Range Not Satisfiable — the `Range` header is malformed or starts beyond the last item."
          }
        }
      },
      "post": {
        "tags": [
          "Budget (Customer)"
        ],
        "summary": "Create a budget (company customers only) assigned to an employee by email.",
        "description": "Creates a new budget from the `BudgetPost` body and returns the created `BudgetGet` (with its\ngenerated id). This is a company-customer feature: a company funds a budget and assigns it to one\nof its employees (identified by email), who becomes the beneficiary that can spend it on lessons\nand materials. Returns `403` when the signed-in customer is a private person rather than a company,\nand `400` with validation details if the body is invalid.",
        "operationId": "CreateBudgetCustomer",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BudgetPost"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BudgetGet"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/budgets/{id}": {
      "get": {
        "tags": [
          "Budget (Customer)"
        ],
        "summary": "Get a single budget by id.",
        "description": "Returns a single budget by its id as a `BudgetGet`. Returns `404` if no such budget exists or if\nit does not involve the signed-in customer (as sponsor or beneficiary).",
        "operationId": "GetBudgetCustomerById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BudgetGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/packages": {
      "get": {
        "tags": [
          "Package (Customer)"
        ],
        "summary": "List packages (customer).",
        "description": "Returns the package catalog — the lesson bundles a customer can purchase — each a `PackageGet`\nwith its marketing title, description, sale price (CHF) and the credit it provides. This is a\npublic catalog, the same for every customer and not restricted to any one account; it is\nread-only (customers buy via `/customer/package-orders`, they cannot create packages).\nSoft-deleted packages are excluded by default. Filter with `searchTerm` (matches title, billing\ntitle and description), a `minPrice` / `maxPrice` range and a `minCredit` / `maxCredit` range.\n\nSupports pagination and sorting: send an optional `Range` request header (`0-49` = first 50,\n`-50` = last 50, `50` = from index 50; 0-based, end inclusive) plus the `orderBy` (a property\nname of the returned object, case-insensitive) and `desc` query parameters. The body is a plain\nJSON array; the total count is returned in the `Content-Range` response header\n(`items {start}-{end}/{total}`). Status is `206` when a `Range` is sent, `416` if the range is invalid.",
        "operationId": "GetPackagesCustomer",
        "parameters": [
          {
            "name": "SearchTerm",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ShowRemoved",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "MinPrice",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "MaxPrice",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "MinCredit",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "MaxCredit",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "description": "Pagination window (zero-based, end inclusive): `{start}-{end}` e.g. `0-49`; `-{n}` = last n; `{n}` = first n. When set, the response is 206 with a `Content-Range` header.",
            "schema": {
              "type": "string",
              "example": "0-49"
            }
          },
          {
            "name": "orderBy",
            "in": "query",
            "description": "Sort by this result property name (case-insensitive). Unknown property → 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "desc",
            "in": "query",
            "description": "Sort descending when true (default false). Applied before pagination.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PackageGet"
                  }
                }
              }
            }
          },
          "206": {
            "description": "Partial Content — returned when a `Range` header is present. Body is the requested window.",
            "headers": {
              "Content-Range": {
                "description": "`items {start}-{end}/{total}` (empty page → `items */{total}`).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PackageGet"
                  }
                }
              }
            }
          },
          "416": {
            "description": "Range Not Satisfiable — the `Range` header is malformed or starts beyond the last item."
          }
        }
      }
    },
    "/customer/packages/{id}": {
      "get": {
        "tags": [
          "Package (Customer)"
        ],
        "summary": "Get a single package by id.",
        "description": "Returns a single catalog package by its id as a `PackageGet`. Returns `404` if no such package\nexists.",
        "operationId": "GetPackageCustomerById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PackageGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/course-prices": {
      "get": {
        "tags": [
          "CoursePrice (Customer)"
        ],
        "summary": "List private-lesson prices (customer portal).",
        "description": "Returns the per-lesson rate card the customer needs to price a private-lesson request\n(the \"Request private lessons\" flow), each a `CoursePriceGet` with the teaching level,\ncourse type, whether the rate is for children and the price per lesson (CHF). Only\nPRIVATE-LESSON course types are ever returned — Private (one-to-one) and Duo\n(semi-private, group of two); group-course prices are office-internal and never exposed\nto the customer. This is a public rate card, the same for every customer and not\nrestricted to any one account; it is read-only. Soft-deleted rows are excluded by\ndefault. Filter with `searchTerm` (matches the custom product name), `levelId`,\n`courseTypeId` (restricted to Private/Duo), `isForChildren` and a `priceMin`/`priceMax`\nrange; the enum ids come from the matching `/lookups/...` endpoints.\n\nSupports pagination and sorting: send an optional `Range` request header (`0-49` = first 50,\n`-50` = last 50, `50` = from index 50; 0-based, end inclusive) plus the `orderBy` (a property\nname of the returned object, case-insensitive) and `desc` query parameters. The body is a plain\nJSON array; the total count is returned in the `Content-Range` response header\n(`items {start}-{end}/{total}`). Status is `206` when a `Range` is sent, `416` if the range is invalid.",
        "operationId": "GetCoursePricesCustomer",
        "parameters": [
          {
            "name": "SearchTerm",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ShowRemoved",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "LevelId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "CourseTypeId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "IsForChildren",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "PriceMin",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "PriceMax",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "description": "Pagination window (zero-based, end inclusive): `{start}-{end}` e.g. `0-49`; `-{n}` = last n; `{n}` = first n. When set, the response is 206 with a `Content-Range` header.",
            "schema": {
              "type": "string",
              "example": "0-49"
            }
          },
          {
            "name": "orderBy",
            "in": "query",
            "description": "Sort by this result property name (case-insensitive). Unknown property → 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "desc",
            "in": "query",
            "description": "Sort descending when true (default false). Applied before pagination.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CoursePriceGet"
                  }
                }
              }
            }
          },
          "206": {
            "description": "Partial Content — returned when a `Range` header is present. Body is the requested window.",
            "headers": {
              "Content-Range": {
                "description": "`items {start}-{end}/{total}` (empty page → `items */{total}`).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CoursePriceGet"
                  }
                }
              }
            }
          },
          "416": {
            "description": "Range Not Satisfiable — the `Range` header is malformed or starts beyond the last item."
          }
        }
      }
    },
    "/customer/course-prices/{id}": {
      "get": {
        "tags": [
          "CoursePrice (Customer)"
        ],
        "summary": "Get a single private-lesson price by id.",
        "description": "Returns a single private-lesson rate by its id as a `CoursePriceGet`. Returns `404` if no\nsuch rate exists or if it is not a private-lesson (Private/Duo) row — group-course prices\nare not addressable from the customer portal.",
        "operationId": "GetCoursePriceCustomerById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CoursePriceGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/package-orders": {
      "get": {
        "tags": [
          "PackageOrder (Customer)"
        ],
        "summary": "List package orders (customer).",
        "description": "Returns the package orders (purchases) that belong to the signed-in customer — orders the\ncustomer either bought or received from another customer — each a `PackageOrderGet` with its\nstatus, the underlying catalog package, the credit used and remaining, per-student consumption\nbreakdown, the booked lessons and any pass-on / assignment info. Orders belonging only to other\ncustomers are never returned. Soft-deleted orders are excluded by default. Filter with\n`searchTerm` (matches the order and package title), `statusId`, `packageId` (resolvable via\n`/lookups/…`) and a `minUsedCredit` / `maxUsedCredit` range.\n\nSupports pagination and sorting: send an optional `Range` request header (`0-49` = first 50,\n`-50` = last 50, `50` = from index 50; 0-based, end inclusive) plus the `orderBy` (a property\nname of the returned object, case-insensitive) and `desc` query parameters. The body is a plain\nJSON array; the total count is returned in the `Content-Range` response header\n(`items {start}-{end}/{total}`). Status is `206` when a `Range` is sent, `416` if the range is invalid.",
        "operationId": "GetPackageOrdersCustomer",
        "parameters": [
          {
            "name": "SearchTerm",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ShowRemoved",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "StatusId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "PackageId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "description": "Pagination window (zero-based, end inclusive): `{start}-{end}` e.g. `0-49`; `-{n}` = last n; `{n}` = first n. When set, the response is 206 with a `Content-Range` header.",
            "schema": {
              "type": "string",
              "example": "0-49"
            }
          },
          {
            "name": "orderBy",
            "in": "query",
            "description": "Sort by this result property name (case-insensitive). Unknown property → 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "desc",
            "in": "query",
            "description": "Sort descending when true (default false). Applied before pagination.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PackageOrderGet"
                  }
                }
              }
            }
          },
          "206": {
            "description": "Partial Content — returned when a `Range` header is present. Body is the requested window.",
            "headers": {
              "Content-Range": {
                "description": "`items {start}-{end}/{total}` (empty page → `items */{total}`).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PackageOrderGet"
                  }
                }
              }
            }
          },
          "416": {
            "description": "Range Not Satisfiable — the `Range` header is malformed or starts beyond the last item."
          }
        }
      }
    },
    "/customer/package-orders/{id}": {
      "get": {
        "tags": [
          "PackageOrder (Customer)"
        ],
        "summary": "Get a single package order by id.",
        "description": "Returns a single package order by its id as a `PackageOrderGet`, including credit usage and booked\nlessons. Returns `404` if no such order exists or if it does not belong to the signed-in customer\n(as buyer or recipient).",
        "operationId": "GetPackageOrderCustomerById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PackageOrderGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/package-orders/{id}/refundable-amount": {
      "get": {
        "tags": [
          "PackageOrder (Customer)"
        ],
        "summary": "Get the refundable amount for a package order (customer).",
        "description": "Returns how much of the package order could currently be refunded as a `RefundableAmountGet`.\nA refund can be requested only when `refundableAmount` is greater than 0.\n\n⚠️ PLACEHOLDER: the concrete refund calculation is NOT yet implemented. This endpoint currently\nreturns a fixed positive stub and sets `isPlaceholder = true`; treat the amount as indicative\nonly. The real amount (used lessons charged at the standard rate, non-refundable fees, materials\nbilled separately, …) is still to be defined — see the TODO in `PackageOrderCrudService`.\n\nReturns `404` if no such order exists or it does not belong to the signed-in customer.",
        "operationId": "GetPackageOrderRefundableAmountCustomer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundableAmountGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/package-orders/{id}/request-refund": {
      "post": {
        "tags": [
          "PackageOrder (Customer)"
        ],
        "summary": "Request a refund for a package order (customer).",
        "description": "Submits a refund request for the customer's own package order and returns the updated\n`PackageOrderGet` (now in the `RefundRequested` status, with `refundRequestedAt` stamped). The\noffice subsequently fulfils the request (→ `Refunded`) or declines it; the customer is notified\nof the outcome. Only a PERSONAL package the customer purchased (not one passed on to / received\nfrom someone else) in the PAID status with a positive refundable amount can be refunded.\n\nReturns `404` if no such order exists or it does not belong to the signed-in customer, and `400`\nif a business rule rejects the request (not personal, wrong status, already requested/refunded,\nor nothing left to refund).",
        "operationId": "RequestPackageOrderRefundCustomer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PackageOrderGet"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/package-purchases": {
      "get": {
        "tags": [
          "PackagePurchase (Customer)"
        ],
        "summary": "List the signed-in customer's package purchases.",
        "description": "Returns the package purchases (checkouts) made by the signed-in customer, each a\n`PackagePurchaseGet` with the member package orders bought together, the purchase status\n(prepayment / invoicing lifecycle) and computed item count / total price. Purchases belonging to\nother customers are never returned, and purchases with no remaining orders (all removed) are not\nlisted. Soft-deleted purchases are excluded by default. Filter with `statusId` (resolvable via\n`/lookups/package-purchase-status`).\n\nSupports pagination and sorting: send an optional `Range` request header (`0-49` = first 50,\n`-50` = last 50, `50` = from index 50; 0-based, end inclusive) plus the `orderBy` and `desc` query\nparameters. The body is a plain JSON array; the total count is returned in the `Content-Range`\nresponse header. Status is `206` when a `Range` is sent, `416` if the range is invalid.",
        "operationId": "GetPackagePurchasesCustomer",
        "parameters": [
          {
            "name": "SearchTerm",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ShowRemoved",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "StatusId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "description": "Pagination window (zero-based, end inclusive): `{start}-{end}` e.g. `0-49`; `-{n}` = last n; `{n}` = first n. When set, the response is 206 with a `Content-Range` header.",
            "schema": {
              "type": "string",
              "example": "0-49"
            }
          },
          {
            "name": "orderBy",
            "in": "query",
            "description": "Sort by this result property name (case-insensitive). Unknown property → 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "desc",
            "in": "query",
            "description": "Sort descending when true (default false). Applied before pagination.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PackagePurchaseGet"
                  }
                }
              }
            }
          },
          "206": {
            "description": "Partial Content — returned when a `Range` header is present. Body is the requested window.",
            "headers": {
              "Content-Range": {
                "description": "`items {start}-{end}/{total}` (empty page → `items */{total}`).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PackagePurchaseGet"
                  }
                }
              }
            }
          },
          "416": {
            "description": "Range Not Satisfiable — the `Range` header is malformed or starts beyond the last item."
          }
        }
      },
      "post": {
        "tags": [
          "PackagePurchase (Customer)"
        ],
        "summary": "Purchase one or more packages (checkout).",
        "description": "Buys the packages listed in the `PackagePurchasePost` body in a single atomic checkout. The buying\ncustomer (payer) is taken from the session; each item may optionally assign its package to another\ncustomer by email. All package orders are created together under one purchase header (status\n`Draft`); because packages are prepaid, one prepayment invoice is raised for the whole purchase out\nof band. Returns the created `PackagePurchaseGet`. Returns `400` with validation details if the\nbody is invalid (e.g. an empty basket or an invalid package / beneficiary email).\n\nAn item's `beneficiaryCustomerEmail` is RESOLVED at checkout: if the address belongs to a customer,\nthe order is assigned to them (`assignedToCustomerId`, which is what makes the package visible in\nthat customer's portal) and the address is cleared; if it belongs to nobody, it is kept as a\npending note and completed later, when a customer is created with — or renamed to — that address.\nThe assignment type (`passedOnType`) is DERIVED from the result and needs not be sent.\nAssigning an item to your OWN address is rejected with `400` — that is not a pass-on, and it would\nblock your own refund.",
        "operationId": "CreatePackagePurchaseCustomer",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PackagePurchasePost"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PackagePurchaseGet"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/package-purchases/{id}": {
      "get": {
        "tags": [
          "PackagePurchase (Customer)"
        ],
        "summary": "Get a single package purchase by id.",
        "description": "Returns a single package purchase by its id as a `PackagePurchaseGet`, including its member\npackage orders. Returns `404` if no such purchase exists or it does not belong to the signed-in\ncustomer.",
        "operationId": "GetPackagePurchaseCustomerById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PackagePurchaseGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/student-invites": {
      "get": {
        "tags": [
          "StudentInvite (Customer)"
        ],
        "summary": "List student invites (customer).",
        "description": "Returns the course invitations addressed to students that belong to the signed-in customer — each\na `StudentInviteGet` with the invited student and course, the invitation status (Pending,\nAccepted, Declined), timestamps and the material-choice workflow (per-material confirmation,\nchosen delivery method and address). Invitations for other customers' students are never\nreturned. Soft-deleted invites are excluded by default. Filter with `searchTerm` (matches student\nand course display names), `courseId`, `studentId` and `statusId` (resolvable via `/lookups/…`).\n\nSupports pagination and sorting: send an optional `Range` request header (`0-49` = first 50,\n`-50` = last 50, `50` = from index 50; 0-based, end inclusive) plus the `orderBy` (a property\nname of the returned object, case-insensitive) and `desc` query parameters. The body is a plain\nJSON array; the total count is returned in the `Content-Range` response header\n(`items {start}-{end}/{total}`). Status is `206` when a `Range` is sent, `416` if the range is invalid.",
        "operationId": "GetStudentInvitesCustomer",
        "parameters": [
          {
            "name": "SearchTerm",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ShowRemoved",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "CourseId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "StudentId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "StatusId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "description": "Pagination window (zero-based, end inclusive): `{start}-{end}` e.g. `0-49`; `-{n}` = last n; `{n}` = first n. When set, the response is 206 with a `Content-Range` header.",
            "schema": {
              "type": "string",
              "example": "0-49"
            }
          },
          {
            "name": "orderBy",
            "in": "query",
            "description": "Sort by this result property name (case-insensitive). Unknown property → 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "desc",
            "in": "query",
            "description": "Sort descending when true (default false). Applied before pagination.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/StudentInviteGet"
                  }
                }
              }
            }
          },
          "206": {
            "description": "Partial Content — returned when a `Range` header is present. Body is the requested window.",
            "headers": {
              "Content-Range": {
                "description": "`items {start}-{end}/{total}` (empty page → `items */{total}`).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/StudentInviteGet"
                  }
                }
              }
            }
          },
          "416": {
            "description": "Range Not Satisfiable — the `Range` header is malformed or starts beyond the last item."
          }
        }
      }
    },
    "/customer/student-invites/{id}": {
      "get": {
        "tags": [
          "StudentInvite (Customer)"
        ],
        "summary": "Get a single student invite by id.",
        "description": "Returns a single student invitation by its id as a `StudentInviteGet`, including its material\nchoices. Returns `404` if no such invitation exists or if it is not addressed to a student of\nthe signed-in customer.",
        "operationId": "GetStudentInviteCustomerById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StudentInviteGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "StudentInvite (Customer)"
        ],
        "summary": "Accept or decline an invitation and submit material choices (customer).",
        "description": "Responds to a course invitation for one of the customer's students: only the fields present in\nthe `StudentInvitePatch` body are changed — typically accepting or declining the invitation and\nsubmitting the material choices (per-material confirmation, delivery method and address). Returns\nthe updated `StudentInviteGet`. Returns `404` if no such invitation exists or it is not addressed\nto a student of the signed-in customer; `400` on validation errors.",
        "operationId": "UpdateStudentInviteCustomer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StudentInvitePatch"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StudentInviteGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/notifications": {
      "get": {
        "tags": [
          "Notification (Customer)"
        ],
        "summary": "List notifications (customer).",
        "description": "Returns the notifications addressed to the signed-in customer — each a `NotificationGet` with the\nissue date, message, read state, category (used for icon/grouping), an optional deep-link URL and,\nwhen the notification concerns one of the customer's students, a reference to that student.\nNotifications for other parties, including the customer's own students, are never returned: each\nrecipient has their own inbox. Soft-deleted notifications are excluded by default.\n\nThe message and the deep-link URL are COMPOSED per request from the notification's key and the\nrecords it references, not stored — so a renamed student or course, or a changed portal route, is\nreflected in notifications that already exist.\n\nFilter with `typeId` / `keyId` (resolvable via `/lookups/notification-type` and\n`/lookups/notification-key`) and `isRead`. **`searchTerm` is not supported here** and is ignored:\nsince the message is composed rather than stored, there is no text column to search, and filtering\nafter the fact would break the pagination contract below.\n\nSupports pagination and sorting: send an optional `Range` request header (`0-49` = first 50,\n`-50` = last 50, `50` = from index 50; 0-based, end inclusive) plus the `orderBy` (a property\nname of the returned object, case-insensitive) and `desc` query parameters. The body is a plain\nJSON array; the total count is returned in the `Content-Range` response header\n(`items {start}-{end}/{total}`). Status is `206` when a `Range` is sent, `416` if the range is invalid.",
        "operationId": "GetNotificationsCustomer",
        "parameters": [
          {
            "name": "SearchTerm",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ShowRemoved",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "TypeId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "KeyId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "IsRead",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "description": "Pagination window (zero-based, end inclusive): `{start}-{end}` e.g. `0-49`; `-{n}` = last n; `{n}` = first n. When set, the response is 206 with a `Content-Range` header.",
            "schema": {
              "type": "string",
              "example": "0-49"
            }
          },
          {
            "name": "orderBy",
            "in": "query",
            "description": "Sort by this result property name (case-insensitive). Unknown property → 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "desc",
            "in": "query",
            "description": "Sort descending when true (default false). Applied before pagination.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/NotificationGet"
                  }
                }
              }
            }
          },
          "206": {
            "description": "Partial Content — returned when a `Range` header is present. Body is the requested window.",
            "headers": {
              "Content-Range": {
                "description": "`items {start}-{end}/{total}` (empty page → `items */{total}`).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/NotificationGet"
                  }
                }
              }
            }
          },
          "416": {
            "description": "Range Not Satisfiable — the `Range` header is malformed or starts beyond the last item."
          }
        }
      }
    },
    "/customer/notifications/{id}": {
      "get": {
        "tags": [
          "Notification (Customer)"
        ],
        "summary": "Get a single notification by id.",
        "description": "Returns a single notification by its id as a `NotificationGet`. Returns `404` if no such\nnotification exists or if it is not addressed to the signed-in customer or one of their students.",
        "operationId": "GetNotificationCustomerById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Notification (Customer)"
        ],
        "summary": "Mark a notification as read/unread (customer).",
        "description": "Updates the read state of one of the customer's notifications: only the fields present in the\n`NotificationPatch` body are changed (typically the read/unread flag). Returns the updated\n`NotificationGet`. Returns `404` if no such notification exists or it is not addressed to the\nsigned-in customer or one of their students; `400` on validation errors.",
        "operationId": "UpdateNotificationCustomer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NotificationPatch"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/notifications/unread-count": {
      "get": {
        "tags": [
          "Notification (Customer)"
        ],
        "summary": "Count the customer's unread notifications.",
        "description": "Returns how many of the signed-in customer's notifications are currently unread, as\n`{ \"unread\": n }`. Intended for a badge or bell indicator: it answers the same question as\nlisting with `isRead=false` but transfers only the number instead of the notifications.\nNotifications addressed to anybody else — including the customer's own students, who have\ntheir own inbox — are never counted.",
        "operationId": "GetNotificationUnreadCountCustomer",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationUnreadCountGet"
                }
              }
            }
          }
        }
      }
    },
    "/customer/notifications/mark-all-read": {
      "post": {
        "tags": [
          "Notification (Customer)"
        ],
        "summary": "Mark all of the customer's notifications as read.",
        "description": "Marks every unread notification of the signed-in customer as read and returns\n`{ \"updated\": n }` — the number of notifications that actually changed. Already-read\nnotifications are not counted, so calling this twice reports `0` the second time. Only the\ncustomer's own inbox is affected; their students' notifications are untouched.",
        "operationId": "MarkAllNotificationsReadCustomer",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationMarkReadResultGet"
                }
              }
            }
          }
        }
      }
    },
    "/customer/notifications/mark-read": {
      "post": {
        "tags": [
          "Notification (Customer)"
        ],
        "summary": "Mark several notifications as read (customer).",
        "description": "Marks the notifications named in the `NotificationMarkReadPost` body (`ids`) as read and\nreturns `{ \"updated\": n }` — the number that actually changed. Ids that are unknown, already\nread, or addressed to somebody else match nothing and are ignored rather than reported\nindividually, so the response cannot be used to probe for other people's notifications.\nReturns `400` when `ids` is missing, empty, contains an empty Guid, or exceeds the per-request\nlimit.",
        "operationId": "MarkNotificationsReadCustomer",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NotificationMarkReadPost"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationMarkReadResultGet"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/enrollment-requests": {
      "get": {
        "tags": [
          "EnrollmentRequest (Customer)"
        ],
        "summary": "List the current customer's course enrollment requests.",
        "description": "Returns the course enrollment requests submitted by the signed-in customer — each a\n`CourseEnrollmentRequestGet` with its status, request date, the requested students (from the\ncustomer's own list), any notes and, on this standalone list, the full customer-portal view of\nthe requested course so the \"requested courses\" screen renders without a second lookup. Requests\nsubmitted by other customers are never returned. Soft-deleted requests are excluded by default.\nFilter with `searchTerm` (matches notes, requester and student names), `courseId`,\n`requestingCustomerId` and `statusId` (resolvable via `/lookups/…`).\n\nSupports pagination and sorting: send an optional `Range` request header (`0-49` = first 50,\n`-50` = last 50, `50` = from index 50; 0-based, end inclusive) plus the `orderBy` (a property\nname of the returned object, case-insensitive) and `desc` query parameters. The body is a plain\nJSON array; the total count is returned in the `Content-Range` response header\n(`items {start}-{end}/{total}`). Status is `206` when a `Range` is sent, `416` if the range is invalid.",
        "operationId": "GetEnrollmentRequestsCustomer",
        "parameters": [
          {
            "name": "SearchTerm",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ShowRemoved",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "CourseId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "RequestingCustomerId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "StatusId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "description": "Pagination window (zero-based, end inclusive): `{start}-{end}` e.g. `0-49`; `-{n}` = last n; `{n}` = first n. When set, the response is 206 with a `Content-Range` header.",
            "schema": {
              "type": "string",
              "example": "0-49"
            }
          },
          {
            "name": "orderBy",
            "in": "query",
            "description": "Sort by this result property name (case-insensitive). Unknown property → 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "desc",
            "in": "query",
            "description": "Sort descending when true (default false). Applied before pagination.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CourseEnrollmentRequestGet"
                  }
                }
              }
            }
          },
          "206": {
            "description": "Partial Content — returned when a `Range` header is present. Body is the requested window.",
            "headers": {
              "Content-Range": {
                "description": "`items {start}-{end}/{total}` (empty page → `items */{total}`).",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CourseEnrollmentRequestGet"
                  }
                }
              }
            }
          },
          "416": {
            "description": "Range Not Satisfiable — the `Range` header is malformed or starts beyond the last item."
          }
        }
      },
      "post": {
        "tags": [
          "EnrollmentRequest (Customer)"
        ],
        "summary": "Submit a course enrollment request.",
        "description": "Submits a request to enrol one or more of the customer's own students into an existing course,\nfrom the `CourseEnrollmentRequestPost` body, and returns the created `CourseEnrollmentRequestGet`\n(with its generated id and an open status; the office reviews and accepts or declines it). Returns\n`400` with validation details if the body is invalid or if a referenced course or student does\nnot belong to / is not accessible by the signed-in customer.",
        "operationId": "CreateEnrollmentRequestCustomer",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CourseEnrollmentRequestPost"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CourseEnrollmentRequestGet"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/enrollment-requests/{id}": {
      "get": {
        "tags": [
          "EnrollmentRequest (Customer)"
        ],
        "summary": "Get a single course enrollment request by id (customer).",
        "description": "Returns a single course enrollment request by its id as a `CourseEnrollmentRequestGet`. Returns\n`404` if no such request exists or if it was not submitted by the signed-in customer.",
        "operationId": "GetEnrollmentRequestCustomerById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CourseEnrollmentRequestGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "EnrollmentRequest (Customer)"
        ],
        "summary": "Update or withdraw a course enrollment request.",
        "description": "Partially updates an existing enrollment request (e.g. adjusting the requested students or notes,\nor withdrawing the request): only the fields present in the `CourseEnrollmentRequestPatch` body\nare changed, the rest stay as they are. Returns the updated `CourseEnrollmentRequestGet`. Returns\n`404` if no such request exists or it was not submitted by the signed-in customer; `400` on\nvalidation errors.",
        "operationId": "UpdateEnrollmentRequestCustomer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CourseEnrollmentRequestPatch"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CourseEnrollmentRequestGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/customer/myprofile": {
      "get": {
        "tags": [
          "Customer MyProfile"
        ],
        "summary": "Get the signed-in customer's own profile.",
        "description": "Returns the signed-in customer's own account as a `CustomerGet` — customer type, company name,\ncorrespondence language, contact person, billing address, the profile-confirmation flag and the\ncustomer's students (office-internal fields excluded). The account is resolved from the signed-in\nuser; no id is taken from the client. Returns `404` if the signed-in user has no linked customer\nrecord.",
        "operationId": "GetCustomerMyProfile",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Customer MyProfile"
        ],
        "summary": "Partially update the signed-in customer's own profile (reduced self-edit DTO).",
        "description": "Partially updates the signed-in customer's own profile from the reduced `MyProfilePatch` body:\nonly the fields present are changed. This self-edit surface is limited to person details,\ncommunication, billing address, correspondence language and the profile-confirmation flag —\nemail, company name, VAT number, notes and activity status can never be changed here. Returns the\nupdated `CustomerGet`. The account is resolved from the signed-in user; returns `404` if the\nsigned-in user has no linked customer record, and `400` on validation errors.",
        "operationId": "UpdateCustomerMyProfile",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MyProfilePatch"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerGet"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpValidationProblemDetails"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AddressInfoDto": {
        "type": "object",
        "properties": {
          "street": {
            "type": "string"
          },
          "houseNumber": {
            "type": "string",
            "nullable": true
          },
          "additionalLine": {
            "type": "string",
            "nullable": true
          },
          "postalCode": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "poBox": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "AddressInfoDto2": {
        "type": "object",
        "properties": {
          "street": {
            "type": "string"
          },
          "houseNumber": {
            "type": "string",
            "nullable": true
          },
          "additionalLine": {
            "type": "string",
            "nullable": true
          },
          "postalCode": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "poBox": {
            "type": "string",
            "nullable": true
          }
        },
        "nullable": true
      },
      "AnnualOverviewGet": {
        "type": "object",
        "properties": {
          "year": {
            "type": "integer",
            "format": "int32"
          },
          "totalAmount": {
            "type": "number",
            "format": "double"
          },
          "invoiceCount": {
            "type": "integer",
            "format": "int32"
          },
          "months": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AnnualOverviewMonth"
            }
          },
          "byStatus": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AnnualOverviewStatus"
            }
          },
          "invoices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InvoiceGet"
            }
          }
        }
      },
      "AnnualOverviewMonth": {
        "type": "object",
        "properties": {
          "month": {
            "type": "integer",
            "format": "int32"
          },
          "totalAmount": {
            "type": "number",
            "format": "double"
          },
          "invoiceCount": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "AnnualOverviewStatus": {
        "type": "object",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/EnumDtoOfEInvoiceStatus"
          },
          "totalAmount": {
            "type": "number",
            "format": "double"
          },
          "invoiceCount": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "AttendanceRecordGet": {
        "type": "object",
        "properties": {
          "ownerRef": {
            "type": "string",
            "format": "uuid"
          },
          "ownerTypeName": {
            "type": "string"
          },
          "studentId": {
            "type": "string",
            "format": "uuid"
          },
          "student": {
            "$ref": "#/components/schemas/StudentRef2"
          },
          "status": {
            "$ref": "#/components/schemas/EnumDtoOfEAttendanceStatus"
          },
          "absenceDocumentPath": {
            "type": "string",
            "nullable": true
          },
          "absenceDocumentId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "absenceDocumentSizeBytes": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "BudgetGet": {
        "type": "object",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/EnumDtoOfEBudgetStatus"
          },
          "totalAmount": {
            "type": "number",
            "format": "double"
          },
          "consumedAmount": {
            "type": "number",
            "format": "double"
          },
          "invoicedAmount": {
            "type": "number",
            "format": "double"
          },
          "itemCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "sponsorCustomerId": {
            "type": "string",
            "format": "uuid"
          },
          "sponsorCustomer": {
            "$ref": "#/components/schemas/CustomerRef"
          },
          "beneficiaryCustomerId": {
            "type": "string",
            "format": "uuid"
          },
          "beneficiaryCustomer": {
            "$ref": "#/components/schemas/CustomerRef"
          },
          "remainingAmount": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "sponsorCustomerDisplay": {
            "type": "string",
            "nullable": true
          },
          "beneficiaryCustomerDisplay": {
            "type": "string",
            "nullable": true
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "BudgetPost": {
        "type": "object",
        "properties": {
          "totalAmount": {
            "type": "number",
            "format": "double"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "beneficiaryCustomerEmail": {
            "type": "string"
          }
        }
      },
      "CourseColorEnumDto": {
        "type": "object",
        "properties": {
          "propertyName": {
            "type": "string"
          },
          "value": {
            "type": "string"
          },
          "enumValue": {
            "$ref": "#/components/schemas/ECourseColor"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "CourseEnrollmentRequestGet": {
        "type": "object",
        "properties": {
          "courseId": {
            "type": "string",
            "format": "uuid"
          },
          "course": {
            "$ref": "#/components/schemas/CourseGet2"
          },
          "requestingCustomerId": {
            "type": "string",
            "format": "uuid"
          },
          "requestingCustomer": {
            "$ref": "#/components/schemas/CustomerRef"
          },
          "requestedStudentIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "requestedStudents": {
            "type": "array",
            "items": { }
          },
          "requestDate": {
            "type": "string",
            "format": "date-time"
          },
          "status": {
            "$ref": "#/components/schemas/EnumDtoOfECourseEnrollmentStatus2"
          },
          "notes": {
            "type": "string",
            "nullable": true
          },
          "declineReason": {
            "type": "string",
            "nullable": true
          },
          "requesterDisplay": {
            "type": "string",
            "nullable": true
          },
          "studentsDisplay": {
            "type": "string",
            "nullable": true
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "CourseEnrollmentRequestPatch": {
        "type": "object",
        "properties": {
          "requestedStudentIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "nullable": true
          },
          "notes": {
            "type": "string",
            "nullable": true
          },
          "statusId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "declineReason": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "CourseEnrollmentRequestPost": {
        "type": "object",
        "properties": {
          "courseId": {
            "type": "string",
            "format": "uuid"
          },
          "requestingCustomerId": {
            "type": "string",
            "format": "uuid"
          },
          "requestedStudentIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "notes": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "CourseGet": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "courseType": {
            "$ref": "#/components/schemas/EnumDtoOfECourseType"
          },
          "subject": {
            "$ref": "#/components/schemas/EnumDtoOfELanguage"
          },
          "level": {
            "$ref": "#/components/schemas/EnumDtoOfETeachingLevel"
          },
          "status": {
            "$ref": "#/components/schemas/EnumDtoOfECourseStatus"
          },
          "capacity": {
            "$ref": "#/components/schemas/EnumDtoOfECourseCapacity"
          },
          "color": {
            "$ref": "#/components/schemas/CourseColorEnumDto"
          },
          "startDate": {
            "type": "string",
            "format": "date"
          },
          "endDate": {
            "type": "string",
            "format": "date"
          },
          "weeklySchedule": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WeeklyScheduleSlotDto"
            }
          },
          "room": {
            "$ref": "#/components/schemas/RoomRef"
          },
          "teacher": {
            "$ref": "#/components/schemas/TeacherRef"
          },
          "requiredMaterials": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MaterialRef"
            },
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "isAvailable": {
            "type": "boolean"
          },
          "isEnrolled": {
            "type": "boolean"
          },
          "isRequested": {
            "type": "boolean"
          },
          "enrollmentStatus": {
            "$ref": "#/components/schemas/EnumDtoOfECourseEnrollmentStatus"
          },
          "enrolledStudents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StudentRef"
            },
            "nullable": true
          },
          "enrollmentRequests": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CourseEnrollmentRequestGet"
            },
            "nullable": true
          },
          "lessons": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CourseLessonGet"
            },
            "nullable": true
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "studentCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "lessonCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "CourseGet2": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "courseType": { },
          "subject": { },
          "level": { },
          "status": { },
          "capacity": {
            "nullable": true
          },
          "color": { },
          "startDate": {
            "type": "string",
            "format": "date"
          },
          "endDate": {
            "type": "string",
            "format": "date"
          },
          "weeklySchedule": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WeeklyScheduleSlotDto"
            }
          },
          "room": {
            "nullable": true
          },
          "teacher": {
            "nullable": true
          },
          "requiredMaterials": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MaterialRef"
            },
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "isAvailable": {
            "type": "boolean"
          },
          "isEnrolled": {
            "type": "boolean"
          },
          "isRequested": {
            "type": "boolean"
          },
          "enrollmentStatus": {
            "nullable": true
          },
          "enrolledStudents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StudentRef"
            },
            "nullable": true
          },
          "enrollmentRequests": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CourseEnrollmentRequestGet"
            },
            "nullable": true
          },
          "lessons": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CourseLessonGet"
            },
            "nullable": true
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "studentCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "lessonCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        },
        "nullable": true
      },
      "CourseLessonGet": {
        "type": "object",
        "properties": {
          "courseId": {
            "type": "string",
            "format": "uuid"
          },
          "startDate": {
            "type": "string",
            "format": "date"
          },
          "endDate": {
            "type": "string",
            "format": "date"
          },
          "startTime": {
            "pattern": "^-?(\\d+\\.)?\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?$",
            "type": "string"
          },
          "endTime": {
            "pattern": "^-?(\\d+\\.)?\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?$",
            "type": "string"
          },
          "teacher": {
            "$ref": "#/components/schemas/TeacherRef"
          },
          "room": {
            "$ref": "#/components/schemas/RoomRef"
          },
          "status": {
            "$ref": "#/components/schemas/EnumDtoOfELessonStatus"
          },
          "isCancelled": {
            "type": "boolean"
          },
          "homeworks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HomeworkGet"
            },
            "nullable": true
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "CoursePriceGet": {
        "type": "object",
        "properties": {
          "level": {
            "$ref": "#/components/schemas/EnumDtoOfETeachingLevel"
          },
          "courseType": {
            "$ref": "#/components/schemas/EnumDtoOfECourseType"
          },
          "isForChildren": {
            "type": "boolean"
          },
          "price": {
            "type": "number",
            "format": "double"
          },
          "productName": {
            "type": "string",
            "nullable": true
          },
          "isCustomProduct": {
            "type": "boolean"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "CourseRef": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "courseType": {
            "$ref": "#/components/schemas/EnumDtoOfECourseType"
          },
          "name": {
            "type": "string"
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "subject": {
            "$ref": "#/components/schemas/EnumDtoOfELanguage"
          },
          "level": {
            "$ref": "#/components/schemas/EnumDtoOfETeachingLevel"
          },
          "status": {
            "$ref": "#/components/schemas/EnumDtoOfECourseStatus"
          },
          "teacher": {
            "$ref": "#/components/schemas/TeacherRef"
          },
          "price": {
            "type": "number",
            "format": "double"
          },
          "roomId": {
            "type": "string",
            "format": "uuid"
          },
          "startDate": {
            "type": "string",
            "format": "date-time"
          },
          "endDate": {
            "type": "string",
            "format": "date-time"
          },
          "weeklySchedule": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WeeklyScheduleSlotDto"
            }
          }
        }
      },
      "CourseRef2": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "courseType": { },
          "name": {
            "type": "string"
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "subject": { },
          "level": { },
          "status": { },
          "teacher": {
            "nullable": true
          },
          "price": {
            "type": "number",
            "format": "double"
          },
          "roomId": {
            "type": "string",
            "format": "uuid"
          },
          "startDate": {
            "type": "string",
            "format": "date-time"
          },
          "endDate": {
            "type": "string",
            "format": "date-time"
          },
          "weeklySchedule": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WeeklyScheduleSlotDto"
            }
          }
        },
        "nullable": true
      },
      "CustomerContactInfoGet": {
        "type": "object",
        "properties": {
          "birthdate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "salutation": {
            "type": "string",
            "nullable": true
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "gender": {
            "$ref": "#/components/schemas/EnumDtoOfEGender"
          },
          "email": {
            "type": "string"
          },
          "mobilePhone": {
            "type": "string"
          },
          "phone": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "CustomerContactInfoPatch": {
        "type": "object",
        "properties": {
          "birthdate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "genderId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "removeGenderId": {
            "type": "boolean"
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "mobilePhone": {
            "type": "string",
            "nullable": true
          },
          "phone": {
            "type": "string",
            "nullable": true
          }
        },
        "nullable": true
      },
      "CustomerContactInfoPost": {
        "type": "object",
        "properties": {
          "birthdate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "genderId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "email": {
            "type": "string"
          },
          "mobilePhone": {
            "type": "string"
          },
          "phone": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "CustomerDashboardGet": {
        "type": "object",
        "properties": {
          "remainingCredit": {
            "$ref": "#/components/schemas/StatCardData"
          },
          "outstandingInvoices": {
            "$ref": "#/components/schemas/StatCardData"
          },
          "upcomingLessonsCount": {
            "$ref": "#/components/schemas/StatCardData"
          },
          "unreadNotifications": {
            "$ref": "#/components/schemas/StatCardData"
          },
          "upcomingLessons": {
            "$ref": "#/components/schemas/MiniListDataOfUpcomingLessonItem"
          },
          "pendingInvites": {
            "$ref": "#/components/schemas/MiniListDataOfPendingInviteItem"
          },
          "recentInvoices": {
            "$ref": "#/components/schemas/MiniListDataOfRecentInvoiceItem"
          },
          "notifications": {
            "$ref": "#/components/schemas/MiniListDataOfNotificationItem"
          }
        }
      },
      "CustomerGet": {
        "type": "object",
        "properties": {
          "customerType": {
            "$ref": "#/components/schemas/EnumDtoOfECustomerType"
          },
          "companyName": {
            "type": "string",
            "nullable": true
          },
          "correspondenceLanguage": {
            "$ref": "#/components/schemas/EnumDtoOfELanguage"
          },
          "profileConfirmed": {
            "type": "boolean"
          },
          "contactInfo": {
            "$ref": "#/components/schemas/CustomerContactInfoGet"
          },
          "billingAddress": {
            "$ref": "#/components/schemas/AddressInfoDto"
          },
          "students": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StudentRef"
            }
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "CustomerPatch": {
        "type": "object",
        "properties": {
          "companyName": {
            "type": "string",
            "nullable": true
          },
          "correspondenceLanguageId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "profileConfirmed": {
            "type": "boolean",
            "nullable": true
          },
          "contactInfo": {
            "$ref": "#/components/schemas/CustomerContactInfoPatch"
          },
          "billingAddress": {
            "$ref": "#/components/schemas/AddressInfoDto2"
          }
        }
      },
      "CustomerPost": {
        "type": "object",
        "properties": {
          "correspondenceLanguageId": {
            "type": "string",
            "format": "uuid"
          },
          "contactInfo": {
            "$ref": "#/components/schemas/CustomerContactInfoPost"
          },
          "billingAddress": {
            "$ref": "#/components/schemas/AddressInfoDto"
          }
        }
      },
      "CustomerRef": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "displayName": {
            "type": "string"
          },
          "customerType": {
            "$ref": "#/components/schemas/EnumDtoOfECustomerType"
          },
          "isActive": {
            "type": "boolean"
          },
          "address": {
            "$ref": "#/components/schemas/AddressInfoDto2"
          }
        },
        "nullable": true
      },
      "DayOfWeek": {
        "type": "integer"
      },
      "EAccountStatus": {
        "type": "integer"
      },
      "EAttendanceStatus": {
        "type": "integer"
      },
      "EBudgetStatus": {
        "type": "integer"
      },
      "ECourseCapacity": {
        "type": "integer"
      },
      "ECourseColor": {
        "type": "integer"
      },
      "ECourseEnrollmentStatus": {
        "type": "integer"
      },
      "ECourseStatus": {
        "type": "integer"
      },
      "ECourseType": {
        "type": "integer"
      },
      "ECustomerType": {
        "type": "integer"
      },
      "EGender": {
        "type": "integer"
      },
      "EInterestStatus": {
        "type": "integer"
      },
      "EInterestType": {
        "type": "integer"
      },
      "EInviteMaterialStatus": {
        "type": "integer"
      },
      "EInviteStatus": {
        "type": "integer"
      },
      "EInvoiceStatus": {
        "type": "integer"
      },
      "ELanguage": {
        "type": "integer"
      },
      "ELessonStatus": {
        "type": "integer"
      },
      "EMaterialDeliveryMethod": {
        "type": "integer"
      },
      "EMaterialLevel": {
        "type": "integer"
      },
      "EMaterialType": {
        "type": "integer"
      },
      "ENotificationKey": {
        "type": "integer"
      },
      "ENotificationType": {
        "type": "integer"
      },
      "EnumDtoOfEAccountStatus": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/EAccountStatus"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfEAttendanceStatus": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/EAttendanceStatus"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfEBudgetStatus": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/EBudgetStatus"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfECourseCapacity": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/ECourseCapacity"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        },
        "nullable": true
      },
      "EnumDtoOfECourseEnrollmentStatus": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/ECourseEnrollmentStatus"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        },
        "nullable": true
      },
      "EnumDtoOfECourseEnrollmentStatus2": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/ECourseEnrollmentStatus"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfECourseStatus": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/ECourseStatus"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfECourseType": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/ECourseType"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfECustomerType": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/ECustomerType"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfEGender": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/EGender"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        },
        "nullable": true
      },
      "EnumDtoOfEInterestStatus": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/EInterestStatus"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfEInterestType": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/EInterestType"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfEInviteMaterialStatus": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/EInviteMaterialStatus"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfEInviteStatus": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/EInviteStatus"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfEInvoiceStatus": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/EInvoiceStatus"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfELanguage": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/ELanguage"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfELanguage2": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/ELanguage"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        },
        "nullable": true
      },
      "EnumDtoOfELessonStatus": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/ELessonStatus"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfEMaterialDeliveryMethod": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/EMaterialDeliveryMethod"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        },
        "nullable": true
      },
      "EnumDtoOfEMaterialLevel": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/EMaterialLevel"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfEMaterialType": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/EMaterialType"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfENotificationKey": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/ENotificationKey"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfENotificationType": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/ENotificationType"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfEPackageAssignment": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/EPackageAssignment"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfEPackageOrderStatus": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/EPackageOrderStatus"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfEPackagePurchaseStatus": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/EPackagePurchaseStatus"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfEPreferredLocation": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/EPreferredLocation"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        },
        "nullable": true
      },
      "EnumDtoOfEPreferredTeachingFormat": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/EPreferredTeachingFormat"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        },
        "nullable": true
      },
      "EnumDtoOfERoomStatus": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/ERoomStatus"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfEStudentStatus": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/EStudentStatus"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EnumDtoOfETeachingLevel": {
        "type": "object",
        "properties": {
          "enumValue": {
            "$ref": "#/components/schemas/ETeachingLevel"
          },
          "displayName": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "EPackageAssignment": {
        "type": "integer"
      },
      "EPackageOrderStatus": {
        "type": "integer"
      },
      "EPackagePurchaseStatus": {
        "type": "integer"
      },
      "EPreferredLocation": {
        "type": "integer"
      },
      "EPreferredTeachingFormat": {
        "type": "integer"
      },
      "ERoomStatus": {
        "type": "integer"
      },
      "EStudentStatus": {
        "type": "integer"
      },
      "ETeachingLevel": {
        "type": "integer"
      },
      "HomeworkGet": {
        "type": "object",
        "properties": {
          "lessonId": {
            "type": "string",
            "format": "uuid"
          },
          "description": {
            "type": "string"
          },
          "dueDate": {
            "type": "string",
            "format": "date"
          },
          "lessonStartDate": {
            "type": "string",
            "format": "date",
            "nullable": true
          },
          "course": {
            "$ref": "#/components/schemas/CourseRef2"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "HomeworkRef": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "description": {
            "type": "string"
          },
          "dueDate": {
            "type": "string",
            "format": "date"
          }
        }
      },
      "HttpValidationProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "detail": {
            "type": "string",
            "nullable": true
          },
          "instance": {
            "type": "string",
            "nullable": true
          },
          "errors": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        }
      },
      "InterestGet": {
        "type": "object",
        "properties": {
          "studentId": {
            "type": "string",
            "format": "uuid"
          },
          "studentRef": {
            "$ref": "#/components/schemas/StudentRef2"
          },
          "requestingCustomerId": {
            "type": "string",
            "format": "uuid"
          },
          "requestingCustomer": {
            "$ref": "#/components/schemas/CustomerRef"
          },
          "requestedStudentIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "requestedStudents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StudentRef"
            },
            "nullable": true
          },
          "preferredLocation": {
            "$ref": "#/components/schemas/EnumDtoOfEPreferredLocation"
          },
          "preferredAddress": {
            "type": "string",
            "nullable": true
          },
          "numberOfLessons": {
            "type": "integer",
            "format": "int32"
          },
          "notes": {
            "type": "string",
            "nullable": true
          },
          "estimatedPrice": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "language": {
            "$ref": "#/components/schemas/EnumDtoOfELanguage"
          },
          "level": {
            "$ref": "#/components/schemas/EnumDtoOfETeachingLevel"
          },
          "interestType": {
            "$ref": "#/components/schemas/EnumDtoOfEInterestType"
          },
          "status": {
            "$ref": "#/components/schemas/EnumDtoOfEInterestStatus"
          },
          "declinedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "declineReason": {
            "type": "string",
            "nullable": true
          },
          "startDate": {
            "type": "string",
            "format": "date-time"
          },
          "endDate": {
            "type": "string",
            "format": "date-time"
          },
          "lessonsPerWeek": {
            "type": "integer",
            "format": "int32"
          },
          "lessonDurationMinutes": {
            "type": "integer",
            "format": "int32"
          },
          "timeSlots": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TimeSlotDto"
            }
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "InterestPatch": {
        "type": "object",
        "properties": {
          "startDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "endDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lessonsPerWeek": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "lessonDurationMinutes": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "timeSlots": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TimeSlotDto"
            },
            "nullable": true
          },
          "requestedStudentIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "nullable": true
          },
          "preferredLocationId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "preferredAddress": {
            "type": "string",
            "nullable": true
          },
          "removePreferredAddress": {
            "type": "boolean"
          },
          "numberOfLessons": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "notes": {
            "type": "string",
            "nullable": true
          },
          "removeNotes": {
            "type": "boolean"
          },
          "statusId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          }
        }
      },
      "InterestPost": {
        "type": "object",
        "properties": {
          "studentId": {
            "type": "string",
            "format": "uuid"
          },
          "requestedStudentIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "nullable": true
          },
          "languageId": {
            "type": "string",
            "format": "uuid"
          },
          "levelId": {
            "type": "string",
            "format": "uuid"
          },
          "interestTypeId": {
            "type": "string",
            "format": "uuid"
          },
          "startDate": {
            "type": "string",
            "format": "date-time"
          },
          "endDate": {
            "type": "string",
            "format": "date-time"
          },
          "lessonsPerWeek": {
            "type": "integer",
            "format": "int32"
          },
          "lessonDurationMinutes": {
            "type": "integer",
            "format": "int32"
          },
          "timeSlots": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TimeSlotDto"
            },
            "nullable": true
          },
          "preferredLocationId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "preferredAddress": {
            "type": "string",
            "nullable": true
          },
          "numberOfLessons": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "notes": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "InviteMaterialChoiceGet": {
        "type": "object",
        "properties": {
          "materialId": {
            "type": "string",
            "format": "uuid"
          },
          "material": {
            "$ref": "#/components/schemas/MaterialRef2"
          },
          "alreadyInPossession": {
            "type": "boolean"
          },
          "status": {
            "$ref": "#/components/schemas/EnumDtoOfEInviteMaterialStatus"
          },
          "deliveryMethod": {
            "$ref": "#/components/schemas/EnumDtoOfEMaterialDeliveryMethod"
          },
          "answeredAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "InviteMaterialChoicePost": {
        "type": "object",
        "properties": {
          "materialId": {
            "type": "string",
            "format": "uuid"
          },
          "alreadyInPossession": {
            "type": "boolean"
          },
          "deliveryMethodId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          }
        }
      },
      "InvoiceGet": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "invoiceDate": {
            "type": "string",
            "format": "date-time"
          },
          "periodYear": {
            "type": "integer",
            "format": "int32"
          },
          "periodMonth": {
            "type": "integer",
            "format": "int32"
          },
          "dueDate": {
            "type": "string",
            "format": "date-time"
          },
          "invoiceNumber": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/EnumDtoOfEInvoiceStatus"
          },
          "totalAmount": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "fileUrl": {
            "type": "string",
            "nullable": true
          },
          "itemCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "lineItems": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InvoiceLineItemGet"
            }
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "InvoiceLineItemGet": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string"
          },
          "courseDisplay": {
            "type": "string",
            "nullable": true
          },
          "studentDisplay": {
            "type": "string",
            "nullable": true
          },
          "units": {
            "type": "integer",
            "format": "int32"
          },
          "amount": {
            "type": "number",
            "format": "double"
          }
        }
      },
      "LessonGet": {
        "type": "object",
        "properties": {
          "courseId": {
            "type": "string",
            "format": "uuid"
          },
          "course": {
            "$ref": "#/components/schemas/CourseRef2"
          },
          "startDate": {
            "type": "string",
            "format": "date"
          },
          "endDate": {
            "type": "string",
            "format": "date"
          },
          "startTime": {
            "pattern": "^-?(\\d+\\.)?\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?$",
            "type": "string"
          },
          "endTime": {
            "pattern": "^-?(\\d+\\.)?\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?$",
            "type": "string"
          },
          "teacher": {
            "$ref": "#/components/schemas/TeacherRef"
          },
          "room": {
            "$ref": "#/components/schemas/RoomRef"
          },
          "status": {
            "$ref": "#/components/schemas/EnumDtoOfELessonStatus"
          },
          "isCancelled": {
            "type": "boolean"
          },
          "homeworks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HomeworkGet"
            },
            "nullable": true
          },
          "attendanceRecords": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AttendanceRecordGet"
            },
            "nullable": true
          },
          "enrolledStudents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StudentRef"
            },
            "nullable": true
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "LessonRef": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "displayName": {
            "type": "string"
          },
          "startDate": {
            "type": "string",
            "format": "date"
          },
          "startTime": {
            "pattern": "^-?(\\d+\\.)?\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?$",
            "type": "string"
          },
          "endTime": {
            "pattern": "^-?(\\d+\\.)?\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?$",
            "type": "string"
          },
          "isCancelled": {
            "type": "boolean"
          },
          "isInvoiced": {
            "type": "boolean"
          },
          "travelAllowance": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "courseDisplay": {
            "type": "string"
          },
          "lessonPrice": {
            "type": "number",
            "format": "double"
          },
          "status": {
            "$ref": "#/components/schemas/EnumDtoOfELessonStatus"
          },
          "course": {
            "$ref": "#/components/schemas/CourseRef2"
          },
          "teacher": {
            "$ref": "#/components/schemas/TeacherRef"
          },
          "homeworks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HomeworkRef"
            },
            "nullable": true
          }
        }
      },
      "MaterialRef": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "isbn": {
            "type": "string"
          },
          "language": {
            "$ref": "#/components/schemas/EnumDtoOfELanguage"
          },
          "level": {
            "$ref": "#/components/schemas/EnumDtoOfEMaterialLevel"
          },
          "price": {
            "type": "number",
            "format": "double"
          },
          "type": {
            "$ref": "#/components/schemas/EnumDtoOfEMaterialType"
          }
        }
      },
      "MaterialRef2": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "isbn": {
            "type": "string"
          },
          "language": {
            "$ref": "#/components/schemas/EnumDtoOfELanguage"
          },
          "level": {
            "$ref": "#/components/schemas/EnumDtoOfEMaterialLevel"
          },
          "price": {
            "type": "number",
            "format": "double"
          },
          "type": {
            "$ref": "#/components/schemas/EnumDtoOfEMaterialType"
          }
        },
        "nullable": true
      },
      "MiniListDataOfNotificationItem": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NotificationItem"
            }
          },
          "viewAllUrl": {
            "type": "string",
            "nullable": true
          },
          "maxItems": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "MiniListDataOfPendingInviteItem": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PendingInviteItem"
            }
          },
          "viewAllUrl": {
            "type": "string",
            "nullable": true
          },
          "maxItems": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "MiniListDataOfRecentInvoiceItem": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RecentInvoiceItem"
            }
          },
          "viewAllUrl": {
            "type": "string",
            "nullable": true
          },
          "maxItems": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "MiniListDataOfUpcomingLessonItem": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UpcomingLessonItem"
            }
          },
          "viewAllUrl": {
            "type": "string",
            "nullable": true
          },
          "maxItems": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "MyProfilePatch": {
        "type": "object",
        "properties": {
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "genderId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "removeGenderId": {
            "type": "boolean"
          },
          "birthdate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "mobilePhone": {
            "type": "string",
            "nullable": true
          },
          "phone": {
            "type": "string",
            "nullable": true
          },
          "removePhone": {
            "type": "boolean"
          },
          "billingAddress": {
            "$ref": "#/components/schemas/AddressInfoDto2"
          },
          "correspondenceLanguageId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "profileConfirmed": {
            "type": "boolean",
            "nullable": true
          }
        }
      },
      "NotificationGet": {
        "type": "object",
        "properties": {
          "targetId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "eventDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "date": {
            "type": "string",
            "format": "date-time"
          },
          "message": {
            "type": "string"
          },
          "isRead": {
            "type": "boolean"
          },
          "targetUrl": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "$ref": "#/components/schemas/EnumDtoOfENotificationType"
          },
          "key": {
            "$ref": "#/components/schemas/EnumDtoOfENotificationKey"
          },
          "relatedStudent": {
            "$ref": "#/components/schemas/StudentRef2"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "NotificationItem": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date-time"
          },
          "type": {
            "$ref": "#/components/schemas/EnumDtoOfENotificationType"
          },
          "isRead": {
            "type": "boolean"
          }
        }
      },
      "NotificationMarkReadPost": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          }
        }
      },
      "NotificationMarkReadResultGet": {
        "type": "object",
        "properties": {
          "updated": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "NotificationPatch": {
        "type": "object",
        "properties": {
          "isRead": {
            "type": "boolean",
            "nullable": true
          }
        }
      },
      "NotificationUnreadCountGet": {
        "type": "object",
        "properties": {
          "unread": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "NullableOfEAccountStatus": {
        "type": "integer"
      },
      "NullableOfEStudentStatus": {
        "type": "integer"
      },
      "PackageGet": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "billingTitle": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "price": {
            "type": "number",
            "format": "double"
          },
          "credit": {
            "type": "number",
            "format": "double"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "PackageGet2": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "billingTitle": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "price": {
            "type": "number",
            "format": "double"
          },
          "credit": {
            "type": "number",
            "format": "double"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        },
        "nullable": true
      },
      "PackageOrderGet": {
        "type": "object",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/EnumDtoOfEPackageOrderStatus"
          },
          "refundRequestedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "refundedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "refundReason": {
            "type": "string",
            "nullable": true
          },
          "packageId": {
            "type": "string",
            "format": "uuid"
          },
          "packageRef": {
            "$ref": "#/components/schemas/PackageGet2"
          },
          "customerId": {
            "type": "string",
            "format": "uuid"
          },
          "customerRef": {
            "$ref": "#/components/schemas/CustomerRef"
          },
          "assignedToCustomerId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "assignedToCustomer": {
            "$ref": "#/components/schemas/CustomerRef"
          },
          "assignedToCustomerEmail": {
            "type": "string",
            "nullable": true
          },
          "passedOnType": {
            "$ref": "#/components/schemas/EnumDtoOfEPackageAssignment"
          },
          "usageByStudent": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PackageStudentUsageDto"
            }
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "usedCredit": {
            "type": "number",
            "format": "double"
          },
          "purchasedPrice": {
            "type": "number",
            "format": "double"
          },
          "purchasedCredit": {
            "type": "number",
            "format": "double"
          },
          "remainingCredit": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "PackagePurchaseGet": {
        "type": "object",
        "properties": {
          "customerId": {
            "type": "string",
            "format": "uuid"
          },
          "customerRef": {
            "$ref": "#/components/schemas/CustomerRef"
          },
          "purchasedAt": {
            "type": "string",
            "format": "date-time"
          },
          "status": {
            "$ref": "#/components/schemas/EnumDtoOfEPackagePurchaseStatus"
          },
          "invoiceId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "orders": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PackageOrderGet"
            }
          },
          "itemCount": {
            "type": "integer",
            "format": "int32"
          },
          "totalPrice": {
            "type": "number",
            "format": "double"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "PackagePurchaseItemPost": {
        "type": "object",
        "properties": {
          "packageId": {
            "type": "string",
            "format": "uuid"
          },
          "beneficiaryCustomerEmail": {
            "type": "string",
            "nullable": true
          },
          "passedOnTypeId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          }
        }
      },
      "PackagePurchasePost": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PackagePurchaseItemPost"
            }
          }
        }
      },
      "PackageStudentUsageDto": {
        "type": "object",
        "properties": {
          "studentId": {
            "type": "string",
            "format": "uuid"
          },
          "student": {
            "$ref": "#/components/schemas/StudentRef2"
          },
          "usedCredit": {
            "type": "number",
            "format": "double"
          },
          "lessonCount": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "PendingInviteItem": {
        "type": "object",
        "properties": {
          "studentName": {
            "type": "string"
          },
          "courseName": {
            "type": "string"
          },
          "invitedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "detail": {
            "type": "string",
            "nullable": true
          },
          "instance": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "RecentInvoiceItem": {
        "type": "object",
        "properties": {
          "invoiceNumber": {
            "type": "string"
          },
          "invoiceDate": {
            "type": "string",
            "format": "date-time"
          },
          "amount": {
            "type": "number",
            "format": "double"
          },
          "status": {
            "$ref": "#/components/schemas/EnumDtoOfEInvoiceStatus"
          },
          "dueDate": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "RefundableAmountGet": {
        "type": "object",
        "properties": {
          "packageOrderId": {
            "type": "string",
            "format": "uuid"
          },
          "refundableAmount": {
            "type": "number",
            "format": "double"
          },
          "isRefundable": {
            "type": "boolean"
          },
          "isPlaceholder": {
            "type": "boolean"
          }
        }
      },
      "RoomRef": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "displayName": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "maxStudents": {
            "type": "integer",
            "format": "int32"
          },
          "status": {
            "$ref": "#/components/schemas/EnumDtoOfERoomStatus"
          }
        },
        "nullable": true
      },
      "SetPasswordPost": {
        "type": "object",
        "properties": {
          "password": {
            "type": "string"
          }
        }
      },
      "StatCardData": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "value": {
            "type": "string"
          },
          "icon": {
            "type": "string",
            "nullable": true
          },
          "trendPercent": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "color": {
            "type": "string",
            "nullable": true
          },
          "link": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "StudentGet": {
        "type": "object",
        "properties": {
          "lastName": {
            "type": "string"
          },
          "firstName": {
            "type": "string"
          },
          "birthdate": {
            "type": "string",
            "format": "date-time"
          },
          "nativeLanguage": {
            "$ref": "#/components/schemas/EnumDtoOfELanguage"
          },
          "gender": {
            "$ref": "#/components/schemas/EnumDtoOfEGender"
          },
          "correspondenceLanguage": {
            "$ref": "#/components/schemas/EnumDtoOfELanguage2"
          },
          "preferredTeachingFormat": {
            "$ref": "#/components/schemas/EnumDtoOfEPreferredTeachingFormat"
          },
          "status": {
            "$ref": "#/components/schemas/EnumDtoOfEStudentStatus"
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "accountStatus": {
            "$ref": "#/components/schemas/EnumDtoOfEAccountStatus"
          },
          "loginNumber": {
            "type": "string",
            "nullable": true
          },
          "phone": {
            "type": "string",
            "nullable": true
          },
          "useCustomerAddress": {
            "type": "boolean"
          },
          "address": {
            "$ref": "#/components/schemas/AddressInfoDto2"
          },
          "subjects": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SubjectGet"
            }
          },
          "notes": {
            "type": "string",
            "nullable": true
          },
          "courses": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CourseRef"
            },
            "nullable": true
          },
          "lessons": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LessonRef"
            },
            "nullable": true
          },
          "age": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "isChild": {
            "type": "boolean",
            "nullable": true
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "StudentInviteGet": {
        "type": "object",
        "properties": {
          "courseId": {
            "type": "string",
            "format": "uuid"
          },
          "course": {
            "$ref": "#/components/schemas/CourseRef2"
          },
          "studentId": {
            "type": "string",
            "format": "uuid"
          },
          "student": {
            "$ref": "#/components/schemas/StudentRef2"
          },
          "status": {
            "$ref": "#/components/schemas/EnumDtoOfEInviteStatus"
          },
          "invitedAt": {
            "type": "string",
            "format": "date-time"
          },
          "respondedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "materialChoices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InviteMaterialChoiceGet"
            }
          },
          "deliveryMethod": {
            "$ref": "#/components/schemas/EnumDtoOfEMaterialDeliveryMethod"
          },
          "deliveryAddress": {
            "$ref": "#/components/schemas/AddressInfoDto2"
          },
          "defaultDeliveryAddress": {
            "$ref": "#/components/schemas/AddressInfoDto2"
          },
          "acceptedDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "declinedDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "isPending": {
            "type": "boolean"
          },
          "materialListComplete": {
            "type": "boolean"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "removed": {
            "type": "boolean"
          }
        }
      },
      "StudentInvitePatch": {
        "type": "object",
        "properties": {
          "statusId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "materialChoices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InviteMaterialChoicePost"
            },
            "nullable": true
          },
          "deliveryMethodId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "deliveryAddress": {
            "$ref": "#/components/schemas/AddressInfoDto2"
          }
        }
      },
      "StudentPatch": {
        "type": "object",
        "properties": {
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "birthdate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "nativeLanguageId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "genderId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "removeGender": {
            "type": "boolean"
          },
          "correspondenceLanguageId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "removeCorrespondenceLanguage": {
            "type": "boolean"
          },
          "preferredTeachingFormatId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "removePreferredTeachingFormat": {
            "type": "boolean"
          },
          "phone": {
            "type": "string",
            "nullable": true
          },
          "useCustomerAddress": {
            "type": "boolean",
            "nullable": true
          },
          "address": {
            "$ref": "#/components/schemas/AddressInfoDto2"
          },
          "removeAddress": {
            "type": "boolean"
          },
          "notes": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "StudentPost": {
        "type": "object",
        "properties": {
          "lastName": {
            "type": "string"
          },
          "firstName": {
            "type": "string"
          },
          "birthdate": {
            "type": "string",
            "format": "date-time"
          },
          "nativeLanguageId": {
            "type": "string",
            "format": "uuid"
          },
          "genderId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "correspondenceLanguageId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "preferredTeachingFormatId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "phone": {
            "type": "string",
            "nullable": true
          },
          "useCustomerAddress": {
            "type": "boolean"
          },
          "address": {
            "$ref": "#/components/schemas/AddressInfoDto2"
          },
          "subjects": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SubjectPost"
            },
            "nullable": true
          },
          "notes": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "StudentRef": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "nativeLanguage": {
            "$ref": "#/components/schemas/EnumDtoOfELanguage"
          },
          "isChild": {
            "type": "boolean",
            "nullable": true
          },
          "age": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        }
      },
      "StudentRef2": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "nativeLanguage": {
            "$ref": "#/components/schemas/EnumDtoOfELanguage"
          },
          "isChild": {
            "type": "boolean",
            "nullable": true
          },
          "age": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "nullable": true
      },
      "SubjectGet": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "language": {
            "$ref": "#/components/schemas/EnumDtoOfELanguage"
          },
          "level": {
            "$ref": "#/components/schemas/EnumDtoOfETeachingLevel"
          }
        }
      },
      "SubjectPost": {
        "type": "object",
        "properties": {
          "languageId": {
            "type": "string",
            "format": "uuid"
          },
          "levelId": {
            "type": "string",
            "format": "uuid"
          }
        }
      },
      "TeacherRef": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "displayName": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "mobilePhone": {
            "type": "string"
          },
          "lessonsToChildren": {
            "type": "boolean"
          },
          "inactive": {
            "type": "boolean"
          },
          "teachingLanguages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EnumDtoOfELanguage"
            }
          }
        },
        "nullable": true
      },
      "TimeSlotDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "day": {
            "$ref": "#/components/schemas/DayOfWeek"
          },
          "startTime": {
            "pattern": "^-?(\\d+\\.)?\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?$",
            "type": "string"
          },
          "endTime": {
            "pattern": "^-?(\\d+\\.)?\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?$",
            "type": "string"
          }
        }
      },
      "UpcomingLessonItem": {
        "type": "object",
        "properties": {
          "studentName": {
            "type": "string"
          },
          "courseName": {
            "type": "string"
          },
          "startDate": {
            "type": "string",
            "format": "date-time"
          },
          "startTime": {
            "pattern": "^-?(\\d+\\.)?\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?$",
            "type": "string"
          },
          "teacherName": {
            "type": "string"
          },
          "roomName": {
            "type": "string"
          }
        }
      },
      "WeeklyScheduleSlotDto": {
        "type": "object",
        "properties": {
          "day": {
            "$ref": "#/components/schemas/DayOfWeek"
          },
          "startTime": {
            "pattern": "^-?(\\d+\\.)?\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?$",
            "type": "string"
          },
          "endTime": {
            "pattern": "^-?(\\d+\\.)?\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?$",
            "type": "string"
          }
        }
      }
    },
    "securitySchemes": {
      "keycloak": {
        "type": "oauth2",
        "description": "Log in via Keycloak (Authorization Code + PKCE). Uses the public 'swagger-ui' client.",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://auth.triskela.com/realms/softlanding/protocol/openid-connect/auth",
            "tokenUrl": "https://auth.triskela.com/realms/softlanding/protocol/openid-connect/token",
            "scopes": {
              "openid": "OpenID Connect",
              "profile": "User profile",
              "email": "User email"
            }
          }
        }
      }
    }
  },
  "security": [
    {
      "keycloak": [
        "openid",
        "profile",
        "email"
      ]
    }
  ],
  "tags": [
    {
      "name": "Dashboard (Customer)"
    },
    {
      "name": "Customer (Customer)"
    },
    {
      "name": "Student (Customer)"
    },
    {
      "name": "Course (Customer)"
    },
    {
      "name": "Interest (Customer)"
    },
    {
      "name": "Lesson (Customer)"
    },
    {
      "name": "Invoice (Customer)"
    },
    {
      "name": "Budget (Customer)"
    },
    {
      "name": "Package (Customer)"
    },
    {
      "name": "CoursePrice (Customer)"
    },
    {
      "name": "PackageOrder (Customer)"
    },
    {
      "name": "PackagePurchase (Customer)"
    },
    {
      "name": "StudentInvite (Customer)"
    },
    {
      "name": "Notification (Customer)"
    },
    {
      "name": "EnrollmentRequest (Customer)"
    },
    {
      "name": "Customer MyProfile"
    }
  ]
}