INFRA-2866 | Create and update incident with assigner and responder from slack (#394)

* INFRA-2866 | create incident modal with product

* INFRA-2866 | Update product flow

* INFRA-2866 | Resolving review comments

* INFRA-2866 | Adding default values for product, assigner and responder

* INFRA-2866 | bug fix in getting assigner and responder team

* INFRA-2866 | bug-fix: users in no team are not getting products

* INFRA-2866 | adding log lines

* INFRA-2866 | adding assigner team members into incident

* INFRA-2866 | updated help command response text

* INFRA-2866 | adding assigner team members by severity

* INFRA-2866 | updating product list for users with no product

* INFRA-2866 | assigner teams = (teamsOfUser ++ teamsOfSelectedProducts)

* INFRA-2866 | renamed assigner to reporting team

* INFRA-2866 | query to seed product as others for current open incidents without any product
This commit is contained in:
Shashank Shekhar
2024-03-19 16:26:30 +05:30
committed by GitHub
parent e9845b3a38
commit 233c632d38
58 changed files with 1982 additions and 675 deletions

View File

@@ -45,28 +45,29 @@ const (
// IncidentEntity all the incident created will go in this table
type IncidentEntity struct {
gorm.Model
Title string `gorm:"column:title"`
Description string `gorm:"column:description"`
Status uint `gorm:"column:status"`
SeverityId uint `gorm:"column:severity_id"`
IncidentName string `gorm:"column:incident_name"`
SlackChannel string `gorm:"column:slack_channel"`
DetectionTime *time.Time `gorm:"column:detection_time"`
StartTime time.Time `gorm:"column:start_time"`
EndTime *time.Time `gorm:"column:end_time"`
TeamId uint `gorm:"column:team_id"`
JiraLinks pq.StringArray `gorm:"column:jira_links;type:text[]"`
ConfluenceId *string `gorm:"column:confluence_id"`
SeverityTat time.Time `gorm:"column:severity_tat"`
RemindMeAt *time.Time `gorm:"column:remind_me_at"`
EnableReminder bool `gorm:"column:enable_reminder"`
CreatedBy string `gorm:"column:created_by"`
UpdatedBy string `gorm:"column:updated_by"`
MetaData JSON `gorm:"column:meta_data;type:jsonb"`
RCA string `gorm:"column:rca_text"`
ConferenceId string `gorm:"column:conference_id"`
ConferenceLink string `gorm:"column:conference_link"`
Products []product.ProductEntity `gorm:"many2many:incident_products;"`
Title string `gorm:"column:title"`
Description string `gorm:"column:description"`
Status uint `gorm:"column:status"`
SeverityId uint `gorm:"column:severity_id"`
IncidentName string `gorm:"column:incident_name"`
SlackChannel string `gorm:"column:slack_channel"`
DetectionTime *time.Time `gorm:"column:detection_time"`
StartTime time.Time `gorm:"column:start_time"`
EndTime *time.Time `gorm:"column:end_time"`
TeamId uint `gorm:"column:team_id"`
JiraLinks pq.StringArray `gorm:"column:jira_links;type:text[]"`
ConfluenceId *string `gorm:"column:confluence_id"`
SeverityTat time.Time `gorm:"column:severity_tat"`
RemindMeAt *time.Time `gorm:"column:remind_me_at"`
EnableReminder bool `gorm:"column:enable_reminder"`
CreatedBy string `gorm:"column:created_by"`
UpdatedBy string `gorm:"column:updated_by"`
MetaData JSON `gorm:"column:meta_data;type:jsonb"`
RCA string `gorm:"column:rca_text"`
ConferenceId string `gorm:"column:conference_id"`
ConferenceLink string `gorm:"column:conference_link"`
ReportingTeamId *uint `gorm:"column:reporting_team_id"`
Products []product.ProductEntity `gorm:"many2many:incident_products;"`
}
func (IncidentEntity) TableName() string {
@@ -79,20 +80,21 @@ func (i *IncidentEntity) ToDTO() IncidentDTO {
products = append(products, *p.ToDTO())
}
return IncidentDTO{
ID: i.ID,
Title: i.Title,
Description: i.Description,
Status: i.Status,
SeverityId: i.SeverityId,
IncidentName: i.IncidentName,
SlackChannel: i.SlackChannel,
TeamId: i.TeamId,
JiraLinks: i.JiraLinks,
ConfluenceId: i.ConfluenceId,
CreatedBy: i.CreatedBy,
RCA: i.RCA,
ConferenceId: i.ConferenceId,
Products: products,
ID: i.ID,
Title: i.Title,
Description: i.Description,
Status: i.Status,
SeverityId: i.SeverityId,
IncidentName: i.IncidentName,
SlackChannel: i.SlackChannel,
TeamId: i.TeamId,
JiraLinks: i.JiraLinks,
ConfluenceId: i.ConfluenceId,
CreatedBy: i.CreatedBy,
RCA: i.RCA,
ConferenceId: i.ConferenceId,
ReportingTeamId: i.ReportingTeamId,
Products: products,
}
}

View File

@@ -69,19 +69,20 @@ func (r *Repository) CreateIncidentEntity(request *CreateIncidentDTO, tx *gorm.D
}
incidentEntity := &IncidentEntity{
Title: request.Title,
Description: request.Description,
Status: incidentStatusEntity.ID,
SeverityId: uint(severityId),
DetectionTime: request.DetectionTime,
StartTime: request.StartTime,
TeamId: uint(teamId),
EnableReminder: request.EnableReminder,
SeverityTat: time.Now().AddDate(0, 0, severity.Sla),
CreatedBy: request.CreatedBy,
UpdatedBy: request.UpdatedBy,
MetaData: request.MetaData,
Products: products,
Title: request.Title,
Description: request.Description,
Status: incidentStatusEntity.ID,
SeverityId: uint(severityId),
DetectionTime: request.DetectionTime,
StartTime: request.StartTime,
TeamId: uint(teamId),
EnableReminder: request.EnableReminder,
SeverityTat: time.Now().AddDate(0, 0, severity.Sla),
CreatedBy: request.CreatedBy,
UpdatedBy: request.UpdatedBy,
MetaData: request.MetaData,
ReportingTeamId: request.ReportingTeamID,
Products: products,
}
tx.Create(incidentEntity)
@@ -310,7 +311,7 @@ func (r *Repository) GetOpenIncidents(limit int) (*[]IncidentSeverityTeamDTO, er
func (r *Repository) FindIncidentByChannelId(channelId string) (*IncidentEntity, error) {
var incidentEntity IncidentEntity
result := r.gormClient.Find(&incidentEntity, "slack_channel = ?", channelId)
result := r.gormClient.Preload("Products").Find(&incidentEntity, "slack_channel = ?", channelId)
if result.Error != nil {
return nil, result.Error
}
@@ -395,7 +396,7 @@ func (r *Repository) FetchAllIncidentsPaginated(
from string,
to string,
) ([]IncidentEntity, int, error) {
var query = r.gormClient.Model([]IncidentEntity{})
var query = r.gormClient.Model([]IncidentEntity{}).Preload("Products")
var incidentEntity []IncidentEntity
if len(TeamsId) != 0 {
query = query.Where("team_id IN ?", TeamsId)

View File

@@ -34,27 +34,27 @@ func (j JSON) Value() (driver.Value, error) {
}
type CreateIncidentDTO struct {
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
Severity string `json:"severity,omitempty"`
Pagerduty string `json:"pagerduty,omitempty"`
Status IncidentStatus `json:"status,omitempty"`
IncidentName string `json:"incident_name,omitempty"`
SlackChannel string `json:"slack_channel,omitempty"`
DetectionTime *time.Time `json:"detection_time,omitempty"`
StartTime time.Time `json:"start_time,omitempty"`
EndTime *time.Time `json:"end_time,omitempty"`
TeamId string `json:"type,omitempty"`
JiraId *string `json:"jira_id,omitempty"`
ConfluenceId *string `json:"confluence_id,omitempty"`
SeverityTat *time.Time `json:"severity_tat,omitempty"`
RemindMeAt *time.Time `json:"remind_me_at,omitempty"`
EnableReminder bool `json:"enable_reminder,omitempty"`
CreatedBy string `json:"created_by,omitempty"`
UpdatedBy string `json:"updated_by,omitempty"`
MetaData JSON `json:"meta_data,omitempty"`
ProductIds []uint `json:"product_ids,omitempty"`
AssignerTeamID uint `json:"assigner_team_id,omitempty"`
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
Severity string `json:"severity,omitempty"`
Pagerduty string `json:"pagerduty,omitempty"`
Status IncidentStatus `json:"status,omitempty"`
IncidentName string `json:"incident_name,omitempty"`
SlackChannel string `json:"slack_channel,omitempty"`
DetectionTime *time.Time `json:"detection_time,omitempty"`
StartTime time.Time `json:"start_time,omitempty"`
EndTime *time.Time `json:"end_time,omitempty"`
TeamId string `json:"type,omitempty"`
JiraId *string `json:"jira_id,omitempty"`
ConfluenceId *string `json:"confluence_id,omitempty"`
SeverityTat *time.Time `json:"severity_tat,omitempty"`
RemindMeAt *time.Time `json:"remind_me_at,omitempty"`
EnableReminder bool `json:"enable_reminder,omitempty"`
CreatedBy string `json:"created_by,omitempty"`
UpdatedBy string `json:"updated_by,omitempty"`
MetaData JSON `json:"meta_data,omitempty"`
ProductIds []uint `json:"product_ids,omitempty"`
ReportingTeamID *uint `json:"reporting_team_id,omitempty"`
}
type IncidentSeverityTeamDTO struct {
@@ -92,19 +92,20 @@ type TeamMetricDetailsOfIncident struct {
}
type IncidentDTO struct {
ID uint `json:"id,omitempty"`
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
SeverityId uint `json:"severity_id,omitempty"`
Status uint `json:"status,omitempty"`
IncidentName string `json:"incident_name,omitempty"`
SlackChannel string `json:"slack_channel,omitempty"`
TeamId uint `json:"team_id,omitempty"`
JiraLinks pq.StringArray `json:"jira_links,omitempty"`
ConfluenceId *string `json:"confluence_id,omitempty"`
CreatedBy string `json:"created_by,omitempty"`
RCA string `json:"rca,omitempty"`
ConferenceId string `json:"conference_id,omitempty"`
ConferenceLink string `json:"conference_link,omitempty"`
Products []product.ProductDTO `json:"products,omitempty"`
ID uint `json:"id,omitempty"`
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
SeverityId uint `json:"severity_id,omitempty"`
Status uint `json:"status,omitempty"`
IncidentName string `json:"incident_name,omitempty"`
SlackChannel string `json:"slack_channel,omitempty"`
TeamId uint `json:"team_id,omitempty"`
JiraLinks pq.StringArray `json:"jira_links,omitempty"`
ConfluenceId *string `json:"confluence_id,omitempty"`
CreatedBy string `json:"created_by,omitempty"`
RCA string `json:"rca,omitempty"`
ConferenceId string `json:"conference_id,omitempty"`
ConferenceLink string `json:"conference_link,omitempty"`
ReportingTeamId *uint `json:"reporting_team_id,omitempty"`
Products []product.ProductDTO `json:"products,omitempty"`
}

View File

@@ -16,7 +16,7 @@ func NewIncidentChannelRepository(
}
}
func (r *Repository) GetIncidentChannels(incidentId uint) (*[]IncidentChannelEntity, error) {
func (r *Repository) GetIncidentChannels(incidentId uint) ([]IncidentChannelEntity, error) {
var incidentChannels []IncidentChannelEntity
result := r.gormClient.Find(&incidentChannels, "incident_id = ?", incidentId)
@@ -28,5 +28,5 @@ func (r *Repository) GetIncidentChannels(incidentId uint) (*[]IncidentChannelEnt
return nil, nil
}
return &incidentChannels, nil
return incidentChannels, nil
}

View File

@@ -94,15 +94,17 @@ func (repo *productsTeamsRepositoryImpl) GetProductTeamsByProductID(productID ui
return nil, result.Error
}
if result.RowsAffected == 0 {
return nil, nil
return nil, gorm.ErrRecordNotFound
}
teamDTOs := make([]team.TeamDTO, 0)
for _, e := range entities {
teamDTOs = append(teamDTOs, team.TeamDTO{
ID: e.Team.ID,
Name: e.Team.Name,
Active: e.Team.Active,
})
if e.Team.ID > 0 {
teamDTOs = append(teamDTOs, team.TeamDTO{
ID: e.Team.ID,
Name: e.Team.Name,
Active: e.Team.Active,
})
}
}
dto := ProductTeamsDTO{
Product: product.ProductDTO{ProductID: entities[0].ProductID, ProductName: entities[0].Product.Name},

View File

@@ -23,8 +23,8 @@ func (TeamEntity) TableName() string {
return "team"
}
func (entity TeamEntity) ToDTO() TeamDTO {
return TeamDTO{
func (entity *TeamEntity) ToDTO() *TeamDTO {
return &TeamDTO{
ID: entity.ID,
Name: entity.Name,
SlackUserIds: entity.SlackUserIds,

View File

@@ -26,7 +26,7 @@ func (entity TeamSeverityEntity) ToDTO() TeamSeverityDTO {
TeamID: entity.TeamID,
SeverityID: entity.SeverityID,
Sla: entity.Sla,
TeamDTO: entity.Team.ToDTO(),
TeamDTO: *entity.Team.ToDTO(),
SeverityDTO: entity.Severity.ToDTO(),
}
}

View File

@@ -24,7 +24,7 @@ func (entity TeamUserEntity) ToDTO() *TeamUserDTO {
ID: entity.ID,
TeamID: entity.TeamID,
UserID: entity.UserID,
Team: entity.Team.ToDTO(),
Team: *entity.Team.ToDTO(),
User: *entity.User.ToDTO(),
}
}