Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated Feature: Activity-based Incident Cost Model #4172

Merged
merged 169 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
169 commits
Select commit Hold shift + click to select a range
ea9ff36
Bump uvloop from 0.18.0 to 0.19.0 (#3896)
dependabot[bot] Oct 23, 2023
d09dfd9
Bump email-validator from 2.0.0.post2 to 2.1.0.post1 (#3897)
dependabot[bot] Oct 23, 2023
d432f5f
Bump vue from 2.7.14 to 2.7.15 in /src/dispatch/static/dispatch (#3895)
dependabot[bot] Oct 23, 2023
13dd691
Bump eslint from 8.51.0 to 8.52.0 in /src/dispatch/static/dispatch (#…
dependabot[bot] Oct 23, 2023
a4242e7
Bump vue-template-compiler in /src/dispatch/static/dispatch (#3893)
dependabot[bot] Oct 23, 2023
60811f9
Bump @vue/compiler-sfc in /src/dispatch/static/dispatch (#3892)
dependabot[bot] Oct 23, 2023
13407c2
Bump ruff from 0.1.0 to 0.1.1 (#3891)
dependabot[bot] Oct 23, 2023
0218e04
Bump schemathesis from 3.19.7 to 3.20.1 (#3890)
dependabot[bot] Oct 23, 2023
6dabefa
Bump faker from 19.10.0 to 19.11.0 (#3887)
dependabot[bot] Oct 23, 2023
1ccc691
Enhances Signals table (#3898)
mvilanova Oct 23, 2023
6430461
Call ('input') in remove method (#3871)
wssheldon Oct 23, 2023
52f0dcb
Reverts package-lock.json file to version in PR 3892 (#3899)
mvilanova Oct 23, 2023
a9acefc
Fixing an issue where we aren't paging for critical (#3902)
kevgliss Oct 25, 2023
d8502fc
Update to vue 3 (#3857)
KaelWD Oct 31, 2023
2114a94
Adds default org for api calls (#3912)
kevgliss Oct 31, 2023
40887f5
Do not print out raw role policies in the incident roles UI section (…
mvilanova Oct 31, 2023
743ceee
Rollback session in case or exceptions (#3917)
kevgliss Nov 1, 2023
f2104d6
Bugfix/table font size (#3921)
kevgliss Nov 1, 2023
b8b5822
Adding padding for spacing on participants and resources tabs (#3920)
whitdog47 Nov 1, 2023
f221d09
Fixing export preview missing scroll for incidents, cases, and tasks …
whitdog47 Nov 1, 2023
884525b
Fixing styling for incident priority settings, search filter settings…
whitdog47 Nov 1, 2023
a0320b7
Fixing validation for stable priority
whitdog47 Nov 1, 2023
ba76710
Ignore v-stepper and other deprecated component linter errors (#3923)
wssheldon Nov 1, 2023
2354d22
Fixes issues with Signals table after migration to Vue3 (#3922)
mvilanova Nov 1, 2023
5d83696
handle possible null actions in interactive.py (#3914)
jschroth Nov 1, 2023
878c1b8
Bump faker from 19.11.0 to 19.13.0 (#3924)
dependabot[bot] Nov 2, 2023
77fe00d
Bump google-api-python-client from 2.104.0 to 2.106.0 (#3916)
dependabot[bot] Nov 2, 2023
2a98e92
Bump ruff from 0.1.1 to 0.1.3 (#3910)
dependabot[bot] Nov 2, 2023
692ca95
Bump werkzeug from 2.3.7 to 3.0.1 (#3908)
dependabot[bot] Nov 2, 2023
ae660c2
Bump cachetools from 5.3.1 to 5.3.2 (#3906)
dependabot[bot] Nov 2, 2023
628511d
Bump black from 23.10.0 to 23.10.1 (#3901)
dependabot[bot] Nov 2, 2023
3cbfa45
Bump ipython from 8.16.1 to 8.17.2 (#3931)
dependabot[bot] Nov 3, 2023
ad50e06
Bump markdown from 3.5 to 3.5.1 (#3930)
dependabot[bot] Nov 3, 2023
f3eeb92
Bump protobuf from 4.24.4 to 4.25.0 (#3929)
dependabot[bot] Nov 3, 2023
40c7eb9
Bump duo-client from 5.1.0 to 5.2.0 (#3928)
dependabot[bot] Nov 3, 2023
8dc45ef
Bump sentry-sdk from 1.32.0 to 1.34.0 (#3927)
dependabot[bot] Nov 3, 2023
6a0a0b9
Fixing participant select and centralizes component (#3925)
kevgliss Nov 3, 2023
9930018
Restyling templates settings page (#3926)
whitdog47 Nov 3, 2023
bfeba11
Bugfix/format timeline fixes (#3932)
whitdog47 Nov 3, 2023
588ad6c
Mirror the incident bottom sheet to prevent focus from being stolen (…
wssheldon Nov 3, 2023
47eb049
return object when an item is selected in case/incident table (#3934)
wssheldon Nov 3, 2023
3aa9d57
return object for tasks data table (#3935)
wssheldon Nov 3, 2023
1d8fa65
Bump eslint from 8.52.0 to 8.53.0 in /src/dispatch/static/dispatch (#…
dependabot[bot] Nov 6, 2023
35236b5
Bump msal from 1.24.1 to 1.25.0 (#3942)
dependabot[bot] Nov 6, 2023
50dd363
Bump vue from 3.3.7 to 3.3.8 in /src/dispatch/static/dispatch (#3941)
dependabot[bot] Nov 6, 2023
ce80d84
Bump ruff from 0.1.3 to 0.1.4 (#3940)
dependabot[bot] Nov 6, 2023
1f7f7c8
Bump uvicorn from 0.23.2 to 0.24.0.post1 (#3939)
dependabot[bot] Nov 6, 2023
c953f5b
Bump schemathesis from 3.20.1 to 3.20.2 (#3938)
dependabot[bot] Nov 6, 2023
45951a8
Bump httpx from 0.24.1 to 0.25.1 (#3937)
dependabot[bot] Nov 6, 2023
6888a93
Fixing issue with new template dialog always appearing (#3936)
whitdog47 Nov 6, 2023
d3029f2
Removing password element from plugin form (#3945)
whitdog47 Nov 7, 2023
1b6a79e
Fixing time not saving correctly in edit event dialog (#3946)
whitdog47 Nov 7, 2023
2e20f56
Project autocomplete (#3944)
kevgliss Nov 7, 2023
31a3d5b
Use real JSONPathError exception (#3951)
wssheldon Nov 7, 2023
ab83ffd
Bump openai from 0.28.1 to 1.2.0 (#3954)
dependabot[bot] Nov 9, 2023
5fe5380
Bump @vitejs/plugin-vue in /src/dispatch/static/dispatch (#3953)
dependabot[bot] Nov 9, 2023
daaba8f
Bump google-api-python-client from 2.106.0 to 2.107.0 (#3952)
dependabot[bot] Nov 9, 2023
82afd75
Bump pytest from 7.4.2 to 7.4.3 (#3949)
dependabot[bot] Nov 9, 2023
2de488f
Bump pandas from 2.1.1 to 2.1.2 (#3948)
dependabot[bot] Nov 9, 2023
b308f80
Bump alembic from 1.12.0 to 1.12.1 (#3947)
dependabot[bot] Nov 9, 2023
f4f5e6c
Only display raw data in signal viewer (#3955)
mvilanova Nov 9, 2023
0f84c0c
Revert "Bump alembic from 1.12.0 to 1.12.1 (#3947)" (#3968)
whitdog47 Nov 10, 2023
f14bd1e
Fixing playwright tests (#3969)
whitdog47 Nov 11, 2023
f2c0962
Continue to work on fixing playwright tests (#3970)
whitdog47 Nov 11, 2023
3e1d896
Have playwright.yml only run on chromium
whitdog47 Nov 11, 2023
b9173b1
Replacing deprecated props (#3971)
whitdog47 Nov 11, 2023
557203a
Making search more reliable (#3967)
kevgliss Nov 13, 2023
1deaab3
Bugfix/vuetify upgrade (#3973)
kevgliss Nov 13, 2023
4aaccb3
Bump faker from 19.13.0 to 20.0.0 (#3972)
dependabot[bot] Nov 13, 2023
a8ec508
Bump schemathesis from 3.20.2 to 3.21.0 (#3966)
dependabot[bot] Nov 13, 2023
8c1ad3c
Bump ruff from 0.1.4 to 0.1.5 (#3965)
dependabot[bot] Nov 13, 2023
3a21011
Bump black from 23.10.1 to 23.11.0 (#3964)
dependabot[bot] Nov 13, 2023
cd72247
Bump openai from 1.2.0 to 1.2.2 (#3963)
dependabot[bot] Nov 13, 2023
428df25
Bump @formkit/vue from 1.2.2 to 1.3.0 in /src/dispatch/static/dispatc…
dependabot[bot] Nov 13, 2023
aa5675b
Bump @vueuse/integrations in /src/dispatch/static/dispatch (#3961)
dependabot[bot] Nov 13, 2023
f59cf6d
Bump @formkit/themes in /src/dispatch/static/dispatch (#3960)
dependabot[bot] Nov 13, 2023
0dbb119
Bump eslint-plugin-vuetify in /src/dispatch/static/dispatch (#3959)
dependabot[bot] Nov 13, 2023
a1bd382
Updates OpenAI plugin (#3975)
mvilanova Nov 14, 2023
e41e818
Bump openai from 1.2.2 to 1.2.4 (#3976)
dependabot[bot] Nov 14, 2023
5115a56
Pre commit/eslint ruff versions (#3957)
wssheldon Nov 14, 2023
72c0a09
Bump vuetify from 3.3.22 to 3.4.0 in /src/dispatch/static/dispatch (#…
dependabot[bot] Nov 14, 2023
a186a92
Removes canary column in signal instance table (#3985)
mvilanova Nov 14, 2023
995bf8f
Only show variant in case notification if it is set (#3984)
mvilanova Nov 14, 2023
4e131b6
Sets resolution reason when case is resolved through signal engagemen…
mvilanova Nov 14, 2023
349c857
Bump slack-sdk from 3.23.0 to 3.23.1 (#3988)
dependabot[bot] Nov 15, 2023
174ac5a
Bump google-api-python-client from 2.107.0 to 2.108.0 (#3987)
dependabot[bot] Nov 15, 2023
f2b71ba
Bump @vueuse/integrations in /src/dispatch/static/dispatch (#3981)
dependabot[bot] Nov 15, 2023
2a259fe
Bump numpy from 1.26.1 to 1.26.2 (#3979)
dependabot[bot] Nov 15, 2023
0fcbe3c
Bump sentry-sdk from 1.34.0 to 1.35.0 (#3978)
dependabot[bot] Nov 15, 2023
9baeb63
Bump pandas from 2.1.2 to 2.1.3 (#3977)
dependabot[bot] Nov 15, 2023
475c353
Declutters Slack case threads (#3994)
mvilanova Nov 15, 2023
47eea0c
Fixes DSN. (#3986)
metroid-samus Nov 15, 2023
0b7e4f9
Uses entity type name in Slack snooze modal (#3995)
mvilanova Nov 15, 2023
a20d0db
Show entity value in entity filter combobox (#3996)
wssheldon Nov 15, 2023
cea774f
Aligns form styles and reverts project autocomplete (#3989)
kevgliss Nov 16, 2023
01039b1
Fixing settings bread crumbs (#3992)
kevgliss Nov 16, 2023
948b0a7
Fixing table cards to remove card outlines (#3990)
kevgliss Nov 16, 2023
4ba3442
Increase min page sizes (#3993)
kevgliss Nov 16, 2023
f2ff71c
Bump slack-sdk from 3.23.1 to 3.24.0 (#4001)
dependabot[bot] Nov 16, 2023
05332c9
Bump faker from 20.0.0 to 20.0.3 (#4000)
dependabot[bot] Nov 16, 2023
7e6b21d
Bump pdpyras from 5.1.2 to 5.1.3 (#3999)
dependabot[bot] Nov 16, 2023
cb7c78e
Bump openai from 1.2.4 to 1.3.0 (#3998)
dependabot[bot] Nov 16, 2023
4816af9
Bump protobuf from 4.25.0 to 4.25.1 (#3997)
dependabot[bot] Nov 16, 2023
1c56d63
Correctly render object title in SignalEngagementCombobox (#4002)
wssheldon Nov 17, 2023
1ca6513
Handle invalid JSONPath with KeyError, Exceptions, and add test cases…
wssheldon Nov 17, 2023
a49cbb1
Bump ruff from 0.1.5 to 0.1.6 (#4016)
dependabot[bot] Nov 20, 2023
9b20803
Fixing project and case type select (#4010)
whitdog47 Nov 20, 2023
c0ede5e
Bugfix/cant add assignee (#4017)
whitdog47 Nov 20, 2023
0cccebe
Bump aiohttp from 3.8.6 to 3.9.0 (#4015)
dependabot[bot] Nov 20, 2023
77716b9
Bump openai from 1.3.0 to 1.3.3 (#4014)
dependabot[bot] Nov 20, 2023
b83faee
Bump eslint from 8.53.0 to 8.54.0 in /src/dispatch/static/dispatch (#…
dependabot[bot] Nov 20, 2023
6b0f29d
Bump schemathesis from 3.21.0 to 3.21.1 (#4006)
dependabot[bot] Nov 20, 2023
1811502
Bump @playwright/test in /src/dispatch/static/dispatch (#4004)
dependabot[bot] Nov 20, 2023
4c69d85
Bump @vitejs/plugin-vue in /src/dispatch/static/dispatch (#4003)
dependabot[bot] Nov 20, 2023
78061ed
Do not send case traige reminders if there is no assignee. (#4008)
metroid-samus Nov 20, 2023
bed1b66
Make assignee combobox behave like participant select (#4018)
whitdog47 Nov 27, 2023
7887f36
Bump sentry-sdk from 1.35.0 to 1.37.0 (#4027)
dependabot[bot] Nov 27, 2023
fd08049
Bump ipython from 8.17.2 to 8.18.0 (#4026)
dependabot[bot] Nov 27, 2023
b3809bc
Bump slack-sdk from 3.24.0 to 3.26.0 (#4025)
dependabot[bot] Nov 27, 2023
07b93a1
Bump openai from 1.3.3 to 1.3.5 (#4024)
dependabot[bot] Nov 27, 2023
aef7a6f
Bump faker from 20.0.3 to 20.1.0 (#4021)
dependabot[bot] Nov 27, 2023
7d8ddcd
Dark mode not persisting through reloads (#4033)
whitdog47 Nov 27, 2023
44f7bba
Bump slack-bolt from 1.18.0 to 1.18.1 (#4032)
dependabot[bot] Nov 27, 2023
b446575
Bump aiohttp from 3.9.0 to 3.9.1 (#4031)
dependabot[bot] Nov 27, 2023
08fb275
Bump sentry-sdk from 1.37.0 to 1.37.1 (#4030)
dependabot[bot] Nov 27, 2023
b7b186b
Bump eslint-plugin-local-rules in /src/dispatch/static/dispatch (#4029)
dependabot[bot] Nov 27, 2023
d6d7dce
Bump vue from 3.3.8 to 3.3.9 in /src/dispatch/static/dispatch (#4028)
dependabot[bot] Nov 27, 2023
1b902ec
Fixes signal instance deduplication check. (#4012)
metroid-samus Nov 27, 2023
cf56613
Swallow send exceptions (#4034)
whitdog47 Nov 27, 2023
3332b93
All backend. Creates new models and adds new API calls for improving …
metroid-samus Oct 20, 2023
48c4b59
Front end
metroid-samus Dec 7, 2023
e47fc3c
Merge branch 'master' into enhancement/activity-based-cost-model
metroid-samus Dec 21, 2023
60ea81a
Refactors incident cost calculations
metroid-samus Dec 21, 2023
6593800
Fixed front end.
metroid-samus Dec 27, 2023
ab660c0
Updates to database schema.
metroid-samus Dec 27, 2023
72432aa
Removes unused code/comments.
metroid-samus Dec 27, 2023
3b326f6
Restores main branch's package-lock.json.
metroid-samus Dec 27, 2023
3817c4e
Fixes Pylint errors.
metroid-samus Dec 27, 2023
767fc18
Fixes JavaScript lint errors.
metroid-samus Dec 27, 2023
e5f3471
Fixes cost model documentation.
metroid-samus Dec 27, 2023
0dfd5ac
Documents which plugin events are currently supported for the inciden…
metroid-samus Dec 28, 2023
564d9e6
Adds image of edit sheet to the incident cost model documentation.
metroid-samus Dec 28, 2023
88f4f29
Increases test code readability.
metroid-samus Dec 28, 2023
cc5ab31
Cleans up import statements.
metroid-samus Dec 28, 2023
cbb7534
Update src/dispatch/incident_cost_model/service.py
metroid-samus Jan 3, 2024
7eea20e
Update src/dispatch/incident_cost_model/service.py
metroid-samus Jan 3, 2024
5bd49c5
Merge branch 'master' into enhancement/activity-based-cost-model
metroid-samus Jan 3, 2024
7aaa47b
Database migration cleanup.
metroid-samus Jan 3, 2024
16d42c8
Merge branch 'master' into enhancement/activity-based-cost-model
metroid-samus Jan 3, 2024
4293ed0
Fixes error messages and adds doc strings to functions.
metroid-samus Jan 3, 2024
85e5f48
Merge branch 'master' into enhancement/activity-based-cost-model
metroid-samus Jan 3, 2024
7bb2ec7
Update src/dispatch/incident_cost_model/service.py
metroid-samus Jan 4, 2024
95e5141
Update src/dispatch/incident_cost/service.py
metroid-samus Jan 4, 2024
ea079ef
Code cleanup.
metroid-samus Jan 4, 2024
335b7c3
Merge branch 'master' into enhancement/activity-based-cost-model
metroid-samus Jan 4, 2024
58e2dec
Code cleanup.
metroid-samus Jan 5, 2024
4cd2d0d
Code cleanup.
metroid-samus Jan 5, 2024
f00f75d
Renames IncidentCostModel* to CostModel*
metroid-samus Jan 10, 2024
07dd7ca
Merge branch 'master' into enhancement/activity-based-cost-model
metroid-samus Jan 10, 2024
2a85069
Fixes lint errors
metroid-samus Jan 10, 2024
cde411b
Fixes markdown link
metroid-samus Jan 10, 2024
67d5910
Adds additional validation.
metroid-samus Jan 11, 2024
6375053
Adds additional validation.
metroid-samus Jan 11, 2024
8b357c5
Merge branch 'master' into enhancement/activity-based-cost-model
metroid-samus Jan 11, 2024
0551dee
Adds cost model selection in Slack interface.
metroid-samus Jan 12, 2024
7d7664a
Updates cost model documentation with concrete cost calculation examp…
metroid-samus Jan 17, 2024
1b0f8fe
Cost Model Activity Dialog only displays Plugins with PluginEvents in…
metroid-samus Jan 18, 2024
168ef2f
Merge branch 'master' into enhancement/activity-based-cost-model
metroid-samus Jan 18, 2024
2629f9a
Fixes database revision change
metroid-samus Jan 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions docs/docs/user-guide/cost_model.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Cost Model

Our Cost Model is a feature that enables teams to estimate response cost for each incident. Users can opt in to create and use personalized cost calculations for each incident based on participant activity.

If no cost model is assigned to an incident, the default classic cost model will be used. See [Incident Cost Type](../administration/settings/incident/incident-cost-type.mdx###calculating-incident-cost).

<div style={{textAlign: 'center'}}>

![](/img/admin-ui-cost-model.png)

</div>

## Key Features

### Customizable Cost Models
Users have the flexibility to define their unique cost models based on their organization's workflow and tools. This customization can be tailored to each incident, providing a versitile approach to cost calculation. The cost model for an incident can be changed at any time during its lifespan. All participant activity costs moving forward will be calculated using the new cost model.

### Plugin-Based Tracking
Users can track costs from their existing tools by using our plugin-based tracking system. Users have the flexibility to select which plugins and specific plugin events they want to track, offering a targeted approach to cost calculation.

### Effort Assignment
For each tracked activity, users can assign a quantifiable measure of effort, represented in seconds of work time. This feature provides a more accurate representation of the cost of an incident.

### Incident Cost Calculation
Incident cost calculation is based on the cost model and effort assignment for each tracked participant activity. This helps in understanding resource utilization and cost of an incident.


## Currently Supported Plugin Events

### Slack: Channel Activity
This event tracks activity within a specific Slack channel. By periodically polling channel messages, this gathers insights into the activity and engagement levels of each participant.

### Slack: Thread Activity
This event tracks activity within a specific Slack thread. By periodically polling thread replies, this gathers insights into the activity and engagement levels of each participant.


<div style={{textAlign: 'center'}}>

![](/img/admin-ui-edit-cost-model.png)

</div>

## Cost Calculation Examples

Below, we illustrate the use of the cost model through two examples. These are based on the following values:

<b>Cost Model 1</b>

| Plugin Event | Response Time (seconds)
| ------------ | -------------
| Slack Channel Activity | 300

The employee hourly rate can be adjusted by modifying the `Annual Employee Cost` and `Business Year Hours` fields in the [project settings](../administration/settings/project.mdx). In these examples, we will use the following value:
```
hourly_rate = 100
```

#### Example 1

Consider the following Slack channel activity for `Incident 1`:

| Slack Channel Activity Timestamp | Participant
| ------------ | -------------
| 100 | Cookie Doe
| 200 | Nate Flex

The resulting recorded participant activity will be:

| Participant | started_at | ended_at | Plugin Event | Incident
| ------------ | ------------- | ------------- | ------------- | -------------
| Cookie Doe | 100 | 400 | Slack Channel Activity | Incident 1
| Nate Flex | 200 | 500 | Slack Channel Activity | Incident 1


The incident cost is then calculated as:

```
( (400 - 100) + (500-200) ) / SECONDS_IN_HOUR * hourly_rate = $16.67
```

#### Example 2

Consider the following Slack channel activity for `Incident 2`:

| Slack Channel Activity Timestamp | Participant
| ------------ | -------------
| 100 | Cookie Doe
| 150 | Cookie Doe
| 200 | Nate Flex
| 500 | Cookie Doe

The resulting recorded participant activity will be:

| Participant | started_at | ended_at | Plugin Event | Incident
| ------------ | ------------- | ------------- | ------------- | -------------
| Cookie Doe | 100 | 450 | Slack Channel Activity | Incident 2
| Nate Flex | 200 | 500 | Slack Channel Activity | Incident 2
| Cookie Doe | 500 | 800 | Slack Channel Activity | Incident 2


The incident cost is then calculated as:

```
( (450 - 100) + (500 - 200) + (800 - 500) ) / SECONDS_IN_HOUR * hourly_rate = $26.39
```
Binary file added docs/static/img/admin-ui-cost-model.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/img/admin-ui-edit-cost-model.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 11 additions & 2 deletions src/dispatch/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
from dispatch.route.models import Recommendation # noqa lgtm[py/unused-import]
from dispatch.conference.models import Conference # noqa lgtm[py/unused-import]
from dispatch.conversation.models import Conversation # noqa lgtm[py/unused-import]
from dispatch.cost_model.models import (
CostModel, # noqa lgtm[py/unused-import]
CostModelActivity, # noqa lgtm[py/unused-import]
)
from dispatch.definition.models import Definition # noqa lgtm[py/unused-import]
from dispatch.document.models import Document # noqa lgtm[py/unused-import]
from dispatch.event.models import Event # noqa lgtm[py/unused-import]
Expand All @@ -37,8 +41,11 @@
from dispatch.individual.models import IndividualContact # noqa lgtm[py/unused-import]
from dispatch.notification.models import Notification # noqa lgtm[py/unused-import]
from dispatch.participant.models import Participant # noqa lgtm[py/unused-import]
from dispatch.participant_activity.models import (
ParticipantActivity, # noqa lgtm[py/unused-import]
)
from dispatch.participant_role.models import ParticipantRole # noqa lgtm[py/unused-import]
from dispatch.plugin.models import Plugin # noqa lgtm[py/unused-import]
from dispatch.plugin.models import Plugin, PluginEvent # noqa lgtm[py/unused-import]
from dispatch.report.models import Report # noqa lgtm[py/unused-import]
from dispatch.service.models import Service # noqa lgtm[py/unused-import]
from dispatch.storage.models import Storage # noqa lgtm[py/unused-import]
Expand All @@ -61,7 +68,9 @@
from dispatch.case.severity.models import CaseSeverity # noqa lgtm[py/unused-import]
from dispatch.case.type.models import CaseType # noqa lgtm[py/unused-import]
from dispatch.signal.models import Signal # noqa lgtm[py/unused-import]
from dispatch.feedback.service.reminder.models import ServiceFeedbackReminder # noqa lgtm[py/unused-import]
from dispatch.feedback.service.reminder.models import (
ServiceFeedbackReminder, # noqa lgtm[py/unused-import]
)
from dispatch.forms.type.models import FormsType # noqa lgtm[py/unused-import]
from dispatch.forms.models import Forms # noqa lgtm[py/unused-import]

Expand Down
11 changes: 8 additions & 3 deletions src/dispatch/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from dispatch.incident.type.views import router as incident_type_router
from dispatch.incident.views import router as incident_router
from dispatch.incident_cost.views import router as incident_cost_router
from dispatch.cost_model.views import router as cost_model_router
from dispatch.incident_cost_type.views import router as incident_cost_type_router
from dispatch.incident_role.views import router as incident_role_router
from dispatch.individual.views import router as individual_contact_router
Expand Down Expand Up @@ -197,6 +198,11 @@ def get_organization_path(organization: OrganizationSlug):
prefix="/case_severities",
tags=["case_severities"],
)
authenticated_organization_api_router.include_router(
cost_model_router,
prefix="/cost_models",
tags=["cost_models"],
)
authenticated_organization_api_router.include_router(
workflow_router, prefix="/workflows", tags=["workflows"]
)
Expand All @@ -223,13 +229,12 @@ def get_organization_path(organization: OrganizationSlug):
authenticated_organization_api_router.include_router(
incident_role_router, prefix="/incident_roles", tags=["role"]
)
authenticated_organization_api_router.include_router(
forms_router, prefix="/forms", tags=["forms"]
)
authenticated_organization_api_router.include_router(forms_router, prefix="/forms", tags=["forms"])
authenticated_organization_api_router.include_router(
forms_type_router, prefix="/forms_type", tags=["forms_type"]
)


@api_router.get("/healthcheck", include_in_schema=False)
def healthcheck():
return {"status": "ok"}
Expand Down
20 changes: 19 additions & 1 deletion src/dispatch/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def install_plugins(force):
from dispatch.common.utils.cli import install_plugins
from dispatch.database.core import SessionLocal
from dispatch.plugin import service as plugin_service
from dispatch.plugin.models import Plugin
from dispatch.plugin.models import Plugin, PluginEvent
from dispatch.plugins.base import plugins

install_plugins()
Expand All @@ -104,6 +104,7 @@ def install_plugins(force):
description=p.description,
)
db_session.add(plugin)
record = plugin
else:
if force:
click.secho(f"Updating plugin... Slug: {p.slug} Version: {p.version}", fg="blue")
Expand All @@ -115,6 +116,23 @@ def install_plugins(force):
record.description = p.description
record.type = p.type

# Registers the plugin events with the plugin or updates the plugin events
for plugin_event_in in p.plugin_events:
click.secho(f" Registering plugin event... Slug: {plugin_event_in.slug}", fg="blue")
if plugin_event := plugin_service.get_plugin_event_by_slug(
db_session=db_session, slug=plugin_event_in.slug
):
plugin_event.name = plugin_event_in.name
plugin_event.description = plugin_event_in.description
plugin_event.plugin = record
else:
plugin_event = PluginEvent(
name=plugin_event_in.name,
slug=plugin_event_in.slug,
description=plugin_event_in.description,
plugin=record,
)
db_session.add(plugin_event)
db_session.commit()


Expand Down
5 changes: 5 additions & 0 deletions src/dispatch/conversation/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,8 @@ class ConversationButtonActions(DispatchEnum):
service_feedback = "service-feedback"
subscribe_user = "subscribe-user"
update_task_status = "update-task-status"


class ConversationFilters(DispatchEnum):
exclude_bots = "exclude-bots"
exclude_channel_join = "exclude-channel-join"
Empty file.
111 changes: 111 additions & 0 deletions src/dispatch/cost_model/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
from datetime import datetime
from pydantic import Field
from sqlalchemy import (
Column,
Integer,
String,
Boolean,
ForeignKey,
PrimaryKeyConstraint,
Table,
)
from sqlalchemy.orm import relationship
from sqlalchemy.sql.schema import UniqueConstraint
from sqlalchemy_utils import TSVectorType
from typing import List, Optional

from dispatch.database.core import Base
from dispatch.models import (
DispatchBase,
NameStr,
Pagination,
PrimaryKey,
ProjectMixin,
TimeStampMixin,
)
from dispatch.plugin.models import PluginEventRead, PluginEvent
from dispatch.project.models import ProjectRead

assoc_cost_model_activities = Table(
"assoc_cost_model_activities",
Base.metadata,
Column("cost_model_id", Integer, ForeignKey("cost_model.id", ondelete="CASCADE")),
Column(
"cost_model_activity_id",
Integer,
ForeignKey("cost_model_activity.id", ondelete="CASCADE"),
),
PrimaryKeyConstraint("cost_model_id", "cost_model_activity_id"),
)


# SQLAlchemy Model
class CostModelActivity(Base):
id = Column(Integer, primary_key=True)
plugin_event_id = Column(Integer, ForeignKey(PluginEvent.id, ondelete="CASCADE"))
plugin_event = relationship(PluginEvent, backref="plugin_event")
response_time_seconds = Column(Integer, default=300)
enabled = Column(Boolean, default=True)


class CostModel(Base, TimeStampMixin, ProjectMixin):
__table_args__ = (UniqueConstraint("name", "project_id"),)
id = Column(Integer, primary_key=True)
name = Column(String)
description = Column(String)
enabled = Column(Boolean)
activities = relationship(
"CostModelActivity",
secondary=assoc_cost_model_activities,
lazy="subquery",
backref="cost_model",
)
search_vector = Column(
TSVectorType("name", "description", weights={"name": "A", "description": "B"})
)


# Pydantic Models
class CostModelActivityBase(DispatchBase):
plugin_event: PluginEventRead
response_time_seconds: Optional[int] = 300
enabled: Optional[bool] = Field(True, nullable=True)


class CostModelActivityCreate(CostModelActivityBase):
pass


class CostModelActivityRead(CostModelActivityBase):
id: PrimaryKey


class CostModelActivityUpdate(CostModelActivityBase):
id: Optional[PrimaryKey]


class CostModelBase(DispatchBase):
name: NameStr
description: Optional[str] = Field(None, nullable=True)
enabled: Optional[bool] = Field(True, nullable=True)
created_at: Optional[datetime]
updated_at: Optional[datetime]
project: ProjectRead


class CostModelUpdate(CostModelBase):
id: PrimaryKey
activities: Optional[List[CostModelActivityUpdate]] = []


class CostModelCreate(CostModelBase):
activities: Optional[List[CostModelActivityCreate]] = []


class CostModelRead(CostModelBase):
id: PrimaryKey
activities: Optional[List[CostModelActivityRead]] = []


class CostModelPagination(Pagination):
items: List[CostModelRead] = []
Loading
Loading