openapi: 3.0.0
info:
  description: "This is the API specification for the ScheduleTogether Backend."
  version: 0.1.0
  title: ScheduleTogether Backend
  termsOfService: http://zervo.org/terms/
  contact:
    email: contact@dev.zervo.org
  license:
    name: AGPL 3.0
    url: https://www.gnu.org/licenses/agpl-3.0.html
tags:
  - name: account
    description: Everything related to account management
    externalDocs:
      description: Find out more
      url: https://git.zervo.org/ScheduleTogether/Backend/src/branch/main/internal/api/handlers/account_handler.go
  - name: users
    description: Everything related to user management
    externalDocs:
      description: Find out more
      url: https://git.zervo.org/ScheduleTogether/Backend/src/branch/main/internal/api/handlers/users_handler.go
  - name: friends
    description: Everything related to friends management
    externalDocs:
      description: Find out more
      url: https://git.zervo.org/ScheduleTogether/Backend/src/branch/main/internal/api/handlers/friends_handler.go
paths:
  /account/register:
    post:
      tags:
        - account
      summary: Register a new user account
      description: "Used to register a new user account. By default, newly created unverified accounts will be deleted after a while. To fully complete registration, an account verify request must be sent following the registration request."
      operationId: registerAccount
      requestBody:
        $ref: "#/components/requestBodies/AccountRegister"
      responses:
        "400":
          description: Request body validation failed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommonError"
        "200":
          description: Registration successful
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AccountRegisterResponse"
  /account/verify:
    post:
      tags:
        - account
      summary: Verify a registered account
      description: "Used to verify a newly registered user account. AKA complete user account registration."
      operationId: verifyAccount
      requestBody:
        $ref: "#/components/requestBodies/AccountVerify"
      responses:
        "200":
          description: Verification successful
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommonMessage"
        "400":
          description: Invalid UUID or verification token
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommonError"
  /account/signin:
    post:
      tags:
        - account
      summary: Sign in to an existing user account
      description: "Used to retrieve a session (jwt) token for a user account, that can in turn be used to authenticate subsequent requests."
      operationId: signinAccount
      requestBody:
        $ref: "#/components/requestBodies/AccountSignin"
      responses:
        "401":
          description: Authentication failed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommonError"
        "400":
          description: Request body validation failed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommonError"
        "200":
          description: Signed in successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AccountSigninResponse"
  /account/logout:
    post:
      tags:
        - account
      summary: Log out of a user account
      description: "Used to invalidate a user account session (aka log out) based on context. REQUIRES: Authentication."
      operationId: logoutAccount
      responses:
        "401":
          description: Unauthorized
        "200":
          description: Successfully logged out
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommonMessage"
                
  /users:  
    get:
      tags:
        - users
      summary: Get all users
      description: "WILL BE PAGINATED IN THE FUTURE. Get all available users on the instance. REQUIRES: Authentication, GetAllUsers permission."
      operationId: getUsers
      responses:
        "500":
          description: Something went wrong
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommonError"
        "401":
          description: Unauthorized
        "200":
          description: Successfully got all users
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetAllUsersResponse"
  /users/id/{userId}:
    get:
      tags:
        - users
      summary: Get user by internal ID
      description: "Get user information about one account by internal user account ID. REQUIRES: Authentication, GetUserById permission."
      operationId: getUserById
      parameters:
        - in: path
          name: userId
          schema:
            type: integer
          required: true
          description: Numeric internal ID of the user to get
      responses:
        "401":
          description: Unauthorized
        "400":
          description: Invalid parameters
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommonError"
        "404":
          description: User not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommonError"
        "200":
          description: Successfully got user
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DetailedUser"
  /users/uuid/{userUuid}:
    get:
      tags:
        - users
      summary: Get user by UUID
      description: "Get user information about one account by public user account UUID. REQUIRES: Authentication, GetUserByUuid permission."
      operationId: getUserByUuid
      parameters:
        - in: path
          name: userUuid
          schema:
            type: string
          required: true
          description: UUID of user to get
      responses:
        "401":
          description: Unauthorized
        "400":
          description: Invalid parameters
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommonError"
        "404":
          description: User not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommonError"
        "200":
          description: Successfully got user
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DetailedUser"     
  /users/self:
    get:
      tags:
        - users
      summary: Get own user by session
      description: "Get user information about the account which was used to authenticate the request. REQUIRES: Authentication, GetOwnUser permission."
      operationId: getOwnUser
      responses:
        "401":
          description: Unauthorized
        "200":
          description: Successfully got user
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DetailedUser"
                
  /friends/add:
    post:
      tags:
        - friends
      summary: Create a friend request
      description: "Create (AKA send) a friend request to another user account. The request is sent from the account used to perform this POST to the provided target account. REQUIRES: Authentication, SendFriendRequest permission."
      operationId: addFriend
      requestBody:
        $ref: "#/components/requestBodies/FriendAdd"
      responses:
        "401":
          description: Unauthorized
        "400":
          description: User does not exist, Already friends with user or Request already sent
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommonError"
        "200":
          description: Friend request added successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommonMessage"
  /friends/accept:
    post:
      tags:
        - friends
      summary: Accept an incoming friend request
      description: "Accept an incoming friend request to your user account, from another user account. The request is accepted by the account used to perform this POST request. REQUIRES: Authentication, AcceptFriendRequest permission."
      operationId: acceptFriend
      requestBody:
        $ref: "#/components/requestBodies/FriendAccept"
      responses:
        "401":
          description: Unauthorized
        "400":
          description: User does not exist, You are already friends with user or Friend request not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommonError"
        "200":
          description: Friend request accepted successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommonMessage"
  /friends:
    get:
      tags:
        - friends
      summary: Get current incoming friend requests
      description: "Get all current incoming friend requests to the user account used to authorize this POST request. REQUIRES: Authentication, GetOwnFriendRequests permission."
      operationId: getFriendRequests
      responses:
        "401":
          description: Unauthorized
        "200":
          description: Retrieved all incoming friend requests successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FriendGetRequestsResponse"
                
externalDocs:
  description: Find out more about ScheduleTogether
  url: https://git.zervo.org/ScheduleTogether
  
servers:
  - url: http://localhost:8080
  - url: https://stbackend.swagger.io/v2
  
components:
  requestBodies:
    AccountRegister:
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/AccountRegisterRequest"
    AccountVerify:
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/AccountVerifyRequest"
    AccountSignin:
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/AccountSigninRequest"
    FriendAdd:
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FriendAddRequest"
    FriendAccept:
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FriendAcceptRequest"

  schemas:
    CommonError:
      type: object
      properties:
        error:
          type: string
          description: A string describing the error
    CommonMessage:
      type: object
      properties:
        message:
          type: string
          description: A message
    
    DetailedUser:
      type: object
      properties:
        id:
          type: integer
          description: Internal user ID
        uuid:
          type: string
          description: Public unique user identifier
        username:
          type: string
        firstName:
          type: string
        lastName:
          type: string
        email:
          type: string
        verified:
          type: boolean
        friends:
          type: array
          items:
            type: string

    AccountRegisterRequest:
      type: object
      properties:
        firstName:
          type: string
        lastName:
          type: string
        username:
          type: string
          minLength: 5
          maxLength: 18
        email:
          type: string
        password:
          type: string
          minLength: 8
          maxLength: 128
    AccountRegisterResponse:
      type: object
      properties:
        message:
          type: string
          description: A message describing the result
        uuid:
          type: string
          description: The UUID of the newly created user
        mustVerify:
          type: boolean
          description: Whether or not user needs to send account verify request to complete registration
    AccountVerifyRequest:
      type: object
      properties:
        uuid:
          type: string
          description: The UUID of the user account to verify
        token:
          type: string
          description: The verification token
    AccountSigninRequest:
      type: object
      properties:
        username:
          type: string
        password:
          type: string
    AccountSigninResponse:
      type: object
      properties:
        token:
          type: string
          description: The token to be used for authenticating all requests for this session
          
    GetAllUsersResponse:
      type: array
      items:
        $ref: "#/components/schemas/DetailedUser"
          
    FriendRequest:
      type: object
      properties:
        created_at:
          type: string
          description: Timestamp at which the friend request was created
        source_username:
          type: string
          description: The username of the requesting user
        source_uuid:
          type: string
          description: The UUID of the requesting user
        target_uuid:
          description: The UUID of the receiving user
    FriendAddRequest:
      type: object
      properties:
        username:
          type: string
          description: The username of the target user
    FriendAcceptRequest:
      type: object
      properties:
        uuid:
          type: string
          description: The UUID of the user from which you want to accept a friend request
    FriendGetRequestsResponse:
      type: object
      properties:
        amount:
          type: integer
          description: The amount of incoming friend requests
        requests:
          type: array
          items:
            $ref: "#/components/schemas/FriendRequest"