generated from 8iq/nodejs-hackathon-boilerplate-starter-kit
-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(condo): DOMA-8408 ticket auto assignment by classifiers (#4435)
* feat(condo): DOMA-8408 added aut assingned * test(condo): DOMA-8404 added tests * feat(condo): DOMA-8404 updated gql. Added translations * refactor(condo): DOMA-8404 refactored naming * feat(condo): DOMA-8404 updated AutoAssigner * chore(condo): DOMA-8404 updated schema * feat(condo): DOMA-8404 added migrations * feat(condo): DOMA-8404 added page for configure of ticket auto assignment * fix(condo): DOMA-8404 fixed refetch of useAllObjects * feat(condo): DOMA-8404 updated direct access config (add schema TicketAutoAssignment) * feat(condo): DOMA-8404 updated migrations * feat(condo): DOMA-8404 updated schema * feat(condo): DOMA-8404 updated migrations after rebase * feat(condo): DOMA-8404 added translations * fix(condo): DOMA-8404 fixed code-style * refactor(condo): DOMA-8404 refactored code * chore(condo): DOMA-8404 uodated docs * refactor(condo): DOMA-8404 refactored code * fix(condo): DOMA-8408 fixed translations * fix(condo): DOMA-8408 fixed AutoAssigner logic * chore(condo): DOMA-8408 changed columns order * feat(condo): DOMA-8408 updated page for managing of TicketAutoAssignment * chore(condo): DOMA-8404 updated migrations * fix(condo): DOMA-8408 fixed translations * fix(condo): DOMA-8637 changed fetchPolicy when get TicketAutoAssignment * fix(condo): DOMA-8637 changed fetchPolicy when get TicketAutoAssignment * fix(condo): DOMA-8636 fixed table with TicketAutoAssignment if no data * chore(condo): DOMA-8408 updated migrations after rebase
- Loading branch information
Showing
20 changed files
with
2,455 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/** | ||
* Generated by `createschema ticket.TicketAutoAssignment 'assignee:Relationship:OrganizationEmployee:SET_NULL;executor:Relationship:OrganizationEmployee:SET_NULL;classifier:Relationship:TicketClassifier:CASCADE;'` | ||
*/ | ||
|
||
const { throwAuthenticationError } = require('@open-condo/keystone/apolloErrorFormatter') | ||
|
||
const { | ||
queryOrganizationEmployeeFor, | ||
queryOrganizationEmployeeFromRelatedOrganizationFor, | ||
} = require('@condo/domains/organization/utils/accessSchema') | ||
const { STAFF } = require('@condo/domains/user/constants/common') | ||
const { canDirectlyReadSchemaObjects, canDirectlyManageSchemaObjects } = require('@condo/domains/user/utils/directAccess') | ||
|
||
|
||
/** | ||
* TicketAutoAssignment can be read by | ||
* 1. Admin | ||
* 2. Support | ||
* 3. Users with direct access | ||
* 4. Employee who can manage tickets | ||
*/ | ||
async function canReadTicketAutoAssignments ({ authentication: { item: user }, listKey }) { | ||
if (!user) return throwAuthenticationError() | ||
if (user.deletedAt) return false | ||
|
||
if (user.isAdmin || user.isSupport) return {} | ||
|
||
const hasDirectAccess = await canDirectlyReadSchemaObjects(user, listKey) | ||
if (hasDirectAccess) return {} | ||
|
||
if (user.type === STAFF) { | ||
return { | ||
organization: { | ||
OR: [ | ||
queryOrganizationEmployeeFor(user.id, 'canManageTickets'), | ||
queryOrganizationEmployeeFromRelatedOrganizationFor(user.id, 'canManageTickets'), | ||
], | ||
deletedAt: null, | ||
}, | ||
} | ||
} | ||
|
||
return false | ||
} | ||
|
||
/** | ||
* TicketAutoAssignment can be manage by | ||
* 1. Admin | ||
* 2. Support | ||
* 3. Users with direct access | ||
*/ | ||
async function canManageTicketAutoAssignments ({ authentication: { item: user }, originalInput, operation, itemId, listKey }) { | ||
if (!user) return throwAuthenticationError() | ||
if (user.deletedAt) return false | ||
|
||
if (user.isAdmin || user.isSupport) return true | ||
|
||
return await canDirectlyManageSchemaObjects(user, listKey, originalInput, operation) | ||
} | ||
|
||
/* | ||
Rules are logical functions that used for list access, and may return a boolean (meaning | ||
all or no items are available) or a set of filters that limit the available items. | ||
*/ | ||
module.exports = { | ||
canReadTicketAutoAssignments, | ||
canManageTicketAutoAssignments, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
apps/condo/domains/ticket/schema/TicketAutoAssignment.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/** | ||
* Generated by `createschema ticket.TicketAutoAssignment 'assignee:Relationship:OrganizationEmployee:SET_NULL;executor:Relationship:OrganizationEmployee:SET_NULL;classifier:Relationship:TicketClassifier:CASCADE;'` | ||
*/ | ||
|
||
const { GQLError, GQLErrorCode: { BAD_USER_INPUT } } = require('@open-condo/keystone/errors') | ||
const { historical, versioned, uuided, tracked, softDeleted, dvAndSender } = require('@open-condo/keystone/plugins') | ||
const { GQLListSchema, getByCondition } = require('@open-condo/keystone/schema') | ||
|
||
const { ORGANIZATION_OWNED_FIELD } = require('@condo/domains/organization/schema/fields') | ||
const access = require('@condo/domains/ticket/access/TicketAutoAssignment') | ||
|
||
const ERRORS = { | ||
ASSIGNEE_NOT_FOUND: { | ||
code: BAD_USER_INPUT, | ||
type: 'ASSIGNEE_NOT_FOUND', | ||
messageForUser: 'api.ticket.TicketAutoAssignment.error.ASSIGNEE_NOT_FOUND', | ||
message: 'There is no such employee (assignee) in the organization', | ||
}, | ||
EXECUTOR_NOT_FOUND: { | ||
code: BAD_USER_INPUT, | ||
type: 'EXECUTOR_NOT_FOUND', | ||
messageForUser: 'api.ticket.TicketAutoAssignment.error.EXECUTOR_NOT_FOUND', | ||
message: 'There is no such employee (executor) in the organization', | ||
}, | ||
} | ||
|
||
const TicketAutoAssignment = new GQLListSchema('TicketAutoAssignment', { | ||
schemaDoc: 'This schema helps decides who should be assigned to ticket as executor and assignee', | ||
fields: { | ||
|
||
organization: ORGANIZATION_OWNED_FIELD, | ||
|
||
assignee: { | ||
schemaDoc: 'An employee who will be appointed as assignee of ticket. ' + | ||
'If "null", then the field will remain empty and dispatcher will have to fill it in independently in UI', | ||
type: 'Relationship', | ||
ref: 'OrganizationEmployee', | ||
isRequired: false, | ||
knexOptions: { isNotNullable: false }, // Required relationship only! | ||
kmigratorOptions: { null: true, on_delete: 'models.SET_NULL' }, | ||
}, | ||
|
||
executor: { | ||
schemaDoc: 'An employee who will be appointed as executor of ticket' + | ||
'If "null", then the field will remain empty and dispatcher will have to fill it in independently in UI', | ||
type: 'Relationship', | ||
ref: 'OrganizationEmployee', | ||
isRequired: false, | ||
knexOptions: { isNotNullable: false }, // Required relationship only! | ||
kmigratorOptions: { null: true, on_delete: 'models.SET_NULL' }, | ||
}, | ||
|
||
classifier: { | ||
schemaDoc: 'Ticket classifier', | ||
type: 'Relationship', | ||
ref: 'TicketClassifier', | ||
isRequired: true, | ||
knexOptions: { isNotNullable: true }, // Required relationship only! | ||
kmigratorOptions: { null: false, on_delete: 'models.CASCADE' }, | ||
}, | ||
|
||
}, | ||
hooks: { | ||
validateInput: async ({ resolvedData, context, existingItem }) => { | ||
const newItem = { ...existingItem, ...resolvedData } | ||
|
||
if (newItem.assignee) { | ||
const assignee = await getByCondition('OrganizationEmployee', { | ||
id: newItem.assignee, | ||
deletedAt: null, | ||
organization: { id: newItem.organization, deletedAt: null }, | ||
}) | ||
if (!assignee) throw new GQLError(ERRORS.ASSIGNEE_NOT_FOUND, context) | ||
} | ||
|
||
if (newItem.executor) { | ||
const executor = await getByCondition('OrganizationEmployee', { | ||
id: newItem.executor, | ||
deletedAt: null, | ||
organization: { id: newItem.organization, deletedAt: null }, | ||
}) | ||
if (!executor) throw new GQLError(ERRORS.EXECUTOR_NOT_FOUND, context) | ||
} | ||
}, | ||
}, | ||
plugins: [uuided(), versioned(), tracked(), softDeleted(), dvAndSender(), historical()], | ||
kmigratorOptions: { | ||
constraints: [ | ||
{ | ||
type: 'models.UniqueConstraint', | ||
fields: ['organization', 'classifier'], | ||
condition: 'Q(deletedAt__isnull=True)', | ||
name: 'ticket_auto_assignment_unique_organization_classifier', | ||
}, | ||
], | ||
}, | ||
access: { | ||
read: access.canReadTicketAutoAssignments, | ||
create: access.canManageTicketAutoAssignments, | ||
update: access.canManageTicketAutoAssignments, | ||
delete: false, | ||
auth: true, | ||
}, | ||
}) | ||
|
||
module.exports = { | ||
TicketAutoAssignment, | ||
ERRORS, | ||
} |
Oops, something went wrong.