Skip to content

Latest commit

 

History

History
1842 lines (1564 loc) · 29.8 KB

File metadata and controls

1842 lines (1564 loc) · 29.8 KB

Backend - Table of Content

Requirements

  • node
  • npm
  • mongoDB server
  • OPTIONAL homebrew (for mongoDB server service)

Build and Run

  1. start your local mongodb server (OPTIONAL)

    npm run start:m
  2. create database, collections and fill collections with demo data

    for development

    npm run setup:db:d

    or

    for testing

    npm run setup:db:t
  3. start server

    development server

    npm run start:d

    or

    production server

    npm run start:p

Use Docker to run a mongo db with mock data

  1. Install some Docker engine for your system (e.g Docker for Mac)

  2. npm script to start the mongodb via docker

#Start a mongo db on the default port which is populated with mock data
npm run docker:db:d

This script starts a mongo db in a docker container and fill it with mock data.

  1. Start your app with npm run start:d

  2. More

  • To add new mock data, add a new mongodb-seed section in the docker-compose file

  • Other docker commands to mangage your environment

#Start a mongodb terminal client to check your db content
npm run docker:c
# Clean up your containers => removes the started docker containers
npm run docker:r

Running tests

npm test
# With docker
npm run test:d

Running lint

npm run lint

API Documentation

Auth

  • POST /api/v1/auth/login

    Request body:

    {
      username: string,
      password: string
    }

    or

    {
      email: string,
      password: string
    }

    Response body:

    {
      token: string,
      socobouser: {
        id: string,
        username: string,
        email: string,
        hasTermsAccepted: boolean,
        role: string|Role,
        provider: string|Provider,
        imageUrl: string,
        created: number,
        lastModified: number
      }
    }

    Error body:

    {
      message: string,
      source: string,
      method: string
    }
  • POST /api/v1/auth/register

    Request body:

    {
      email: string,
      password: string,
      role: Role
    }

    Response body:

    {
      id: string,
      username: string,
      email: string,
      hasTermsAccepted: boolean,
      role: string|Role,
      provider: string|Provider,
      imageUrl: string,
      created: number,
      lastModified: number
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }

FoodItemTemplate

  • GET /api/v1/fooditemtemplate

    Query Parameter:

    • resolve: If this query parameter is set, the response will not only contain the category ids and unit id, but the complete category and unit data

    Response body:

    [
      {
        id: string,
        categoryIds: [string],
        unitId: string,
        name: string,
        created: number,
        lastModified: number
      },
      {
        ...
      }
    ]

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • GET /api/v1/fooditemtemplate/:id

    Path Parameter:

    • id: Fooditem Template id

    Query Parameter:

    • resolve: If this query parameter is set, the response will not only contain the category ids and unit id, but the complete category and unit data

    Response body:

    {
      id: string,
      categoryIds: [string],
      unitId: string,
      name: string,
      created: number,
      lastModified: number
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • PUT /api/v1/fooditemtemplate/:id

    Path Parameter:

    • Fooditem Template id

    Request body:

    {
      categoryIds: [string],
      unitId: string,
      name: string,
      created: number
    }

    Response body:

    {
      id: string,
      categoryIds: [string],
      unitId: string,
      name: string,
      created: number,
      lastModified: number
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • POST /api/v1/fooditemtemplate/

    Path Parameter:

    • Fooditem Template id

    Request body:

    {
      categoryIds: [string],
      unitId: string,
      name: string
    }

    Response body:

    {
      id: string,
      categoryIds: [string],
      unitId: string,
      name: string,
      created: number,
      lastModified: number
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • DELETE /api/v1/fooditemtemplate/:id

    Path Parameter:

    • id: Fooditem Template id

    Response body:

    {
      id: string
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }

FoodItemCategory

  • GET /api/v1/fooditemcategory

    Response body:

    [
      {
        id: string,
        foodItemId: string,
        name: string,
        created: number,
        lastModified: number
      },
      {
        ...
      }
    ]

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • GET /api/v1/fooditemcategory/:id

    Path Parameter:

    • id: Fooditem Category id

    Response body:

    {
      id: string,
      foodItemId: string,
      name: string,
      created: number,
      lastModified: number
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • PUT /api/v1/fooditemcategory/:id

    Path Parameter:

    • Fooditem Category id

    Request body:

    {
      foodItemId: string,
      name: string
    }

    Response body:

    {
      id: string,
      foodItemId: string,
      name: string,
      created: number,
      lastModified: number
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • POST /api/v1/fooditemcategory/

    Path Parameter:

    • Fooditem Category id

    Request body:

    {
      foodItemId: string,
      name: string
    }

    Response body:

    {
      id: string,
      foodItemId: string,
      name: string,
      created: number,
      lastModified: number
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • DELETE /api/v1/fooditemcategory/:id

    Path Parameter:

    • id: Fooditem Category id

    Response body:

    {
      id: string
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }

FoodItemUnit

  • GET /api/v1/fooditemunit

    Response body:

    [
      {
        id: string,
        foodItemId: string,
        name: string,
        created: number,
        lastModified: number
      },
      {
        ...
      }
    ]

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • GET /api/v1/fooditemunit/:id

    Path Parameter:

    • id: Fooditem Unit id

    Response body:

    {
      id: string,
      foodItemId: string,
      name: string,
      created: number,
      lastModified: number
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • PUT /api/v1/fooditemunit/:id

    Path Parameter:

    • Fooditem Unit id

    Request body:

    {
      foodItemId: string,
      name: string
    }

    Response body:

    {
      id: string,
      foodItemId: string,
      name: string,
      created: number,
      lastModified: number
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • POST /api/v1/fooditemunit/

    Path Parameter:

    • Fooditem Unit id

    Request body:

    {
      foodItemId: string,
      name: string
    }

    Response body:

    {
      id: string,
      foodItemId: string,
      name: string,
      created: number,
      lastModified: number
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • DELETE /api/v1/fooditemunit/:id

    Path Parameter:

    • id: Fooditem Unit id

    Response body:

    {
      id: string
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }

FoodItem

  • GET /api/v1/fooditem

    Query Parameter:

    • socobouserid: If this query parameter is set, the response will only contain the food items for the specfic user

    Response body:

    [
      {
        id: string,
        foodItemTemplateId: string,
        socoboUserId: string,
        amount: string,
        bestBefore: number,
        created: number,
        lastModified: number
      },
      {
        ...
      }
    ]

    Query Parameter:

    • resolve: If this query parameter is set, the response will not only contain the template and user ids, but the complete template and user data
    [
      {
        id: string,
        foodItemTemplate: {
          id: string,
          categoryIds: [string],
          unitId: string,
          name: string,
          created: number,
          lastModified: number
        },
        socoboUser: {
          id: string,
          username: string,
          email: string,
          hasTermsAccepted: boolean,
          role: string|Role,
          provider: string|Provider,
          imageUrl: string,
          created: number,
          lastModified: number
        },
        amount: string,
        bestBefore: number,
        created: number,
        lastModified: number
      },
      {
        ...
      }
    ]

    Query Parameter:

    • resolve-deep: If this query parameter is set, the response will not only contain the template and user ids, but the complete template w/ complete categories and unit data and user data
    [
      {
        id: string,
        foodItemTemplate: {
          id: string,
          categories: [
            {
              id: string,
              name: string,
              created: number,
              lastModified: number
            },
            {
              ...
            }
          ],
          unit: {
            id: string,
            name: string,
            created: number,
            lastModified: number
          },
          name: string,
          created: number,
          lastModified: number
        },
        socoboUser: {
          id: string,
          username: string,
          email: string,
          hasTermsAccepted: boolean,
          role: string|Role,
          provider: string|Provider,
          imageUrl: string,
          created: number,
          lastModified: number
        },
        amount: string,
        bestBefore: number,
        created: number,
        lastModified: number
      },
      {
        ...
      }
    ]

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • GET /api/v1/fooditem/:id

    Path Parameter:

    • id: Fooditem id

    Response body:

    {
      id: string,
      foodItemTemplateId: string,
      socoboUserId: string,
      amount: string,
      bestBefore: number,
      created: number,
      lastModified: number
    }

    Query Parameter:

    • resolve: If this query parameter is set, the response will not only contain the template and user ids, but the complete template and user data
    {
      id: string,
      foodItemTemplate: {
        id: string,
        categoryIds: [string],
        unitId: string,
        name: string,
        created: number,
        lastModified: number
      },
      socoboUser: {
        id: string,
        username: string,
        email: string,
        hasTermsAccepted: boolean,
        role: string|Role,
        provider: string|Provider,
        imageUrl: string,
        created: number,
        lastModified: number
      },
      amount: string,
      bestBefore: number,
      created: number,
      lastModified: number
    }

    Query Parameter:

    • resolve-deep: If this query parameter is set, the response will not only contain the template and user ids, but the complete template w/ complete categories and unit data and user data
    {
      id: string,
      foodItemTemplate: {
        id: string,
        categories: [
          {
            id: string,
            name: string,
            created: number,
            lastModified: number
          },
          {
            ...
          }
        ],
        unit: {
          id: string,
          name: string,
          created: number,
          lastModified: number
        },
        name: string,
        created: number,
        lastModified: number
      },
      socoboUser: {
        id: string,
        username: string,
        email: string,
        hasTermsAccepted: boolean,
        role: string|Role,
        provider: string|Provider,
        imageUrl: string,
        created: number,
        lastModified: number
      },
      amount: string,
      bestBefore: number,
      created: number,
      lastModified: number
    }
  • PUT /api/v1/fooditem/:id

    Path Parameter:

    • Fooditem id

    Request body:

    {
      foodItemTemplateId: string,
      socoboUserId: string,
      amount: string,
      bestBefore: number,
      created: number
    }

    Response body:

    {
      id: string,
      foodItemTemplateId: string,
      socoboUserId: string,
      amount: string,
      bestBefore: number,
      created: number,
      lastModified: number
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • POST /api/v1/fooditem/

    Path Parameter:

    • Fooditem id

    Request body:

    {
      foodItemTemplateId: string,
      socoboUserId: string,
      amount: string,
      bestBefore: number
    }

    Response body:

    {
      id: string,
      foodItemTemplateId: string,
      socoboUserId: string,
      amount: string,
      bestBefore: number,
      created: number,
      lastModified: number
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • DELETE /api/v1/fooditem/:id

    Path Parameter:

    • id: Fooditem id

    Response body:

    {
      id: string
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }

Log

  • GET /api/v1/log/errors

    This route is only with admin rights accessable!

    Response body:

    [
      {
        message: string.
        name: string
        timestamp: number,
        statusCode: number,
        code: string,
        source: string,
        sourceMethod: string,
        error: Object,
        query?: string
      },
      {...}
    ]

Recipe

  • GET /api/v1/recipes

    Query Parameter:

    • resolve: If this query parameter is set, the response will not only contain the category id but the complete category data

    Response body:

    [
      {
        id: number,
        title: string,
        userid: number,
        description: number,
        imageurl: string,
        ingredients: [
          ingredientId: string,
          ...
        ],
        created: Date,
        categoryId: string,
        steps: [
          {
            id: number,
            stepNumber: number,
            stepTitle: string,
            stepDescription?: string
          },
          {
            ...
          }
        ]
      },
      {
        ...
      }
    ]
    

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • GET /api/v1/recipes/:id?resolve

    Path Parameter:

    • id: Recipe id

    Query Parameter

    • resolve: If this query parameter is set, the response will not only contain the category id but the complete category data

    Response body:

    {
      id: number,
      title: string,
      userid: number,
      description: number,
      imageurl: string,
      ingredients: [
        ingredientId: string,
        ...
      ],
      created: Date,
      categoryId: string,
      steps: [
        {
          id: number,
          stepNumber: number,
          stepTitle: string,
          stepDescription?: string
        },
        {
          ...
        }
      ]
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • GET /api/v1/recipes/search/field?property=searchTerm

    Searches for a specified term inside a the given recipe property and returns the matching subset of recipes

    Query parameter:

    • property: The name of the recipe property after which should be searched
    • searchTerm: The term which will be searched

    Response body:

    [
      {
        id: number,
        title: string,
        userid: number,
        description: number,
        imageurl: string,
        ingredients: [
          ingredientId: string,
          ...
        ],
        created: Date,
        categoryId: string,
        steps: [
          {
            id: number,
            stepNumber: number,
            stepTitle: string,
            stepDescription?: string
          },
          {
            ...
          }
        ]
      },
      {
        ...
      }
    ]
    

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • PUT /api/v1/recipes/:id

    Alters the properties, defined in the request body, on the recipe with the provided id. If the request body only conatains single fields of a recipe, only these fields will be updated. This is true for the first level of properties. E.g. if you update the steps of a recipe and you only provide a single step all remaining steps are removed since there are no data in the request.

    Path Parameter:

    • id: Recipe id

    Request body (could also be a subset of these values):

    {
      title?: string,
      userId?: string,
      description?: string,
      imageurl?: string,
      categoryId?: string,
      ingredients: [
        ingredientId: string,
        ...
      ],
      steps?: [
        {
          stepNumber: number,
          stepTitle: string,
          stepDescription?: string
        },
        {
          ...
        }
      ]
    }

    Response body:

    {
      id: number,
      title: string,
      userid: number,
      description: string,
      imageurl: string,
      created: Date,
      categoryId: string,
      ingredients: [
        ingredientId: string,
        ...
      ],
      steps: [
        {
          id: number,
          stepNumber: number,
          stepTitle: string,
          stepDescription?: string
        },
        {
          ...
        }
      ]
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • POST /api/v1/recipes

    Special constraints:

    • At least one ingredient necessary
    • Steps must be in correct order

    Request body:

    {
      title: string,
      userId: string,
      description?: string,
      imageurl?: string,
      ingredients: [
        ingredientId: string,
        ...
      ],
      steps?: [
        {
          stepNumber: number,
          stepTitle: string,
          stepDescription?: string
        },
        {
          ...
        }
      ]
    }

    Response body:

    {
      id: number,
      userId: number,
      title: string,
      description: string,
      imageurl: string,
      ingredients: [
        ingredientId: string,
        ...
      ],
      created: Date,
      categoryId: string,
      steps: [
        {
          id: number,
          stepNumber: number,
          stepTitle: string,
          stepDescription?: string
        },
        {
          ...
        }
      ]
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • POST /api/v1/recipes/:id/image

    Uploads a provided image file to the server for the current user and updates the related recipe in the database.

    Request body:

      multipart/form-data:
    
      key: recipeImage
      value: image file
    

    Response body:

    {
      id: number,
      title: string,
      userid: number,
      description: string,
      imageurl: string,
      ingredients: [
        ingredientId: string,
        ...
      ],
      created: Date,
      categoryId: string,
      steps: [
        {
          id: number,
          stepNumber: number,
          stepTitle: string,
          stepDescription?: string
        },
        {
          ...
        }
      ]
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • DELETE /api/v1/recipes/:id

    Deletes the recipe found for the given id

    Path Parameter:

    • id: The id of the recipe which should be deleted

    Error body:

    {
      message: string,
      method: string,
      source: string
    }

Recipe Category

  • GET /api/v1/recipecategory

    Response body:

    [
    {
        _id: string,
        updatedAt: string,
        createdAt: string,
        title: string,
        description: string
    }
    ]
    

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • GET /api/v1/recipecategory/:id

    Path Parameter:

    • id: the category id

    Response body:

    {
        _id: string,
        updatedAt: string,
        createdAt: string,
        title: string,
        description: string
    }
    

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • POST /api/v1/recipecategory

    This route is only with admin rights accessable!

    Request body:

    {
      title: string,
      description: string
    }

    Response body:

    {
        _id: string,
        updatedAt: string,
        createdAt: string,
        title: string,
        description: string
    }
    

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • PUT /api/v1/recipecategory/:id

    This route is only with admin rights accessable!

    Path Parameter:

    • id: the category id

    Request body:

    {
      title: string,
      description: string
    }

    Response body:

    {
        _id: string,
        updatedAt: string,
        createdAt: string,
        title: string,
        description: string
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • DELETE /api/v1/recipecategory/:id

    This route is only with admin rights accessable!

    Path Parameter:

    • id: the category id

    Error body:

    {
      message: string,
      method: string,
      source: string
    }

Recipe Ingredient

  • GET /api/v1/recipeingredient

    Query Parameter:

    • resolve: (no value needed) loads the fooditem template and adds it to the response body instead of the fooditemTemplateId

    Response body:

    [
    {
        _id: string,
        updatedAt: string,
        createdAt: string,
        amount: int,
        fooditemTemplateId: string
    }
    ]
    

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • GET /api/v1/recipeingredient/:id

    Path Parameter:

    • id: the recipeingredient id

    Query Parameter:

    • resolve: (no value needed) loads the fooditem template and adds it to the response body instead of the fooditemTemplateId

    Response body:

    {
        _id: string,
        updatedAt: string,
        createdAt: string,
        amount: int,
        fooditemTemplateId: string
    }
    

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • POST /api/v1/recipeingredient

    Request body:

    {
      amount: int,
      fooditemTemplateId: string
    }

    Response body:

    {
        _id: string,
        updatedAt: string,
        createdAt: string,
        amount: int,
        fooditemTemplateId: string
    }
    

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • PUT /api/v1/recipeingredient/:id

    Path Parameter:

    • id: the recipeingredient id

    Request body:

    {
      amount: int,
      fooditemTemplateId: string
    }

    Response body:

    {
        _id: string,
        updatedAt: string,
        createdAt: string,
        amount: int,
        fooditemTemplateId: string
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • DELETE /api/v1/recipeingredient/:id

    Path Parameter:

    • id: the recipeingredient id

    Error body:

    {
      message: string,
      method: string,
      source: string
    }

SocoboUser

  • GET /api/v1/socobouser

    This route is only with admin rights accessable!

    Response body:

    [
      {
        id: string,
        username: string,
        email: string,
        hasTermsAccepted: boolean,
        role: string|Role,
        provider: string|Provider,
        imageUrl: string,
        created: number,
        lastModified: number
      },
      {
        ...
      }
    ]

    Error body:

    {
      message: string,
      method: string,
      source: string
    }

SocoboUser

  • GET /api/v1/socobouser

    This route is only with admin rights accessable!

    Response body:

    [
      {
        id: string,
        username: string,
        email: string,
        hasTermsAccepted: boolean,
        role: string|Role,
        provider: string|Provider,
        imageUrl: string,
        created: number,
        lastModified: number
      },
      {
        ...
      }
    ]

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • GET /api/v1/socobouser/:id

    Path Parameter:

    • id: User id

    Response body:

    {
      id: string,
      username: string,
      email: string,
      hasTermsAccepted: boolean,
      role: string|Role,
      provider: string|Provider,
      imageUrl: string,
      created: number,
      lastModified: number
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • PUT /api/v1/socobouser/:id

    Path Parameter:

    • id: User id

    Request body:

    {
      updateType: UpdateType,
      fieldValues: {
        update-type specific socoboUser-Property: number|string|boolean|Role|Provider,
        ...
      }
    }

    Response body:

    {
      id: string,
      username: string,
      email: string,
      hasTermsAccepted: boolean,
      role: string|Role,
      provider: string|Provider,
      imageUrl: string,
      created: number,
      lastModified: number
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • POST /api/v1/socobouser/:id/upload

    Uploads a provided image file to the server for the current user and updates the related user in the database.

    Path Parameter:

    • id: User id

    Request header:

    Content-Type = multipart/form-data

    Request body:

    key = socoboUserImage,
    value = file

    Response body:

    {
      id: string,
      username: string,
      email: string,
      hasTermsAccepted: boolean,
      role: string|Role,
      provider: string|Provider,
      imageUrl: string,
      created: number,
      lastModified: number
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }
  • DELETE /api/v1/socobouser/:id

    Path Parameter:

    • id: User id

    Response body:

    {
      id: string
    }

    Error body:

    {
      message: string,
      method: string,
      source: string
    }

Enums

  • Role:

    • Admin
    • User
  • Provider:

    • Email
    • Username
  • UpdateType:

    • 0 = full
      • fields: username, email, password, imageUrl, role, provider, hasTermsAccepted
    • 1 = username
      • fields: username
    • 2 = email
      • fields: email
    • 3 = password
      • fields: password
    • 4 = image
      • fields: imageUrl
    • 5 = role
      • fields: role
    • 6 = provider:
      • fields: provider
    • 7 = terms
      • fields: hasTermsAccepted