alerts.tsx 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. import type {SchemaFormConfig} from 'sentry/views/settings/organizationIntegrations/sentryAppExternalForm';
  2. import type {IssueConfigField} from './integrations';
  3. export const enum IssueAlertActionType {
  4. SLACK = 'sentry.integrations.slack.notify_action.SlackNotifyServiceAction',
  5. NOTIFY_EMAIL = 'sentry.mail.actions.NotifyEmailAction',
  6. DISCORD = 'sentry.integrations.discord.notify_action.DiscordNotifyServiceAction',
  7. SENTRY_APP = 'sentry.rules.actions.notify_event_sentry_app.NotifyEventSentryAppAction',
  8. MS_TEAMS = 'sentry.integrations.msteams.notify_action.MsTeamsNotifyServiceAction',
  9. PAGER_DUTY = 'sentry.integrations.pagerduty.notify_action.PagerDutyNotifyServiceAction',
  10. OPSGENIE = 'sentry.integrations.opsgenie.notify_action.OpsgenieNotifyTeamAction',
  11. /**
  12. * Legacy integrations
  13. */
  14. NOTIFY_EVENT_ACTION = 'sentry.rules.actions.notify_event.NotifyEventAction',
  15. /**
  16. * Webhooks
  17. */
  18. NOTIFY_EVENT_SERVICE_ACTION = 'sentry.rules.actions.notify_event_service.NotifyEventServiceAction',
  19. /**
  20. * Ticket integrations
  21. */
  22. JIRA_CREATE_TICKET = 'sentry.integrations.jira.notify_action.JiraCreateTicketAction',
  23. JIRA_SERVER_CREATE_TICKET = 'sentry.integrations.jira_server.notify_action.JiraServerCreateTicketAction',
  24. GITHUB_CREATE_TICKET = 'sentry.integrations.github.notify_action.GitHubCreateTicketAction',
  25. GITHUB_ENTERPRISE_CREATE_TICKET = 'sentry.integrations.github_enterprise.notify_action.GitHubEnterpriseCreateTicketAction',
  26. AZURE_DEVOPS_CREATE_TICKET = 'sentry.integrations.vsts.notify_action.AzureDevopsCreateTicketAction',
  27. }
  28. export const enum IssueAlertConditionType {
  29. EVERY_EVENT = 'sentry.rules.conditions.every_event.EveryEventCondition',
  30. FIRST_SEEN_EVENT = 'sentry.rules.conditions.first_seen_event.FirstSeenEventCondition',
  31. REGRESSION_EVENT = 'sentry.rules.conditions.regression_event.RegressionEventCondition',
  32. REAPPEARED_EVENT = 'sentry.rules.conditions.reappeared_event.ReappearedEventCondition',
  33. EVENT_FREQUENCY = 'sentry.rules.conditions.event_frequency.EventFrequencyCondition',
  34. EVENT_UNIQUE_USER_FREQUENCY = 'sentry.rules.conditions.event_frequency.EventUniqueUserFrequencyCondition',
  35. EVENT_FREQUENCY_PERCENT = 'sentry.rules.conditions.event_frequency.EventFrequencyPercentCondition',
  36. HIGH_PRIORITY_ISSUE = 'sentry.rules.conditions.high_priority_issue.HighPriorityIssueCondition',
  37. }
  38. export const enum IssueAlertFilterType {
  39. AGE_COMPARISON = 'sentry.rules.filters.age_comparison.AgeComparisonFilter',
  40. ISSUE_OCCURRENCES = 'sentry.rules.filters.issue_occurrences.IssueOccurrencesFilter',
  41. ASSIGNED_TO = 'sentry.rules.filters.assigned_to.AssignedToFilter',
  42. LATEST_ADOPTED_RELEASE = 'sentry.rules.filters.latest_adopted_release_filter.LatestAdoptedReleaseFilter',
  43. LATEST_RELEASE = 'sentry.rules.filters.latest_release.LatestReleaseFilter',
  44. ISSUE_CATEGORY = 'sentry.rules.filters.issue_category.IssueCategoryFilter',
  45. EVENT_ATTRIBUTE = 'sentry.rules.filters.event_attribute.EventAttributeFilter',
  46. TAGGED_EVENT = 'sentry.rules.filters.tagged_event.TaggedEventFilter',
  47. LEVEL = 'sentry.rules.filters.level.LevelFilter',
  48. }
  49. interface IssueAlertFormFieldChoice {
  50. type: 'choice';
  51. choices?: Array<[key: string | number, name: string]>;
  52. initial?: string;
  53. placeholder?: string;
  54. }
  55. interface IssueAlertFormFieldString {
  56. type: 'string';
  57. initial?: string;
  58. placeholder?: string;
  59. }
  60. interface IssueAlertFormFieldNumber {
  61. type: 'number';
  62. initial?: string;
  63. placeholder?: number | string;
  64. }
  65. /**
  66. * The fields that are used to render the form for an action or condition.
  67. */
  68. type IssueAlertRuleFormField =
  69. | IssueAlertFormFieldChoice
  70. | IssueAlertFormFieldString
  71. | IssueAlertFormFieldNumber;
  72. /**
  73. * All issue alert configuration objects have these properties.
  74. */
  75. interface IssueAlertConfigBase {
  76. enabled: boolean;
  77. label: string;
  78. /**
  79. * "Send a Slack notification"
  80. */
  81. prompt?: string;
  82. }
  83. /**
  84. * Generic alert configuration. Do not add properties unless they are used by all filters.
  85. */
  86. interface IssueAlertGenericActionConfig extends IssueAlertConfigBase {
  87. id:
  88. | `${IssueAlertActionType.SLACK}`
  89. | `${IssueAlertActionType.NOTIFY_EMAIL}`
  90. | `${IssueAlertActionType.DISCORD}`
  91. | `${IssueAlertActionType.SENTRY_APP}`
  92. | `${IssueAlertActionType.MS_TEAMS}`
  93. | `${IssueAlertActionType.PAGER_DUTY}`
  94. | `${IssueAlertActionType.OPSGENIE}`
  95. | `${IssueAlertActionType.NOTIFY_EVENT_ACTION}`
  96. | `${IssueAlertActionType.NOTIFY_EVENT_SERVICE_ACTION}`;
  97. formFields?: Record<string, IssueAlertRuleFormField>;
  98. }
  99. /**
  100. * Currently filters and conditions are basically the same, just with different IDs.
  101. * Do not add properties unless they are used by all filters.
  102. */
  103. export interface IssueAlertGenericConditionConfig extends IssueAlertConfigBase {
  104. id: `${IssueAlertConditionType}` | `${IssueAlertFilterType}`;
  105. formFields?: Record<string, IssueAlertRuleFormField>;
  106. }
  107. /**
  108. * The object describing the options the slack action can use.
  109. */
  110. interface IssueAlertSlackConfig extends IssueAlertConfigBase {
  111. formFields: {
  112. channel: IssueAlertFormFieldString;
  113. channel_id: IssueAlertFormFieldString;
  114. tags: IssueAlertFormFieldString;
  115. workspace: IssueAlertFormFieldChoice;
  116. };
  117. id: `${IssueAlertActionType.SLACK}`;
  118. }
  119. interface IssueAlertTicketIntegrationConfig extends IssueAlertConfigBase {
  120. actionType: 'ticket';
  121. formFields: SchemaFormConfig;
  122. id:
  123. | `${IssueAlertActionType.JIRA_CREATE_TICKET}`
  124. | `${IssueAlertActionType.JIRA_SERVER_CREATE_TICKET}`
  125. | `${IssueAlertActionType.GITHUB_CREATE_TICKET}`
  126. | `${IssueAlertActionType.GITHUB_ENTERPRISE_CREATE_TICKET}`
  127. | `${IssueAlertActionType.AZURE_DEVOPS_CREATE_TICKET}`;
  128. link: string;
  129. ticketType: string;
  130. }
  131. interface IssueAlertSentryAppIntegrationConfig extends IssueAlertConfigBase {
  132. actionType: 'sentryapp';
  133. formFields: SchemaFormConfig;
  134. id: `${IssueAlertActionType.SENTRY_APP}`;
  135. sentryAppInstallationUuid: string;
  136. }
  137. /**
  138. * The actions that an organization has enabled and can be used to create an issue alert.
  139. */
  140. export type IssueAlertConfigurationAction =
  141. | IssueAlertGenericActionConfig
  142. | IssueAlertTicketIntegrationConfig
  143. | IssueAlertSentryAppIntegrationConfig
  144. | IssueAlertSlackConfig;
  145. /**
  146. * Describes the actions, filters, and conditions that can be used
  147. * to create an issue alert.
  148. */
  149. export interface IssueAlertConfiguration {
  150. actions: IssueAlertConfigurationAction[];
  151. conditions: IssueAlertGenericConditionConfig[];
  152. filters: IssueAlertGenericConditionConfig[];
  153. }
  154. /**
  155. * These templates that tell the UI how to render the action or condition
  156. * and what fields it needs
  157. */
  158. export interface IssueAlertRuleActionTemplate {
  159. enabled: boolean;
  160. id: string;
  161. label: string;
  162. actionType?: 'ticket' | 'sentryapp';
  163. formFields?:
  164. | {
  165. [key: string]: IssueAlertRuleFormField;
  166. }
  167. | SchemaFormConfig;
  168. link?: string;
  169. prompt?: string;
  170. sentryAppInstallationUuid?: string;
  171. ticketType?: string;
  172. }
  173. export type IssueAlertRuleConditionTemplate = IssueAlertRuleActionTemplate;
  174. /**
  175. * These are the action or condition data that the user is editing or has saved.
  176. */
  177. export interface IssueAlertRuleAction
  178. extends Omit<IssueAlertRuleActionTemplate, 'formFields' | 'enabled' | 'label'> {
  179. // These are the same values as the keys in `formFields` for a template
  180. [key: string]: any;
  181. dynamic_form_fields?: IssueConfigField[];
  182. }
  183. export type IssueAlertRuleCondition = Omit<
  184. IssueAlertRuleConditionTemplate,
  185. 'formFields' | 'enabled' | 'label'
  186. > & {
  187. dynamic_form_fields?: IssueConfigField[];
  188. } & {
  189. // These are the same values as the keys in `formFields` for a template
  190. [key: string]: number | string;
  191. };
  192. export interface UnsavedIssueAlertRule {
  193. /** When an issue matches [actionMatch] of the following */
  194. actionMatch: 'all' | 'any' | 'none';
  195. actions: IssueAlertRuleAction[];
  196. conditions: IssueAlertRuleCondition[];
  197. /** If that issue has [filterMatch] of these properties */
  198. filterMatch: 'all' | 'any' | 'none';
  199. filters: IssueAlertRuleCondition[];
  200. frequency: number;
  201. name: string;
  202. environment?: null | string;
  203. owner?: string | null;
  204. }
  205. // Issue-based alert rule
  206. export interface IssueAlertRule extends UnsavedIssueAlertRule {
  207. createdBy: {email: string; id: number; name: string} | null;
  208. dateCreated: string;
  209. id: string;
  210. projects: string[];
  211. snooze: boolean;
  212. status: 'active' | 'disabled';
  213. /**
  214. * Date alert is set to be disabled unless action is taken
  215. */
  216. disableDate?: string;
  217. disableReason?: 'noisy';
  218. errors?: {detail: string}[];
  219. lastTriggered?: string;
  220. /**
  221. * Set to true to opt out of the rule being automatically disabled
  222. * see also - status=disabled, disableDate, disableReason
  223. * TODO(scttcper): This is only used in the edit request and we should
  224. * move it to its own interface
  225. */
  226. optOutEdit?: boolean;
  227. snoozeCreatedBy?: string;
  228. snoozeForEveryone?: boolean;
  229. }
  230. // Project's alert rule stats
  231. export type ProjectAlertRuleStats = {
  232. count: number;
  233. date: string;
  234. };
  235. export enum MailActionTargetType {
  236. ISSUE_OWNERS = 'IssueOwners',
  237. TEAM = 'Team',
  238. MEMBER = 'Member',
  239. RELEASE_MEMBERS = 'ReleaseMembers',
  240. }
  241. export enum AssigneeTargetType {
  242. UNASSIGNED = 'Unassigned',
  243. TEAM = 'Team',
  244. MEMBER = 'Member',
  245. }
  246. export type NoteType = {
  247. mentions: string[];
  248. text: string;
  249. };
  250. /**
  251. * Used when determining what types of actions a rule has. The default action is "sentry.mail.actions.NotifyEmailAction"
  252. * while other actions can be integration (Slack, PagerDuty, etc) actions. We need to know this to determine what kind of muting
  253. * the alert should have.
  254. */
  255. export enum RuleActionsCategories {
  256. ALL_DEFAULT = 'all_default',
  257. SOME_DEFAULT = 'some_default',
  258. NO_DEFAULT = 'no_default',
  259. }