Skip to content

Commit

Permalink
Add Business hour logic to routing and triage (#365)
Browse files Browse the repository at this point in the history
* holiday config

* add capability to add multiple offices per channel

* add comment about using office for notify-for-triage

* add more holiday logic

* clean up moment tz installation

* lot of tests :)

* use 2023 chrimstas instead of 2022

* don't add date, just subtract loop counter for holidays

* add test case for rerouted issues

* initial businessHour logic seems to work

* tests for business hours

* fix case of last day of month

* fix flaky issue notifier tests

* remove it.only

* add some comments

* clean up some logic, variable renaming

* fix bug related to utc time conversion, use moment for most of the logic

* see if this fixes warnings

* add full iso string to tests

* completely refactor logic

* fix typescript errors

* rename some functions
  • Loading branch information
hubertdeng123 authored Dec 14, 2022
1 parent 393bde6 commit c0de7a3
Show file tree
Hide file tree
Showing 12 changed files with 469 additions and 184 deletions.
21 changes: 21 additions & 0 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
Binary file not shown.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"knex": "^0.95.12",
"middie": "^5.3.0",
"module-alias": "^2.2.2",
"moment-timezone": "^0.5.39",
"pg": "^8.5.1",
"source-map-support": "^0.5.21",
"tar": "^6.1.11",
Expand Down
33 changes: 11 additions & 22 deletions src/brain/issueNotifier/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,9 @@ describe('issueNotifier Tests', function () {
expect(say).lastCalledWith(
'This channel is set to receive notifications for: Team: Test (no office specified)'
);
expect(await getLabelsTable().where({ channel_id })).toEqual([
expect(await getLabelsTable().where({ channel_id })).toMatchObject([
{
channel_id: 'CHNLIDRND1',
id: 1,
label_name: 'Team: Test',
offices: null,
},
Expand All @@ -202,10 +201,9 @@ describe('issueNotifier Tests', function () {
expect(say).lastCalledWith(
'Add office location sfo on the current channel (test) for Team: Test'
);
expect(await getLabelsTable().where({ channel_id })).toEqual([
expect(await getLabelsTable().where({ channel_id })).toMatchObject([
{
channel_id: 'CHNLIDRND1',
id: 1,
label_name: 'Team: Test',
offices: ['sfo'],
},
Expand All @@ -222,10 +220,9 @@ describe('issueNotifier Tests', function () {
expect(say).lastCalledWith(
'This channel is set to receive notifications for: Team: Test (sfo)'
);
expect(await getLabelsTable().where({ channel_id })).toEqual([
expect(await getLabelsTable().where({ channel_id })).toMatchObject([
{
channel_id: 'CHNLIDRND1',
id: 1,
label_name: 'Team: Test',
offices: ['sfo'],
},
Expand All @@ -242,10 +239,9 @@ describe('issueNotifier Tests', function () {
expect(say).lastCalledWith(
'Add office location sea on the current channel (test) for Team: Test'
);
expect(await getLabelsTable().where({ channel_id })).toEqual([
expect(await getLabelsTable().where({ channel_id })).toMatchObject([
{
channel_id: 'CHNLIDRND1',
id: 1,
label_name: 'Team: Test',
offices: ['sfo', 'sea'],
},
Expand All @@ -262,10 +258,9 @@ describe('issueNotifier Tests', function () {
expect(say).lastCalledWith(
'This channel is set to receive notifications for: Team: Test (sfo, sea)'
);
expect(await getLabelsTable().where({ channel_id })).toEqual([
expect(await getLabelsTable().where({ channel_id })).toMatchObject([
{
channel_id: 'CHNLIDRND1',
id: 1,
label_name: 'Team: Test',
offices: ['sfo', 'sea'],
},
Expand All @@ -282,10 +277,9 @@ describe('issueNotifier Tests', function () {
expect(say).lastCalledWith(
'Add office location vie on the current channel (test) for Team: Test'
);
expect(await getLabelsTable().where({ channel_id })).toEqual([
expect(await getLabelsTable().where({ channel_id })).toMatchObject([
{
channel_id: 'CHNLIDRND1',
id: 1,
label_name: 'Team: Test',
offices: ['sfo', 'sea', 'vie'],
},
Expand All @@ -302,10 +296,9 @@ describe('issueNotifier Tests', function () {
expect(say).lastCalledWith(
'Add office location yyz on the current channel (test) for Team: Test'
);
expect(await getLabelsTable().where({ channel_id })).toEqual([
expect(await getLabelsTable().where({ channel_id })).toMatchObject([
{
channel_id: 'CHNLIDRND1',
id: 1,
label_name: 'Team: Test',
offices: ['sfo', 'sea', 'vie', 'yyz'],
},
Expand All @@ -322,10 +315,9 @@ describe('issueNotifier Tests', function () {
expect(say).lastCalledWith(
'This channel (test) will no longer get notifications for Team: Test during sea business hours.'
);
expect(await getLabelsTable().where({ channel_id })).toEqual([
expect(await getLabelsTable().where({ channel_id })).toMatchObject([
{
channel_id: 'CHNLIDRND1',
id: 1,
label_name: 'Team: Test',
offices: ['sfo', 'vie', 'yyz'],
},
Expand All @@ -342,10 +334,9 @@ describe('issueNotifier Tests', function () {
expect(say).lastCalledWith(
'This channel (test) is not subscribed to Team: Test during sea business hours.'
);
expect(await getLabelsTable().where({ channel_id })).toEqual([
expect(await getLabelsTable().where({ channel_id })).toMatchObject([
{
channel_id: 'CHNLIDRND1',
id: 1,
label_name: 'Team: Test',
offices: ['sfo', 'vie', 'yyz'],
},
Expand All @@ -362,10 +353,9 @@ describe('issueNotifier Tests', function () {
expect(say).lastCalledWith(
'This channel (test) will no longer get notifications for Team: Test during yyz business hours.'
);
expect(await getLabelsTable().where({ channel_id })).toEqual([
expect(await getLabelsTable().where({ channel_id })).toMatchObject([
{
channel_id: 'CHNLIDRND1',
id: 1,
label_name: 'Team: Test',
offices: ['sfo', 'vie'],
},
Expand All @@ -382,10 +372,9 @@ describe('issueNotifier Tests', function () {
expect(say).lastCalledWith(
'This channel (test) will no longer get notifications for Team: Test during sfo business hours.'
);
expect(await getLabelsTable().where({ channel_id })).toEqual([
expect(await getLabelsTable().where({ channel_id })).toMatchObject([
{
channel_id: 'CHNLIDRND1',
id: 1,
label_name: 'Team: Test',
offices: ['vie'],
},
Expand Down
4 changes: 2 additions & 2 deletions src/brain/issueNotifier/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { EmitterWebhookEvent } from '@octokit/webhooks';
import { TEAM_LABEL_PREFIX, UNROUTED_LABEL, UNTRIAGED_LABEL } from '@/config';
import { githubEvents } from '@api/github';
import { bolt } from '@api/slack';
import { cacheOfficesForTeam } from '@utils/businessHours';
import { cacheOffices } from '@utils/businessHours';
import { db } from '@utils/db';
import { wrapHandler } from '@utils/wrapHandler';

Expand Down Expand Up @@ -212,7 +212,7 @@ export const slackHandler = async ({ command, ack, say, respond, client }) => {
break;
}
// Update cache for the offices mapped to each team
await cacheOfficesForTeam(label_name);
await cacheOffices(label_name);
}
await Promise.all(pending);
};
Expand Down
12 changes: 12 additions & 0 deletions src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,15 @@ export const MAX_ROUTE_DAYS = 1;
* Personal Access Token for the Sentry bot used to do things that aren't possible with the App account, e.g. querying org membership
*/
export const GH_USER_TOKEN = process.env.GH_USER_TOKEN || '';

/**
* Business Hours by Office
*/

export const OFFICE_TIME_ZONES = {
vie: 'Europe/Vienna',
ams: 'Europe/Amsterdam',
yyz: 'America/Toronto',
sfo: 'America/Los_Angeles',
sea: 'America/Los_Angeles',
};
Loading

0 comments on commit c0de7a3

Please sign in to comment.