Technical University of Munich feedback API

APIs to give feedback

OpenAPI Specification

tum-feedback-api-openapi.yml Raw ↑
openapi: 3.0.1
info:
  title: eat-api calendar feedback API
  version: '2.1'
  description: Simple static API for some (student) food places in Munich.
servers:
- url: https://tum-dev.github.io/eat-api/{language}
  variables:
    language:
      description: For localization the base path may have to be extended by the language.
      default: ''
      enum:
      - ''
      - en/
tags:
- name: feedback
  description: APIs to give feedback
paths:
  /api/feedback/feedback:
    post:
      tags:
      - feedback
      summary: Post feedback
      description: '***Do not abuse this endpoint.***


        This posts the actual feedback to GitHub and returns the GitHub link.

        This API will create issues instead of pull-requests

        => all feedback is allowed, but [`/api/feedback/propose_edits`](#tag/feedback/operation/propose_edits) is preferred, if it can be posted there.


        For this Endpoint to work, you need to generate a token via the [`/api/feedback/get_token`](#tag/feedback/operation/get_token) endpoint.


        # Note


        Tokens are only used if we return a 201 Created response.

        Otherwise, they are still valid'
      operationId: send_feedback
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PostFeedbackRequest'
        required: true
      responses:
        '201':
          description: The feedback has been **successfully posted to GitHub**. We return the link to the GitHub issue.
          content:
            text/plain:
              schema:
                type: string
                format: uri
              example: https://github.com/TUM-Dev/navigatum/issues/9
        '400':
          description: '**Bad Request.** Not all fields in the body are present as defined above'
        '403':
          description: '**Forbidden.** Causes are (delivered via the body):


            - `Invalid token`: You have not supplied a token generated via the `gen_token`-Endpoint.

            - `Token not old enough, please wait`: Tokens are only valid after 10s.

            - `Token expired`: Tokens are only valid for 12h.

            - `Token already used`: Tokens are non reusable/refreshable single-use items.'
          content:
            text/plain:
              schema:
                type: string
        '422':
          description: '**Unprocessable Entity.** Subject or body missing or too short.'
        '451':
          description: '**Unavailable for legal reasons.** Using this endpoint without accepting the privacy policy is not allowed. For us to post to GitHub, this has to be `true`'
        '500':
          description: '**Internal Server Error.** We have a problem communicating with GitHubs servers. Please try again later'
        '503':
          description: '**Service unavailable.** We have not configured a GitHub Access Token. This could be because we are experiencing technical difficulties or intentional. Please try again later.'
  /api/feedback/get_token:
    post:
      tags:
      - feedback
      summary: Get a feedback-token
      description: '***Do not abuse this endpoint.***


        This returns a JWT token usable for submitting feedback.

        You should request a token, ***if (and only if) a user is on a feedback page***


        As a rudimentary way of rate-limiting feedback, this endpoint returns a token.

        To post feedback, you will need this token.


        Tokens gain validity after 5s, and are invalid after 12h of being issued.

        They are not refreshable, and are only valid for one usage.


        # Note:


        Global Rate-Limiting allows bursts with up to 20 requests and replenishes 50 requests per day'
      operationId: get_token
      responses:
        '201':
          description: '**Created** a usable token'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        '429':
          description: '**Too many requests.** We are rate-limiting everyone''s requests, please try again later.'
        '503':
          description: '**Service unavailable.** We have not configured a GitHub Access Token. This could be because we are experiencing technical difficulties or intentional. Please try again later.'
  /api/feedback/propose_edits:
    post:
      tags:
      - feedback
      summary: Post Edit-Requests
      description: '***Do not abuse this endpoint.***


        This posts the actual feedback to GitHub and returns the github link.

        This API will create pull-requests instead of issues => only a subset of feedback is allowed.

        For this Endpoint to work, you need to generate a token via the [`/api/feedback/get_token`](#tag/feedback/operation/get_token) endpoint.


        # Note:


        Tokens are only used if we return a 201 Created response. Otherwise, they are still valid'
      operationId: propose_edits
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EditRequest'
        required: true
      responses:
        '201':
          description: The edit request feedback has been **successfully posted to GitHub**. We return the link to the GitHub issue.
          content:
            text/plain:
              schema:
                type: string
                format: uri
              example: https://github.com/TUM-Dev/navigatum/issues/9
        '400':
          description: '**Bad Request.** Not all fields in the body are present as defined above'
        '403':
          description: '**Forbidden.** Causes are (delivered via the body):


            - `Invalid token`: You have not supplied a token generated via the `gen_token`-Endpoint.

            - `Token not old enough, please wait`: Tokens are only valid after 10s.

            - `Token expired`: Tokens are only valid for 12h.

            - `Token already used`: Tokens are non reusable/refreshable single-use items.'
        '422':
          description: '**Unprocessable Entity.** Subject or body missing or too short.'
        '451':
          description: '**Unavailable for legal reasons.** Using this endpoint without accepting the privacy policy is not allowed. For us to post to GitHub, this has to be true'
        '500':
          description: '**Internal Server Error.** We have a problem communicating with GitHubs servers. Please try again later.'
        '503':
          description: Service unavailable. We have not configured a GitHub Access Token. This could be because we are experiencing technical difficulties or intentional. Please try again later.
components:
  schemas:
    NewPoi:
      type: object
      required:
      - parent
      - name
      - usage_name
      - coords
      properties:
        comment:
          oneOf:
          - type: 'null'
          - $ref: '#/components/schemas/TranslatableStr'
        coords:
          $ref: '#/components/schemas/Coordinate'
        generic_props:
          type: array
          items:
            $ref: '#/components/schemas/GenericProp'
        links:
          type: array
          items:
            $ref: '#/components/schemas/PoiLink'
        name:
          type: string
        parent:
          type: string
        usage_name:
          type: string
    Coordinate:
      type: object
      required:
      - lat
      - lon
      properties:
        lat:
          type: number
          format: double
          description: Latitude
          example: 48.26244490906312
        lon:
          type: number
          format: double
          description: Longitude
          example: 48.26244490906312
    Property:
      type: object
      required:
      - text
      properties:
        text:
          type: string
        url:
          type: string
          nullable: true
    NewRoom:
      type: object
      required:
      - parent_building_id
      - alt_name
      - arch_name
      - usage_id
      - coords
      properties:
        address:
          oneOf:
          - type: 'null'
          - $ref: '#/components/schemas/RoomAddress'
        alt_name:
          type: string
        arch_name:
          type: string
        coords:
          $ref: '#/components/schemas/Coordinate'
        floor_level:
          type: string
          nullable: true
        floor_type:
          type: string
          nullable: true
        links:
          type: array
          items:
            $ref: '#/components/schemas/RoomLink'
        parent_building_id:
          type: string
        seats:
          oneOf:
          - type: 'null'
          - $ref: '#/components/schemas/Seats'
        usage_id:
          type: integer
          format: int32
          minimum: 0
    ImageMetadata:
      type: object
      required:
      - author
      - license
      properties:
        author:
          type: string
          description: Who created the image
        license:
          $ref: '#/components/schemas/Property'
          description: The license under which the image is distributed
        offsets:
          oneOf:
          - type: 'null'
          - $ref: '#/components/schemas/Offsets'
            description: Advanced metadata to control how the image is displayed
    FeedbackCategory:
      type: string
      enum:
      - bug
      - feature
      - search
      - navigation
      - entry
      - general
      - other
    RoomAddress:
      type: object
      required:
      - place
      - street
      - zip_code
      properties:
        place:
          type: string
        street:
          type: string
        zip_code:
          type: string
    TokenResponse:
      type: object
      required:
      - created_at
      - token
      properties:
        created_at:
          type: integer
          format: int64
          description: Unix timestamp of when the token was created
          example: '1629564181'
        token:
          type: string
          description: The JWT token, that can be used to generate feedback
          example: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2Njk2MzczODEsImlhdCI6MTY2OTU5NDE4MSwibmJmIjoxNjY5NTk0MTkxLCJraWQiOjE1ODU0MTUyODk5MzI0MjU0Mzg2fQ.sN0WwXzsGhjOVaqWPe-Fl5x-gwZvh28MMUM-74MoNj4
    GenericProp:
      type: object
      required:
      - name
      - text
      properties:
        name:
          $ref: '#/components/schemas/TranslatableStr'
        text:
          type: string
    LimitedHashMap_String_Addition:
      type: object
      additionalProperties:
        oneOf:
        - allOf:
          - $ref: '#/components/schemas/NewRoom'
          - type: object
            required:
            - kind
            properties:
              kind:
                type: string
                enum:
                - room
        - allOf:
          - $ref: '#/components/schemas/NewBuilding'
          - type: object
            required:
            - kind
            properties:
              kind:
                type: string
                enum:
                - building
        - allOf:
          - $ref: '#/components/schemas/NewPoi'
          - type: object
            required:
            - kind
            properties:
              kind:
                type: string
                enum:
                - poi
      propertyNames:
        type: string
    EditRequest:
      type: object
      required:
      - token
      - additional_context
      - privacy_checked
      properties:
        additional_context:
          type: string
          description: 'Additional context for the edit.


            Will be displayed in the discription field of the PR'
          example: I have a picture of the room, please add it to the roomfinder
        additions:
          $ref: '#/components/schemas/LimitedHashMap_String_Addition'
          description: New rooms/buildings/POIs to add. Keyed by the new entry's ID. Validated server-side.
        edits:
          $ref: '#/components/schemas/LimitedHashMap_String_Edit'
          description: The edits to be made to the room. The keys are the ID of the props to be edited, the values are the proposed Edits.
        privacy_checked:
          type: boolean
          description: 'Whether the user has checked the privacy-checkbox.


            We are posting the feedback publicly on GitHub (not a EU-Company).

            **You MUST also include such a checkmark.**'
        token:
          type: string
          description: The JWT token, that can be used to generate feedback
          example: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2Njk2MzczODEsImlhdCI6MTY2OTU5NDE4MSwibmJmIjoxNjY5NTk0MTkxLCJraWQiOjE1ODU0MTUyODk5MzI0MjU0Mzg2fQ.sN0WwXzsGhjOVaqWPe-Fl5x-gwZvh28MMUM-74MoNj4
    LimitedHashMap_String_Edit:
      type: object
      additionalProperties:
        type: object
        properties:
          coordinate:
            oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/Coordinate'
          image:
            oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/Image'
          properties:
            type: array
            items:
              $ref: '#/components/schemas/PropertyEdit'
            nullable: true
      propertyNames:
        type: string
    Seats:
      type: object
      properties:
        sitting:
          type: integer
          format: int32
          minimum: 0
          nullable: true
        standing:
          type: integer
          format: int32
          minimum: 0
          nullable: true
        wheelchair:
          type: integer
          format: int32
          minimum: 0
          nullable: true
    Image:
      type: object
      required:
      - content
      - metadata
      properties:
        content:
          type: string
          description: The image encoded as base64
          contentEncoding: base64
        metadata:
          $ref: '#/components/schemas/ImageMetadata'
    Offsets:
      type: object
      properties:
        header:
          type: integer
          format: int32
          nullable: true
        thumb:
          type: integer
          format: int32
          nullable: true
    PropertyEdit:
      oneOf:
      - type: object
        required:
        - type
        properties:
          name:
            type: string
            nullable: true
          short_name:
            type: string
            nullable: true
          type:
            type: string
            enum:
            - name
      - type: object
        required:
        - name_de
        - name_en
        - type
        properties:
          din_277:
            type: string
            nullable: true
          din_277_desc:
            type: string
            nullable: true
          name_de:
            type: string
          name_en:
            type: string
          type:
            type: string
            enum:
            - usage
      - type: object
        required:
        - text_de
        - text_en
        - url
        - type
        properties:
          text_de:
            type: string
          text_en:
            type: string
          type:
            type: string
            enum:
            - link
          url:
            type: string
    RoomLink:
      type: object
      required:
      - text_de
      - text_en
      - url
      properties:
        text_de:
          type: string
        text_en:
          type: string
        url:
          type: string
    TranslatableStr:
      type: object
      required:
      - de
      - en
      properties:
        de:
          type: string
        en:
          type: string
    BuildingKind:
      type: string
      enum:
      - building
      - joined_building
      - area
    PostFeedbackRequest:
      type: object
      required:
      - token
      - subject
      - body
      - privacy_checked
      - deletion_requested
      properties:
        body:
          type: string
          description: 'The body/description of the feedback


            Controll characters will be stripped, too long input truncated and newlines made to render in markdown'
          example: A clear description what happened where and how we should improve it
          maxLength: 1048576
          minLength: 10
        category:
          $ref: '#/components/schemas/FeedbackCategory'
          description: The category of the feedback.
        deletion_requested:
          type: boolean
          description: 'Whether the user has requested to delete the issue.


            This flag means:

            - If the user has requested to delete the issue, we will delete it from GitHub after processing it

            - If the user has not requested to delete the issue, we will not delete it from GitHub and it will remain as a closed issue.'
        privacy_checked:
          type: boolean
          description: 'Whether the user has checked the privacy-checkbox.


            We are posting the feedback publicly on GitHub (not a EU-Company).

            **You MUST also include such a checkmark.**'
        subject:
          type: string
          description: 'The subject/title of the feedback


            Controll characters will be stripped, too long input truncated and newlines made to render in markdown'
          example: A catchy title
          maxLength: 512
          minLength: 4
        token:
          type: string
          description: The JWT token, that can be used to generate feedback
          example: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2Njk2MzczODEsImlhdCI6MTY2OTU5NDE4MSwibmJmIjoxNjY5NTk0MTkxLCJraWQiOjE1ODU0MTUyODk5MzI0MjU0Mzg2fQ.sN0WwXzsGhjOVaqWPe-Fl5x-gwZvh28MMUM-74MoNj4
    NewBuilding:
      type: object
      required:
      - parent_id
      - node_kind
      - building_prefixes
      - name
      - coords
      properties:
        building_prefixes:
          type: array
          items:
            type: string
        coords:
          $ref: '#/components/schemas/Coordinate'
        internal_id:
          type: string
          nullable: true
        name:
          type: string
        node_kind:
          $ref: '#/components/schemas/BuildingKind'
        parent_id:
          type: string
        short_name:
          type: string
          nullable: true
        visible_id:
          type: string
          nullable: true
    PoiLink:
      type: object
      required:
      - text
      - url
      properties:
        text:
          $ref: '#/components/schemas/TranslatableStr'
        url:
          type: string