alerts.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  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. NEW_HIGH_PRIORITY_ISSUE = 'sentry.rules.conditions.high_priority_issue.NewHighPriorityIssueCondition',
  37. EXISTING_HIGH_PRIORITY_ISSUE = 'sentry.rules.conditions.high_priority_issue.ExistingHighPriorityIssueCondition',
  38. }
  39. export const enum IssueAlertFilterType {
  40. AGE_COMPARISON = 'sentry.rules.filters.age_comparison.AgeComparisonFilter',
  41. ISSUE_OCCURRENCES = 'sentry.rules.filters.issue_occurrences.IssueOccurrencesFilter',
  42. ASSIGNED_TO = 'sentry.rules.filters.assigned_to.AssignedToFilter',
  43. LATEST_ADOPTED_RELEASE = 'sentry.rules.filters.latest_adopted_release_filter.LatestAdoptedReleaseFilter',
  44. LATEST_RELEASE = 'sentry.rules.filters.latest_release.LatestReleaseFilter',
  45. ISSUE_CATEGORY = 'sentry.rules.filters.issue_category.IssueCategoryFilter',
  46. EVENT_ATTRIBUTE = 'sentry.rules.filters.event_attribute.EventAttributeFilter',
  47. TAGGED_EVENT = 'sentry.rules.filters.tagged_event.TaggedEventFilter',
  48. LEVEL = 'sentry.rules.filters.level.LevelFilter',
  49. }
  50. interface IssueAlertFormFieldChoice {
  51. type: 'choice';
  52. choices?: Array<[key: string | number, name: string]>;
  53. initial?: string;
  54. placeholder?: string;
  55. }
  56. interface IssueAlertFormFieldString {
  57. type: 'string';
  58. initial?: string;
  59. placeholder?: string;
  60. }
  61. interface IssueAlertFormFieldNumber {
  62. type: 'number';
  63. initial?: string;
  64. placeholder?: number | string;
  65. }
  66. /**
  67. * The fields that are used to render the form for an action or condition.
  68. */
  69. type IssueAlertRuleFormField =
  70. | IssueAlertFormFieldChoice
  71. | IssueAlertFormFieldString
  72. | IssueAlertFormFieldNumber;
  73. /**
  74. * All issue alert configuration objects have these properties.
  75. */
  76. interface IssueAlertConfigBase {
  77. enabled: boolean;
  78. label: string;
  79. /**
  80. * "Send a Slack notification"
  81. */
  82. prompt?: string;
  83. }
  84. /**
  85. * Generic alert configuration. Do not add properties unless they are used by all filters.
  86. */
  87. interface IssueAlertGenericActionConfig extends IssueAlertConfigBase {
  88. id:
  89. | `${IssueAlertActionType.SLACK}`
  90. | `${IssueAlertActionType.NOTIFY_EMAIL}`
  91. | `${IssueAlertActionType.DISCORD}`
  92. | `${IssueAlertActionType.SENTRY_APP}`
  93. | `${IssueAlertActionType.MS_TEAMS}`
  94. | `${IssueAlertActionType.PAGER_DUTY}`
  95. | `${IssueAlertActionType.OPSGENIE}`
  96. | `${IssueAlertActionType.NOTIFY_EVENT_ACTION}`
  97. | `${IssueAlertActionType.NOTIFY_EVENT_SERVICE_ACTION}`;
  98. formFields?: Record<string, IssueAlertRuleFormField>;
  99. }
  100. /**
  101. * Currently filters and conditions are basically the same, just with different IDs.
  102. * Do not add properties unless they are used by all filters.
  103. */
  104. export interface IssueAlertGenericConditionConfig extends IssueAlertConfigBase {
  105. id: `${IssueAlertConditionType}` | `${IssueAlertFilterType}`;
  106. formFields?: Record<string, IssueAlertRuleFormField>;
  107. }
  108. /**
  109. * The object describing the options the slack action can use.
  110. */
  111. interface IssueAlertSlackConfig extends IssueAlertConfigBase {
  112. formFields: {
  113. channel: IssueAlertFormFieldString;
  114. channel_id: IssueAlertFormFieldString;
  115. tags: IssueAlertFormFieldString;
  116. workspace: IssueAlertFormFieldChoice;
  117. };
  118. id: `${IssueAlertActionType.SLACK}`;
  119. }
  120. interface IssueAlertTicketIntegrationConfig extends IssueAlertConfigBase {
  121. actionType: 'ticket';
  122. formFields: SchemaFormConfig;
  123. id:
  124. | `${IssueAlertActionType.JIRA_CREATE_TICKET}`
  125. | `${IssueAlertActionType.JIRA_SERVER_CREATE_TICKET}`
  126. | `${IssueAlertActionType.GITHUB_CREATE_TICKET}`
  127. | `${IssueAlertActionType.GITHUB_ENTERPRISE_CREATE_TICKET}`
  128. | `${IssueAlertActionType.AZURE_DEVOPS_CREATE_TICKET}`;
  129. link: string;
  130. ticketType: string;
  131. }
  132. interface IssueAlertSentryAppIntegrationConfig extends IssueAlertConfigBase {
  133. actionType: 'sentryapp';
  134. formFields: SchemaFormConfig;
  135. id: `${IssueAlertActionType.SENTRY_APP}`;
  136. sentryAppInstallationUuid: string;
  137. }
  138. /**
  139. * The actions that an organization has enabled and can be used to create an issue alert.
  140. */
  141. export type IssueAlertConfigurationAction =
  142. | IssueAlertGenericActionConfig
  143. | IssueAlertTicketIntegrationConfig
  144. | IssueAlertSentryAppIntegrationConfig
  145. | IssueAlertSlackConfig;
  146. /**
  147. * Describes the actions, filters, and conditions that can be used
  148. * to create an issue alert.
  149. */
  150. export interface IssueAlertConfiguration {
  151. actions: IssueAlertConfigurationAction[];
  152. conditions: IssueAlertGenericConditionConfig[];
  153. filters: IssueAlertGenericConditionConfig[];
  154. }
  155. /**
  156. * These templates that tell the UI how to render the action or condition
  157. * and what fields it needs
  158. */
  159. export interface IssueAlertRuleActionTemplate {
  160. enabled: boolean;
  161. id: string;
  162. label: string;
  163. actionType?: 'ticket' | 'sentryapp';
  164. formFields?:
  165. | {
  166. [key: string]: IssueAlertRuleFormField;
  167. }
  168. | SchemaFormConfig;
  169. link?: string;
  170. prompt?: string;
  171. sentryAppInstallationUuid?: string;
  172. ticketType?: string;
  173. }
  174. export type IssueAlertRuleConditionTemplate = IssueAlertRuleActionTemplate;
  175. /**
  176. * These are the action or condition data that the user is editing or has saved.
  177. */
  178. export interface IssueAlertRuleAction
  179. extends Omit<IssueAlertRuleActionTemplate, 'formFields' | 'enabled' | 'label'> {
  180. // These are the same values as the keys in `formFields` for a template
  181. [key: string]: any;
  182. dynamic_form_fields?: IssueConfigField[];
  183. }
  184. export type IssueAlertRuleCondition = Omit<
  185. IssueAlertRuleConditionTemplate,
  186. 'formFields' | 'enabled' | 'label'
  187. > & {
  188. dynamic_form_fields?: IssueConfigField[];
  189. } & {
  190. // These are the same values as the keys in `formFields` for a template
  191. [key: string]: number | string;
  192. };
  193. interface SlackAction {
  194. channel: string | undefined;
  195. id: IssueAlertActionType.SLACK;
  196. workspace: string | undefined;
  197. channel_id?: string | undefined;
  198. notes?: string | undefined;
  199. tags?: string | undefined;
  200. }
  201. interface DiscordAction {
  202. channel_id: string | undefined;
  203. id: IssueAlertActionType.DISCORD;
  204. server: string | undefined;
  205. tags?: string | undefined;
  206. }
  207. interface MSTeamsAction {
  208. channel: string | undefined;
  209. id: IssueAlertActionType.MS_TEAMS;
  210. team: string | undefined;
  211. }
  212. export type IntegrationAction = SlackAction | DiscordAction | MSTeamsAction;
  213. export interface UnsavedIssueAlertRule {
  214. /** When an issue matches [actionMatch] of the following */
  215. actionMatch: 'all' | 'any' | 'none';
  216. actions: IssueAlertRuleAction[];
  217. conditions: IssueAlertRuleCondition[];
  218. /** If that issue has [filterMatch] of these properties */
  219. filterMatch: 'all' | 'any' | 'none';
  220. filters: IssueAlertRuleCondition[];
  221. frequency: number;
  222. name: string;
  223. environment?: null | string;
  224. owner?: string | null;
  225. }
  226. // Issue-based alert rule
  227. export interface IssueAlertRule extends UnsavedIssueAlertRule {
  228. createdBy: {email: string; id: number; name: string} | null;
  229. dateCreated: string;
  230. id: string;
  231. projects: string[];
  232. snooze: boolean;
  233. status: 'active' | 'disabled';
  234. /**
  235. * Date alert is set to be disabled unless action is taken
  236. */
  237. disableDate?: string;
  238. disableReason?: 'noisy';
  239. errors?: {detail: string}[];
  240. lastTriggered?: string;
  241. /**
  242. * Set to true to opt out of the rule being automatically disabled
  243. * see also - status=disabled, disableDate, disableReason
  244. * TODO(scttcper): This is only used in the edit request and we should
  245. * move it to its own interface
  246. */
  247. optOutEdit?: boolean;
  248. snoozeCreatedBy?: string;
  249. snoozeForEveryone?: boolean;
  250. }
  251. // Project's alert rule stats
  252. export type ProjectAlertRuleStats = {
  253. count: number;
  254. date: string;
  255. };
  256. export enum MailActionTargetType {
  257. ISSUE_OWNERS = 'IssueOwners',
  258. TEAM = 'Team',
  259. MEMBER = 'Member',
  260. RELEASE_MEMBERS = 'ReleaseMembers',
  261. }
  262. export enum AssigneeTargetType {
  263. UNASSIGNED = 'Unassigned',
  264. TEAM = 'Team',
  265. MEMBER = 'Member',
  266. }
  267. export type NoteType = {
  268. mentions: string[];
  269. text: string;
  270. };
  271. /**
  272. * Used when determining what types of actions a rule has. The default action is "sentry.mail.actions.NotifyEmailAction"
  273. * while other actions can be integration (Slack, PagerDuty, etc) actions. We need to know this to determine what kind of muting
  274. * the alert should have.
  275. */
  276. export enum RuleActionsCategories {
  277. ALL_DEFAULT = 'all_default',
  278. SOME_DEFAULT = 'some_default',
  279. NO_DEFAULT = 'no_default',
  280. }
  281. export enum MonitorType {
  282. CONTINUOUS = 0,
  283. ACTIVATED = 1,
  284. }
  285. export enum ActivationConditionType {
  286. RELEASE_CREATION = 0,
  287. DEPLOY_CREATION = 1,
  288. }
  289. export type AlertRuleActivation = {
  290. activator: string;
  291. alertRuleId: string;
  292. conditionType: string;
  293. dateCreated: string;
  294. finishedAt: string;
  295. id: string;
  296. isComplete: boolean;
  297. querySubscriptionId: string;
  298. metricValue?: number;
  299. };
  300. export enum ActivationTrigger {
  301. ACTIVATED = 'activated',
  302. FINISHED = 'finished',
  303. }
  304. export type ActivationTriggerActivity = {
  305. activator: string;
  306. conditionType: string;
  307. dateCreated: string;
  308. type: ActivationTrigger;
  309. };