Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

Table of Contents

...

GraphQL

Purpose

This WS is designed to assign pair of master_person_id and person_id to a reviewer.

Statements 

...

Table of Contents

Purpose

This WS is designed to assign pair of master_person_id and person_id to a reviewer.


Specification

Page Properties
idAPI_Specification

Link

API paragraph not found

Resource

API paragraph not found

Scope

merge_candidate:assign

Components

API paragraph not found

Microservices

API paragraph not found

Protocol type

API paragraph not found

Request type

API paragraph not found

Sync/Async

API paragraph not found

Public/Private/Internal

Private

GraphQL schema
Expand
titleRequest example
Code Block
"""
Methods to use when ordering `Merge Request`.
"""
enum MergeRequestOrderBy {
  "Sort Person by inserted at in ascending order."
  INSERTED_AT_ASC
  "Sort Person by inserted at in descending order."
  INSERTED_AT_DESC
  "Sort Person by birth date in ascending order."
  STATUS_ASC
  "Sort Person by birth date in descending order."
  STATUS_DESC
}

"""
A connection to a list of `MergeRequest` values.
"""
type MergeRequestConnection {
  "Information to aid in pagination."
  pageInfo: PageInfo!
  "Flag which shows whether NEW merge candidate can be assigned to the User"
  canAssignNew: Boolean!
  "A list of nodes."
  nodes: [MergeRequest]
  "A list of edges."
  edges: [MergeRequestEdge]
}

"""
Reads and enables pagination through a set of `MergeRequest`.
"""
type MergeRequestEdge {
  "The item at the end of the edge."
  node: MergeRequest!
  "A cursor for use in pagination."
  cursor: String!
}

"""
Return type for `assignMergeCandidate` mutation.
"""
type AssignMergeCandidatePayload {
  "Information of pair of persons which can be same."
  mergeRequest: MergeRequest!
}

"""
Input for `updateMergeRequest` mutation.
In order to update status user must have a scope `merge_request:write`
"""
input UpdateMergeRequestInput {
  "Primary key identifier from the database"
  id: ID!
  "next status of merge request"
  status: MergeRequestStatus!
  "comment which user can leave"
  comment: String
}

"""
Return type for `updateMergeRequest` mutation.
"""
type UpdateMergeRequestPayload {
  "Information of pair of persons which can be same."
  mergeRequest: MergeRequest!
}

"""
This is Merge Request details. In order to obtain details user must have a scope **merge_request:read**
"""
type MergeRequest implements Node {
  "The ID of an object"
  id: ID!
  "Primary key identifier from the database"
  databaseId: UUID!
  "The pair of persons which is considerated to be the same person"
  manualMergeCandidate: ManualMergeCandidate!
  "status of merge request"
  status: MergeRequestStatus!
  "comment which user can leave"
  comment: String
  "Technical information when the patient was inserted into the DB."
  insertedAt: DateTime!
  "Technical information when the patient was updated in the DB."
  updatedAt: DateTime!
}

"""
List of MergeRequest statuses.
"""
enum MergeRequestStatus {
  "Status `MERGE` for a merge request"
  MERGE
  "Status `NEW` for a merge request"
  NEW
  "Status `POSTPONE` for a merge request"
  POSTPONE
  "Status `SPLIT` for a merge request"
  SPLIT
  "Status `TRASH` for a merge request"
  TRASH
}

"""
Information about Manual Merge Candidate.
"""
type ManualMergeCandidate {
  "The ID of an object"
  id: ID!
  "Primary key identifier from the database"
  databaseId: UUID!
  "The pair of persons which is considerated to be the same person"
  mergeCandidate: MergeCandidate!
  "status of merge candidate"
  status: ManualMergeCandidateStatus
  "Technical information when the patient was inserted into the DB."
  insertedAt: DateTime!
  "Technical information when the patient was updated in the DB."
  updatedAt: DateTime!
}

"""
Information about Merge Candidate.
"""
type MergeCandidate {
  "The ID of an object"
  id: ID!
  "Primary key identifier from the database"
  databaseId: UUID!
  "The person wich will be deactivated"
  person: Person!
  "The person wich will remain"
  masterPerson: Person!
}

"""
List of Merge candidate statuses
"""
enum ManualMergeCandidateStatus {
  "Status `NEW` for a merge request"
  NEW
  "Status `PROCESSED` for a merge request"
  PROCESSED
}

Logic

  1. One assignee can have only one merge_request in status 'NEW'

  2. One assignee can't have more than max_postponed_value marge_requests in status 'POSTPONED'

  3. If assignee reach postponed_requests_limit, new merge_request can't be assigned to him

  4. Assignee can't assign same merge_request more than once

  5. Assignee can postpone merge request

  6. Until assignee won't make final decision, assignee can't be change for merge_request

Authorize

    1. Verify the validity of access token

      1. in case of error return 401 ('Access denied')

    2. Check user scope merge_candidate:assign in order to perform this action

      1. in case of error generate 401 response ('Invalid scopes')

Headers

API paragraph not found

Request data validation

Verify role

Extract from token:

  1. Validate client_id (is_blocked=false)

    1. in case of error return 403 Error ('Client is blocked')

  2. Check user_roles by client_id 

    1. check whether exist role NHS_REVIEWER 

      1. in case of error return 403 Error ('User doesn't have required role')

Identify User 

Knowing token and client find user_id from mithril.users

Fetch manual_merge_candidate

From table manual_merge_candidate find:

  1. Record in status = 'NEW'

  2. Assignee_id=null

  3. Priority by records which already has some decisions 

    1. join table  manual_merge_requests

...

    1. on manual_merge_requests.merge_candidate_id=manual_merge_candidates.merge_candidate_id

...

    1. and manual_merge_requests.assignee_id<>$user_id

    2. choose manual_merge_requests.merge_candidate_id  order by

...

    1.  count()

...

    1.  DESC

  1. manual_merge_candidate must satisfy constraint: merge_candidate_id+assignee_id in table manual_merge_requests

Validate request

  1. Check whether this user doesn't have other merge_requests in status='NEW'

    1. check manual_merge_requests by assignee_id=$user_id and status='NEW'

      1. in case of error return conflict error 'CONFLICT' - 'Assignee is not allowed to ask for new merge request'

  2. Check amount of postponed merge_requests for current employee_id

    1. check qty from manual_merge_requests by assignee_id=$user_id and status='POSTPONED'

      1. in case of qty<postponed_requests_limit return conflict error 'CONFLICT' - 'Assignee reached limit in postponed merge_requests'

  3. Check there is no record for merge_candidate_id+assignee

...

  1. _

...

  1. in case of such record exists return conflict error 'CONFLICT' - 'Assignee can review merge_request only once'

...

  1. id  and whether merge_candidate_id can be reviewed

...

    1. verify merge_candidate_id has status NEW and assignee_id is null in table manual_merge_candidates

...

    1. in table manual_merge_requests shouldn't be a record with condition merge_candidate_id+$user_id

      1. in case there is no merge candidate in status NEW which wasn't verified by $user_id return 204 No content

Processing

Update assignee for merge_candidate

  1. Update assignee_id in manual_merge_candidates  to $user_id

  2. Update updated_at = now()

  3. Update updated_at = $user_id

manual_merge_candidates

Field 

Value

assignee_id

$user_id

updated_at

now()

updated_at$user_id

Make merge_request for assignee

Insert into table manual_merge_requests a record

column

value

id

UUID

merge_candidate_id

$merge_candidate_id

assignee_id

$user_id

inserted_at

now()

updated_at

now()

status

NEW

comment

null

Add a record to audit log

After status was changed  add new record to audit_log

field

value

id

generate UUID

actor_id

$user_id

resource

'manual_merge_process'

resource_id

$manual_merge_process.id

changeset

{status:NEW}

inserted_at

DATETIME

Response structure

API paragraph not found

Post-processing processes

API paragraph not found

HTTP status codes

API paragraph not found