diff --git a/.gitlab-ci.old.yml b/.gitlab-ci.old.yml
new file mode 100644
index 0000000000000000000000000000000000000000..95eb8708f163e3986bff41a46aec700312bb3a45
--- /dev/null
+++ b/.gitlab-ci.old.yml
@@ -0,0 +1,149 @@
+image: docker:stable
+
+stages:
+  - build
+  - test
+  - deploy
+  - rollback
+
+build:
+  stage: build
+  script:
+    # Setup
+    - export AWS_REGION="eu-west-1"
+    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
+    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
+    - export REPO=$CI_ECR_URL
+    - apk update
+    - apk --no-cache add --update curl python python-dev py-pip
+    - pip install awscli --upgrade --user
+    - export PATH=~/.local/bin:/usr/bin/:$PATH
+    # AUTH
+    - CERT=`aws ecr get-login --no-include-email --region ${AWS_REGION}`
+    - ${CERT}
+    # Build
+    - docker build -t ${CI_PROJECT_NAME}:$CI_COMMIT_SHA .
+    - docker tag $CI_PROJECT_NAME:$CI_COMMIT_SHA $REPO:latest
+    - docker push $REPO:latest
+  environment:
+    name: qa
+    url: $CI_ALB_URL
+
+lint:
+  image: $CI_ECR_URL:latest
+  stage: test
+  variables:
+    GIT_STRATEGY: none
+  script:
+    - cd ${HOME}
+    - npm run lint
+
+test:
+  image: $CI_ECR_URL:latest
+  stage: test
+  variables:
+    GIT_STRATEGY: none
+  script:
+    - cd ${HOME}
+    - npm run test
+
+create-rollback:
+  stage: test
+  only:
+    - master
+  script:
+    - export AWS_REGION="eu-west-1"
+    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
+    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
+    - apk --no-cache add --update curl python python-dev py-pip jq
+    - pip install awscli --upgrade --user
+    - export PATH=~/.local/bin:/usr/bin/:$PATH
+    # Discover the ALB name
+    - ALB=`aws elbv2 describe-load-balancers --region ${AWS_REGION} --names ${CI_ALB_NAME} | jq .LoadBalancers[0].DNSName`
+    # Test Keepalive
+    - /usr/bin/curl --fail http://${ALB//'"'}/keepalive
+    # IF Keepalive return 200...
+    # Retrieve & Store this revision as 'last known successful revision' in S3 Bucket
+    - REV=`aws ecs describe-services --region ${AWS_REGION} --cluster ${CI_CLUSTER_NAME} --service ${CI_SERVICE_NAME} |jq -r '.services[0].deployments[0].taskDefinition'`
+    - echo successful revision is ${REV} Storing it in S3 Bucket
+    - echo ${REV} > /${CI_SERVICE_NAME}
+    # sync rev to S3 here
+    - aws s3 cp /${CI_SERVICE_NAME} s3://${CI_REV_BUCKET}
+  environment:
+    name: qa
+    url: $CI_ALB_URL
+
+deploy:
+  stage: deploy
+  only:
+    - master
+  script:
+    - export AWS_REGION="eu-west-1"
+    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
+    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
+    - apk --no-cache add --update python python-dev py-pip
+    - pip install ecs-deploy
+    # Deploy
+    - ecs deploy ${CI_CLUSTER_NAME} ${CI_SERVICE_NAME} --region ${AWS_REGION} --timeout 600 -e ${CI_CONTAINER_NAME} AWS_S3_ACCESS_KEY $AWS_S3_ACCESS_KEY -e ${CI_CONTAINER_NAME} AWS_S3_SECRET_KEY $AWS_S3_SECRET_KEY -e ${CI_CONTAINER_NAME} AWS_S3_REGION $AWS_S3_REGION -e ${CI_CONTAINER_NAME} AWS_S3_BUCKET $AWS_S3_BUCKET -e ${CI_CONTAINER_NAME} AWS_SES_SECRET_KEY $AWS_SES_SECRET_KEY -e ${CI_CONTAINER_NAME} AWS_SES_ACCESS_KEY $AWS_SES_ACCESS_KEY -e ${CI_CONTAINER_NAME} AWS_SES_REGION $AWS_SES_REGION -e ${CI_CONTAINER_NAME} EMAIL_SENDER $EMAIL_SENDER -e ${CI_CONTAINER_NAME} secret $SECRET -e ${CI_CONTAINER_NAME} DATABASE $DATABASE -e ${CI_CONTAINER_NAME} DB_USER $DB_USER -e ${CI_CONTAINER_NAME} DB_PASS $DB_PASS -e ${CI_CONTAINER_NAME} DB_HOST $DB_HOST -e ${CI_CONTAINER_NAME} ORCID_CLIENT_ID $ORCID_CLIENT_ID -e ${CI_CONTAINER_NAME} ORCID_CLIENT_SECRET $ORCID_CLIENT_SECRET -e ${CI_CONTAINER_NAME} CLIENT_BASE_URL $CLIENT_BASE_URL -e ${CI_CONTAINER_NAME} FTP_USERNAME $FTP_USERNAME -e ${CI_CONTAINER_NAME} FTP_PASSWORD $FTP_PASSWORD -e ${CI_CONTAINER_NAME} FTP_HOST $FTP_HOST 
+  environment:
+    name: qa
+    url: $CI_ALB_URL
+
+aws-qa:
+  stage: deploy
+  when: manual
+  only:
+    - develop
+  script:
+    - export AWS_REGION="eu-west-1"
+    - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
+    - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
+    - apk --no-cache add --update python python-dev py-pip
+    - pip install ecs-deploy
+    # Deploy
+    - ecs deploy ${CI_CLUSTER_NAME} ${CI_SERVICE_NAME} --region ${AWS_REGION} --timeout 600 -e ${CI_CONTAINER_NAME} AWS_S3_ACCESS_KEY $AWS_S3_ACCESS_KEY -e ${CI_CONTAINER_NAME} AWS_S3_SECRET_KEY $AWS_S3_SECRET_KEY -e ${CI_CONTAINER_NAME} AWS_S3_REGION $AWS_S3_REGION -e ${CI_CONTAINER_NAME} AWS_S3_BUCKET $AWS_S3_BUCKET -e ${CI_CONTAINER_NAME} AWS_SES_SECRET_KEY $AWS_SES_SECRET_KEY -e ${CI_CONTAINER_NAME} AWS_SES_ACCESS_KEY $AWS_SES_ACCESS_KEY -e ${CI_CONTAINER_NAME} AWS_SES_REGION $AWS_SES_REGION -e ${CI_CONTAINER_NAME} EMAIL_SENDER $EMAIL_SENDER -e ${CI_CONTAINER_NAME} secret $SECRET -e ${CI_CONTAINER_NAME} DATABASE $DATABASE -e ${CI_CONTAINER_NAME} DB_USER $DB_USER -e ${CI_CONTAINER_NAME} DB_PASS $DB_PASS -e ${CI_CONTAINER_NAME} DB_HOST $DB_HOST -e ${CI_CONTAINER_NAME} ORCID_CLIENT_ID $ORCID_CLIENT_ID -e ${CI_CONTAINER_NAME} ORCID_CLIENT_SECRET $ORCID_CLIENT_SECRET -e ${CI_CONTAINER_NAME} CLIENT_BASE_URL $CLIENT_BASE_URL -e ${CI_CONTAINER_NAME} FTP_USERNAME $FTP_USERNAME -e ${CI_CONTAINER_NAME} FTP_PASSWORD $FTP_PASSWORD -e ${CI_CONTAINER_NAME} FTP_HOST $FTP_HOST 
+  environment:
+    name: qa
+    url: $CI_ALB_URL
+
+rollback:
+  stage: rollback
+  when: on_failure
+  only:
+    - master
+  script:
+    - export AWS_REGION="us-east-1"
+    - export AWS_ACCESS_KEY_ID=$aws_access_key_id
+    - export AWS_SECRET_ACCESS_KEY=$aws_secret_access_key
+    - apk --no-cache add --update curl python python-dev py-pip
+    - pip install awscli --upgrade --user
+    - export PATH=~/.local/bin:/usr/bin/:$PATH
+    - pip install ecs-deploy
+    - aws s3 cp s3://${CI_REV_BUCKET}/${CI_SERVICE_NAME} ./
+    - REV=`cat ./${CI_SERVICE_NAME}`
+    - echo rev is $REV
+    - ecs deploy --region ${AWS_REGION} ${CLUSTER_NAME} ${CI_SERVICE_NAME} --task ${REV} -e ${CI_CONTAINER_NAME} AWS_S3_ACCESS_KEY $AWS_S3_ACCESS_KEY -e ${CI_CONTAINER_NAME} AWS_S3_SECRET_KEY $AWS_S3_SECRET_KEY -e ${CI_CONTAINER_NAME} AWS_S3_REGION $AWS_S3_REGION -e ${CI_CONTAINER_NAME} AWS_S3_BUCKET $AWS_S3_BUCKET -e ${CI_CONTAINER_NAME} AWS_SES_SECRET_KEY $AWS_SES_SECRET_KEY -e ${CI_CONTAINER_NAME} AWS_SES_ACCESS_KEY $AWS_SES_ACCESS_KEY -e ${CI_CONTAINER_NAME} AWS_SES_REGION $AWS_SES_REGION -e ${CI_CONTAINER_NAME} EMAIL_SENDER $EMAIL_SENDER -e ${CI_CONTAINER_NAME} secret $SECRET -e ${CI_CONTAINER_NAME} DATABASE $DATABASE -e ${CI_CONTAINER_NAME} DB_USER $DB_USER -e ${CI_CONTAINER_NAME} DB_PASS $DB_PASS -e ${CI_CONTAINER_NAME} DB_HOST $DB_HOST -e ${CI_CONTAINER_NAME} ORCID_CLIENT_ID $ORCID_CLIENT_ID -e ${CI_CONTAINER_NAME} ORCID_CLIENT_SECRET $ORCID_CLIENT_SECRET -e ${CI_CONTAINER_NAME} CLIENT_BASE_URL $CLIENT_BASE_URL -e ${CI_CONTAINER_NAME} FTP_USERNAME $FTP_USERNAME -e ${CI_CONTAINER_NAME} FTP_PASSWORD $FTP_PASSWORD -e ${CI_CONTAINER_NAME} FTP_HOST $FTP_HOST 
+  environment:
+    name: qa
+    url: $CI_ALB_URL
+
+rollback-qa:
+  stage: rollback
+  when: manual
+  only:
+    - develop
+  script:
+    - export AWS_REGION="us-east-1"
+    - export AWS_ACCESS_KEY_ID=$aws_access_key_id
+    - export AWS_SECRET_ACCESS_KEY=$aws_secret_access_key
+    - apk --no-cache add --update curl python python-dev py-pip
+    - pip install awscli --upgrade --user
+    - export PATH=~/.local/bin:/usr/bin/:$PATH
+    - pip install ecs-deploy
+    - aws s3 cp s3://${CI_REV_BUCKET}/${CI_SERVICE_NAME} ./
+    - REV=`cat ./${CI_SERVICE_NAME}`
+    - echo rev is $REV
+    - ecs deploy --region ${AWS_REGION} ${CLUSTER_NAME} ${CI_SERVICE_NAME} --task ${REV} -e ${CI_CONTAINER_NAME} AWS_S3_ACCESS_KEY $AWS_S3_ACCESS_KEY -e ${CI_CONTAINER_NAME} AWS_S3_SECRET_KEY $AWS_S3_SECRET_KEY -e ${CI_CONTAINER_NAME} AWS_S3_REGION $AWS_S3_REGION -e ${CI_CONTAINER_NAME} AWS_S3_BUCKET $AWS_S3_BUCKET -e ${CI_CONTAINER_NAME} AWS_SES_SECRET_KEY $AWS_SES_SECRET_KEY -e ${CI_CONTAINER_NAME} AWS_SES_ACCESS_KEY $AWS_SES_ACCESS_KEY -e ${CI_CONTAINER_NAME} AWS_SES_REGION $AWS_SES_REGION -e ${CI_CONTAINER_NAME} EMAIL_SENDER $EMAIL_SENDER -e ${CI_CONTAINER_NAME} secret $SECRET -e ${CI_CONTAINER_NAME} DATABASE $DATABASE -e ${CI_CONTAINER_NAME} DB_USER $DB_USER -e ${CI_CONTAINER_NAME} DB_PASS $DB_PASS -e ${CI_CONTAINER_NAME} DB_HOST $DB_HOST -e ${CI_CONTAINER_NAME} ORCID_CLIENT_ID $ORCID_CLIENT_ID -e ${CI_CONTAINER_NAME} ORCID_CLIENT_SECRET $ORCID_CLIENT_SECRET -e ${CI_CONTAINER_NAME} CLIENT_BASE_URL $CLIENT_BASE_URL -e ${CI_CONTAINER_NAME} FTP_USERNAME $FTP_USERNAME -e ${CI_CONTAINER_NAME} FTP_PASSWORD $FTP_PASSWORD -e ${CI_CONTAINER_NAME} FTP_HOST $FTP_HOST 
+  environment:
+    name: qa
+    url: $CI_ALB_URL
\ No newline at end of file
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 95eb8708f163e3986bff41a46aec700312bb3a45..9d76f567afded10a195ae13549b3ebb089ab9b9c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,19 +1,22 @@
-image: docker:stable
+variables:
+  CONFIGURATION_REPOSITORY: https://gitlab.coko.foundation/bogdan/xpub-faraday-deployment-config.git
+  DOCKER_REPO: $CI_ECR_URL
 
 stages:
   - build
   - test
+  - push
   - deploy
   - rollback
 
 build:
+  image: docker:latest
   stage: build
   script:
     # Setup
     - export AWS_REGION="eu-west-1"
     - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
     - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
-    - export REPO=$CI_ECR_URL
     - apk update
     - apk --no-cache add --update curl python python-dev py-pip
     - pip install awscli --upgrade --user
@@ -23,14 +26,11 @@ build:
     - ${CERT}
     # Build
     - docker build -t ${CI_PROJECT_NAME}:$CI_COMMIT_SHA .
-    - docker tag $CI_PROJECT_NAME:$CI_COMMIT_SHA $REPO:latest
-    - docker push $REPO:latest
-  environment:
-    name: qa
-    url: $CI_ALB_URL
+    - docker tag $CI_PROJECT_NAME:$CI_COMMIT_SHA $DOCKER_REPO:$CI_COMMIT_SHA
+    - docker push $DOCKER_REPO:$CI_COMMIT_SHA
 
 lint:
-  image: $CI_ECR_URL:latest
+  image: $DOCKER_REPO:$CI_COMMIT_SHA
   stage: test
   variables:
     GIT_STRATEGY: none
@@ -39,7 +39,7 @@ lint:
     - npm run lint
 
 test:
-  image: $CI_ECR_URL:latest
+  image: $DOCKER_REPO:$CI_COMMIT_SHA
   stage: test
   variables:
     GIT_STRATEGY: none
@@ -47,49 +47,49 @@ test:
     - cd ${HOME}
     - npm run test
 
-create-rollback:
-  stage: test
+push:qa:
+  image: docker:latest
+  stage: push
   only:
-    - master
+    - develop
   script:
+    # Setup
     - export AWS_REGION="eu-west-1"
     - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
     - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
-    - apk --no-cache add --update curl python python-dev py-pip jq
+    - apk update
+    - apk --no-cache add --update curl python python-dev py-pip
     - pip install awscli --upgrade --user
     - export PATH=~/.local/bin:/usr/bin/:$PATH
-    # Discover the ALB name
-    - ALB=`aws elbv2 describe-load-balancers --region ${AWS_REGION} --names ${CI_ALB_NAME} | jq .LoadBalancers[0].DNSName`
-    # Test Keepalive
-    - /usr/bin/curl --fail http://${ALB//'"'}/keepalive
-    # IF Keepalive return 200...
-    # Retrieve & Store this revision as 'last known successful revision' in S3 Bucket
-    - REV=`aws ecs describe-services --region ${AWS_REGION} --cluster ${CI_CLUSTER_NAME} --service ${CI_SERVICE_NAME} |jq -r '.services[0].deployments[0].taskDefinition'`
-    - echo successful revision is ${REV} Storing it in S3 Bucket
-    - echo ${REV} > /${CI_SERVICE_NAME}
-    # sync rev to S3 here
-    - aws s3 cp /${CI_SERVICE_NAME} s3://${CI_REV_BUCKET}
-  environment:
-    name: qa
-    url: $CI_ALB_URL
+    # AUTH
+    - CERT=`aws ecr get-login --no-include-email --region ${AWS_REGION}`
+    - ${CERT}
+    # Tag
+    - docker tag $DOCKER_REPO:$CI_COMMIT_SHA $DOCKER_REPO:latest
+    - docker push $DOCKER_REPO:latest
 
-deploy:
-  stage: deploy
+push:staging:
+  image: docker:latest
+  stage: push
   only:
     - master
   script:
+    # Setup
     - export AWS_REGION="eu-west-1"
     - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
     - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
-    - apk --no-cache add --update python python-dev py-pip
-    - pip install ecs-deploy
-    # Deploy
-    - ecs deploy ${CI_CLUSTER_NAME} ${CI_SERVICE_NAME} --region ${AWS_REGION} --timeout 600 -e ${CI_CONTAINER_NAME} AWS_S3_ACCESS_KEY $AWS_S3_ACCESS_KEY -e ${CI_CONTAINER_NAME} AWS_S3_SECRET_KEY $AWS_S3_SECRET_KEY -e ${CI_CONTAINER_NAME} AWS_S3_REGION $AWS_S3_REGION -e ${CI_CONTAINER_NAME} AWS_S3_BUCKET $AWS_S3_BUCKET -e ${CI_CONTAINER_NAME} AWS_SES_SECRET_KEY $AWS_SES_SECRET_KEY -e ${CI_CONTAINER_NAME} AWS_SES_ACCESS_KEY $AWS_SES_ACCESS_KEY -e ${CI_CONTAINER_NAME} AWS_SES_REGION $AWS_SES_REGION -e ${CI_CONTAINER_NAME} EMAIL_SENDER $EMAIL_SENDER -e ${CI_CONTAINER_NAME} secret $SECRET -e ${CI_CONTAINER_NAME} DATABASE $DATABASE -e ${CI_CONTAINER_NAME} DB_USER $DB_USER -e ${CI_CONTAINER_NAME} DB_PASS $DB_PASS -e ${CI_CONTAINER_NAME} DB_HOST $DB_HOST -e ${CI_CONTAINER_NAME} ORCID_CLIENT_ID $ORCID_CLIENT_ID -e ${CI_CONTAINER_NAME} ORCID_CLIENT_SECRET $ORCID_CLIENT_SECRET -e ${CI_CONTAINER_NAME} CLIENT_BASE_URL $CLIENT_BASE_URL -e ${CI_CONTAINER_NAME} FTP_USERNAME $FTP_USERNAME -e ${CI_CONTAINER_NAME} FTP_PASSWORD $FTP_PASSWORD -e ${CI_CONTAINER_NAME} FTP_HOST $FTP_HOST 
-  environment:
-    name: qa
-    url: $CI_ALB_URL
+    - apk update
+    - apk --no-cache add --update curl python python-dev py-pip
+    - pip install awscli --upgrade --user
+    - export PATH=~/.local/bin:/usr/bin/:$PATH
+    # AUTH
+    - CERT=`aws ecr get-login --no-include-email --region ${AWS_REGION}`
+    - ${CERT}
+    # Tag
+    - docker tag $DOCKER_REPO:$CI_COMMIT_SHA $DOCKER_REPO:staging
+    - docker push $DOCKER_REPO:staging
 
-aws-qa:
+deploy:aws-qa:
   stage: deploy
   when: manual
   only:
@@ -101,49 +101,39 @@ aws-qa:
     - apk --no-cache add --update python python-dev py-pip
     - pip install ecs-deploy
     # Deploy
-    - ecs deploy ${CI_CLUSTER_NAME} ${CI_SERVICE_NAME} --region ${AWS_REGION} --timeout 600 -e ${CI_CONTAINER_NAME} AWS_S3_ACCESS_KEY $AWS_S3_ACCESS_KEY -e ${CI_CONTAINER_NAME} AWS_S3_SECRET_KEY $AWS_S3_SECRET_KEY -e ${CI_CONTAINER_NAME} AWS_S3_REGION $AWS_S3_REGION -e ${CI_CONTAINER_NAME} AWS_S3_BUCKET $AWS_S3_BUCKET -e ${CI_CONTAINER_NAME} AWS_SES_SECRET_KEY $AWS_SES_SECRET_KEY -e ${CI_CONTAINER_NAME} AWS_SES_ACCESS_KEY $AWS_SES_ACCESS_KEY -e ${CI_CONTAINER_NAME} AWS_SES_REGION $AWS_SES_REGION -e ${CI_CONTAINER_NAME} EMAIL_SENDER $EMAIL_SENDER -e ${CI_CONTAINER_NAME} secret $SECRET -e ${CI_CONTAINER_NAME} DATABASE $DATABASE -e ${CI_CONTAINER_NAME} DB_USER $DB_USER -e ${CI_CONTAINER_NAME} DB_PASS $DB_PASS -e ${CI_CONTAINER_NAME} DB_HOST $DB_HOST -e ${CI_CONTAINER_NAME} ORCID_CLIENT_ID $ORCID_CLIENT_ID -e ${CI_CONTAINER_NAME} ORCID_CLIENT_SECRET $ORCID_CLIENT_SECRET -e ${CI_CONTAINER_NAME} CLIENT_BASE_URL $CLIENT_BASE_URL -e ${CI_CONTAINER_NAME} FTP_USERNAME $FTP_USERNAME -e ${CI_CONTAINER_NAME} FTP_PASSWORD $FTP_PASSWORD -e ${CI_CONTAINER_NAME} FTP_HOST $FTP_HOST 
+    - ecs deploy ${CI_CLUSTER_NAME} ${CI_SERVICE_NAME} --region ${AWS_REGION} --timeout 1200 -e ${CI_CONTAINER_NAME} AWS_S3_ACCESS_KEY $AWS_S3_ACCESS_KEY -e ${CI_CONTAINER_NAME} AWS_S3_SECRET_KEY $AWS_S3_SECRET_KEY -e ${CI_CONTAINER_NAME} AWS_S3_REGION $AWS_S3_REGION -e ${CI_CONTAINER_NAME} AWS_S3_BUCKET $AWS_S3_BUCKET -e ${CI_CONTAINER_NAME} AWS_SES_SECRET_KEY $AWS_SES_SECRET_KEY -e ${CI_CONTAINER_NAME} AWS_SES_ACCESS_KEY $AWS_SES_ACCESS_KEY -e ${CI_CONTAINER_NAME} AWS_SES_REGION $AWS_SES_REGION -e ${CI_CONTAINER_NAME} EMAIL_SENDER $EMAIL_SENDER -e ${CI_CONTAINER_NAME} secret $SECRET -e ${CI_CONTAINER_NAME} DATABASE $DATABASE -e ${CI_CONTAINER_NAME} DB_USER $DB_USER -e ${CI_CONTAINER_NAME} DB_PASS $DB_PASS -e ${CI_CONTAINER_NAME} DB_HOST $DB_HOST -e ${CI_CONTAINER_NAME} ORCID_CLIENT_ID $ORCID_CLIENT_ID -e ${CI_CONTAINER_NAME} ORCID_CLIENT_SECRET $ORCID_CLIENT_SECRET -e ${CI_CONTAINER_NAME} CLIENT_BASE_URL $CLIENT_BASE_URL -e ${CI_CONTAINER_NAME} FTP_USERNAME $FTP_USERNAME -e ${CI_CONTAINER_NAME} FTP_PASSWORD $FTP_PASSWORD -e ${CI_CONTAINER_NAME} FTP_HOST $FTP_HOST 
   environment:
     name: qa
     url: $CI_ALB_URL
 
-rollback:
-  stage: rollback
-  when: on_failure
+deploy:qa:
+  image: pubsweet/deployer:latest
+  stage: deploy
+  when: manual
   only:
-    - master
-  script:
-    - export AWS_REGION="us-east-1"
-    - export AWS_ACCESS_KEY_ID=$aws_access_key_id
-    - export AWS_SECRET_ACCESS_KEY=$aws_secret_access_key
-    - apk --no-cache add --update curl python python-dev py-pip
-    - pip install awscli --upgrade --user
-    - export PATH=~/.local/bin:/usr/bin/:$PATH
-    - pip install ecs-deploy
-    - aws s3 cp s3://${CI_REV_BUCKET}/${CI_SERVICE_NAME} ./
-    - REV=`cat ./${CI_SERVICE_NAME}`
-    - echo rev is $REV
-    - ecs deploy --region ${AWS_REGION} ${CLUSTER_NAME} ${CI_SERVICE_NAME} --task ${REV} -e ${CI_CONTAINER_NAME} AWS_S3_ACCESS_KEY $AWS_S3_ACCESS_KEY -e ${CI_CONTAINER_NAME} AWS_S3_SECRET_KEY $AWS_S3_SECRET_KEY -e ${CI_CONTAINER_NAME} AWS_S3_REGION $AWS_S3_REGION -e ${CI_CONTAINER_NAME} AWS_S3_BUCKET $AWS_S3_BUCKET -e ${CI_CONTAINER_NAME} AWS_SES_SECRET_KEY $AWS_SES_SECRET_KEY -e ${CI_CONTAINER_NAME} AWS_SES_ACCESS_KEY $AWS_SES_ACCESS_KEY -e ${CI_CONTAINER_NAME} AWS_SES_REGION $AWS_SES_REGION -e ${CI_CONTAINER_NAME} EMAIL_SENDER $EMAIL_SENDER -e ${CI_CONTAINER_NAME} secret $SECRET -e ${CI_CONTAINER_NAME} DATABASE $DATABASE -e ${CI_CONTAINER_NAME} DB_USER $DB_USER -e ${CI_CONTAINER_NAME} DB_PASS $DB_PASS -e ${CI_CONTAINER_NAME} DB_HOST $DB_HOST -e ${CI_CONTAINER_NAME} ORCID_CLIENT_ID $ORCID_CLIENT_ID -e ${CI_CONTAINER_NAME} ORCID_CLIENT_SECRET $ORCID_CLIENT_SECRET -e ${CI_CONTAINER_NAME} CLIENT_BASE_URL $CLIENT_BASE_URL -e ${CI_CONTAINER_NAME} FTP_USERNAME $FTP_USERNAME -e ${CI_CONTAINER_NAME} FTP_PASSWORD $FTP_PASSWORD -e ${CI_CONTAINER_NAME} FTP_HOST $FTP_HOST 
+    - develop
+  variables:
+    PACKAGE_NAME: xpub-faraday
+    IMAGE_TAG: latest
   environment:
     name: qa
-    url: $CI_ALB_URL
+    url: http://qa.faraday.hindawi.com
+  script:
+    - source deploy.sh
+    - create_deployment
 
-rollback-qa:
-  stage: rollback
+deploy:staging:
+  image: pubsweet/deployer:latest
+  stage: deploy
   when: manual
   only:
-    - develop
-  script:
-    - export AWS_REGION="us-east-1"
-    - export AWS_ACCESS_KEY_ID=$aws_access_key_id
-    - export AWS_SECRET_ACCESS_KEY=$aws_secret_access_key
-    - apk --no-cache add --update curl python python-dev py-pip
-    - pip install awscli --upgrade --user
-    - export PATH=~/.local/bin:/usr/bin/:$PATH
-    - pip install ecs-deploy
-    - aws s3 cp s3://${CI_REV_BUCKET}/${CI_SERVICE_NAME} ./
-    - REV=`cat ./${CI_SERVICE_NAME}`
-    - echo rev is $REV
-    - ecs deploy --region ${AWS_REGION} ${CLUSTER_NAME} ${CI_SERVICE_NAME} --task ${REV} -e ${CI_CONTAINER_NAME} AWS_S3_ACCESS_KEY $AWS_S3_ACCESS_KEY -e ${CI_CONTAINER_NAME} AWS_S3_SECRET_KEY $AWS_S3_SECRET_KEY -e ${CI_CONTAINER_NAME} AWS_S3_REGION $AWS_S3_REGION -e ${CI_CONTAINER_NAME} AWS_S3_BUCKET $AWS_S3_BUCKET -e ${CI_CONTAINER_NAME} AWS_SES_SECRET_KEY $AWS_SES_SECRET_KEY -e ${CI_CONTAINER_NAME} AWS_SES_ACCESS_KEY $AWS_SES_ACCESS_KEY -e ${CI_CONTAINER_NAME} AWS_SES_REGION $AWS_SES_REGION -e ${CI_CONTAINER_NAME} EMAIL_SENDER $EMAIL_SENDER -e ${CI_CONTAINER_NAME} secret $SECRET -e ${CI_CONTAINER_NAME} DATABASE $DATABASE -e ${CI_CONTAINER_NAME} DB_USER $DB_USER -e ${CI_CONTAINER_NAME} DB_PASS $DB_PASS -e ${CI_CONTAINER_NAME} DB_HOST $DB_HOST -e ${CI_CONTAINER_NAME} ORCID_CLIENT_ID $ORCID_CLIENT_ID -e ${CI_CONTAINER_NAME} ORCID_CLIENT_SECRET $ORCID_CLIENT_SECRET -e ${CI_CONTAINER_NAME} CLIENT_BASE_URL $CLIENT_BASE_URL -e ${CI_CONTAINER_NAME} FTP_USERNAME $FTP_USERNAME -e ${CI_CONTAINER_NAME} FTP_PASSWORD $FTP_PASSWORD -e ${CI_CONTAINER_NAME} FTP_HOST $FTP_HOST 
+    - master
+  variables:
+    PACKAGE_NAME: xpub-faraday
+    IMAGE_TAG: staging
   environment:
-    name: qa
-    url: $CI_ALB_URL
\ No newline at end of file
+    name: staging
+    url: http://faraday.hindawi.com
+  script:
+    - source deploy.sh
+    - create_deployment
diff --git a/Dockerfile b/Dockerfile
index af297f67bc3ab2c6bfea7267b9eecc736b0e93b9..d00693285f68ab5f0c4f5e4d97d59e0d9fd7ae09 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -5,22 +5,18 @@ WORKDIR ${HOME}
 COPY package.json yarn.lock ./
 COPY lerna.json .babelrc .eslintignore .eslintrc .prettierrc .stylelintignore .stylelintrc ./
 COPY packages packages
-COPY now now
 
 RUN [ "yarn", "config", "set", "workspaces-experimental", "true" ]
 
-# We do a development install because react-styleguidist is a dev dependency
 RUN [ "yarn", "install", "--frozen-lockfile" ]
-
-# Remove cache and offline mirror
 RUN [ "yarn", "cache", "clean"]
 RUN [ "rm", "-rf", "/npm-packages-offline-cache"]
 
-
-ENV NODE_ENV "development"
+ENV NODE_ENV "production"
 WORKDIR ${HOME}/packages/xpub-faraday
-# RUN [ "npm", "run", "server "]
+
+RUN [ "npx", "pubsweet", "build"]
 
 EXPOSE 3000
 
-CMD [ "npm", "run", "start-now" ]
\ No newline at end of file
+CMD []
\ No newline at end of file
diff --git a/Dockerfile-development b/Dockerfile-development
new file mode 100644
index 0000000000000000000000000000000000000000..abc8753aa68cd5dfdc765fdd66fa7f0bc28b31bf
--- /dev/null
+++ b/Dockerfile-development
@@ -0,0 +1,20 @@
+FROM xpub/xpub:base
+
+WORKDIR ${HOME}
+
+COPY package.json yarn.lock ./
+COPY lerna.json .babelrc .eslintignore .eslintrc .prettierrc .stylelintignore .stylelintrc ./
+COPY packages packages
+
+RUN [ "yarn", "config", "set", "workspaces-experimental", "true" ]
+
+RUN [ "yarn", "install", "--frozen-lockfile" ]
+RUN [ "yarn", "cache", "clean"]
+RUN [ "rm", "-rf", "/npm-packages-offline-cache"]
+
+ENV NODE_ENV "development"
+WORKDIR ${HOME}/packages/xpub-faraday
+
+EXPOSE 3000
+
+CMD [ "npm", "run", "start-now" ]
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index 34e800990414df3e1fd12e239c51d7bdeec5c072..b4aa1dc1be2196cb8b1290417b8af9e915fac345 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -4,7 +4,7 @@ services:
   app:
     build:
       context: .
-      dockerfile: ./Dockerfile
+      dockerfile: ./Dockerfile-development
     command: sh -c "cd packages/xpub-faraday && yarn install --frozen-lockfile && ./scripts/wait-for-it.sh postgres:5432 -s -t 40 -- npx pubsweet server"
     ports:
       - ${PORT:-3000}:3000
diff --git a/packages/component-email/src/routes/emails/notifications.js b/packages/component-email/src/routes/emails/notifications.js
index 23fea64c842350cd283d72b55f58c1b86a920d95..e5783fd5e02ea2586a854a7836fb2096495c2fb0 100644
--- a/packages/component-email/src/routes/emails/notifications.js
+++ b/packages/component-email/src/routes/emails/notifications.js
@@ -11,7 +11,7 @@ const { getEmailCopy } = require('./emailCopy')
 module.exports = {
   async sendNotifications({ user, baseUrl, role, UserModel }) {
     const userHelper = new User({ UserModel })
-    const { firstName, lastName } = await userHelper.getEditorInChief()
+    const { firstName, lastName } = await userHelper.getEditorsInChief()
     const eicName = `${firstName} ${lastName}`
 
     const email = new Email({
diff --git a/packages/component-faraday-selectors/src/index.js b/packages/component-faraday-selectors/src/index.js
index 65af2dd10ea67925098d318bc9f5d7ff13223d28..f1d9bcb1960a84d6656d68c25bf8616b2b4c02a8 100644
--- a/packages/component-faraday-selectors/src/index.js
+++ b/packages/component-faraday-selectors/src/index.js
@@ -7,10 +7,16 @@ export const isHEToManuscript = (state, collectionId) => {
   return get(collection, 'handlingEditor.id') === currentUserId
 }
 
+const canMakeRecommendationStatuses = [
+  'reviewCompleted',
+  'heAssigned',
+  'underReview',
+]
 export const canMakeRecommendation = (state, collection, fragment = {}) => {
   if (fragment.id !== last(collection.fragments)) return false
   const isHE = isHEToManuscript(state, collection.id)
-  return isHE && get(collection, 'status') === 'reviewCompleted'
+  const status = get(collection, 'status')
+  return isHE && canMakeRecommendationStatuses.includes(status)
 }
 
 export const currentUserIs = ({ currentUser: { user } }, role) => {
@@ -22,6 +28,10 @@ export const currentUserIs = ({ currentUser: { user } }, role) => {
       return isHe
     case 'staff':
       return isAdmin || isEic || isHe
+    case 'isEiC':
+      return isEic
+    case 'isAdmin':
+      return isAdmin
     case 'adminEiC':
       return isAdmin || isEic
     default:
@@ -60,15 +70,31 @@ export const getHERecommendation = (state, collectionId, fragmentId) => {
   )
 }
 
-const cantMakeDecisionStatuses = ['rejected', 'published', 'draft']
+const canMakeDecisionStatuses = ['submitted', 'pendingApproval']
 export const canMakeDecision = (state, collection, fragment = {}) => {
   if (fragment.id !== last(collection.fragments)) return false
   const status = get(collection, 'status')
 
-  if (!status || cantMakeDecisionStatuses.includes(status)) return false
-
   const isEIC = currentUserIs(state, 'adminEiC')
-  return isEIC && status
+  return isEIC && canMakeDecisionStatuses.includes(status)
+}
+
+const canEditManuscriptStatuses = ['draft', 'technicalChecks', 'inQA']
+export const canEditManuscript = (state, collection, fragment = {}) => {
+  const isAdmin = currentUserIs(state, 'isAdmin')
+  if (!isAdmin || fragment.id !== last(collection.fragments)) return false
+  const status = get(collection, 'status')
+
+  return canEditManuscriptStatuses.includes(status)
+}
+
+const canOverrideTechnicalChecksStatuses = ['technicalChecks', 'inQA']
+export const canOverrideTechnicalChecks = (state, collection) => {
+  const isAdmin = currentUserIs(state, 'isAdmin')
+  if (!isAdmin) return false
+  const status = get(collection, 'status')
+
+  return canOverrideTechnicalChecksStatuses.includes(status)
 }
 
 export const canSeeReviewersReports = (state, collectionId) => {
diff --git a/packages/component-fixture-manager/src/fixtures/collections.js b/packages/component-fixture-manager/src/fixtures/collections.js
index c6d401815491578a0262f7cb8cb06b2e3ed66c56..84583485feff68c50c532e4a5f4a396147177df2 100644
--- a/packages/component-fixture-manager/src/fixtures/collections.js
+++ b/packages/component-fixture-manager/src/fixtures/collections.js
@@ -11,7 +11,7 @@ const collections = {
     type: 'collection',
     fragments: [fragment.id],
     owners: [user.id],
-    save: jest.fn(),
+    save: jest.fn(() => collections.collection),
     invitations: [
       {
         id: chance.guid(),
@@ -44,6 +44,7 @@ const collections = {
     technicalChecks: {
       token: chance.guid(),
     },
+    status: 'pendingApproval',
   },
 }
 
diff --git a/packages/component-helper-service/src/services/User.js b/packages/component-helper-service/src/services/User.js
index 074414d59f43dcf979d912244249fce897b7d7b7..09c722d31cabe70492fb2c0fcdae381ee4c0c1ef 100644
--- a/packages/component-helper-service/src/services/User.js
+++ b/packages/component-helper-service/src/services/User.js
@@ -41,12 +41,16 @@ class User {
     return newUser
   }
 
-  async getEditorInChief() {
+  async getEditorsInChief() {
     const { UserModel } = this
     const users = await UserModel.all()
-    const eic = users.find(user => user.editorInChief || user.admin)
 
-    return eic
+    const eics = users.filter(user => user.editorInChief)
+    if (eics.length === 0) {
+      throw new Error('No Editor in Chief has been found')
+    }
+
+    return eics
   }
 
   async updateUserTeams({ userId, teamId }) {
@@ -65,6 +69,13 @@ class User {
 
     return authors.filter(author => activeUsers.includes(author.id))
   }
+
+  async getEiCName() {
+    const editorsInChief = await this.getEditorsInChief()
+    const firstName = get(editorsInChief, '0.firstName', 'Editor')
+    const lastName = get(editorsInChief, '0.lastName', 'in Chief')
+    return `${firstName} ${lastName}`
+  }
 }
 
 module.exports = User
diff --git a/packages/component-helper-service/src/services/email/Email.js b/packages/component-helper-service/src/services/email/Email.js
index 8d5b688b6993b3ebb9df7ab25630b926aa7762c6..53436b212dd89df765028f90fc779d4f2e0045bf 100644
--- a/packages/component-helper-service/src/services/email/Email.js
+++ b/packages/component-helper-service/src/services/email/Email.js
@@ -1,6 +1,7 @@
 const config = require('config')
 const helpers = require('./helpers')
 const SendEmail = require('@pubsweet/component-send-email')
+const logger = require('@pubsweet/logger')
 
 class Email {
   constructor({
@@ -64,14 +65,20 @@ class Email {
   }
 
   sendEmail({ text, html }) {
+    const fromEmail = config.get('mailer.from')
     const mailData = {
-      from: config.get('mailer.from'),
+      from: fromEmail,
       to: this.toUser.email,
       subject: this.content.subject,
       text,
       html,
     }
 
+    logger.info(
+      `EMAIL: Sent email from ${fromEmail} to ${
+        this.toUser.email
+      } with subject '${this.content.subject}'`,
+    )
     SendEmail.send(mailData)
   }
 }
diff --git a/packages/component-invite/src/routes/collectionsInvitations/emails/notifications.js b/packages/component-invite/src/routes/collectionsInvitations/emails/notifications.js
index 44c00f6856cbb40b92f735a8744df41ce73532b7..90df1a7ce364a2445dd79238dd9f4837392be5c8 100644
--- a/packages/component-invite/src/routes/collectionsInvitations/emails/notifications.js
+++ b/packages/component-invite/src/routes/collectionsInvitations/emails/notifications.js
@@ -36,7 +36,8 @@ module.exports = {
     } ${submittingAuthor.lastName}`
 
     const userHelper = new User({ UserModel })
-    const eic = await userHelper.getEditorInChief()
+    const eics = await userHelper.getEditorsInChief()
+    const eic = eics[0]
     const eicName = `${eic.firstName} ${eic.lastName}`
     const subjectBaseText = `${collection.customId}: Manuscript `
 
diff --git a/packages/component-invite/src/routes/fragmentsInvitations/emails/invitations.js b/packages/component-invite/src/routes/fragmentsInvitations/emails/invitations.js
index 9dc87ef106e786fc431f3be81acdd054d62313cf..b66445efe0a40c6470d9e04f3485710b5e8432ac 100644
--- a/packages/component-invite/src/routes/fragmentsInvitations/emails/invitations.js
+++ b/packages/component-invite/src/routes/fragmentsInvitations/emails/invitations.js
@@ -91,7 +91,7 @@ module.exports = {
         unsubscribeLink: services.createUrl(baseUrl, unsubscribeSlug, {
           id: invitedUser.id,
         }),
-        authorsList,
+        authorsList: authorsList.join(', '),
       },
     })
 
diff --git a/packages/component-invite/src/routes/fragmentsInvitations/emails/notifications.js b/packages/component-invite/src/routes/fragmentsInvitations/emails/notifications.js
index 12cad6a9d5283e486784a5a08c037b1b4c23d669..9eeb709b629ee52e0ab63624c4a25019b1dc1a95 100644
--- a/packages/component-invite/src/routes/fragmentsInvitations/emails/notifications.js
+++ b/packages/component-invite/src/routes/fragmentsInvitations/emails/notifications.js
@@ -37,8 +37,7 @@ module.exports = {
 
     const handlingEditor = get(collection, 'handlingEditor')
     const userHelper = new User({ UserModel })
-    const { firstName, lastName } = await userHelper.getEditorInChief()
-    const eicName = `${firstName} ${lastName}`
+    const eicName = await userHelper.getEiCName()
     const subjectBaseText = isCanceled
       ? `${collection.customId}: Reviewer `
       : `${collection.customId}: Manuscript `
diff --git a/packages/component-manuscript-manager/src/routes/fragments/notifications/notifications.js b/packages/component-manuscript-manager/src/routes/fragments/notifications/notifications.js
index 012113ffdbbd6df5542523b231860bdacaab7032..ee0f6f2918511fe268a35a1b9bca28c6e8d9e4c9 100644
--- a/packages/component-manuscript-manager/src/routes/fragments/notifications/notifications.js
+++ b/packages/component-manuscript-manager/src/routes/fragments/notifications/notifications.js
@@ -49,9 +49,7 @@ module.exports = {
     })
 
     const userHelper = new User({ UserModel })
-    const eic = await userHelper.getEditorInChief()
-    const eicName = `${eic.firstName} ${eic.lastName}`
-
+    const eicName = await userHelper.getEiCName()
     if (isNewVersion) {
       sendHandlingEditorEmail({
         email,
@@ -76,8 +74,8 @@ module.exports = {
 
     if (isTechnicalCheck) {
       sendEQSEmail({
-        eic,
         email,
+        eicName,
         baseUrl,
         collection,
         subjectBaseText,
@@ -157,7 +155,13 @@ const sendReviewersEmail = async ({
   })
 }
 
-const sendEQSEmail = ({ eic, email, baseUrl, collection, subjectBaseText }) => {
+const sendEQSEmail = ({
+  email,
+  eicName,
+  baseUrl,
+  collection,
+  subjectBaseText,
+}) => {
   const emailType = 'eqs-manuscript-submitted'
 
   email.toUser = {
@@ -166,7 +170,7 @@ const sendEQSEmail = ({ eic, email, baseUrl, collection, subjectBaseText }) => {
   }
 
   email.content.unsubscribeLink = baseUrl
-  email.content.signatureName = `${eic.firstName} ${eic.lastName}`
+  email.content.signatureName = eicName
   email.content.subject = `${subjectBaseText} Submitted`
   email.content.ctaLink = services.createUrl(
     baseUrl,
diff --git a/packages/component-manuscript-manager/src/routes/fragments/post.js b/packages/component-manuscript-manager/src/routes/fragments/post.js
index 6150932b318d711b2eed23d7db81b6588e2a0799..2ec4ab94af0427c9014609b1927f0db01e40a498 100644
--- a/packages/component-manuscript-manager/src/routes/fragments/post.js
+++ b/packages/component-manuscript-manager/src/routes/fragments/post.js
@@ -52,7 +52,7 @@ module.exports = models => async (req, res) => {
       },
     }
 
-    await MTS.sendPackage(packageFragment)
+    await MTS.sendPackage({ fragment: packageFragment })
 
     notifications.sendNotifications({
       fragment,
diff --git a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/emailCopy.js b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/emailCopy.js
index d4046f5a95f38e0c56bca849133118d98ccbd421..5b3840f79d5c78f1d6abedfb513c89b086f06737 100644
--- a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/emailCopy.js
+++ b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/emailCopy.js
@@ -1,4 +1,5 @@
 const getEmailCopy = ({
+  customId,
   emailType,
   titleText,
   comments = '',
@@ -19,7 +20,6 @@ const getEmailCopy = ({
       break
     case 'author-manuscript-published':
       paragraph = `I am delighted to inform you that ${titleText} has passed through the review process and will be published in Hindawi.<br/><br/>
-    ${comments}<br/><br/>
     Thanks again for choosing to publish with us.`
       hasLink = false
       break
@@ -77,6 +77,9 @@ const getEmailCopy = ({
       paragraph = `In order for ${titleText} to proceed to publication, there needs to be a revision. <br/><br/>
         For more information about what is required, please visit the manuscript details page.`
       break
+    case 'eqa-manuscript-request-for-approval':
+      paragraph = `Manuscript ID ${customId} has passed peer-review and is now ready for EQA. Please click on the link below to either approve or return the manuscript to the Editor in Chief:`
+      break
     default:
       throw new Error(`The ${emailType} email type is not defined.`)
   }
diff --git a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/notifications.js b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/notifications.js
index f99bbd3b5c8ef78a1ed89ff6453df8945a1cc26f..c86bbd35a818229fbc82d1992ee27cbe9e91b00e 100644
--- a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/notifications.js
+++ b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/notifications.js
@@ -1,5 +1,5 @@
 const config = require('config')
-const { chain, get } = require('lodash')
+const { chain, get, isEmpty } = require('lodash')
 
 const {
   User,
@@ -10,10 +10,12 @@ const {
 
 const { getEmailCopy } = require('./emailCopy')
 
+const editorialAssistantEmail = config.get('mailer.editorialAssistant')
 const unsubscribeSlug = config.get('unsubscribe.url')
 
 module.exports = {
   async sendNotifications({
+    hasEQA,
     baseUrl,
     fragment,
     UserModel,
@@ -33,12 +35,15 @@ module.exports = {
       fragmentAuthors.submittingAuthor.firstName
     } ${fragmentAuthors.submittingAuthor.lastName}`
 
+    const userHelper = new User({ UserModel })
+    const eicName = await userHelper.getEiCName()
+
     const email = new Email({
       type: 'user',
       content: {
         unsubscribeLink: baseUrl,
         ctaText: 'MANUSCRIPT DETAILS',
-        signatureName: get(collection, 'handlingEditor.name', 'N/A'),
+        signatureName: eicName,
         ctaLink: services.createUrl(
           baseUrl,
           `/projects/${collection.id}/versions/${fragment.id}/details`,
@@ -46,77 +51,94 @@ module.exports = {
       },
     })
 
-    const userHelper = new User({ UserModel })
-    const {
-      email: eicEmail,
-      firstName,
-      lastName,
-    } = await userHelper.getEditorInChief()
-    const eicName = `${firstName} ${lastName}`
-
-    let comments
-    if (isEditorInChief) {
-      const eicComments = chain(newRecommendation)
-        .get('comments')
-        .find(comm => !comm.public)
-        .get('content')
-        .value()
-
-      comments = eicComments
-    }
-
-    if (isEditorInChief || newRecommendation.recommendationType === 'review') {
-      // the request came from either the Editor in Chief or a reviewer, so the HE needs to be notified
-      sendHandlingEditorEmail({
-        email,
-        eicName,
-        baseUrl,
-        comments,
-        titleText,
-        targetUserName,
-        subjectBaseText,
-        handlingEditor: get(collection, 'handlingEditor', {}),
-        recommendation: newRecommendation.recommendation,
-        recommendationType: newRecommendation.recommendationType,
-      })
-    }
-
     if (
-      newRecommendation.recommendationType !== 'review' &&
-      newRecommendation.recommendation !== 'return-to-handling-editor'
+      !hasEQA &&
+      isEditorInChief &&
+      newRecommendation.recommendation === 'publish'
     ) {
-      sendAuthorsEmail({
+      sendEQAEmail({
         email,
+        eicName,
         baseUrl,
-        titleText,
-        parsedFragment,
-        fragmentAuthors,
-        isEditorInChief,
+        collection,
         subjectBaseText,
-        newRecommendation,
       })
+    } else {
+      let comments
+      if (isEditorInChief) {
+        const eicComments = chain(newRecommendation)
+          .get('comments')
+          .find(comm => !comm.public)
+          .get('content')
+          .value()
 
-      sendReviewersEmail({
-        email,
-        baseUrl,
-        UserModel,
-        titleText,
-        fragmentHelper,
-        isEditorInChief,
-        subjectBaseText,
-        recommendation: newRecommendation.recommendation,
-        handlingEditorName: get(collection, 'handlingEditor.name', 'N/A'),
-      })
+        comments = eicComments
+      }
 
-      sendEiCEmail({
-        email,
-        baseUrl,
-        eicName,
-        eicEmail,
-        titleText,
-        subjectBaseText,
-        recommendation: newRecommendation,
-      })
+      const hasPeerReview = (collection = {}) =>
+        !isEmpty(collection.handlingEditor)
+
+      if (
+        (isEditorInChief ||
+          newRecommendation.recommendationType === 'review') &&
+        hasPeerReview(collection)
+      ) {
+        // the request came from either the Editor in Chief or a reviewer, so the HE needs to be notified
+        sendHandlingEditorEmail({
+          email,
+          eicName: await userHelper.getEiCName(),
+          baseUrl,
+          comments,
+          titleText,
+          targetUserName,
+          subjectBaseText,
+          handlingEditor: get(collection, 'handlingEditor', {}),
+          recommendation: newRecommendation.recommendation,
+          recommendationType: newRecommendation.recommendationType,
+        })
+      }
+
+      if (
+        newRecommendation.recommendationType !== 'review' &&
+        newRecommendation.recommendation !== 'return-to-handling-editor'
+      ) {
+        if (isEditorInChief || collection.status === 'revisionRequested') {
+          sendAuthorsEmail({
+            email,
+            baseUrl,
+            titleText,
+            parsedFragment,
+            fragmentAuthors,
+            isEditorInChief,
+            subjectBaseText,
+            newRecommendation,
+            handlingEditorName: get(collection, 'handlingEditor.name', eicName),
+          })
+        }
+
+        if (hasPeerReview(collection)) {
+          sendReviewersEmail({
+            email,
+            baseUrl,
+            UserModel,
+            titleText,
+            fragmentHelper,
+            isEditorInChief,
+            subjectBaseText,
+            recommendation: newRecommendation.recommendation,
+            handlingEditorName: get(collection, 'handlingEditor.name', eicName),
+          })
+
+          sendEiCsEmail({
+            email,
+            baseUrl,
+            userHelper,
+            titleText,
+            subjectBaseText,
+            recommendation: newRecommendation,
+          })
+        }
+      }
     }
   },
 }
@@ -161,7 +183,9 @@ const sendHandlingEditorEmail = ({
   email.content.unsubscribeLink = services.createUrl(baseUrl, unsubscribeSlug, {
     id: handlingEditor.id,
   })
+
   email.content.signatureName = eicName
+
   const { html, text } = email.getBody({
     body: getEmailCopy({
       emailType,
@@ -181,6 +205,7 @@ const sendAuthorsEmail = async ({
   subjectBaseText,
   fragmentAuthors,
   newRecommendation,
+  handlingEditorName,
   parsedFragment: { heRecommendation },
 }) => {
   let emailType, authors, comments
@@ -201,7 +226,7 @@ const sendAuthorsEmail = async ({
       email.content.subject = `${subjectBaseText} Published`
     } else {
       emailType = 'author-manuscript-rejected'
-      email.content.subject = `${subjectBaseText} Rejected`
+      email.content.subject = `${subjectBaseText} Decision`
     }
 
     authors = fragmentAuthors.activeAuthors.map(author => ({
@@ -214,7 +239,10 @@ const sendAuthorsEmail = async ({
     }))
   } else {
     emailType = 'author-request-to-revision'
+
     email.content.subject = `${subjectBaseText} Recommendation`
+    email.content.signatureName = handlingEditorName
+
     const authorNote = newRecommendation.comments.find(comm => comm.public)
     const content = get(authorNote, 'content')
     const authorNoteText = content ? `Reason & Details: "${content}"` : ''
@@ -328,20 +356,18 @@ const sendReviewersEmail = async ({
       },
     )
     const { html, text } = email.getBody({
-      body: { paragraph: reviewer.paragraph },
-      hasLink: reviewer.hasLink,
+      body: { paragraph: reviewer.paragraph, hasLink: reviewer.hasLink },
     })
     email.sendEmail({ html, text })
   })
 }
 
-const sendEiCEmail = ({
+const sendEiCsEmail = async ({
   email,
-  eicName,
-  eicEmail,
   titleText,
-  recommendation: { recommendation, comments: recComments = [] },
+  userHelper,
   subjectBaseText,
+  recommendation: { recommendation, comments: recComments = [] },
 }) => {
   let emailType
 
@@ -361,19 +387,63 @@ const sendEiCEmail = ({
       throw new Error(`undefined recommendation: ${recommendation} `)
   }
 
+  const privateNote = recComments.find(comm => !comm.public)
+  const content = get(privateNote, 'content')
+  const comments = content ? `Note to Editor: "${content}"` : ''
+
+  const editors = (await userHelper.getEditorsInChief()).map(eic => ({
+    ...eic,
+    ...getEmailCopy({
+      emailType,
+      titleText,
+      comments,
+    }),
+  }))
+
+  editors.forEach(eic => {
+    email.toUser = {
+      email: eic.email,
+      name: `${eic.firstName} ${eic.lastName}`,
+    }
+    const { html, text } = email.getBody({
+      body: { paragraph: eic.paragraph, hasLink: eic.hasLink },
+    })
+    email.sendEmail({ html, text })
+  })
+}
+
+const sendEQAEmail = ({
+  email,
+  eicName,
+  baseUrl,
+  collection,
+  subjectBaseText,
+}) => {
+  const emailType = 'eqa-manuscript-request-for-approval'
+
   email.toUser = {
-    email: eicEmail,
-    name: eicName,
+    email: editorialAssistantEmail,
+    name: 'Editorial Assistant',
   }
 
-  const privateNote = recComments.find(comm => comm.private)
-  const content = get(privateNote, 'content')
-  const comments = content ? `Note to Editor: "${content}"` : ''
+  email.content.unsubscribeLink = baseUrl
+  email.content.signatureName = eicName
+  email.content.subject = `${subjectBaseText} Request for EQA Approval`
+  email.content.ctaLink = services.createUrl(
+    baseUrl,
+    config.get('eqa-decision.url'),
+    {
+      collectionId: collection.id,
+      customId: collection.customId,
+      token: collection.technicalChecks.token,
+    },
+  )
+  email.content.ctaText = 'MAKE DECISION'
+
   const { html, text } = email.getBody({
     body: getEmailCopy({
       emailType,
-      titleText,
-      comments,
+      customId: collection.customId,
     }),
   })
   email.sendEmail({ html, text })
diff --git a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js
index 37677984272615861c98b4d2b2b7f341078933f6..f67754387a6deef1b7dd8f2d93f31221c7bd52d5 100644
--- a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js
+++ b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js
@@ -1,5 +1,7 @@
 const uuid = require('uuid')
-const { pick } = require('lodash')
+const { pick, get, set, has } = require('lodash')
+const config = require('config')
+const { v4 } = require('uuid')
 
 const {
   services,
@@ -7,6 +9,10 @@ const {
   Collection,
 } = require('pubsweet-component-helper-service')
 
+const s3Config = get(config, 'pubsweet-component-aws-s3', {})
+const mtsConfig = get(config, 'mts-service', {})
+const MTSService = require('pubsweet-component-mts-package')
+
 const notifications = require('./notifications/notifications')
 
 module.exports = models => async (req, res) => {
@@ -70,7 +76,43 @@ module.exports = models => async (req, res) => {
       fragment.revision = pick(fragment, ['authors', 'files', 'metadata'])
     }
 
+    const technicalChecks = get(collection, 'technicalChecks', {})
+    const { hasEQA } = technicalChecks
+
+    if (isEditorInChief && recommendation === 'publish' && !hasEQA) {
+      const { journal, xmlParser, ftp } = mtsConfig
+      const MTS = new MTSService(journal, xmlParser, s3Config, ftp)
+      const packageFragment = {
+        ...fragment,
+        metadata: {
+          ...fragment.metadata,
+          customId: collection.customId,
+        },
+      }
+
+      await MTS.sendPackage({ fragment: packageFragment, isEQA: true })
+
+      collection.status = 'inQA'
+      set(collection, 'technicalChecks.token', v4())
+      set(collection, 'technicalChecks.hasEQA', false)
+      await collection.save()
+    }
+
+    /* if the EiC returns the manuscript to the HE after the EQA has been performed
+       then remove all properties from the technicalChecks property so that the manuscript
+       can go through the EQA process again
+    */
+    if (
+      isEditorInChief &&
+      recommendation === 'return-to-handling-editor' &&
+      has(collection.technicalChecks, 'hasEQA')
+    ) {
+      collection.technicalChecks = {}
+      await collection.save()
+    }
+
     notifications.sendNotifications({
+      hasEQA,
       fragment,
       collection,
       isEditorInChief,
diff --git a/packages/component-manuscript-manager/src/routes/technicalChecks/notifications/emailCopy.js b/packages/component-manuscript-manager/src/routes/technicalChecks/notifications/emailCopy.js
index c562e8be47b57e98d965e88681150adead6057b0..0c36acca52a116cc5f9584d0679a52944e635b02 100644
--- a/packages/component-manuscript-manager/src/routes/technicalChecks/notifications/emailCopy.js
+++ b/packages/component-manuscript-manager/src/routes/technicalChecks/notifications/emailCopy.js
@@ -1,14 +1,34 @@
-const getEmailCopy = ({ emailType, titleText }) => {
+const getEmailCopy = ({ emailType, titleText, comments }) => {
   let paragraph
+  let hasLink = true
   switch (emailType) {
     case 'eqs-manuscript-accepted':
       paragraph = `We are please to inform you that ${titleText} has passed the Hindawi technical check process and is now submitted. Please click the link below to access the manuscript.`
       break
+    case 'he-manuscript-published':
+      hasLink = false
+      paragraph = `Thank you for your recommendation to publish ${titleText} based on the reviews you received.<br/><br/>
+      I can confirm this article will now go through to publication.`
+      break
+    case 'author-manuscript-published':
+      paragraph = `I am delighted to inform you that ${titleText} has passed through the review process and will be published in Hindawi.<br/><br/>
+        Thanks again for choosing to publish with us.`
+      hasLink = false
+      break
+    case 'submitted-reviewers-after-publish':
+      hasLink = false
+      paragraph = `Thank you for your review on ${titleText}. After taking into account the reviews and the recommendation of the Handling Editor, I can confirm this article will now be published.<br/><br/>
+      If you have any queries about this decision, then please email them to Hindawi as soon as possible.`
+      break
+    case 'eqa-manuscript-returned-to-eic':
+      paragraph = `We regret to inform you that ${titleText} has been returned with comments. Please click the link below to access the manuscript.<br/><br/>
+        Comments: ${comments}<br/><br/>`
+      break
     default:
       throw new Error(`The ${emailType} email type is not defined.`)
   }
 
-  return { paragraph, hasLink: true }
+  return { paragraph, hasLink }
 }
 
 module.exports = {
diff --git a/packages/component-manuscript-manager/src/routes/technicalChecks/notifications/notifications.js b/packages/component-manuscript-manager/src/routes/technicalChecks/notifications/notifications.js
index 0da35cdfd11321ba4fbced245cd01a8e8a9ba22f..89cc1d71180c06f2fed6c78f2650a974ec8501ea 100644
--- a/packages/component-manuscript-manager/src/routes/technicalChecks/notifications/notifications.js
+++ b/packages/component-manuscript-manager/src/routes/technicalChecks/notifications/notifications.js
@@ -1,3 +1,6 @@
+const config = require('config')
+const { get } = require('lodash')
+
 const {
   User,
   Email,
@@ -6,10 +9,15 @@ const {
 } = require('pubsweet-component-helper-service')
 const { getEmailCopy } = require('./emailCopy')
 
+const unsubscribeSlug = config.get('unsubscribe.url')
+
 module.exports = {
   async sendNotifications({
+    isEQA,
+    agree,
     baseUrl,
     collection,
+    comments = '',
     User: UserModel,
     Fragment: FragmentModel,
   }) {
@@ -18,30 +26,29 @@ module.exports = {
     const parsedFragment = await fragmentHelper.getFragmentData({
       handlingEditor: collection.handlingEditor,
     })
-    const { submittingAuthor } = await fragmentHelper.getAuthorData({
+
+    const {
+      activeAuthors: authors,
+      submittingAuthor,
+    } = await fragmentHelper.getAuthorData({
       UserModel,
     })
 
     const titleText = `the manuscript titled "${parsedFragment.title}" by ${
       submittingAuthor.firstName
     } ${submittingAuthor.lastName}`
+    const subjectBaseText = `${collection.customId}: Manuscript`
 
     const userHelper = new User({ UserModel })
-    const {
-      lastName,
-      firstName,
-      email: eicEmail,
-    } = await userHelper.getEditorInChief()
+    const subject = `${subjectBaseText} ${
+      agree ? '' : 'Not '
+    }Passed Technical Checks`
 
     const email = new Email({
       type: 'user',
-      toUser: {
-        email: eicEmail,
-        name: `${firstName} ${lastName}`,
-      },
       content: {
-        subject: `${collection.customId}: Manuscript Passed Technical Checks`,
-        signatureName: 'EQS Team',
+        subject,
+        signatureName: 'EQA Team',
         ctaLink: services.createUrl(
           baseUrl,
           `/projects/${collection.id}/versions/${fragment.id}/details`,
@@ -51,12 +58,173 @@ module.exports = {
       },
     })
 
-    const { html, text } = email.getBody({
-      body: getEmailCopy({
+    if (isEQA && agree) {
+      const eicName = await userHelper.getEiCName()
+      email.content.signatureName = eicName
+
+      sendAuthorsEmail({
+        email,
+        baseUrl,
+        titleText,
+        subjectBaseText,
+        fragmentAuthors: authors,
+      })
+      sendHandlingEditorEmail({
+        email,
+        baseUrl,
+        titleText,
+        subjectBaseText,
+        handlingEditor: get(collection, 'handlingEditor', {}),
+      })
+      sendSubmittedReviewersEmail({
+        email,
+        baseUrl,
         titleText,
-        emailType: 'eqs-manuscript-accepted',
-      }),
+        UserModel,
+        fragmentHelper,
+        subjectBaseText,
+      })
+    } else {
+      sendEditorsEmail({ email, agree, comments, userHelper, titleText })
+    }
+  },
+}
+
+const sendEditorsEmail = async ({
+  email,
+  agree,
+  comments = '',
+  userHelper,
+  titleText,
+}) => {
+  const emailType = agree
+    ? 'eqs-manuscript-accepted'
+    : 'eqa-manuscript-returned-to-eic'
+
+  const editors = (await userHelper.getEditorsInChief()).map(eic => ({
+    ...eic,
+    ...getEmailCopy({
+      emailType,
+      titleText,
+      comments,
+    }),
+  }))
+
+  editors.forEach(eic => {
+    email.toUser = {
+      email: eic.email,
+      name: `${eic.firstName} ${eic.lastName}`,
+    }
+    const { html, text } = email.getBody({
+      body: { paragraph: eic.paragraph, hasLink: eic.hasLink },
     })
     email.sendEmail({ html, text })
-  },
+  })
+}
+
+const sendHandlingEditorEmail = ({
+  email,
+  baseUrl,
+  titleText,
+  handlingEditor,
+  subjectBaseText,
+}) => {
+  email.content.subject = `${subjectBaseText} Decision`
+  const emailType = 'he-manuscript-published'
+
+  email.toUser = {
+    email: handlingEditor.email,
+    name: handlingEditor.name,
+  }
+  email.content.unsubscribeLink = services.createUrl(baseUrl, unsubscribeSlug, {
+    id: handlingEditor.id,
+  })
+
+  const { html, text } = email.getBody({
+    body: getEmailCopy({
+      emailType,
+      titleText,
+    }),
+  })
+  email.sendEmail({ html, text })
+}
+
+const sendSubmittedReviewersEmail = async ({
+  email,
+  baseUrl,
+  titleText,
+  UserModel,
+  fragmentHelper,
+  subjectBaseText,
+}) => {
+  email.content.subject = `${subjectBaseText} Decision`
+
+  const reviewers = (await fragmentHelper.getReviewers({
+    UserModel,
+    type: 'submitted',
+  })).map(rev => ({
+    ...rev,
+    ...getEmailCopy({
+      emailType: 'submitted-reviewers-after-publish',
+      titleText,
+    }),
+  }))
+
+  reviewers.forEach(reviewer => {
+    email.toUser = {
+      email: reviewer.email,
+      name: `${reviewer.firstName} ${reviewer.lastName}`,
+    }
+    email.content.unsubscribeLink = services.createUrl(
+      baseUrl,
+      unsubscribeSlug,
+      {
+        id: reviewer.id,
+      },
+    )
+    const { html, text } = email.getBody({
+      body: { paragraph: reviewer.paragraph, hasLink: reviewer.hasLink },
+    })
+    email.sendEmail({ html, text })
+  })
+}
+
+const sendAuthorsEmail = ({
+  email,
+  baseUrl,
+  titleText,
+  subjectBaseText,
+  fragmentAuthors,
+}) => {
+  const emailType = 'author-manuscript-published'
+  email.content.subject = `${subjectBaseText} Published`
+
+  const authors = fragmentAuthors.map(author => ({
+    ...author,
+    ...getEmailCopy({
+      emailType,
+      titleText,
+    }),
+  }))
+
+  authors.forEach(author => {
+    email.toUser = {
+      email: author.email,
+      name: `${author.firstName} ${author.lastName}`,
+    }
+    email.content.unsubscribeLink = services.createUrl(
+      baseUrl,
+      unsubscribeSlug,
+      {
+        id: author.id,
+      },
+    )
+    const { html, text } = email.getBody({
+      body: {
+        paragraph: author.paragraph,
+        hasLink: author.hasLink,
+      },
+    })
+    email.sendEmail({ html, text })
+  })
 }
diff --git a/packages/component-manuscript-manager/src/routes/technicalChecks/patch.js b/packages/component-manuscript-manager/src/routes/technicalChecks/patch.js
index 934709a746946699d07062c71084b3013f4fff13..14e68a7cc4b745752a5ddd2d23a733876f0f9a85 100644
--- a/packages/component-manuscript-manager/src/routes/technicalChecks/patch.js
+++ b/packages/component-manuscript-manager/src/routes/technicalChecks/patch.js
@@ -12,13 +12,13 @@ const setNewStatus = (step, agree) => {
   if (step === TECHNICAL_STEPS.EQS) {
     return agree ? 'submitted' : 'rejected'
   } else if (step === TECHNICAL_STEPS.EQA) {
-    return agree ? 'accepted' : 'rejected'
+    return agree ? 'accepted' : 'pendingApproval'
   }
 }
 
 module.exports = ({ Collection, Fragment, User }) => async (req, res) => {
   const { collectionId } = req.params
-  const { token, agree, step } = req.body
+  const { token, agree, step, comments } = req.body
 
   try {
     const collection = await Collection.find(collectionId)
@@ -37,17 +37,21 @@ module.exports = ({ Collection, Fragment, User }) => async (req, res) => {
     }
 
     delete collection.technicalChecks.token
+    if (step === TECHNICAL_STEPS.EQA) {
+      collection.technicalChecks.hasEQA = true
+    }
     collection.status = setNewStatus(step, agree)
     await collection.save()
 
-    if (agree) {
-      sendNotifications({
-        User,
-        Fragment,
-        collection,
-        baseUrl: services.getBaseUrl(req),
-      })
-    }
+    sendNotifications({
+      User,
+      agree,
+      comments,
+      Fragment,
+      collection,
+      baseUrl: services.getBaseUrl(req),
+      isEQA: step === TECHNICAL_STEPS.EQA,
+    })
 
     return res.status(200).json(collection)
   } catch (e) {
diff --git a/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js b/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js
index 0f0f048e62835ecbd5d6c9df1f36ad3de740b183..686124cb9518df27b9c722fae0f645c764a4d415 100644
--- a/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js
+++ b/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js
@@ -11,6 +11,7 @@ const chance = new Chance()
 jest.mock('@pubsweet/component-send-email', () => ({
   send: jest.fn(),
 }))
+jest.mock('pubsweet-component-mts-package')
 
 const reqBody = {
   recommendation: 'accept',
@@ -206,4 +207,129 @@ describe('Post fragments recommendations route handler', () => {
     const data = JSON.parse(res._getData())
     expect(data.error).toEqual('Unauthorized.')
   })
+  it('should return success when the EiC recommends to reject without peer review', async () => {
+    const { editorInChief } = testFixtures.users
+    const { collection } = testFixtures.collections
+    const { fragment } = testFixtures.fragments
+    body.recommendation = 'reject'
+    body.recommendationType = 'editorRecommendation'
+
+    delete fragment.recommendations
+    delete fragment.revision
+    delete fragment.invitations
+    delete collection.invitations
+    delete collection.handlingEditor
+
+    const res = await requests.sendRequest({
+      body,
+      userId: editorInChief.id,
+      models,
+      route,
+      path,
+      params: {
+        collectionId: collection.id,
+        fragmentId: fragment.id,
+      },
+    })
+
+    expect(res.statusCode).toBe(200)
+    const data = JSON.parse(res._getData())
+
+    expect(data.userId).toEqual(editorInChief.id)
+    expect(data.recommendation).toBe('reject')
+  })
+  it('should return success when the EiC recommends to publish without EQA', async () => {
+    const { editorInChief } = testFixtures.users
+    const { collection } = testFixtures.collections
+    const { fragment } = testFixtures.fragments
+    body.recommendation = 'publish'
+    body.recommendationType = 'editorRecommendation'
+    delete collection.technicalChecks
+
+    const res = await requests.sendRequest({
+      body,
+      userId: editorInChief.id,
+      models,
+      route,
+      path,
+      params: {
+        collectionId: collection.id,
+        fragmentId: fragment.id,
+      },
+    })
+
+    expect(res.statusCode).toBe(200)
+    const data = JSON.parse(res._getData())
+
+    expect(collection.status).toBe('inQA')
+    expect(collection.technicalChecks).toHaveProperty('hasEQA')
+    expect(collection.technicalChecks.hasEQA).toBeFalsy()
+    expect(data.userId).toEqual(editorInChief.id)
+    expect(data.recommendation).toBe('publish')
+  })
+  it('should return success when the EiC recommends to publish with EQA accepted', async () => {
+    const { editorInChief } = testFixtures.users
+    const { collection } = testFixtures.collections
+    const { fragment } = testFixtures.fragments
+    body.recommendation = 'publish'
+    body.recommendationType = 'editorRecommendation'
+
+    collection.technicalChecks.hasEQA = true
+
+    const res = await requests.sendRequest({
+      body,
+      userId: editorInChief.id,
+      models,
+      route,
+      path,
+      params: {
+        collectionId: collection.id,
+        fragmentId: fragment.id,
+      },
+    })
+
+    expect(res.statusCode).toBe(200)
+    const data = JSON.parse(res._getData())
+
+    expect(collection.status).toBe('accepted')
+    expect(data.userId).toEqual(editorInChief.id)
+    expect(data.recommendation).toBe('publish')
+  })
+  it('should return success when the EiC returns the manuscript to HE with comments after EQA returned to EiC', async () => {
+    const { editorInChief } = testFixtures.users
+    const { collection } = testFixtures.collections
+    const { fragment } = testFixtures.fragments
+    body.recommendation = 'return-to-handling-editor'
+    body.recommendationType = 'editorRecommendation'
+    body.comments = 'This needs more work'
+
+    delete fragment.recommendations
+    delete fragment.revision
+    delete fragment.invitations
+    delete collection.invitations
+    delete collection.handlingEditor
+    collection.technicalChecks.hasEQA = false
+
+    const res = await requests.sendRequest({
+      body,
+      userId: editorInChief.id,
+      models,
+      route,
+      path,
+      params: {
+        collectionId: collection.id,
+        fragmentId: fragment.id,
+      },
+    })
+
+    expect(res.statusCode).toBe(200)
+    const data = JSON.parse(res._getData())
+
+    expect(collection.status).toBe('reviewCompleted')
+    expect(collection.technicalChecks).not.toHaveProperty('token')
+    expect(collection.technicalChecks).not.toHaveProperty('hasEQA')
+
+    expect(data.userId).toEqual(editorInChief.id)
+    expect(data.recommendation).toBe('return-to-handling-editor')
+  })
 })
diff --git a/packages/component-manuscript-manager/src/tests/technicalChecks/patch.test.js b/packages/component-manuscript-manager/src/tests/technicalChecks/patch.test.js
index 37c2ca388c56320be9a1527db7aa22c6f310a002..f8b6ccd6bc92c2817aeb60b454c6347a7d6eb47b 100644
--- a/packages/component-manuscript-manager/src/tests/technicalChecks/patch.test.js
+++ b/packages/component-manuscript-manager/src/tests/technicalChecks/patch.test.js
@@ -29,7 +29,7 @@ describe('Patch technical checks route handler', () => {
     models = Model.build(testFixtures)
   })
 
-  it('should return success when the parameters are correct', async () => {
+  it('should return success when the EQS is accepted', async () => {
     const { collection } = testFixtures.collections
     body.token = collection.technicalChecks.token
 
@@ -46,6 +46,62 @@ describe('Patch technical checks route handler', () => {
     expect(res.statusCode).toBe(200)
   })
 
+  it('should return success when the EQS is rejected', async () => {
+    const { collection } = testFixtures.collections
+    body.token = collection.technicalChecks.token
+    body.agree = false
+
+    const res = await requests.sendRequest({
+      body,
+      models,
+      route,
+      path,
+      params: {
+        collectionId: collection.id,
+      },
+    })
+
+    expect(res.statusCode).toBe(200)
+  })
+
+  it('should return success when the EQA is accepted', async () => {
+    const { collection } = testFixtures.collections
+    body.token = collection.technicalChecks.token
+    body.step = 'eqa'
+
+    const res = await requests.sendRequest({
+      body,
+      models,
+      route,
+      path,
+      params: {
+        collectionId: collection.id,
+      },
+    })
+
+    expect(res.statusCode).toBe(200)
+  })
+
+  it('should return success when the EQA is returned with comments', async () => {
+    const { collection } = testFixtures.collections
+    body.token = collection.technicalChecks.token
+    body.agree = false
+    body.step = 'eqa'
+    body.comments = 'suspicion of plagiarism'
+
+    const res = await requests.sendRequest({
+      body,
+      models,
+      route,
+      path,
+      params: {
+        collectionId: collection.id,
+      },
+    })
+
+    expect(res.statusCode).toBe(200)
+  })
+
   it('should return an error when the collection does not exist', async () => {
     const res = await requests.sendRequest({
       body,
diff --git a/packages/component-manuscript/src/components/ManuscriptLayout.js b/packages/component-manuscript/src/components/ManuscriptLayout.js
index 7c68d8ef1d2db6d3f13592a8afaa2a4a6e0408a7..c0ed8a1f1635315f2e1f5aa3ea048fec535ab306 100644
--- a/packages/component-manuscript/src/components/ManuscriptLayout.js
+++ b/packages/component-manuscript/src/components/ManuscriptLayout.js
@@ -30,7 +30,6 @@ const ManuscriptLayout = ({
   editorInChief,
   canMakeRevision,
   editorialRecommendations,
-  responseToReviewers,
   hasResponseToReviewers,
   project = {},
   version = {},
diff --git a/packages/component-manuscript/src/components/SideBarActions.js b/packages/component-manuscript/src/components/SideBarActions.js
index d5e8b16b033cf934842da48a3126b4fd686545d0..ea233bbbc75e697bdfb16c76f7fbdb8c50ed3fcd 100644
--- a/packages/component-manuscript/src/components/SideBarActions.js
+++ b/packages/component-manuscript/src/components/SideBarActions.js
@@ -1,5 +1,5 @@
 import React from 'react'
-import { compose } from 'recompose'
+import { compose, withHandlers } from 'recompose'
 import { Icon } from '@pubsweet/ui'
 import { connect } from 'react-redux'
 import styled from 'styled-components'
@@ -11,18 +11,21 @@ import {
   Recommendation,
 } from 'pubsweet-components-faraday/src/components'
 
-import { createRevision } from 'pubsweet-component-wizard/src/redux/conversion'
-
 import {
   canMakeDecision,
   canMakeRecommendation,
+  canEditManuscript,
+  canOverrideTechnicalChecks,
 } from 'pubsweet-component-faraday-selectors/src'
 
 const SideBarActions = ({
   project,
   version,
-  createRevision,
+  goToEdit,
   canMakeDecision,
+  canEditManuscript,
+  goToTechnicalCheck,
+  canOverrideTechChecks,
   canMakeRecommendation,
 }) => (
   <Root>
@@ -31,9 +34,9 @@ const SideBarActions = ({
         collectionId={project.id}
         fragmentId={version.id}
         modalKey={`decide-${version.id}`}
+        status={project.status}
       />
     )}
-
     {canMakeRecommendation && (
       <Recommendation
         collectionId={project.id}
@@ -41,6 +44,24 @@ const SideBarActions = ({
         modalKey={`recommend-${version.id}`}
       />
     )}
+    {canOverrideTechChecks && (
+      <ClickableIcon
+        data-test="button-technical-checks"
+        onClick={goToTechnicalCheck(project)}
+        title="Technical Checks"
+      >
+        <Icon>check-square</Icon>
+      </ClickableIcon>
+    )}
+    {canEditManuscript && (
+      <ClickableIcon
+        data-test="button-edit-manuscript"
+        onClick={goToEdit(project, version)}
+        title="Edit Manuscript"
+      >
+        <Icon>edit</Icon>
+      </ClickableIcon>
+    )}
     <ZipFiles
       archiveName={`ID-${project.customId}`}
       collectionId={project.id}
@@ -55,15 +76,27 @@ const SideBarActions = ({
 
 export default compose(
   withRouter,
-  connect(
-    (state, { project, version }) => ({
-      canMakeDecision: canMakeDecision(state, project, version),
-      canMakeRecommendation: canMakeRecommendation(state, project, version),
-    }),
-    (dispatch, { project, version, history }) => ({
-      createRevision: () => dispatch(createRevision(project, version, history)),
-    }),
-  ),
+  connect((state, { project, version }) => ({
+    canMakeDecision: canMakeDecision(state, project, version),
+    canMakeRecommendation: canMakeRecommendation(state, project, version),
+    canEditManuscript: canEditManuscript(state, project, version),
+    canOverrideTechChecks: canOverrideTechnicalChecks(state, project),
+  })),
+  withHandlers({
+    goToEdit: ({ history }) => (project, version) => () => {
+      history.push(`/projects/${project.id}/versions/${version.id}/submit`, {
+        editMode: true,
+      })
+    },
+    goToTechnicalCheck: ({ history }) => project => () => {
+      const { status, id, customId, technicalChecks: { token = '' } } = project
+      const stage = status === 'technicalChecks' ? 'eqs' : 'eqa'
+      history.push({
+        pathname: `/${stage}-decision`,
+        search: `?collectionId=${id}&customId=${customId}&token=${token}`,
+      })
+    },
+  }),
 )(SideBarActions)
 
 // #region styled-components
diff --git a/packages/component-manuscript/src/components/SubmitRevision.js b/packages/component-manuscript/src/components/SubmitRevision.js
index a962668fb2bbb1537795e8057505a23526e109ad..afaf7697ebebc111d39a773e01ccf69e594c5e48 100644
--- a/packages/component-manuscript/src/components/SubmitRevision.js
+++ b/packages/component-manuscript/src/components/SubmitRevision.js
@@ -24,6 +24,7 @@ import {
 import { AuthorList, Files } from 'pubsweet-components-faraday/src/components'
 import { submitRevision } from 'pubsweet-component-wizard/src/redux/conversion'
 import AutosaveIndicator from 'pubsweet-component-wizard/src/components/AutosaveIndicator'
+import { selectReviewRecommendations } from 'pubsweet-components-faraday/src/redux/recommendations'
 import {
   toClass,
   compose,
@@ -60,6 +61,7 @@ const SubmitRevision = ({
   removeFile,
   handleSubmit,
   responseFiles,
+  reviews = [],
   submitFailed,
 }) => (
   <Root>
@@ -108,39 +110,41 @@ const SubmitRevision = ({
           />
         </CustomValidatedField>
       </Expandable>
-      <Expandable label="RESPONSE TO REVIEWER COMMENTS" startExpanded>
-        <Title>Reply text*</Title>
-        <Row>
-          <FullWidth className="full-width">
-            <ValidatedField
-              component={TextAreaField}
-              name="commentsToReviewers"
-              validate={
-                isEmpty(get(formValues, 'files.responseToReviewers'))
-                  ? [required]
-                  : []
-              }
-            />
-          </FullWidth>
-        </Row>
-        <Row left>
-          {responseFiles.map(file => (
-            <FileItem
-              compact
-              id={file.id}
-              key={file.id}
-              {...file}
-              removeFile={removeFile}
-            />
-          ))}
-        </Row>
-        <FilePicker
-          allowedFileExtensions={['pdf', 'doc', 'docx']}
-          onUpload={addFile}
-        >
-          <ActionText left={12}>Upload file</ActionText>
-        </FilePicker>
-      </Expandable>
+      {!isEmpty(reviews) && (
+        <Expandable label="RESPONSE TO REVIEWER COMMENTS" startExpanded>
+          <Title>Reply text*</Title>
+          <Row>
+            <FullWidth className="full-width">
+              <ValidatedField
+                component={TextAreaField}
+                name="commentsToReviewers"
+                validate={
+                  isEmpty(get(formValues, 'files.responseToReviewers'))
+                    ? [required]
+                    : []
+                }
+              />
+            </FullWidth>
+          </Row>
+          <Row left>
+            {responseFiles.map(file => (
+              <FileItem
+                compact
+                id={file.id}
+                key={file.id}
+                {...file}
+                removeFile={removeFile}
+              />
+            ))}
+          </Row>
+          <FilePicker
+            allowedFileExtensions={['pdf', 'doc', 'docx']}
+            onUpload={addFile}
+          >
+            <ActionText left={12}>Upload file</ActionText>
+          </FilePicker>
+        </Expandable>
+      )}
       <SubmitContainer>
         {submitFailed &&
           formError && <Error>There are some errors above.</Error>}
@@ -169,8 +173,9 @@ export default compose(
     modalComponent: ConfirmationModal,
   })),
   connect(
-    state => ({
+    (state, { version }) => ({
       fileFetching: getRequestStatus(state),
+      reviews: selectReviewRecommendations(state, version.id),
       formValues: getFormValues('revision')(state),
       formError: getFormSyncErrors('revision')(state),
     }),
diff --git a/packages/component-mts-package/readme.md b/packages/component-mts-package/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..45347c011043112bece9ecd1a88f0fe9bf233775
--- /dev/null
+++ b/packages/component-mts-package/readme.md
@@ -0,0 +1,45 @@
+## MTS service integration
+
+This component is running as a service to integrate current Hindawi Manuscript Tracking System for Editorial Quality Screening and for Editorial Quality Assurance.
+
+### Use-case
+
+As an Editor in Chief, I want the manuscript to go through Editorial Quality Screening before I assign a Handling Editor to it and start the review process.
+
+### Workflow
+
+Stage 1: When an article is submitted, Faraday needs to convert the submission to XML JATS format, and upload as a .zip file to a FTP server.
+
+Stage 2: When new .zip file has been detected on FTP server, then third party system MTS (Manuscript Tracking System - Hindawi) needs to consume package and populate DB records.
+
+Stage 3: When check is completed, then Faraday system needs to be updated to move status from Technical Checks to Submitted - which allows the Editor in Chief to assign a Handling Editor.
+
+
+
+### Configuration
+| Params        | Required           | Description  |
+| ------------- |:-------------:| -----|
+| journalConfig     | Yes | Journal configuration in .xml file as: doctype, dtdVersion, journalTitle, articleType, journal email, journalIdPublisher, issn |
+| xmlParserOptions      | No      |   parsing config options used by xml-js library |
+| s3Config | Yes      |  Access to AWS S3 Bucket where fragment files are saved  |
+| FTPConfig | Yes | FTP server connection credentials |
+
+
+### Usage
+
+MTS service gathers all the fragment files, creates an .xml file in a specific JATS format out of fragment JSON, creates a .zip archive and sends it to a specific FTP server with a configurable package name (also a backup it's uploaded to AWS S3).
+
+.xml structure of Hindawi use-case can be checked `/tests/sample.xml` from generated json  `/tests/sample.json`.
+
+#### Example
+
+```javascript
+const fragment = {} //fragment json here
+const { journalConfig, xmlParser, s3Config, ftpConfig } = config //import your config
+const MTS = new MTSService(journalConfig, xmlParser, s3Config, ftpConfig)
+MTS.sendPackage({ fragment })
+```
+ 
+[GIFs Demo](https://gitlab.coko.foundation/xpub/xpub-faraday/wikis/mts-integration)
+ 
+
diff --git a/packages/component-mts-package/src/MTS.js b/packages/component-mts-package/src/MTS.js
index 0d52a235a9d63630cadd9b88cf5e036aced1e11c..a8a9421139c0beafbf844b974658b8e602822b17 100644
--- a/packages/component-mts-package/src/MTS.js
+++ b/packages/component-mts-package/src/MTS.js
@@ -216,15 +216,19 @@ class MTS {
     return this.convertToXML(this.composeJson(fragment))
   }
 
-  sendPackage(fragment = {}) {
+  sendPackage({ fragment = {}, isEQA = false }) {
     const xmlFile = this.convertFragmentToXML(fragment)
 
     return PackageManager.createFilesPackage(this.s3Config)({
       fragment,
       xmlFile,
+      isEQA,
     }).then(() => {
-      const manuscriptName = get(xmlFile, 'name', '').replace('.xml', '')
-      const filename = `${manuscriptName}.zip`
+      const packageName = get(xmlFile, 'name', '').replace('.xml', '')
+      const filename = isEQA
+        ? `ACCEPTED_${packageName}.zip`
+        : `${packageName}.zip`
+
       return PackageManager.uploadFiles({
         filename,
         s3Config: this.s3Config,
diff --git a/packages/component-mts-package/src/PackageManager.js b/packages/component-mts-package/src/PackageManager.js
index 43d9386c5037e78176ee3a41116fdaf071dfe366..b98dbf10308c84b927b10d3f670b285a1b6ca8b7 100644
--- a/packages/component-mts-package/src/PackageManager.js
+++ b/packages/component-mts-package/src/PackageManager.js
@@ -17,29 +17,29 @@ const createFilesPackage = (s3Config, archiver = nodeArchiver) => {
   })
   const s3 = new AWS.S3()
   const asyncGetObject = promisify(s3.getObject.bind(s3))
-  const asyncListObjects = promisify(s3.listObjects.bind(s3))
 
-  return async ({ fragment, fileTypes, xmlFile }) => {
-    const { id } = fragment
-    const manuscriptName = get(xmlFile, 'name', '').replace('.xml', '')
+  return async ({ fragment, fileTypes, xmlFile, isEQA = false }) => {
+    const { files = {} } = fragment
+    let packageName = get(xmlFile, 'name', '').replace('.xml', '')
+    if (isEQA) {
+      packageName = `ACCEPTED_${packageName}`
+    }
     try {
-      const params = {
-        Bucket: s3Config.bucket,
-        Prefix: `${id}`,
-      }
-      const s3Items = await asyncListObjects(params)
-      if (s3Items) {
+      const s3FileIDs = Object.values(files)
+        .reduce((acc, f) => [...acc, ...f], [])
+        .map(f => f.id)
+
+      if (s3FileIDs) {
         const s3Files = await Promise.all(
-          s3Items.Contents.map(content =>
+          s3FileIDs.map(fileID =>
             asyncGetObject({
               Bucket: s3Config.bucket,
-              Key: content.Key,
+              Key: fileID,
             }),
           ),
         )
-
         if (s3Files) {
-          const packageOutput = fs.createWriteStream(`${manuscriptName}.zip`)
+          const packageOutput = fs.createWriteStream(`${packageName}.zip`)
           const archive = archiver('zip')
 
           archive.pipe(packageOutput)
@@ -53,6 +53,7 @@ const createFilesPackage = (s3Config, archiver = nodeArchiver) => {
           })
 
           archive.on('error', err => {
+            logger.error(err)
             throw err
           })
           archive.on('end', err => {
diff --git a/packages/component-mts-package/tests/MTS.test.js b/packages/component-mts-package/tests/MTS.test.js
index 6655fbe07f3602b353cb89be4371bde679d4ddff..42c67eafd272402699e9be402e3f9d3f1860e0a6 100644
--- a/packages/component-mts-package/tests/MTS.test.js
+++ b/packages/component-mts-package/tests/MTS.test.js
@@ -27,7 +27,7 @@ describe('MTS integration', () => {
   })
 
   it('should contain configured journal name ', () => {
-    const result = MTS.composeJson(mocks.fragment)
+    const result = MTS.composeJson({ fragment: mocks.fragment })
     expect(result).toHaveProperty(
       'article.front.journal-meta.journal-title-group.journal-title._text',
       'Bioinorganic Chemistry and Applications',
diff --git a/packages/component-mts-package/tests/sample.json b/packages/component-mts-package/tests/sample.json
index 21ccc5f10edeed4f9c776ff30bc1bb0fd58e6053..17f672cb1edf947a633dac1beb4818bb08662dbc 100644
--- a/packages/component-mts-package/tests/sample.json
+++ b/packages/component-mts-package/tests/sample.json
@@ -24,12 +24,12 @@
             "_attributes": {
               "journal-id-type": "email"
             },
-            "_text": "trashjo@ariessys.com"
+            "_text": "faraday@hindawi.com"
           }
         ],
         "journal-title-group": {
           "journal-title": {
-            "_text": "Research"
+            "_text": "Bioinorganic Chemistry and Applications"
           }
         },
         "issn": [
@@ -37,7 +37,7 @@
             "_attributes": {
               "pub-type": "ppub"
             },
-            "_text": "0000-000Y"
+            "_text": "2474-7394"
           },
           {
             "_attributes": {
@@ -52,60 +52,28 @@
             "_attributes": {
               "pub-id-type": "publisher-id"
             },
-            "_text": "RESEARCH-D-18-00005"
+            "_text": "RESEARCH-F-3326913"
           },
           {
             "_attributes": {
               "pub-id-type": "manuscript"
             },
-            "_text": "RESEARCH-D-18-00005"
+            "_text": "RESEARCH-F-3326913"
           }
         ],
         "article-categories": {
-          "subj-group": [
-            {
-              "_attributes": {
-                "subj-group-type": "Article Type"
-              },
-              "subject": {
-                "_text": "Research Article"
-              }
-            },
-            {
-              "_attributes": {
-                "subj-group-type": "Category"
-              },
-              "subject": {
-                "_text": "Information science"
-              }
-            },
-            {
-              "_attributes": {
-                "subj-group-type": "Classification"
-              },
-              "subject": {
-                "_text": "Applied sciences and engineering"
-              }
+          "subj-group": {
+            "_attributes": {
+              "subj-group-type": "Article Type"
             },
-            {
-              "_attributes": {
-                "subj-group-type": "Classification"
-              },
-              "subject": {
-                "_text": "Scientific community"
-              }
+            "subject": {
+              "_text": "clinical-study"
             }
-          ]
+          }
         },
         "title-group": {
           "article-title": {
-            "_text": "January 24 sample article with new email trigger in place"
-          },
-          "alt-title": {
-            "_attributes": {
-              "alt-title-type": "running-head"
-            },
-            "_text": "let's hope this works"
+            "_text": "Demo sprint 16 no fun"
           }
         },
         "contrib-group": {
@@ -121,17 +89,17 @@
             },
             "name": {
               "surname": {
-                "_text": "Heckner"
+                "_text": "Raluca"
               },
               "given-names": {
-                "_text": "Hannah"
+                "_text": "Authorescu"
               },
               "prefix": {
-                "_text": "Ms."
+                "_text": "miss"
               }
             },
             "email": {
-              "_text": "hheckner@aaas.org"
+              "_text": "raluca.gramschi+auth@thinslices.com"
             },
             "xref": {
               "_attributes": {
@@ -144,8 +112,9 @@
             "_attributes": {
               "id": "aff1"
             },
-            "country": {
-              "_text": "UNITED STATES"
+            "country": {},
+            "addr-line": {
+              "_text": "Technical University Gheorghe Asachi Iasi"
             }
           }
         },
@@ -155,10 +124,10 @@
               "date-type": "received"
             },
             "day": {
-              "_text": "24"
+              "_text": "3"
             },
             "month": {
-              "_text": "01"
+              "_text": "8"
             },
             "year": {
               "_text": "2018"
@@ -166,78 +135,58 @@
           }
         },
         "abstract": {
-          "p": {
-            "_text": "Abstract\nThis article explains and illustrates the use of LATEX in preparing manuscripts for submission to the American Journal of Physics (AJP). While it is not a comprehensive reference, we hope it will suffice for the needs of most AJP authors."
-          }
+          "_text": "<p>some abstract here</p>"
         },
-        "kwd-group": {
-          "kwd": [
-            {
-              "_text": "manuscript"
+        "funding-group": {}
+      },
+      "files": {
+        "file": [
+          {
+            "item_type": {
+              "_text": "coverLetter"
             },
-            {
-              "_text": "submissions"
+            "item_description": {
+              "_text": "sample cover letter_ms 1.doc"
             },
-            {
-              "_text": "ftp site"
-            }
-          ]
-        },
-        "funding-group": {},
-        "counts": {
-          "fig-count": {
-            "_attributes": {
-              "count": "0"
+            "item_name": {
+              "_text": "sample cover letter_ms 1.doc"
             }
-          }
-        },
-        "custom-meta-group": {
-          "custom-meta": [
-            {
-              "meta-name": {
-                "_text": "Black and White Image Count"
-              },
-              "meta-value": {
-                "_text": "0"
-              }
+          },
+          {
+            "item_type": {
+              "_text": "manuscripts"
             },
-            {
-              "meta-name": {
-                "_text": "Color Image Count"
-              },
-              "meta-value": {
-                "_text": "0"
-              }
+            "item_description": {
+              "_text": "manuscript.pdf"
+            },
+            "item_name": {
+              "_text": "manuscript.pdf"
             }
-          ]
-        }
-      }
-    },
-    "body": {
-      "fig": [
-        {
-          "label": {
-            "_text": "Figure 1"
           },
-          "graphic": {
-            "_attributes": {
-              "xlink:href": "GasBulbData.eps",
-              "xmlns:xlink": "http://www.w3.org/1999/xlink"
+          {
+            "item_type": {
+              "_text": "supplementary"
+            },
+            "item_description": {
+              "_text": "important-emails.md"
+            },
+            "item_name": {
+              "_text": "important-emails.md"
             }
-          }
-        },
-        {
-          "label": {
-            "_text": "Figure 2"
           },
-          "graphic": {
-            "_attributes": {
-              "xlink:href": "ThreeSunsets.jpg",
-              "xmlns:xlink": "http://www.w3.org/1999/xlink"
+          {
+            "item_type": {
+              "_text": "supplementary"
+            },
+            "item_description": {
+              "_text": "important-emails.md"
+            },
+            "item_name": {
+              "_text": "important-emails (1).md"
             }
           }
-        }
-      ]
+        ]
+      }
     }
   }
 }
\ No newline at end of file
diff --git a/packages/component-mts-package/tests/sample.xml b/packages/component-mts-package/tests/sample.xml
index 697e0e64c760dc9f1acdda45ff087c984303906e..d91397fb44989adaffbcc7d597b457138b71b714 100644
--- a/packages/component-mts-package/tests/sample.xml
+++ b/packages/component-mts-package/tests/sample.xml
@@ -4,89 +4,71 @@
   <front>
     <journal-meta>
       <journal-id journal-id-type="publisher">research</journal-id>
-      <journal-id journal-id-type="email">trashjo@ariessys.com</journal-id>
+      <journal-id journal-id-type="email">faraday@hindawi.com</journal-id>
       <journal-title-group>
-        <journal-title>Research</journal-title>
+        <journal-title>Bioinorganic Chemistry and Applications</journal-title>
       </journal-title-group>
-      <issn pub-type="ppub">0000-000Y</issn>
+      <issn pub-type="ppub">2474-7394</issn>
       <issn pub-type="epub"></issn>
     </journal-meta>
     <article-meta>
-      <article-id pub-id-type="publisher-id">RESEARCH-D-18-00005</article-id>
-      <article-id pub-id-type="manuscript">RESEARCH-D-18-00005</article-id>
+      <article-id pub-id-type="publisher-id">RESEARCH-F-3326913</article-id>
+      <article-id pub-id-type="manuscript">RESEARCH-F-3326913</article-id>
       <article-categories>
         <subj-group subj-group-type="Article Type">
-          <subject>Research Article</subject>
-        </subj-group>
-        <subj-group subj-group-type="Category">
-          <subject>Information science</subject>
-        </subj-group>
-        <subj-group subj-group-type="Classification">
-          <subject>Applied sciences and engineering</subject>
-        </subj-group>
-        <subj-group subj-group-type="Classification">
-          <subject>Scientific community</subject>
+          <subject>clinical-study</subject>
         </subj-group>
       </article-categories>
       <title-group>
-        <article-title>January 24 sample article with new email trigger in place</article-title>
-        <alt-title alt-title-type="running-head">let's hope this works</alt-title>
+        <article-title>Demo sprint 16 no fun</article-title>
       </title-group>
       <contrib-group>
         <contrib contrib-type="author" corresp="yes">
-          <role content-type="1" />
+          <role content-type="1"></role>
           <name>
-            <surname>Heckner</surname>
-            <given-names>Hannah</given-names>
-            <prefix>Ms.</prefix>
+            <surname>Raluca</surname>
+            <given-names>Authorescu</given-names>
+            <prefix>miss</prefix>
           </name>
-          <email>hheckner@aaas.org</email>
-          <xref ref-type="aff" rid="aff1" />
+          <email>raluca.gramschi+auth@thinslices.com</email>
+          <xref ref-type="aff" rid="aff1"></xref>
         </contrib>
         <aff id="aff1">
-          <country>UNITED STATES</country>
+          <country></country>
+          <addr-line>Technical University Gheorghe Asachi Iasi</addr-line>
         </aff>
       </contrib-group>
       <history>
         <date date-type="received">
-          <day>24</day>
-          <month>01</month>
+          <day>3</day>
+          <month>8</month>
           <year>2018</year>
         </date>
       </history>
-      <abstract>
-        <p>Abstract
-This article explains and illustrates the use of LATEX in preparing manuscripts for submission to the American Journal of Physics (AJP). While it is not a comprehensive reference, we hope it will suffice for the needs of most AJP authors.</p>
-      </abstract>
-      <kwd-group>
-        <kwd>manuscript</kwd>
-        <kwd>submissions</kwd>
-        <kwd>ftp site</kwd>
-      </kwd-group>
-      <funding-group />
-      <counts>
-        <fig-count count="0" />
-      </counts>
-      <custom-meta-group>
-        <custom-meta>
-          <meta-name>Black and White Image Count</meta-name>
-          <meta-value>0</meta-value>
-        </custom-meta>
-        <custom-meta>
-          <meta-name>Color Image Count</meta-name>
-          <meta-value>0</meta-value>
-        </custom-meta>
-      </custom-meta-group>
+      <abstract>&lt;p&gt;some abstract here&lt;/p&gt;</abstract>
+      <funding-group></funding-group>
     </article-meta>
+    <files>
+      <file>
+        <item_type>coverLetter</item_type>
+        <item_description>sample cover letter_ms 1.doc</item_description>
+        <item_name>sample cover letter_ms 1.doc</item_name>
+      </file>
+      <file>
+        <item_type>manuscripts</item_type>
+        <item_description>manuscript.pdf</item_description>
+        <item_name>manuscript.pdf</item_name>
+      </file>
+      <file>
+        <item_type>supplementary</item_type>
+        <item_description>important-emails.md</item_description>
+        <item_name>important-emails.md</item_name>
+      </file>
+      <file>
+        <item_type>supplementary</item_type>
+        <item_description>important-emails.md</item_description>
+        <item_name>important-emails (1).md</item_name>
+      </file>
+    </files>
   </front>
-  <body>
-    <fig>
-      <label>Figure 1</label>
-      <graphic xlink:href="GasBulbData.eps" xmlns:xlink="http://www.w3.org/1999/xlink" />
-    </fig>
-    <fig>
-      <label>Figure 2</label>
-      <graphic xlink:href="ThreeSunsets.jpg" xmlns:xlink="http://www.w3.org/1999/xlink" />
-    </fig>
-  </body>
 </article>
\ No newline at end of file
diff --git a/packages/component-user-manager/src/routes/fragmentsUsers/emails/emailCopy.js b/packages/component-user-manager/src/routes/fragmentsUsers/emails/emailCopy.js
index d6e87cc86947dee0dd26537455c9ed458a929500..68132122b47e8b66bed920a01a9afcacc16ba8c6 100644
--- a/packages/component-user-manager/src/routes/fragmentsUsers/emails/emailCopy.js
+++ b/packages/component-user-manager/src/routes/fragmentsUsers/emails/emailCopy.js
@@ -1,8 +1,8 @@
 const getEmailCopy = ({ emailType, titleText }) => {
   let paragraph
   switch (emailType) {
-    case 'co-author-added-to-manuscript':
-      paragraph = `You have been added as co-author to ${titleText}. The manuscript will become visible on your dashboard once it's submitted. Please click on the link below to access your dashboard.`
+    case 'author-added-to-manuscript':
+      paragraph = `You have been added as an author to ${titleText}. The manuscript will become visible on your dashboard once it's submitted. Please click on the link below to access your dashboard.`
       break
     case 'new-author-added-to-manuscript':
       paragraph = `You have been added as an author to ${titleText}. In order to gain access to the manuscript, please confirm your account and set your account details by clicking on the link below.`
diff --git a/packages/component-user-manager/src/routes/fragmentsUsers/emails/notifications.js b/packages/component-user-manager/src/routes/fragmentsUsers/emails/notifications.js
index 8ee396d5206c25e20e52c5145938a8242cbde576..9a9281fa22b59b1e76db7dcb8cc8ee00b6170641 100644
--- a/packages/component-user-manager/src/routes/fragmentsUsers/emails/notifications.js
+++ b/packages/component-user-manager/src/routes/fragmentsUsers/emails/notifications.js
@@ -9,16 +9,17 @@ const {
   services,
   Fragment,
 } = require('pubsweet-component-helper-service')
+
 const { getEmailCopy } = require('./emailCopy')
 
 module.exports = {
   async sendNotifications({
     user,
     baseUrl,
-    isSubmitting,
     fragment,
     UserModel,
     collection,
+    reqUser,
   }) {
     const fragmentHelper = new Fragment({ fragment })
     const { title } = await fragmentHelper.getFragmentData({
@@ -33,8 +34,6 @@ module.exports = {
     } ${submittingAuthor.lastName}`
 
     const userHelper = new User({ UserModel })
-    const { firstName, lastName } = await userHelper.getEditorInChief()
-    const eicName = `${firstName} ${lastName}`
     const subjectBaseText = `${collection.customId}: Manuscript`
 
     const email = new Email({
@@ -42,25 +41,34 @@ module.exports = {
       content: {
         ctaLink: baseUrl,
         ctaText: 'VIEW DASHBOARD',
-        signatureName: eicName,
+        signatureName: await userHelper.getEiCName(),
       },
     })
 
-    if (!isSubmitting) {
-      sendCoAuthorEmail({ email, baseUrl, user, titleText, subjectBaseText })
+    if (!user.isConfirmed) {
+      sendNewAuthorEmail({
+        email,
+        user,
+        baseUrl,
+        titleText,
+        subjectBaseText,
+      })
     }
 
-    sendNewAuthorEmail({
-      email,
-      user,
-      baseUrl,
-      titleText,
-      subjectBaseText,
-    })
+    const requestUser = await UserModel.find(reqUser)
+    if (requestUser.id !== user.id) {
+      sendAddedToManuscriptEmail({
+        email,
+        baseUrl,
+        user,
+        titleText,
+        subjectBaseText,
+      })
+    }
   },
 }
 
-const sendCoAuthorEmail = ({
+const sendAddedToManuscriptEmail = ({
   email,
   baseUrl,
   user,
@@ -79,7 +87,7 @@ const sendCoAuthorEmail = ({
 
   const { html, text } = email.getBody({
     body: getEmailCopy({
-      emailType: 'co-author-added-to-manuscript',
+      emailType: 'author-added-to-manuscript',
       titleText,
     }),
   })
@@ -87,13 +95,7 @@ const sendCoAuthorEmail = ({
   email.sendEmail({ html, text })
 }
 
-const sendNewAuthorEmail = ({
-  email,
-  baseUrl,
-  user,
-  titleText,
-  subjectBaseText,
-}) => {
+const sendNewAuthorEmail = ({ email, baseUrl, user, titleText }) => {
   email.toUser = {
     email: user.email,
     name: `${user.firstName} ${user.lastName}`,
diff --git a/packages/component-user-manager/src/routes/fragmentsUsers/post.js b/packages/component-user-manager/src/routes/fragmentsUsers/post.js
index 0d88c22046537c5d3c63bf08c2ac69d7d855e595..fa0b2b2f352cd5a03988d3b537dd86b37cd87370 100644
--- a/packages/component-user-manager/src/routes/fragmentsUsers/post.js
+++ b/packages/component-user-manager/src/routes/fragmentsUsers/post.js
@@ -92,6 +92,15 @@ module.exports = models => async (req, res) => {
       collection.save()
     }
 
+    notifications.sendNotifications({
+      user,
+      baseUrl,
+      fragment,
+      collection,
+      reqUser: req.user,
+      UserModel: models.User,
+    })
+
     return res.status(200).json({
       ...pick(user, authorKeys),
       isSubmitting,
@@ -128,7 +137,6 @@ module.exports = models => async (req, res) => {
         collection,
         user: newUser,
         UserModel: models.User,
-        isSubmitting,
       })
 
       if (!collection.owners.includes(newUser.id)) {
diff --git a/packages/component-wizard/src/components/SubmissionWizard.js b/packages/component-wizard/src/components/SubmissionWizard.js
index 162de41426cb1e4d6ab014aeac2c8e9f6c632031..76ea5eadbacef57a645c6a36255b53b9c7f1ea55 100644
--- a/packages/component-wizard/src/components/SubmissionWizard.js
+++ b/packages/component-wizard/src/components/SubmissionWizard.js
@@ -10,7 +10,13 @@ import { DragDropContext } from 'react-dnd'
 import { Icon, Button } from '@pubsweet/ui'
 import HTML5Backend from 'react-dnd-html5-backend'
 import { selectCollection, selectFragment } from 'xpub-selectors'
-import { withStateHandlers, compose, toClass, withProps } from 'recompose'
+import {
+  withStateHandlers,
+  compose,
+  toClass,
+  withProps,
+  withHandlers,
+} from 'recompose'
 
 import {
   withModal,
@@ -44,9 +50,11 @@ const NewWizard = ({
   step,
   history,
   prevStep,
+  isEditMode,
   isLastStep,
   isFirstStep,
   handleSubmit,
+  getButtonText,
   journal: { manuscriptTypes = [] },
   ...rest
 }) => (
@@ -76,7 +84,7 @@ const NewWizard = ({
             >{`< BACK`}</Button>
           )}
           <Button data-test="submission-next" onClick={handleSubmit} primary>
-            {isLastStep ? `SUBMIT MANUSCRIPT` : `NEXT STEP >`}
+            {getButtonText()}
           </Button>
         </ButtonContainer>
       </Row>
@@ -132,13 +140,22 @@ export default compose(
     },
   ),
   withProps(setInitialValues),
-  withProps(({ formValues, formSyncErrors, submitFailed, step }) => ({
+  withProps(({ formValues, formSyncErrors, submitFailed, step, location }) => ({
     isFirstStep: step === 0,
     isLastStep: step === wizardSteps.length - 1,
     filesError: submitFailed && get(formSyncErrors, 'files', ''),
     authorsError: submitFailed && get(formSyncErrors, 'authors', ''),
     hasConflicts: get(formValues, 'conflicts.hasConflicts', 'no') === 'yes',
+    isEditMode: get(location, 'state.editMode', false),
   })),
+  withHandlers({
+    getButtonText: ({ isLastStep, isEditMode }) => () => {
+      if (isEditMode && isLastStep) {
+        return 'SAVE CHANGES'
+      }
+      return isLastStep ? `SUBMIT MANUSCRIPT` : `NEXT STEP >`
+    },
+  }),
   withModal(() => ({
     modalComponent: ModalWrapper,
   })),
diff --git a/packages/component-wizard/src/components/utils.js b/packages/component-wizard/src/components/utils.js
index 27f14a882079cbb52d613d6f26e4385bc87c0315..eaef4c5aa092b554fae967b24d7755f0f5665ebc 100644
--- a/packages/component-wizard/src/components/utils.js
+++ b/packages/component-wizard/src/components/utils.js
@@ -82,6 +82,7 @@ export const onSubmit = (
     nextStep,
     showModal,
     hideModal,
+    isEditMode,
     setModalError,
     autosaveRequest,
     autosaveSuccess,
@@ -93,7 +94,7 @@ export const onSubmit = (
 ) => {
   if (step !== 2) {
     nextStep()
-  } else {
+  } else if (!isEditMode) {
     showModal({
       title:
         'By submitting the manuscript you agree to the following statements:',
@@ -119,5 +120,7 @@ export const onSubmit = (
       },
       onCancel: hideModal,
     })
+  } else {
+    history.goBack()
   }
 }
diff --git a/packages/components-faraday/src/components/Dashboard/DashboardCard.js b/packages/components-faraday/src/components/Dashboard/DashboardCard.js
index 2d6ec271f17846f5956c043627d6a5302b8235cf..d0b8f03d47f45aa1f8a155754152933b970757a5 100644
--- a/packages/components-faraday/src/components/Dashboard/DashboardCard.js
+++ b/packages/components-faraday/src/components/Dashboard/DashboardCard.js
@@ -66,6 +66,7 @@ const DashboardCard = ({
                   collectionId={project.id}
                   fragmentId={version.id}
                   modalKey={`decide-${version.id}`}
+                  status={project.status}
                 />
               )}
               {canMakeRecommendation && (
diff --git a/packages/components-faraday/src/components/MakeDecision/Decision.js b/packages/components-faraday/src/components/MakeDecision/Decision.js
index cf4279e1615dc66ec08c8deb6cd8fab98ca16207..be2b86e66f15032614dea4d9d832b43823d13bc0 100644
--- a/packages/components-faraday/src/components/MakeDecision/Decision.js
+++ b/packages/components-faraday/src/components/MakeDecision/Decision.js
@@ -1,17 +1,21 @@
 import React from 'react'
 import { th } from '@pubsweet/ui'
+import { connect } from 'react-redux'
 import styled from 'styled-components'
-import { compose, withHandlers, setDisplayName } from 'recompose'
+import { actions } from 'pubsweet-client'
+import { compose, withHandlers, setDisplayName, withProps } from 'recompose'
 
 import {
   ConfirmationModal,
   withModal,
 } from 'pubsweet-component-modal/src/components'
+import { handleError } from '../utils'
+import { createRecommendation } from '../../redux/recommendations'
 
 import { DecisionForm } from './'
 
-const Decision = ({ showDecisionModal }) => (
-  <Root onClick={showDecisionModal}>Make decision</Root>
+const Decision = ({ showDecisionModal, buttonText }) => (
+  <Root onClick={showDecisionModal}>{buttonText}</Root>
 )
 
 const ModalComponent = ({ type, ...rest }) => {
@@ -28,19 +32,55 @@ export default compose(
   withModal(() => ({
     modalComponent: ModalComponent,
   })),
+  connect(null, {
+    createRecommendation,
+    getFragments: actions.getFragments,
+    getCollections: actions.getCollections,
+  }),
+  withProps(({ status }) => ({
+    buttonText: status === 'submitted' ? 'Reject' : 'Make Decision',
+  })),
   withHandlers({
     showDecisionModal: ({
+      status,
       showModal,
       hideModal,
       fragmentId,
       collectionId,
+      getFragments,
+      setModalError,
+      getCollections,
+      createRecommendation,
     }) => () => {
-      showModal({
-        type: 'decision',
-        hideModal,
-        fragmentId,
-        collectionId,
-      })
+      status !== 'submitted'
+        ? showModal({
+            type: 'decision',
+            hideModal,
+            fragmentId,
+            collectionId,
+          })
+        : showModal({
+            hideModal,
+            fragmentId,
+            collectionId,
+            title: 'Reject Manuscript?',
+            confirmText: 'Reject',
+            onConfirm: () => {
+              const recommendation = {
+                recommendation: 'reject',
+                recommendationType: 'editorRecommendation',
+              }
+              createRecommendation(
+                collectionId,
+                fragmentId,
+                recommendation,
+              ).then(() => {
+                getCollections()
+                getFragments()
+                hideModal()
+              }, handleError(setModalError))
+            },
+          })
     },
   }),
 )(Decision)
diff --git a/packages/components-faraday/src/components/MakeDecision/DecisionForm.js b/packages/components-faraday/src/components/MakeDecision/DecisionForm.js
index 0a53c9423317ac06571ebf6470b6ee16b957fb0f..3fab58f21c15bcdd312cc0fa0f8df64ef928350e 100644
--- a/packages/components-faraday/src/components/MakeDecision/DecisionForm.js
+++ b/packages/components-faraday/src/components/MakeDecision/DecisionForm.js
@@ -27,7 +27,6 @@ const {
 const Form = RootContainer.withComponent(FormContainer)
 
 const DecisionForm = ({
-  aHERec,
   decision,
   hideModal,
   handleSubmit,
diff --git a/packages/components-faraday/src/components/MakeRecommendation/RecommendWizard.js b/packages/components-faraday/src/components/MakeRecommendation/RecommendWizard.js
index fb7452baf0ba87d8e6d3edb530511df05a9a4bfa..6ad740fde0799055cbc4a8684935b0e37e8b2511 100644
--- a/packages/components-faraday/src/components/MakeRecommendation/RecommendWizard.js
+++ b/packages/components-faraday/src/components/MakeRecommendation/RecommendWizard.js
@@ -9,7 +9,10 @@ import { getFormValues, reset as resetForm } from 'redux-form'
 
 import { FormItems } from '../UIComponents'
 import { StepOne, StepTwo, utils } from './'
-import { createRecommendation } from '../../redux/recommendations'
+import {
+  createRecommendation,
+  selectReviewRecommendations,
+} from '../../redux/recommendations'
 
 const RecommendWizard = ({
   step,
@@ -40,8 +43,9 @@ const RecommendWizard = ({
 
 export default compose(
   connect(
-    state => ({
+    (state, { fragmentId }) => ({
       decision: get(getFormValues('recommendation')(state), 'decision'),
+      reviews: selectReviewRecommendations(state, fragmentId),
     }),
     {
       resetForm,
diff --git a/packages/components-faraday/src/components/MakeRecommendation/Recommendation.js b/packages/components-faraday/src/components/MakeRecommendation/Recommendation.js
index 10d7fc6d98a6a1f1ce932aa5b6622015eee59530..dff35cbd4f9388814ac47cb005a418462845e9a5 100644
--- a/packages/components-faraday/src/components/MakeRecommendation/Recommendation.js
+++ b/packages/components-faraday/src/components/MakeRecommendation/Recommendation.js
@@ -30,12 +30,14 @@ export default compose(
   })),
   withHandlers({
     showFirstStep: ({
+      status,
       showModal,
       hideModal,
       fragmentId,
       collectionId,
     }) => () => {
       showModal({
+        status,
         hideModal,
         fragmentId,
         collectionId,
diff --git a/packages/components-faraday/src/components/MakeRecommendation/StepOne.js b/packages/components-faraday/src/components/MakeRecommendation/StepOne.js
index 6185a09a1677c060032875ce80ebf83c4e1139be..1cb644c274d3bf7732c58e245090397fa33f2da6 100644
--- a/packages/components-faraday/src/components/MakeRecommendation/StepOne.js
+++ b/packages/components-faraday/src/components/MakeRecommendation/StepOne.js
@@ -1,5 +1,6 @@
 import React from 'react'
 import { reduxForm } from 'redux-form'
+import { isEmpty } from 'lodash'
 import { RadioGroup, ValidatedField, Button } from '@pubsweet/ui'
 
 import { utils } from './'
@@ -7,7 +8,7 @@ import { FormItems } from '../UIComponents'
 
 const { Row, Title, RowItem, RootContainer, CustomRadioGroup } = FormItems
 
-const StepOne = ({ hideModal, disabled, onSubmit }) => (
+const StepOne = ({ hideModal, disabled, onSubmit, reviews }) => (
   <RootContainer>
     <Title>Recommendation for Next Phase</Title>
     <Row>
@@ -20,7 +21,11 @@ const StepOne = ({ hideModal, disabled, onSubmit }) => (
             >
               <RadioGroup
                 name="decision"
-                options={utils.recommendationOptions}
+                options={
+                  !isEmpty(reviews)
+                    ? utils.recommendationOptions
+                    : utils.recommendationOptions.slice(1)
+                }
                 {...input}
               />
             </CustomRadioGroup>
diff --git a/packages/components-faraday/src/components/MakeRecommendation/utils.js b/packages/components-faraday/src/components/MakeRecommendation/utils.js
index 2884cdb904717cfdd4958cc99accf9f852adc489..69e5b63f12e4b979dba34332a98fa8bec20eed17 100644
--- a/packages/components-faraday/src/components/MakeRecommendation/utils.js
+++ b/packages/components-faraday/src/components/MakeRecommendation/utils.js
@@ -1,8 +1,8 @@
 import { omit } from 'lodash'
 
 export const recommendationOptions = [
-  { value: 'reject', label: 'Reject' },
   { value: 'publish', label: 'Publish' },
+  { value: 'reject', label: 'Reject' },
   { value: 'revise', label: 'Request revision' },
 ]
 
diff --git a/packages/components-faraday/src/components/SignUp/utils.js b/packages/components-faraday/src/components/SignUp/utils.js
index ae98c93c7df0b2d169affe222f81c2c79f412311..c5564bfe044faa2d7903253efb4ac688082567d5 100644
--- a/packages/components-faraday/src/components/SignUp/utils.js
+++ b/packages/components-faraday/src/components/SignUp/utils.js
@@ -15,6 +15,7 @@ const generatePasswordHash = () =>
 export const parseSignupAuthor = ({ token, confirmPassword, ...values }) => ({
   ...values,
   admin: false,
+  isActive: true,
   isConfirmed: false,
   editorInChief: false,
   handlingEditor: false,
diff --git a/packages/components-faraday/src/components/UIComponents/EQADecisionPage.js b/packages/components-faraday/src/components/UIComponents/EQADecisionPage.js
new file mode 100644
index 0000000000000000000000000000000000000000..c1fb89f349ec68b04e977988e1e0bfea9a5fda79
--- /dev/null
+++ b/packages/components-faraday/src/components/UIComponents/EQADecisionPage.js
@@ -0,0 +1,231 @@
+import React from 'react'
+import { isEmpty } from 'lodash'
+import { connect } from 'react-redux'
+import { Button } from '@pubsweet/ui'
+import styled from 'styled-components'
+import { th } from '@pubsweet/ui-toolkit'
+import {
+  compose,
+  withState,
+  lifecycle,
+  withHandlers,
+  setDisplayName,
+} from 'recompose'
+
+import {
+  withModal,
+  ConfirmationModal,
+} from 'pubsweet-component-modal/src/components'
+
+import { Err, Subtitle } from './FormItems'
+import { parseSearchParams } from '../utils'
+import {
+  technicalDecision,
+  technicalCheckFetching,
+} from '../../redux/technicalCheck'
+
+const EQADecisionPage = ({
+  params,
+  showEQAModal,
+  errorMessage,
+  successMessage,
+}) => (
+  <Root>
+    <Title>
+      Take a decision for manuscript <b>{params.customId}</b>.
+    </Title>
+    {errorMessage && <Err>{errorMessage}</Err>}
+    {successMessage && <Subtitle>{successMessage}</Subtitle>}
+    {isEmpty(errorMessage) &&
+      isEmpty(successMessage) && (
+        <ButtonContainer>
+          <Button onClick={showEQAModal(false)}>RETURN TO EiC</Button>
+          <Button onClick={showEQAModal(true)} primary>
+            ACCEPT
+          </Button>
+        </ButtonContainer>
+      )}
+  </Root>
+)
+
+const DeclineModal = compose(
+  withState('reason', 'setReason', ''),
+  withHandlers({
+    changeReason: ({ setReason }) => e => {
+      setReason(e.target.value)
+    },
+  }),
+)(({ reason, changeReason, hideModal, onConfirm, modalError }) => (
+  <DeclineRoot>
+    <span>Return Manuscript to Editor in Chief</span>
+    <textarea
+      onChange={changeReason}
+      placeholder="Return reason*"
+      value={reason}
+    />
+    {modalError && <ErrorMessage>{modalError}</ErrorMessage>}
+    <ButtonContainer data-test="eqa-buttons">
+      <Button onClick={hideModal}>Cancel</Button>
+      <Button disabled={!reason} onClick={onConfirm(reason)} primary>
+        Send
+      </Button>
+    </ButtonContainer>
+  </DeclineRoot>
+))
+
+const ModalComponent = ({ type, ...rest }) =>
+  type === 'decline' ? (
+    <DeclineModal {...rest} />
+  ) : (
+    <ConfirmationModal {...rest} />
+  )
+
+export default compose(
+  setDisplayName('EQA Decision page'),
+  connect(
+    state => ({
+      isFetching: technicalCheckFetching(state),
+    }),
+    { technicalDecision },
+  ),
+  withModal(({ isFetching }) => ({
+    isFetching,
+    modalComponent: ModalComponent,
+  })),
+  withState('params', 'setParams', {
+    token: null,
+    customId: null,
+    collectionId: null,
+  }),
+  withState('successMessage', 'setSuccess', ''),
+  lifecycle({
+    componentDidMount() {
+      const { location, setParams } = this.props
+      const { customId, collectionId, token } = parseSearchParams(
+        location.search,
+      )
+      setParams({ customId, collectionId, token })
+    },
+  }),
+  withHandlers({
+    showEQAModal: ({
+      showModal,
+      hideModal,
+      setSuccess,
+      setModalError,
+      technicalDecision,
+      params: { collectionId, token },
+    }) => decision => () => {
+      const acceptConfig = {
+        title: `Are you sure you want to accept this EQA package?`,
+        onConfirm: () => {
+          technicalDecision({
+            step: 'eqa',
+            agree: decision,
+            collectionId,
+            token,
+          }).then(() => {
+            setSuccess(
+              `Manuscript accepted. Thank you for your technical check!`,
+            )
+            hideModal()
+          }, setModalError)
+        },
+        onCancel: hideModal,
+      }
+      const declineConfig = {
+        type: 'decline',
+        title: 'Return Manuscript to Editor in Chief',
+        onConfirm: reason => () => {
+          technicalDecision({
+            step: 'eqa',
+            agree: decision,
+            comments: reason,
+            collectionId,
+            token,
+          }).then(() => {
+            setSuccess(
+              `Manuscript returned with comments. An email has been sent to Editor In Chief. Thank you for your technical check!`,
+            )
+            hideModal()
+          }, setModalError)
+        },
+      }
+
+      const cfg = decision ? acceptConfig : declineConfig
+      showModal(cfg)
+    },
+  }),
+)(EQADecisionPage)
+
+// #region styles
+const Root = styled.div`
+  align-items: center;
+  color: ${th('colorText')};
+  display: flex;
+  flex-direction: column;
+  justify-content: flex-start;
+  margin: 0 auto;
+  text-align: center;
+  width: 70vw;
+
+  a {
+    color: ${th('colorText')};
+  }
+`
+
+const Title = styled.div`
+  color: ${th('colorPrimary')};
+  font-size: ${th('fontSizeHeading5')};
+  font-family: ${th('fontHeading')};
+  margin: 10px auto;
+`
+
+const ButtonContainer = styled.div`
+  align-items: center;
+  display: flex;
+  justify-content: space-around;
+  padding: calc(${th('gridUnit')} / 2);
+  width: calc(${th('gridUnit')} * 15);
+`
+const ErrorMessage = styled.div`
+  color: ${th('colorError')};
+  margin: ${th('subGridUnit')};
+  text-align: center;
+`
+const DeclineRoot = styled.div`
+  align-items: center;
+  background-color: ${th('backgroundColor')};
+  display: flex;
+  flex-direction: column;
+  height: calc(${th('gridUnit')} * 13);
+  justify-content: space-between;
+  padding: calc(${th('subGridUnit')} * 7);
+  width: calc(${th('gridUnit')} * 24);
+
+  & span {
+    color: ${th('colorPrimary')};
+    font-size: ${th('fontSizeHeading5')};
+    font-family: ${th('fontHeading')};
+    margin-bottom: ${th('gridUnit')};
+  }
+
+  & textarea {
+    height: 100%;
+    padding: calc(${th('subGridUnit')} * 2);
+    width: 100%;
+  }
+
+  & textarea:focus,
+  & textarea:active {
+    outline: none;
+  }
+
+  & div {
+    display: flex;
+    justify-content: space-evenly;
+    margin: ${th('gridUnit')} auto 0;
+    width: 100%;
+  }
+`
+// #endregion
diff --git a/packages/components-faraday/src/components/UIComponents/EQSDecisionPage.js b/packages/components-faraday/src/components/UIComponents/EQSDecisionPage.js
index 6aaa02bb30d2245e08ac88c503cbc111651d7c63..165361b6ff2853f62f96dbb9082870a66ed87781 100644
--- a/packages/components-faraday/src/components/UIComponents/EQSDecisionPage.js
+++ b/packages/components-faraday/src/components/UIComponents/EQSDecisionPage.js
@@ -21,7 +21,7 @@ import { Err, Subtitle } from './FormItems'
 import { parseSearchParams } from '../utils'
 import {
   technicalDecision,
-  technicalCheckFetcing,
+  technicalCheckFetching,
 } from '../../redux/technicalCheck'
 
 const EQSDecisionPage = ({
@@ -52,7 +52,7 @@ export default compose(
   setDisplayName('EQS Decision page'),
   connect(
     state => ({
-      isFetching: technicalCheckFetcing(state),
+      isFetching: technicalCheckFetching(state),
     }),
     { technicalDecision },
   ),
diff --git a/packages/components-faraday/src/components/UIComponents/index.js b/packages/components-faraday/src/components/UIComponents/index.js
index a619f97e10cfcf1546e5428b5773ed6e6530e336..ff001b8fb3a18548136a1a88e64816e3cde7a4b8 100644
--- a/packages/components-faraday/src/components/UIComponents/index.js
+++ b/packages/components-faraday/src/components/UIComponents/index.js
@@ -8,5 +8,6 @@ export { default as InfoPage } from './InfoPage'
 export { default as ErrorPage } from './ErrorPage'
 export { default as DateParser } from './DateParser'
 export { default as EQSDecisionPage } from './EQSDecisionPage'
+export { default as EQADecisionPage } from './EQADecisionPage'
 export { default as ConfirmationPage } from './ConfirmationPage'
 export { default as BreadcrumbsHeader } from './BreadcrumbsHeader'
diff --git a/packages/components-faraday/src/redux/technicalCheck.js b/packages/components-faraday/src/redux/technicalCheck.js
index 8cb3a074bf9eed5220f56f7f476a7510cda8dc57..5c8d7b9c2e5125ecfa487aab80cab12234a3c361 100644
--- a/packages/components-faraday/src/redux/technicalCheck.js
+++ b/packages/components-faraday/src/redux/technicalCheck.js
@@ -22,6 +22,7 @@ export const technicalDecision = ({
   step,
   agree,
   token,
+  comments,
   collectionId,
 }) => dispatch => {
   dispatch(decisionRequest())
@@ -29,19 +30,25 @@ export const technicalDecision = ({
     step,
     token,
     agree,
+    comments,
   }).then(
     r => {
       dispatch(decisionSuccess())
       return r
     },
     err => {
-      dispatch(decisionError(err))
-      throw err
+      const errorMessage = get(
+        JSON.parse(err.response),
+        'error',
+        'Oops! Something went wrong!',
+      )
+      dispatch(decisionError(errorMessage))
+      throw errorMessage
     },
   )
 }
 
-export const technicalCheckFetcing = state =>
+export const technicalCheckFetching = state =>
   get(state, 'technicalCheck.fetching', false)
 
 export default (state = {}, action = {}) => {
diff --git a/packages/xpub-faraday/app/index.html b/packages/xpub-faraday/app/index.html
index fe975b733e9074fe352d024bee816dc961bf195d..9dfcd619060052a1bd0709f36fcd48e52c1e0e1a 100644
--- a/packages/xpub-faraday/app/index.html
+++ b/packages/xpub-faraday/app/index.html
@@ -6,6 +6,6 @@
 </head>
 <body style="margin: 0;">
   <div id="root"></div>
-  <script src="/assets/app.js"></script>
+  <script type="text/javascript" src="/assets/app.js"></script>
 </body>
 </html>
diff --git a/packages/xpub-faraday/app/routes.js b/packages/xpub-faraday/app/routes.js
index 05e3106ebac869d37c6b1401cf8764def29ab516..e3cb4ba8b9a232317471c34f98ac6f73b3ce92cd 100644
--- a/packages/xpub-faraday/app/routes.js
+++ b/packages/xpub-faraday/app/routes.js
@@ -16,6 +16,7 @@ import {
   InfoPage,
   ErrorPage,
   EQSDecisionPage,
+  EQADecisionPage,
   ConfirmationPage,
 } from 'pubsweet-components-faraday/src/components/UIComponents/'
 import {
@@ -120,6 +121,7 @@ const Routes = () => (
         path="/projects/:project/versions/:version/details"
       />
       <Route component={EQSDecisionPage} exact path="/eqs-decision" />
+      <Route component={EQADecisionPage} exact path="/eqa-decision" />
       <Route component={ErrorPage} exact path="/error-page" />
       <Route component={InfoPage} exact path="/info-page" />
       <Route component={NotFound} />
diff --git a/packages/xpub-faraday/config/default.js b/packages/xpub-faraday/config/default.js
index 0e8568e0dc11ee83148a032d079c88617345c49a..819278c83b59ebec49ad8628363421503c649948 100644
--- a/packages/xpub-faraday/config/default.js
+++ b/packages/xpub-faraday/config/default.js
@@ -46,7 +46,7 @@ module.exports = {
     API_ENDPOINT: '/api',
     baseUrl: process.env.CLIENT_BASE_URL || 'http://localhost:3000',
     'login-redirect': '/',
-    'redux-log': process.env.NODE_ENV === 'development',
+    'redux-log': process.env.NODE_ENV !== 'production',
     theme: process.env.PUBSWEET_THEME,
   },
   orcid: {
@@ -97,6 +97,9 @@ module.exports = {
   'eqs-decision': {
     url: process.env.PUBSWEET_EQS_DECISION || '/eqs-decision',
   },
+  'eqa-decision': {
+    url: process.env.PUBSWEET_EQA_DECISION || '/eqa-decision',
+  },
   unsubscribe: {
     url: process.env.PUBSWEET_UNSUBSCRIBE_URL || '/unsubscribe',
   },
@@ -110,9 +113,14 @@ module.exports = {
     },
   },
   mailer: {
-    from: 'faraday@hindawi.com',
+    from: 'hindawi@thinslices.com',
     path: `${__dirname}/mailer`,
-    editorialAssistant: 'hindawi@thinslices.com',
+    editorialAssistant: 'hindawi+editorial@thinslices.com',
+  },
+  SES: {
+    accessKey: process.env.AWS_SES_ACCESS_KEY,
+    secretKey: process.env.AWS_SES_SECRET_KEY,
+    region: process.env.AWS_SES_REGION,
   },
   publicKeys: ['pubsweet-client', 'authsome', 'validations'],
   statuses: {
diff --git a/packages/xpub-faraday/config/production.js b/packages/xpub-faraday/config/production.js
new file mode 100644
index 0000000000000000000000000000000000000000..9950c9b354fa8710a4f043a07ac2b86a3cf6bd2f
--- /dev/null
+++ b/packages/xpub-faraday/config/production.js
@@ -0,0 +1,3 @@
+const defaultConfig = require('xpub-faraday/config/default')
+
+module.exports = defaultConfig
diff --git a/packages/xpub-faraday/config/validations.js b/packages/xpub-faraday/config/validations.js
index 4a96afcddc925807a78fa9495b8be0aa53aedec8..25f2501d38bb6ffaa7619b683bcb3825e28e0883 100644
--- a/packages/xpub-faraday/config/validations.js
+++ b/packages/xpub-faraday/config/validations.js
@@ -13,6 +13,7 @@ module.exports = {
     handlingEditor: Joi.object(),
     technicalChecks: Joi.object({
       token: Joi.string(),
+      hasEQA: Joi.boolean(),
     }),
   },
   fragment: [