feat(sla): persist applied sla on conversations

This commit is contained in:
2026-06-05 07:16:05 +08:00
parent 4cf68d1639
commit a11bb965fa
6 changed files with 270 additions and 30 deletions
@@ -82,6 +82,9 @@ func (s *ConversationCrudTestSuite) SetupSuite() {
&model.AccountUser{},
&model.Team{},
&model.TeamMember{},
&model.SlaPolicy{},
&model.AppliedSLA{},
&model.SlaEvent{},
)
s.Require().NoError(err)
@@ -95,6 +98,8 @@ func (s *ConversationCrudTestSuite) SetupSuite() {
teamRepo := repository.NewTeamRepo(db)
teamMemberRepo := repository.NewTeamMemberRepo(db)
conversationSvc := service.NewConversationService(convRepo, msgRepo, dispatcher, inboxMemberSvc, accountUserRepo, teamRepo, teamMemberRepo)
appliedSlaSvc := service.NewAppliedSlaService(repository.NewAppliedSlaRepo(db), repository.NewSlaEventRepo(db), repository.NewSlaPolicyRepo(db), convRepo)
conversationSvc.SetAppliedSlaService(appliedSlaSvc)
mockLLM := &mockConvCrudLLMProvider{}
messageSvc := service.NewMessageService(msgRepo, dispatcher, mockLLM)
handler := NewConversationHandler(conversationSvc, messageSvc)
@@ -163,6 +168,8 @@ func (s *ConversationCrudTestSuite) SetupTest() {
}
func (s *ConversationCrudTestSuite) TearDownTest() {
s.db.Exec("DELETE FROM sla_events")
s.db.Exec("DELETE FROM applied_slas")
s.db.Exec("DELETE FROM conversation_labels")
s.db.Exec("DELETE FROM conversations")
s.db.Exec("DELETE FROM contact_inboxes")
@@ -174,6 +181,7 @@ func (s *ConversationCrudTestSuite) TearDownTest() {
s.db.Exec("DELETE FROM accounts")
s.db.Exec("DELETE FROM teams")
s.db.Exec("DELETE FROM team_members")
s.db.Exec("DELETE FROM sla_policies")
}
func (s *ConversationCrudTestSuite) accountURL() string {
@@ -352,6 +360,44 @@ func (s *ConversationCrudTestSuite) TestUpdate_Success() {
assert.Equal(s.T(), "resolved", resp["status"])
}
func (s *ConversationCrudTestSuite) TestUpdate_WithSlaPolicyCreatesAppliedSlaPayload() {
policy := &model.SlaPolicy{
AccountID: s.testAccount.ID,
Name: "Gold SLA",
Description: "Priority customers",
FirstResponseTimeThreshold: 15,
NextResponseTimeThreshold: 30,
ResolutionTimeThreshold: 120,
}
s.Require().NoError(s.db.Create(policy).Error)
body, _ := json.Marshal(map[string]interface{}{
"sla_policy_id": policy.ID,
})
w := httptest.NewRecorder()
req, _ := http.NewRequest("PUT", s.convURL(s.testConv.ID), bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
s.router.ServeHTTP(w, req)
assert.Equal(s.T(), http.StatusOK, w.Code)
var resp map[string]interface{}
err := json.Unmarshal(w.Body.Bytes(), &resp)
assert.NoError(s.T(), err)
assert.Equal(s.T(), float64(policy.ID), resp["sla_policy_id"])
applied, ok := resp["applied_sla"].(map[string]interface{})
s.Require().True(ok)
assert.Equal(s.T(), float64(policy.ID), applied["sla_id"])
assert.Equal(s.T(), "active", applied["sla_status"])
assert.Equal(s.T(), "Gold SLA", applied["sla_name"])
assert.Equal(s.T(), float64(15), applied["sla_first_response_time_threshold"])
var count int64
s.Require().NoError(s.db.Model(&model.AppliedSLA{}).Where("conversation_id = ?", s.testConv.ID).Count(&count).Error)
assert.Equal(s.T(), int64(1), count)
}
func (s *ConversationCrudTestSuite) TestUpdate_InvalidAccountID() {
body, _ := json.Marshal(map[string]interface{}{
"status": "resolved",