diff --git a/cmd/automation.go b/cmd/automation.go index 1a81d94..1bb7953 100644 --- a/cmd/automation.go +++ b/cmd/automation.go @@ -45,10 +45,11 @@ func handleToggleAutomationRule(r *fastglue.Request) error { app = r.Context.(*App) id, _ = strconv.Atoi(r.RequestCtx.UserValue("id").(string)) ) - if err := app.automation.ToggleRule(id); err != nil { + toggledRule, err := app.automation.ToggleRule(id) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + return r.SendEnvelope(toggledRule) } // handleUpdateAutomationRule updates an automation rule @@ -66,10 +67,11 @@ func handleUpdateAutomationRule(r *fastglue.Request) error { return r.SendErrorEnvelope(fasthttp.StatusBadRequest, app.i18n.Ts("globals.messages.errorParsing", "name", "{globals.terms.request}"), nil, envelope.InputError) } - if err = app.automation.UpdateRule(id, rule); err != nil { + updatedRule, err := app.automation.UpdateRule(id, rule) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + return r.SendEnvelope(updatedRule) } // handleCreateAutomationRule creates a new automation rule @@ -81,10 +83,11 @@ func handleCreateAutomationRule(r *fastglue.Request) error { if err := r.Decode(&rule, "json"); err != nil { return r.SendErrorEnvelope(fasthttp.StatusBadRequest, app.i18n.Ts("globals.messages.errorParsing", "name", "{globals.terms.request}"), nil, envelope.InputError) } - if err := app.automation.CreateRule(rule); err != nil { + createdRule, err := app.automation.CreateRule(rule) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + return r.SendEnvelope(createdRule) } // handleDeleteAutomationRule deletes an automation rule diff --git a/cmd/business_hours.go b/cmd/business_hours.go index f8a99a6..8f067f4 100644 --- a/cmd/business_hours.go +++ b/cmd/business_hours.go @@ -55,11 +55,12 @@ func handleCreateBusinessHours(r *fastglue.Request) error { return r.SendErrorEnvelope(fasthttp.StatusBadRequest, app.i18n.Ts("globals.messages.empty", "name", "`name`"), nil, envelope.InputError) } - if err := app.businessHours.Create(businessHours.Name, businessHours.Description, businessHours.IsAlwaysOpen, businessHours.Hours, businessHours.Holidays); err != nil { + createdBusinessHours, err := app.businessHours.Create(businessHours.Name, businessHours.Description, businessHours.IsAlwaysOpen, businessHours.Hours, businessHours.Holidays) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + return r.SendEnvelope(createdBusinessHours) } // handleDeleteBusinessHour deletes the business hour with the given id. @@ -93,8 +94,9 @@ func handleUpdateBusinessHours(r *fastglue.Request) error { if businessHours.Name == "" { return r.SendErrorEnvelope(fasthttp.StatusBadRequest, app.i18n.Ts("globals.messages.invalid", "name", "`name`"), nil, envelope.InputError) } - if err := app.businessHours.Update(id, businessHours.Name, businessHours.Description, businessHours.IsAlwaysOpen, businessHours.Hours, businessHours.Holidays); err != nil { + updatedBusinessHours, err := app.businessHours.Update(id, businessHours.Name, businessHours.Description, businessHours.IsAlwaysOpen, businessHours.Hours, businessHours.Holidays) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + return r.SendEnvelope(updatedBusinessHours) } diff --git a/cmd/custom_attributes.go b/cmd/custom_attributes.go index 33b34ac..4299921 100644 --- a/cmd/custom_attributes.go +++ b/cmd/custom_attributes.go @@ -70,10 +70,11 @@ func handleCreateCustomAttribute(r *fastglue.Request) error { if err := validateCustomAttribute(app, attribute); err != nil { return sendErrorEnvelope(r, err) } - if err := app.customAttribute.Create(attribute); err != nil { + createdAttr, err := app.customAttribute.Create(attribute) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + return r.SendEnvelope(createdAttr) } // handleUpdateCustomAttribute updates an existing custom attribute in the database. @@ -92,10 +93,11 @@ func handleUpdateCustomAttribute(r *fastglue.Request) error { if err := validateCustomAttribute(app, attribute); err != nil { return sendErrorEnvelope(r, err) } - if err = app.customAttribute.Update(id, attribute); err != nil { + updatedAttr, err := app.customAttribute.Update(id, attribute) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + return r.SendEnvelope(updatedAttr) } // handleDeleteCustomAttribute deletes a custom attribute from the database. diff --git a/cmd/inboxes.go b/cmd/inboxes.go index f53960d..1c8edba 100644 --- a/cmd/inboxes.go +++ b/cmd/inboxes.go @@ -47,11 +47,12 @@ func handleCreateInbox(r *fastglue.Request) error { return r.SendErrorEnvelope(fasthttp.StatusBadRequest, app.i18n.Ts("globals.messages.errorParsing", "name", "{globals.terms.request}"), err.Error(), envelope.InputError) } - if err := app.inbox.Create(inbox); err != nil { + createdInbox, err := app.inbox.Create(inbox) + if err != nil { return sendErrorEnvelope(r, err) } - if err := validateInbox(app, inbox); err != nil { + if err := validateInbox(app, createdInbox); err != nil { return sendErrorEnvelope(r, err) } @@ -59,7 +60,13 @@ func handleCreateInbox(r *fastglue.Request) error { return r.SendErrorEnvelope(fasthttp.StatusInternalServerError, app.i18n.Ts("globals.messages.couldNotReload", "name", "{globals.terms.inbox}"), nil, envelope.GeneralError) } - return r.SendEnvelope(true) + // Clear passwords before returning. + if err := createdInbox.ClearPasswords(); err != nil { + app.lo.Error("error clearing inbox passwords from response", "error", err) + return envelope.NewError(envelope.GeneralError, app.i18n.Ts("globals.messages.errorFetching", "name", "{globals.terms.inbox}"), nil) + } + + return r.SendEnvelope(createdInbox) } // handleUpdateInbox updates an inbox @@ -82,7 +89,7 @@ func handleUpdateInbox(r *fastglue.Request) error { return sendErrorEnvelope(r, err) } - err = app.inbox.Update(id, inbox) + updatedInbox, err := app.inbox.Update(id, inbox) if err != nil { return sendErrorEnvelope(r, err) } @@ -91,7 +98,13 @@ func handleUpdateInbox(r *fastglue.Request) error { return r.SendErrorEnvelope(fasthttp.StatusInternalServerError, app.i18n.Ts("globals.messages.couldNotReload", "name", "{globals.terms.inbox}"), nil, envelope.GeneralError) } - return r.SendEnvelope(inbox) + // Clear passwords before returning. + if err := updatedInbox.ClearPasswords(); err != nil { + app.lo.Error("error clearing inbox passwords from response", "error", err) + return envelope.NewError(envelope.GeneralError, app.i18n.Ts("globals.messages.errorFetching", "name", "{globals.terms.inbox}"), nil) + } + + return r.SendEnvelope(updatedInbox) } // handleToggleInbox toggles an inbox @@ -105,7 +118,8 @@ func handleToggleInbox(r *fastglue.Request) error { app.i18n.Ts("globals.messages.invalid", "name", "`id`"), nil, envelope.InputError) } - if err = app.inbox.Toggle(id); err != nil { + toggledInbox, err := app.inbox.Toggle(id) + if err != nil { return err } @@ -113,7 +127,13 @@ func handleToggleInbox(r *fastglue.Request) error { return r.SendErrorEnvelope(fasthttp.StatusInternalServerError, app.i18n.Ts("globals.messages.couldNotReload", "name", "{globals.terms.inbox}"), nil, envelope.GeneralError) } - return r.SendEnvelope(true) + // Clear passwords before returning + if err := toggledInbox.ClearPasswords(); err != nil { + app.lo.Error("error clearing inbox passwords from response", "error", err) + return envelope.NewError(envelope.GeneralError, app.i18n.Ts("globals.messages.errorFetching", "name", "{globals.terms.inbox}"), nil) + } + + return r.SendEnvelope(toggledInbox) } // handleDeleteInbox deletes an inbox diff --git a/cmd/macro.go b/cmd/macro.go index 22589c8..6d1b15a 100644 --- a/cmd/macro.go +++ b/cmd/macro.go @@ -81,11 +81,12 @@ func handleCreateMacro(r *fastglue.Request) error { return sendErrorEnvelope(r, err) } - if err := app.macro.Create(macro.Name, macro.MessageContent, macro.UserID, macro.TeamID, macro.Visibility, macro.VisibleWhen, macro.Actions); err != nil { + createdMacro, err := app.macro.Create(macro.Name, macro.MessageContent, macro.UserID, macro.TeamID, macro.Visibility, macro.VisibleWhen, macro.Actions) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(macro) + return r.SendEnvelope(createdMacro) } // handleUpdateMacro updates a macro. @@ -109,11 +110,12 @@ func handleUpdateMacro(r *fastglue.Request) error { return sendErrorEnvelope(r, err) } - if err = app.macro.Update(id, macro.Name, macro.MessageContent, macro.UserID, macro.TeamID, macro.Visibility, macro.VisibleWhen, macro.Actions); err != nil { + updatedMacro, err := app.macro.Update(id, macro.Name, macro.MessageContent, macro.UserID, macro.TeamID, macro.Visibility, macro.VisibleWhen, macro.Actions) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(macro) + return r.SendEnvelope(updatedMacro) } // handleDeleteMacro deletes macro. diff --git a/cmd/oidc.go b/cmd/oidc.go index 8bc293d..8c6c048 100644 --- a/cmd/oidc.go +++ b/cmd/oidc.go @@ -65,7 +65,8 @@ func handleCreateOIDC(r *fastglue.Request) error { return sendErrorEnvelope(r, err) } - if err := app.oidc.Create(req); err != nil { + createdOIDC, err := app.oidc.Create(req) + if err != nil { return sendErrorEnvelope(r, err) } @@ -73,7 +74,11 @@ func handleCreateOIDC(r *fastglue.Request) error { if err := reloadAuth(app); err != nil { return r.SendErrorEnvelope(fasthttp.StatusInternalServerError, app.i18n.Ts("globals.messages.couldNotReload", "name", "OIDC"), nil, envelope.GeneralError) } - return r.SendEnvelope("OIDC created successfully") + + // Clear client secret before returning + createdOIDC.ClientSecret = strings.Repeat(stringutil.PasswordDummy, 10) + + return r.SendEnvelope(createdOIDC) } // handleUpdateOIDC updates an OIDC record. @@ -96,7 +101,8 @@ func handleUpdateOIDC(r *fastglue.Request) error { return sendErrorEnvelope(r, err) } - if err = app.oidc.Update(id, req); err != nil { + updatedOIDC, err := app.oidc.Update(id, req) + if err != nil { return sendErrorEnvelope(r, err) } @@ -104,7 +110,11 @@ func handleUpdateOIDC(r *fastglue.Request) error { if err := reloadAuth(app); err != nil { return r.SendErrorEnvelope(fasthttp.StatusInternalServerError, app.i18n.Ts("globals.messages.couldNotReload", "name", "OIDC"), nil, envelope.GeneralError) } - return r.SendEnvelope(true) + + // Clear client secret before returning + updatedOIDC.ClientSecret = strings.Repeat(stringutil.PasswordDummy, 10) + + return r.SendEnvelope(updatedOIDC) } // handleDeleteOIDC deletes an OIDC record. diff --git a/cmd/roles.go b/cmd/roles.go index a0a5e5f..c7726a9 100644 --- a/cmd/roles.go +++ b/cmd/roles.go @@ -55,10 +55,11 @@ func handleCreateRole(r *fastglue.Request) error { if err := r.Decode(&req, "json"); err != nil { return r.SendErrorEnvelope(fasthttp.StatusBadRequest, app.i18n.Ts("globals.messages.errorParsing", "name", "{globals.terms.request}"), nil, envelope.InputError) } - if err := app.role.Create(req); err != nil { + createdRole, err := app.role.Create(req) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + return r.SendEnvelope(createdRole) } // handleUpdateRole updates a role @@ -71,8 +72,9 @@ func handleUpdateRole(r *fastglue.Request) error { if err := r.Decode(&req, "json"); err != nil { return r.SendErrorEnvelope(fasthttp.StatusBadRequest, app.i18n.Ts("globals.messages.errorParsing", "name", "{globals.terms.request}"), nil, envelope.InputError) } - if err := app.role.Update(id, req); err != nil { + updatedRole, err := app.role.Update(id, req) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + return r.SendEnvelope(updatedRole) } diff --git a/cmd/sla.go b/cmd/sla.go index c6f2fb2..513a652 100644 --- a/cmd/sla.go +++ b/cmd/sla.go @@ -54,11 +54,12 @@ func handleCreateSLA(r *fastglue.Request) error { return sendErrorEnvelope(r, err) } - if err := app.sla.Create(sla.Name, sla.Description, sla.FirstResponseTime, sla.ResolutionTime, sla.NextResponseTime, sla.Notifications); err != nil { + createdSLA, err := app.sla.Create(sla.Name, sla.Description, sla.FirstResponseTime, sla.ResolutionTime, sla.NextResponseTime, sla.Notifications) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope("SLA created successfully.") + return r.SendEnvelope(createdSLA) } // handleUpdateSLA updates the SLA with the given ID. @@ -81,11 +82,12 @@ func handleUpdateSLA(r *fastglue.Request) error { return sendErrorEnvelope(r, err) } - if err := app.sla.Update(id, sla.Name, sla.Description, sla.FirstResponseTime, sla.ResolutionTime, sla.NextResponseTime, sla.Notifications); err != nil { + updatedSLA, err := app.sla.Update(id, sla.Name, sla.Description, sla.FirstResponseTime, sla.ResolutionTime, sla.NextResponseTime, sla.Notifications) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + return r.SendEnvelope(updatedSLA) } // handleDeleteSLA deletes the SLA with the given ID. diff --git a/cmd/statuses.go b/cmd/statuses.go index c947a78..6beca3b 100644 --- a/cmd/statuses.go +++ b/cmd/statuses.go @@ -33,12 +33,12 @@ func handleCreateStatus(r *fastglue.Request) error { return r.SendErrorEnvelope(fasthttp.StatusBadRequest, app.i18n.Ts("globals.messages.empty", "name", "`name`"), nil, envelope.InputError) } - err := app.status.Create(status.Name) + createdStatus, err := app.status.Create(status.Name) if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + return r.SendEnvelope(createdStatus) } func handleDeleteStatus(r *fastglue.Request) error { @@ -74,10 +74,10 @@ func handleUpdateStatus(r *fastglue.Request) error { return r.SendErrorEnvelope(fasthttp.StatusBadRequest, app.i18n.Ts("globals.messages.empty", "name", "`name`"), nil, envelope.InputError) } - err = app.status.Update(id, status.Name) + updatedStatus, err := app.status.Update(id, status.Name) if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + return r.SendEnvelope(updatedStatus) } diff --git a/cmd/tags.go b/cmd/tags.go index 92ac607..799f53f 100644 --- a/cmd/tags.go +++ b/cmd/tags.go @@ -35,11 +35,12 @@ func handleCreateTag(r *fastglue.Request) error { return r.SendErrorEnvelope(fasthttp.StatusBadRequest, app.i18n.Ts("globals.messages.empty", "name", "`name`"), nil, envelope.InputError) } - if err := app.tag.Create(tag.Name); err != nil { + createdTag, err := app.tag.Create(tag.Name) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + return r.SendEnvelope(createdTag) } // handleDeleteTag deletes a tag from the database. @@ -78,9 +79,10 @@ func handleUpdateTag(r *fastglue.Request) error { return r.SendErrorEnvelope(fasthttp.StatusBadRequest, app.i18n.Ts("globals.messages.empty", "name", "`name`"), nil, envelope.InputError) } - if err = app.tag.Update(id, tag.Name); err != nil { + updatedTag, err := app.tag.Update(id, tag.Name) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + return r.SendEnvelope(updatedTag) } diff --git a/cmd/teams.go b/cmd/teams.go index 70e6773..5d4046b 100644 --- a/cmd/teams.go +++ b/cmd/teams.go @@ -60,10 +60,11 @@ func handleCreateTeam(r *fastglue.Request) error { return sendErrorEnvelope(r, envelope.NewError(envelope.InputError, app.i18n.Ts("globals.messages.errorParsing", "name", "{globals.terms.request}"), nil)) } - if err := app.team.Create(req.Name, req.Timezone, req.ConversationAssignmentType, req.BusinessHoursID, req.SLAPolicyID, req.Emoji.String, req.MaxAutoAssignedConversations); err != nil { + createdTeam, err := app.team.Create(req.Name, req.Timezone, req.ConversationAssignmentType, req.BusinessHoursID, req.SLAPolicyID, req.Emoji.String, req.MaxAutoAssignedConversations) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + return r.SendEnvelope(createdTeam) } // handleUpdateTeam updates an existing team. @@ -82,10 +83,11 @@ func handleUpdateTeam(r *fastglue.Request) error { return sendErrorEnvelope(r, envelope.NewError(envelope.InputError, app.i18n.Ts("globals.messages.errorParsing", "name", "{globals.terms.request}"), nil)) } - if err := app.team.Update(id, req.Name, req.Timezone, req.ConversationAssignmentType, req.BusinessHoursID, req.SLAPolicyID, req.Emoji.String, req.MaxAutoAssignedConversations); err != nil { + updatedTeam, err := app.team.Update(id, req.Name, req.Timezone, req.ConversationAssignmentType, req.BusinessHoursID, req.SLAPolicyID, req.Emoji.String, req.MaxAutoAssignedConversations); + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + return r.SendEnvelope(updatedTeam) } // handleDeleteTeam deletes a team diff --git a/cmd/templates.go b/cmd/templates.go index b98e824..4557c50 100644 --- a/cmd/templates.go +++ b/cmd/templates.go @@ -53,10 +53,11 @@ func handleCreateTemplate(r *fastglue.Request) error { if req.Name == "" { return r.SendErrorEnvelope(fasthttp.StatusBadRequest, app.i18n.Ts("globals.messages.empty", "name", "`name`"), nil, envelope.InputError) } - if err := app.tmpl.Create(req); err != nil { + template, err := app.tmpl.Create(req) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + return r.SendEnvelope(template) } // handleUpdateTemplate updates a template. @@ -76,10 +77,11 @@ func handleUpdateTemplate(r *fastglue.Request) error { if req.Name == "" { return r.SendErrorEnvelope(fasthttp.StatusBadRequest, app.i18n.Ts("globals.messages.empty", "name", "`name`"), nil, envelope.InputError) } - if err = app.tmpl.Update(id, req); err != nil { + updatedTemplate, err := app.tmpl.Update(id, req) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + return r.SendEnvelope(updatedTemplate) } // handleDeleteTemplate deletes a template. diff --git a/cmd/views.go b/cmd/views.go index 5cb1657..71885fd 100644 --- a/cmd/views.go +++ b/cmd/views.go @@ -47,10 +47,11 @@ func handleCreateUserView(r *fastglue.Request) error { if string(view.Filters) == "" { return r.SendErrorEnvelope(fasthttp.StatusBadRequest, app.i18n.Ts("globals.messages.empty", "name", "`Filters`"), nil, envelope.InputError) } - if err := app.view.Create(view.Name, view.Filters, user.ID); err != nil { + createdView, err := app.view.Create(view.Name, view.Filters, user.ID) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + return r.SendEnvelope(createdView) } // handleDeleteUserView deletes a view for a user. @@ -111,8 +112,9 @@ func handleUpdateUserView(r *fastglue.Request) error { if v.UserID != user.ID { return r.SendErrorEnvelope(fasthttp.StatusForbidden, app.i18n.Ts("globals.messages.denied", "name", "{globals.terms.permission}"), nil, envelope.PermissionError) } - if err = app.view.Update(id, view.Name, view.Filters); err != nil { + updatedView, err := app.view.Update(id, view.Name, view.Filters) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + return r.SendEnvelope(updatedView) } diff --git a/cmd/webhooks.go b/cmd/webhooks.go index b99a51e..22b4ecb 100644 --- a/cmd/webhooks.go +++ b/cmd/webhooks.go @@ -67,12 +67,15 @@ func handleCreateWebhook(r *fastglue.Request) error { return r.SendEnvelope(err) } - _, err := app.webhook.Create(webhook) + webhook, err := app.webhook.Create(webhook) if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + // Clear secret before returning + webhook.Secret = strings.Repeat(stringutil.PasswordDummy, 10) + + return r.SendEnvelope(webhook) } // handleUpdateWebhook updates an existing webhook in the database. @@ -105,11 +108,15 @@ func handleUpdateWebhook(r *fastglue.Request) error { webhook.Secret = existingWebhook.Secret } - if err := app.webhook.Update(id, webhook); err != nil { + updatedWebhook, err := app.webhook.Update(id, webhook) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + // Clear secret before returning + updatedWebhook.Secret = strings.Repeat(stringutil.PasswordDummy, 10) + + return r.SendEnvelope(updatedWebhook) } // handleDeleteWebhook deletes a webhook from the database. @@ -140,11 +147,15 @@ func handleToggleWebhook(r *fastglue.Request) error { return r.SendErrorEnvelope(fasthttp.StatusBadRequest, app.i18n.Ts("globals.messages.invalid", "name", "`id`"), nil, envelope.InputError) } - if err := app.webhook.Toggle(id); err != nil { + toggledWebhook, err := app.webhook.Toggle(id) + if err != nil { return sendErrorEnvelope(r, err) } - return r.SendEnvelope(true) + // Clear secret before returning + toggledWebhook.Secret = strings.Repeat(stringutil.PasswordDummy, 10) + + return r.SendEnvelope(toggledWebhook) } // handleTestWebhook sends a test payload to a webhook. diff --git a/internal/automation/automation.go b/internal/automation/automation.go index 6a7b44d..605eeb8 100644 --- a/internal/automation/automation.go +++ b/internal/automation/automation.go @@ -198,42 +198,45 @@ func (e *Engine) GetRule(id int) (models.RuleRecord, error) { } // ToggleRule toggles the active status of a rule by ID. -func (e *Engine) ToggleRule(id int) error { - if _, err := e.q.ToggleRule.Exec(id); err != nil { +func (e *Engine) ToggleRule(id int) (models.RuleRecord, error) { + var result models.RuleRecord + if err := e.q.ToggleRule.Get(&result, id); err != nil { e.lo.Error("error toggling rule", "error", err) - return envelope.NewError(envelope.GeneralError, e.i18n.Ts("globals.messages.errorUpdating", "name", e.i18n.Ts("globals.terms.rule")), nil) + return models.RuleRecord{}, envelope.NewError(envelope.GeneralError, e.i18n.Ts("globals.messages.errorUpdating", "name", e.i18n.Ts("globals.terms.rule")), nil) } // Reload rules. e.ReloadRules() - return nil + return result, nil } // UpdateRule updates an existing rule. -func (e *Engine) UpdateRule(id int, rule models.RuleRecord) error { +func (e *Engine) UpdateRule(id int, rule models.RuleRecord) (models.RuleRecord, error) { if rule.Events == nil { rule.Events = pq.StringArray{} } - if _, err := e.q.UpdateRule.Exec(id, rule.Name, rule.Description, rule.Type, rule.Events, rule.Rules, rule.Enabled); err != nil { + var result models.RuleRecord + if err := e.q.UpdateRule.Get(&result, id, rule.Name, rule.Description, rule.Type, rule.Events, rule.Rules, rule.Enabled); err != nil { e.lo.Error("error updating rule", "error", err) - return envelope.NewError(envelope.GeneralError, e.i18n.Ts("globals.messages.errorUpdating", "name", e.i18n.Ts("globals.terms.rule")), nil) + return models.RuleRecord{}, envelope.NewError(envelope.GeneralError, e.i18n.Ts("globals.messages.errorUpdating", "name", e.i18n.Ts("globals.terms.rule")), nil) } // Reload rules. e.ReloadRules() - return nil + return result, nil } // CreateRule creates a new rule. -func (e *Engine) CreateRule(rule models.RuleRecord) error { +func (e *Engine) CreateRule(rule models.RuleRecord) (models.RuleRecord, error) { if rule.Events == nil { rule.Events = pq.StringArray{} } - if _, err := e.q.InsertRule.Exec(rule.Name, rule.Description, rule.Type, rule.Events, rule.Rules); err != nil { + var result models.RuleRecord + if err := e.q.InsertRule.Get(&result, rule.Name, rule.Description, rule.Type, rule.Events, rule.Rules); err != nil { e.lo.Error("error creating rule", "error", err) - return envelope.NewError(envelope.GeneralError, e.i18n.Ts("globals.messages.errorCreating", "name", e.i18n.Ts("globals.terms.rule")), nil) + return models.RuleRecord{}, envelope.NewError(envelope.GeneralError, e.i18n.Ts("globals.messages.errorCreating", "name", e.i18n.Ts("globals.terms.rule")), nil) } // Reload rules. e.ReloadRules() - return nil + return result, nil } // DeleteRule deletes a rule by ID. diff --git a/internal/automation/queries.sql b/internal/automation/queries.sql index 89f4083..bf9815a 100644 --- a/internal/automation/queries.sql +++ b/internal/automation/queries.sql @@ -24,10 +24,13 @@ DO UPDATE SET rules = EXCLUDED.rules, enabled = EXCLUDED.enabled, updated_at = now() -WHERE $1 > 0; +WHERE $1 > 0 +RETURNING *; -- name: insert-rule -INSERT into automation_rules (name, description, type, events, rules) values ($1, $2, $3, $4, $5); +INSERT into automation_rules (name, description, type, events, rules) +values ($1, $2, $3, $4, $5) +RETURNING *; -- name: delete-rule delete from automation_rules where id = $1; @@ -35,7 +38,8 @@ delete from automation_rules where id = $1; -- name: toggle-rule UPDATE automation_rules SET enabled = NOT enabled, updated_at = NOW() -WHERE id = $1; +WHERE id = $1 +RETURNING *; -- name: update-rule-weight UPDATE automation_rules diff --git a/internal/business_hours/business_hours.go b/internal/business_hours/business_hours.go index 3411d41..5665388 100644 --- a/internal/business_hours/business_hours.go +++ b/internal/business_hours/business_hours.go @@ -80,12 +80,13 @@ func (m *Manager) GetAll() ([]models.BusinessHours, error) { } // Create creates new business hours. -func (m *Manager) Create(name string, description null.String, isAlwaysOpen bool, workingHrs, holidays types.JSONText) error { - if _, err := m.q.InsertBusinessHours.Exec(name, description, isAlwaysOpen, workingHrs, holidays); err != nil { +func (m *Manager) Create(name string, description null.String, isAlwaysOpen bool, workingHrs, holidays types.JSONText) (models.BusinessHours, error) { + var result models.BusinessHours + if err := m.q.InsertBusinessHours.Get(&result, name, description, isAlwaysOpen, workingHrs, holidays); err != nil { m.lo.Error("error inserting business hours", "error", err) - return envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.businessHour}"), nil) + return models.BusinessHours{}, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.businessHour}"), nil) } - return nil + return result, nil } // Delete deletes business hours by ID. @@ -101,10 +102,11 @@ func (m *Manager) Delete(id int) error { } // Update updates business hours by ID. -func (m *Manager) Update(id int, name string, description null.String, isAlwaysOpen bool, workingHrs, holidays types.JSONText) error { - if _, err := m.q.UpdateBusinessHours.Exec(id, name, description, isAlwaysOpen, workingHrs, holidays); err != nil { +func (m *Manager) Update(id int, name string, description null.String, isAlwaysOpen bool, workingHrs, holidays types.JSONText) (models.BusinessHours, error) { + var result models.BusinessHours + if err := m.q.UpdateBusinessHours.Get(&result, id, name, description, isAlwaysOpen, workingHrs, holidays); err != nil { m.lo.Error("error updating business hours", "error", err) - return envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.businessHour}"), nil) + return models.BusinessHours{}, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.businessHour}"), nil) } - return nil + return result, nil } diff --git a/internal/business_hours/queries.sql b/internal/business_hours/queries.sql index 3722599..bf45495 100644 --- a/internal/business_hours/queries.sql +++ b/internal/business_hours/queries.sql @@ -27,7 +27,8 @@ INSERT INTO business_hours ( hours, holidays ) -VALUES ($1, $2, $3, $4, $5); +VALUES ($1, $2, $3, $4, $5) +RETURNING *; -- name: delete-business-hours DELETE FROM business_hours @@ -41,4 +42,5 @@ SET "name" = $2, hours = $5, holidays = $6, updated_at = NOW() -WHERE id = $1; \ No newline at end of file +WHERE id = $1 +RETURNING *; \ No newline at end of file diff --git a/internal/conversation/status/queries.sql b/internal/conversation/status/queries.sql index 7ea26bb..8fb7158 100644 --- a/internal/conversation/status/queries.sql +++ b/internal/conversation/status/queries.sql @@ -12,10 +12,10 @@ select id, from conversation_statuses; -- name: insert-status -INSERT into conversation_statuses(name) values ($1); +INSERT into conversation_statuses(name) values ($1) RETURNING *; -- name: delete-status DELETE from conversation_statuses where id = $1; -- name: update-status -UPDATE conversation_statuses set name = $2 where id = $1; \ No newline at end of file +UPDATE conversation_statuses set name = $2 where id = $1 RETURNING *; \ No newline at end of file diff --git a/internal/conversation/status/status.go b/internal/conversation/status/status.go index 01573c8..628e33f 100644 --- a/internal/conversation/status/status.go +++ b/internal/conversation/status/status.go @@ -70,15 +70,16 @@ func (m *Manager) GetAll() ([]models.Status, error) { } // Create creates a new status. -func (m *Manager) Create(name string) error { +func (m *Manager) Create(name string) (models.Status, error) { + var status models.Status if err := m.validateStatusName(name); err != nil { - return err + return status, err } - if _, err := m.q.InsertStatus.Exec(name); err != nil { + if err := m.q.InsertStatus.Get(&status, name); err != nil { m.lo.Error("error inserting status", "error", err) - return envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorCreating", "name", m.i18n.T("globals.terms.status")), nil) + return status, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorCreating", "name", m.i18n.T("globals.terms.status")), nil) } - return nil + return status, nil } // Delete deletes a status by ID. @@ -104,25 +105,26 @@ func (m *Manager) Delete(id int) error { } // Update updates a status by id. -func (m *Manager) Update(id int, name string) error { +func (m *Manager) Update(id int, name string) (models.Status, error) { + var updatedStatus models.Status if err := m.validateStatusName(name); err != nil { - return err + return updatedStatus, err } // Disallow updating of default statuses. status, err := m.Get(id) if err != nil { - return envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorFetching", "name", m.i18n.Ts("globals.terms.status")), nil) + return updatedStatus, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorFetching", "name", m.i18n.Ts("globals.terms.status")), nil) } if slices.Contains(models.DefaultStatuses, status.Name) { - return envelope.NewError(envelope.InputError, m.i18n.T("conversationStatus.cannotUpdateDefault"), nil) + return updatedStatus, envelope.NewError(envelope.InputError, m.i18n.T("conversationStatus.cannotUpdateDefault"), nil) } - if _, err := m.q.UpdateStatus.Exec(id, name); err != nil { + if err := m.q.UpdateStatus.Get(&updatedStatus, id, name); err != nil { m.lo.Error("error updating status", "error", err) - return envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorUpdating", "name", m.i18n.Ts("globals.terms.status")), nil) + return updatedStatus, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorUpdating", "name", m.i18n.Ts("globals.terms.status")), nil) } - return nil + return updatedStatus, nil } // Get retrieves a status by ID. diff --git a/internal/custom_attribute/custom_attribute.go b/internal/custom_attribute/custom_attribute.go index 70f6ddd..ac828db 100644 --- a/internal/custom_attribute/custom_attribute.go +++ b/internal/custom_attribute/custom_attribute.go @@ -78,24 +78,26 @@ func (m *Manager) GetAll(appliesTo string) ([]models.CustomAttribute, error) { } // Create creates a new custom attribute. -func (m *Manager) Create(attr models.CustomAttribute) error { - if _, err := m.q.InsertCustomAttribute.Exec(attr.AppliesTo, attr.Name, attr.Description, attr.Key, pq.Array(attr.Values), attr.DataType, attr.Regex, attr.RegexHint); err != nil { +func (m *Manager) Create(attr models.CustomAttribute) (models.CustomAttribute, error) { + var createdAttr models.CustomAttribute + if err := m.q.InsertCustomAttribute.Get(&createdAttr, attr.AppliesTo, attr.Name, attr.Description, attr.Key, pq.Array(attr.Values), attr.DataType, attr.Regex, attr.RegexHint); err != nil { if dbutil.IsUniqueViolationError(err) { - return envelope.NewError(envelope.InputError, m.i18n.Ts("globals.messages.errorAlreadyExists", "name", m.i18n.P("globals.terms.customAttribute")), nil) + return models.CustomAttribute{}, envelope.NewError(envelope.InputError, m.i18n.Ts("globals.messages.errorAlreadyExists", "name", m.i18n.P("globals.terms.customAttribute")), nil) } m.lo.Error("error inserting custom attribute", "error", err) - return envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.customAttribute}"), nil) + return models.CustomAttribute{}, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.customAttribute}"), nil) } - return nil + return createdAttr, nil } // Update updates a custom attribute by ID. -func (m *Manager) Update(id int, attr models.CustomAttribute) error { - if _, err := m.q.UpdateCustomAttribute.Exec(id, attr.AppliesTo, attr.Name, attr.Description, pq.Array(attr.Values), attr.Regex, attr.RegexHint); err != nil { +func (m *Manager) Update(id int, attr models.CustomAttribute) (models.CustomAttribute, error) { + var updatedAttr models.CustomAttribute + if err := m.q.UpdateCustomAttribute.Get(&updatedAttr, id, attr.AppliesTo, attr.Name, attr.Description, pq.Array(attr.Values), attr.Regex, attr.RegexHint); err != nil { m.lo.Error("error updating custom attribute", "error", err) - return envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.customAttribute}"), nil) + return models.CustomAttribute{}, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.customAttribute}"), nil) } - return nil + return updatedAttr, nil } // Delete deletes a custom attribute by ID. diff --git a/internal/custom_attribute/queries.sql b/internal/custom_attribute/queries.sql index 5f02525..8377b3d 100644 --- a/internal/custom_attribute/queries.sql +++ b/internal/custom_attribute/queries.sql @@ -43,6 +43,7 @@ INSERT INTO custom_attribute_definitions (applies_to, name, description, key, values, data_type, regex, regex_hint) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) +RETURNING * -- name: delete-custom-attribute DELETE FROM @@ -62,4 +63,5 @@ SET regex_hint = $7, updated_at = NOW() WHERE - id = $1; \ No newline at end of file + id = $1 +RETURNING *; \ No newline at end of file diff --git a/internal/inbox/inbox.go b/internal/inbox/inbox.go index 7b45b56..d9c0783 100644 --- a/internal/inbox/inbox.go +++ b/internal/inbox/inbox.go @@ -169,12 +169,13 @@ func (m *Manager) GetAll() ([]imodels.Inbox, error) { } // Create creates an inbox in the DB. -func (m *Manager) Create(inbox imodels.Inbox) error { - if _, err := m.queries.InsertInbox.Exec(inbox.Channel, inbox.Config, inbox.Name, inbox.From, inbox.CSATEnabled); err != nil { +func (m *Manager) Create(inbox imodels.Inbox) (imodels.Inbox, error) { + var createdInbox imodels.Inbox + if err := m.queries.InsertInbox.Get(&createdInbox, inbox.Channel, inbox.Config, inbox.Name, inbox.From, inbox.CSATEnabled); err != nil { m.lo.Error("error creating inbox", "error", err) - return envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.inbox}"), nil) + return imodels.Inbox{}, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.inbox}"), nil) } - return nil + return createdInbox, nil } // InitInboxes initializes and registers active inboxes with the manager. @@ -254,10 +255,10 @@ func (m *Manager) Reload(ctx context.Context, initFn initFn) error { } // Update updates an inbox in the DB. -func (m *Manager) Update(id int, inbox imodels.Inbox) error { +func (m *Manager) Update(id int, inbox imodels.Inbox) (imodels.Inbox, error) { current, err := m.GetDBRecord(id) if err != nil { - return err + return imodels.Inbox{}, err } // Preserve existing passwords if update has empty password @@ -274,22 +275,22 @@ func (m *Manager) Update(id int, inbox imodels.Inbox) error { if err := json.Unmarshal(current.Config, ¤tCfg); err != nil { m.lo.Error("error unmarshalling current config", "id", id, "error", err) - return envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorParsing", "name", "{globals.terms.config}"), nil) + return imodels.Inbox{}, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorParsing", "name", "{globals.terms.config}"), nil) } if len(inbox.Config) == 0 { - return envelope.NewError(envelope.InputError, m.i18n.Ts("globals.messages.empty", "name", "{globals.terms.config}"), nil) + return imodels.Inbox{}, envelope.NewError(envelope.InputError, m.i18n.Ts("globals.messages.empty", "name", "{globals.terms.config}"), nil) } if err := json.Unmarshal(inbox.Config, &updateCfg); err != nil { m.lo.Error("error unmarshalling update config", "id", id, "error", err) - return envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorParsing", "name", "{globals.terms.config}"), nil) + return imodels.Inbox{}, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorParsing", "name", "{globals.terms.config}"), nil) } if len(updateCfg.IMAP) == 0 { - return envelope.NewError(envelope.InputError, m.i18n.T("inbox.emptyIMAP"), nil) + return imodels.Inbox{}, envelope.NewError(envelope.InputError, m.i18n.T("inbox.emptyIMAP"), nil) } if len(updateCfg.SMTP) == 0 { - return envelope.NewError(envelope.InputError, m.i18n.T("inbox.emptySMTP"), nil) + return imodels.Inbox{}, envelope.NewError(envelope.InputError, m.i18n.T("inbox.emptySMTP"), nil) } // Preserve existing IMAP passwords if update has empty password @@ -308,27 +309,29 @@ func (m *Manager) Update(id int, inbox imodels.Inbox) error { updatedConfig, err := json.Marshal(updateCfg) if err != nil { m.lo.Error("error marshalling updated config", "id", id, "error", err) - return err + return imodels.Inbox{}, err } inbox.Config = updatedConfig } // Update the inbox in the DB. - if _, err := m.queries.Update.Exec(id, inbox.Channel, inbox.Config, inbox.Name, inbox.From, inbox.CSATEnabled, inbox.Enabled); err != nil { + var updatedInbox imodels.Inbox + if err := m.queries.Update.Get(&updatedInbox, id, inbox.Channel, inbox.Config, inbox.Name, inbox.From, inbox.CSATEnabled, inbox.Enabled); err != nil { m.lo.Error("error updating inbox", "error", err) - return envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.inbox}"), nil) + return imodels.Inbox{}, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.inbox}"), nil) } - return nil + return updatedInbox, nil } // Toggle toggles the status of an inbox in the DB. -func (m *Manager) Toggle(id int) error { - if _, err := m.queries.Toggle.Exec(id); err != nil { +func (m *Manager) Toggle(id int) (imodels.Inbox, error) { + var updatedInbox imodels.Inbox + if err := m.queries.Toggle.Get(&updatedInbox, id); err != nil { m.lo.Error("error toggling inbox", "error", err) - return envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.inbox}"), nil) + return imodels.Inbox{}, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.inbox}"), nil) } - return nil + return updatedInbox, nil } // SoftDelete soft deletes an inbox in the DB. diff --git a/internal/inbox/queries.sql b/internal/inbox/queries.sql index 0cc195e..ade0873 100644 --- a/internal/inbox/queries.sql +++ b/internal/inbox/queries.sql @@ -8,6 +8,7 @@ SELECT id, created_at, updated_at, name, channel, enabled from inboxes where del INSERT INTO inboxes (channel, config, "name", "from", csat_enabled) VALUES($1, $2, $3, $4, $5) +RETURNING * -- name: get-inbox SELECT * from inboxes where id = $1 and deleted_at is NULL; @@ -15,7 +16,8 @@ SELECT * from inboxes where id = $1 and deleted_at is NULL; -- name: update UPDATE inboxes set channel = $2, config = $3, "name" = $4, "from" = $5, csat_enabled = $6, enabled = $7, updated_at = now() -where id = $1 and deleted_at is NULL; +where id = $1 and deleted_at is NULL +RETURNING *; -- name: soft-delete UPDATE inboxes set deleted_at = now(), config = '{}' where id = $1 and deleted_at is NULL; @@ -23,4 +25,5 @@ UPDATE inboxes set deleted_at = now(), config = '{}' where id = $1 and deleted_a -- name: toggle UPDATE inboxes SET enabled = NOT enabled, updated_at = NOW() -WHERE id = $1; \ No newline at end of file +WHERE id = $1 +RETURNING *; \ No newline at end of file diff --git a/internal/macro/macro.go b/internal/macro/macro.go index 6ad925e..89f0812 100644 --- a/internal/macro/macro.go +++ b/internal/macro/macro.go @@ -68,26 +68,25 @@ func (m *Manager) Get(id int) (models.Macro, error) { } // Create adds a new macro. -func (m *Manager) Create(name, messageContent string, userID, teamID *int, visibility string, visibleWhen []string, actions json.RawMessage) error { - _, err := m.q.Create.Exec(name, messageContent, userID, teamID, visibility, pq.StringArray(visibleWhen), actions) +func (m *Manager) Create(name, messageContent string, userID, teamID *int, visibility string, visibleWhen []string, actions json.RawMessage) (models.Macro, error) { + var createdMacro models.Macro + err := m.q.Create.Get(&createdMacro, name, messageContent, userID, teamID, visibility, pq.StringArray(visibleWhen), actions) if err != nil { m.lo.Error("error creating macro", "error", err) - return envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.macro}"), nil) + return models.Macro{}, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.macro}"), nil) } - return nil + return createdMacro, nil } // Update modifies an existing macro. -func (m *Manager) Update(id int, name, messageContent string, userID, teamID *int, visibility string, visibleWhen []string, actions json.RawMessage) error { - result, err := m.q.Update.Exec(id, name, messageContent, userID, teamID, visibility, pq.StringArray(visibleWhen), actions) +func (m *Manager) Update(id int, name, messageContent string, userID, teamID *int, visibility string, visibleWhen []string, actions json.RawMessage) (models.Macro, error) { + var updatedMacro models.Macro + err := m.q.Update.Get(&updatedMacro, id, name, messageContent, userID, teamID, visibility, pq.StringArray(visibleWhen), actions) if err != nil { m.lo.Error("error updating macro", "error", err) - return envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.macro}"), nil) + return models.Macro{}, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.macro}"), nil) } - if rows, _ := result.RowsAffected(); rows == 0 { - return envelope.NewError(envelope.NotFoundError, m.i18n.Ts("globals.messages.notFound", "name", "{globals.terms.macro}"), nil) - } - return nil + return updatedMacro, nil } // GetAll returns all macros. diff --git a/internal/macro/queries.sql b/internal/macro/queries.sql index 44ac323..28fabe4 100644 --- a/internal/macro/queries.sql +++ b/internal/macro/queries.sql @@ -38,7 +38,8 @@ ORDER BY INSERT INTO macros (name, message_content, user_id, team_id, visibility, visible_when, actions) VALUES - ($1, $2, $3, $4, $5, $6, $7); + ($1, $2, $3, $4, $5, $6, $7) +RETURNING *; -- name: update UPDATE @@ -53,7 +54,8 @@ SET actions = $8, updated_at = NOW() WHERE - id = $1; + id = $1 +RETURNING *; -- name: delete DELETE FROM diff --git a/internal/oidc/oidc.go b/internal/oidc/oidc.go index c297081..6cd822c 100644 --- a/internal/oidc/oidc.go +++ b/internal/oidc/oidc.go @@ -125,28 +125,30 @@ func (o *Manager) GetAllEnabled() ([]models.OIDC, error) { } // Create adds a new oidc. -func (o *Manager) Create(oidc models.OIDC) error { - if _, err := o.q.InsertOIDC.Exec(oidc.Name, oidc.Provider, oidc.ProviderURL, oidc.ClientID, oidc.ClientSecret); err != nil { +func (o *Manager) Create(oidc models.OIDC) (models.OIDC, error) { + var createdOIDC models.OIDC + if err := o.q.InsertOIDC.Get(&createdOIDC, oidc.Name, oidc.Provider, oidc.ProviderURL, oidc.ClientID, oidc.ClientSecret); err != nil { o.lo.Error("error inserting oidc", "error", err) - return envelope.NewError(envelope.GeneralError, o.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.oidcProvider}"), nil) + return models.OIDC{}, envelope.NewError(envelope.GeneralError, o.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.oidcProvider}"), nil) } - return nil + return createdOIDC, nil } // Update updates a oidc by id. -func (o *Manager) Update(id int, oidc models.OIDC) error { +func (o *Manager) Update(id int, oidc models.OIDC) (models.OIDC, error) { current, err := o.Get(id, true) if err != nil { - return err + return models.OIDC{}, err } if oidc.ClientSecret == "" { oidc.ClientSecret = current.ClientSecret } - if _, err := o.q.UpdateOIDC.Exec(id, oidc.Name, oidc.Provider, oidc.ProviderURL, oidc.ClientID, oidc.ClientSecret, oidc.Enabled); err != nil { + var updatedOIDC models.OIDC + if err := o.q.UpdateOIDC.Get(&updatedOIDC, id, oidc.Name, oidc.Provider, oidc.ProviderURL, oidc.ClientID, oidc.ClientSecret, oidc.Enabled); err != nil { o.lo.Error("error updating oidc", "error", err) - return envelope.NewError(envelope.GeneralError, o.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.oidcProvider}"), nil) + return models.OIDC{}, envelope.NewError(envelope.GeneralError, o.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.oidcProvider}"), nil) } - return nil + return updatedOIDC, nil } // Delete deletes a oidc by its id. diff --git a/internal/oidc/queries.sql b/internal/oidc/queries.sql index 56352a1..946bf11 100644 --- a/internal/oidc/queries.sql +++ b/internal/oidc/queries.sql @@ -9,12 +9,14 @@ SELECT * FROM oidc WHERE id = $1; -- name: insert-oidc INSERT INTO oidc (name, provider, provider_url, client_id, client_secret) -VALUES ($1, $2, $3, $4, $5); +VALUES ($1, $2, $3, $4, $5) +RETURNING *; -- name: update-oidc UPDATE oidc SET name = $2, provider = $3, provider_url = $4, client_id = $5, client_secret = $6, enabled = $7, updated_at = now() -WHERE id = $1; +WHERE id = $1 +RETURNING *; -- name: delete-oidc DELETE FROM oidc WHERE id = $1; diff --git a/internal/role/queries.sql b/internal/role/queries.sql index 3740594..d4a5645 100644 --- a/internal/role/queries.sql +++ b/internal/role/queries.sql @@ -8,7 +8,7 @@ SELECT * FROM roles where id = $1; DELETE FROM roles where id = $1; -- name: insert-role -INSERT INTO roles (name, description, permissions) VALUES ($1, $2, $3); +INSERT INTO roles (name, description, permissions) VALUES ($1, $2, $3) RETURNING *; -- name: update-role -UPDATE roles SET name = $2, description = $3, permissions = $4 WHERE id = $1; \ No newline at end of file +UPDATE roles SET name = $2, description = $3, permissions = $4 WHERE id = $1 RETURNING *; \ No newline at end of file diff --git a/internal/role/role.go b/internal/role/role.go index c418744..0df4c17 100644 --- a/internal/role/role.go +++ b/internal/role/role.go @@ -101,47 +101,49 @@ func (u *Manager) Delete(id int) error { } // Create creates a new role. -func (u *Manager) Create(r models.Role) error { +func (u *Manager) Create(r models.Role) (models.Role, error) { validPermissions, err := u.filterValidPermissions(r.Permissions) if err != nil { - return err + return models.Role{}, err } if len(validPermissions) == 0 { - return envelope.NewError(envelope.InputError, u.i18n.Ts("globals.messages.empty", "name", u.i18n.P("globals.terms.permission")), nil) + return models.Role{}, envelope.NewError(envelope.InputError, u.i18n.Ts("globals.messages.empty", "name", u.i18n.P("globals.terms.permission")), nil) } - if _, err := u.q.Insert.Exec(r.Name, r.Description, pq.Array(validPermissions)); err != nil { + var result models.Role + if err := u.q.Insert.Get(&result, r.Name, r.Description, pq.Array(validPermissions)); err != nil { if dbutil.IsUniqueViolationError(err) { - return envelope.NewError(envelope.InputError, u.i18n.Ts("globals.messages.errorAlreadyExists", "name", "{globals.terms.role}"), nil) + return models.Role{}, envelope.NewError(envelope.InputError, u.i18n.Ts("globals.messages.errorAlreadyExists", "name", "{globals.terms.role}"), nil) } u.lo.Error("error inserting role", "error", err) - return envelope.NewError(envelope.GeneralError, u.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.role}"), nil) + return models.Role{}, envelope.NewError(envelope.GeneralError, u.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.role}"), nil) } - return nil + return result, nil } // Update updates an existing role. -func (u *Manager) Update(id int, r models.Role) error { +func (u *Manager) Update(id int, r models.Role) (models.Role, error) { validPermissions, err := u.filterValidPermissions(r.Permissions) if err != nil { - return err + return models.Role{}, err } if len(validPermissions) == 0 { - return envelope.NewError(envelope.InputError, u.i18n.Ts("globals.messages.empty", "name", u.i18n.P("globals.terms.permission")), nil) + return models.Role{}, envelope.NewError(envelope.InputError, u.i18n.Ts("globals.messages.empty", "name", u.i18n.P("globals.terms.permission")), nil) } // Disallow updating `Admin` role, as the main System login requires it. role, err := u.Get(id) if err != nil { - return err + return models.Role{}, err } if role.Name == models.RoleAdmin { - return envelope.NewError(envelope.InputError, u.i18n.T("admin.role.cannotModifyAdminRole"), nil) + return models.Role{}, envelope.NewError(envelope.InputError, u.i18n.T("admin.role.cannotModifyAdminRole"), nil) } - if _, err := u.q.Update.Exec(id, r.Name, r.Description, pq.Array(validPermissions)); err != nil { + var result models.Role + if err := u.q.Update.Get(&result, id, r.Name, r.Description, pq.Array(validPermissions)); err != nil { u.lo.Error("error updating role", "error", err) - return envelope.NewError(envelope.GeneralError, u.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.role}"), nil) + return models.Role{}, envelope.NewError(envelope.GeneralError, u.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.role}"), nil) } - return nil + return result, nil } // filterValidPermissions filters out invalid permissions, logs warnings for unknown permissions. diff --git a/internal/sla/queries.sql b/internal/sla/queries.sql index b1f5493..076b8db 100644 --- a/internal/sla/queries.sql +++ b/internal/sla/queries.sql @@ -12,7 +12,8 @@ INSERT INTO sla_policies ( resolution_time, next_response_time, notifications -) VALUES ($1, $2, $3, $4, $5, $6); +) VALUES ($1, $2, $3, $4, $5, $6) +RETURNING *; -- name: update-sla-policy UPDATE sla_policies SET @@ -23,7 +24,8 @@ UPDATE sla_policies SET next_response_time = $6, notifications = $7, updated_at = NOW() -WHERE id = $1; +WHERE id = $1 +RETURNING *; -- name: delete-sla-policy DELETE FROM sla_policies WHERE id = $1; diff --git a/internal/sla/sla.go b/internal/sla/sla.go index af21002..05c1578 100644 --- a/internal/sla/sla.go +++ b/internal/sla/sla.go @@ -186,21 +186,23 @@ func (m *Manager) GetAll() ([]models.SLAPolicy, error) { } // Create creates a new SLA policy. -func (m *Manager) Create(name, description string, firstResponseTime, resolutionTime, nextResponseTime null.String, notifications models.SlaNotifications) error { - if _, err := m.q.InsertSLAPolicy.Exec(name, description, firstResponseTime, resolutionTime, nextResponseTime, notifications); err != nil { +func (m *Manager) Create(name, description string, firstResponseTime, resolutionTime, nextResponseTime null.String, notifications models.SlaNotifications) (models.SLAPolicy, error) { + var result models.SLAPolicy + if err := m.q.InsertSLAPolicy.Get(&result, name, description, firstResponseTime, resolutionTime, nextResponseTime, notifications); err != nil { m.lo.Error("error inserting SLA", "error", err) - return envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.sla}"), nil) + return models.SLAPolicy{}, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.sla}"), nil) } - return nil + return result, nil } // Update updates a SLA policy. -func (m *Manager) Update(id int, name, description string, firstResponseTime, resolutionTime, nextResponseTime null.String, notifications models.SlaNotifications) error { - if _, err := m.q.UpdateSLAPolicy.Exec(id, name, description, firstResponseTime, resolutionTime, nextResponseTime, notifications); err != nil { +func (m *Manager) Update(id int, name, description string, firstResponseTime, resolutionTime, nextResponseTime null.String, notifications models.SlaNotifications) (models.SLAPolicy, error) { + var result models.SLAPolicy + if err := m.q.UpdateSLAPolicy.Get(&result, id, name, description, firstResponseTime, resolutionTime, nextResponseTime, notifications); err != nil { m.lo.Error("error updating SLA", "error", err) - return envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.sla}"), nil) + return models.SLAPolicy{}, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.sla}"), nil) } - return nil + return result, nil } // Delete deletes an SLA policy. diff --git a/internal/tag/queries.sql b/internal/tag/queries.sql index f2bef48..39d0206 100644 --- a/internal/tag/queries.sql +++ b/internal/tag/queries.sql @@ -11,7 +11,8 @@ from INSERT into tags (name) values - ($1); + ($1) +RETURNING *; -- name: delete-tag DELETE from @@ -26,4 +27,5 @@ set name = $2, updated_at = now() where - id = $1; \ No newline at end of file + id = $1 +RETURNING *; \ No newline at end of file diff --git a/internal/tag/tag.go b/internal/tag/tag.go index cba7ccf..fe6d4d1 100644 --- a/internal/tag/tag.go +++ b/internal/tag/tag.go @@ -64,15 +64,16 @@ func (t *Manager) GetAll() ([]models.Tag, error) { } // Create creates a new tag. -func (t *Manager) Create(name string) error { - if _, err := t.q.InsertTag.Exec(name); err != nil { +func (t *Manager) Create(name string) (models.Tag, error) { + var tag models.Tag + if err := t.q.InsertTag.Get(&tag, name); err != nil { if dbutil.IsUniqueViolationError(err) { - return envelope.NewError(envelope.ConflictError, t.i18n.Ts("globals.messages.errorAlreadyExists", "name", "{globals.terms.tag}"), nil) + return tag, envelope.NewError(envelope.ConflictError, t.i18n.Ts("globals.messages.errorAlreadyExists", "name", "{globals.terms.tag}"), nil) } t.lo.Error("error inserting tag", "error", err) - return envelope.NewError(envelope.GeneralError, t.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.tag}"), nil) + return tag, envelope.NewError(envelope.GeneralError, t.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.tag}"), nil) } - return nil + return tag, nil } // Delete deletes a tag by ID. @@ -85,10 +86,11 @@ func (t *Manager) Delete(id int) error { } // Update updates a tag by id. -func (t *Manager) Update(id int, name string) error { - if _, err := t.q.UpdateTag.Exec(id, name); err != nil { +func (t *Manager) Update(id int, name string) (models.Tag, error) { + var tag models.Tag + if err := t.q.UpdateTag.Get(&tag, id, name); err != nil { t.lo.Error("error updating tag", "error", err) - return envelope.NewError(envelope.GeneralError, t.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.tag}"), nil) + return tag, envelope.NewError(envelope.GeneralError, t.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.tag}"), nil) } - return nil + return tag, nil } diff --git a/internal/team/queries.sql b/internal/team/queries.sql index f2af327..cbb2b71 100644 --- a/internal/team/queries.sql +++ b/internal/team/queries.sql @@ -18,10 +18,10 @@ JOIN teams t ON t.id = tm.team_id WHERE t.id = $1 AND u.deleted_at IS NULL AND u.type = 'agent' AND u.enabled = true; -- name: insert-team -INSERT INTO teams (name, timezone, conversation_assignment_type, business_hours_id, sla_policy_id, emoji, max_auto_assigned_conversations) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING id; +INSERT INTO teams (name, timezone, conversation_assignment_type, business_hours_id, sla_policy_id, emoji, max_auto_assigned_conversations) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING *; -- name: update-team -UPDATE teams set name = $2, timezone = $3, conversation_assignment_type = $4, business_hours_id = $5, sla_policy_id = $6, emoji = $7, max_auto_assigned_conversations = $8, updated_at = now() where id = $1; +UPDATE teams set name = $2, timezone = $3, conversation_assignment_type = $4, business_hours_id = $5, sla_policy_id = $6, emoji = $7, max_auto_assigned_conversations = $8, updated_at = now() where id = $1 RETURNING *; -- name: upsert-user-teams WITH delete_old_teams AS ( diff --git a/internal/team/team.go b/internal/team/team.go index 952287a..fad55d1 100644 --- a/internal/team/team.go +++ b/internal/team/team.go @@ -105,24 +105,26 @@ func (u *Manager) Get(id int) (models.Team, error) { } // Create creates a new team. -func (u *Manager) Create(name, timezone, conversationAssignmentType string, businessHrsID, slaPolicyID null.Int, emoji string, maxAutoAssignedConversations int) error { - if _, err := u.q.InsertTeam.Exec(name, timezone, conversationAssignmentType, businessHrsID, slaPolicyID, emoji, maxAutoAssignedConversations); err != nil { +func (u *Manager) Create(name, timezone, conversationAssignmentType string, businessHrsID, slaPolicyID null.Int, emoji string, maxAutoAssignedConversations int) (models.Team, error) { + var team models.Team + if err := u.q.InsertTeam.Get(&team, name, timezone, conversationAssignmentType, businessHrsID, slaPolicyID, emoji, maxAutoAssignedConversations); err != nil { if dbutil.IsUniqueViolationError(err) { - return envelope.NewError(envelope.GeneralError, u.i18n.Ts("globals.messages.errorAlreadyExists", "name", "{globals.terms.team}"), nil) + return team, envelope.NewError(envelope.GeneralError, u.i18n.Ts("globals.messages.errorAlreadyExists", "name", "{globals.terms.team}"), nil) } u.lo.Error("error inserting team", "error", err) - return envelope.NewError(envelope.GeneralError, u.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.team}"), nil) + return team, envelope.NewError(envelope.GeneralError, u.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.team}"), nil) } - return nil + return team, nil } // Update updates an existing team. -func (u *Manager) Update(id int, name, timezone, conversationAssignmentType string, businessHrsID, slaPolicyID null.Int, emoji string, maxAutoAssignedConversations int) error { - if _, err := u.q.UpdateTeam.Exec(id, name, timezone, conversationAssignmentType, businessHrsID, slaPolicyID, emoji, maxAutoAssignedConversations); err != nil { +func (u *Manager) Update(id int, name, timezone, conversationAssignmentType string, businessHrsID, slaPolicyID null.Int, emoji string, maxAutoAssignedConversations int) (models.Team, error) { + var team models.Team + if err := u.q.UpdateTeam.Get(&team, id, name, timezone, conversationAssignmentType, businessHrsID, slaPolicyID, emoji, maxAutoAssignedConversations); err != nil { u.lo.Error("error updating team", "error", err) - return envelope.NewError(envelope.GeneralError, u.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.team}"), nil) + return team, envelope.NewError(envelope.GeneralError, u.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.team}"), nil) } - return nil + return team, nil } // Delete deletes a team by ID also deletes all the team members and unassigns all the conversations belonging to the team. diff --git a/internal/template/queries.sql b/internal/template/queries.sql index 9173151..66773e1 100644 --- a/internal/template/queries.sql +++ b/internal/template/queries.sql @@ -1,6 +1,7 @@ -- name: insert INSERT INTO templates ("name", body, is_default, subject, type) -VALUES ($1, $2, $3, $4, $5); +VALUES ($1, $2, $3, $4, $5) +RETURNING *; -- name: update WITH u AS ( @@ -13,11 +14,9 @@ WITH u AS ( type = $6::template_type, updated_at = NOW() WHERE id = $1 - RETURNING id + RETURNING * ) -UPDATE templates -SET is_default = FALSE -WHERE id != $1 AND $4 = TRUE; +SELECT * FROM u LIMIT 1; -- name: get-default SELECT id, type, name, body, subject FROM templates WHERE is_default is TRUE; diff --git a/internal/template/template.go b/internal/template/template.go index 10eb2fc..7dcf5c8 100644 --- a/internal/template/template.go +++ b/internal/template/template.go @@ -66,27 +66,29 @@ func New(lo *logf.Logger, db *sqlx.DB, webTpls *template.Template, tpls *templat } // Update updates a new template with the given name, and body. -func (m *Manager) Update(id int, t models.Template) error { - if _, err := m.q.UpdateTemplate.Exec(id, t.Name, t.Body, t.IsDefault, t.Subject, t.Type); err != nil { +func (m *Manager) Update(id int, t models.Template) (models.Template, error) { + var result models.Template + if err := m.q.UpdateTemplate.Get(&result, id, t.Name, t.Body, t.IsDefault, t.Subject, t.Type); err != nil { m.lo.Error("error updating template", "error", err) - return envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.template}"), nil) + return models.Template{}, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.template}"), nil) } - return nil + return result, nil } // Create creates a template. -func (m *Manager) Create(t models.Template) error { +func (m *Manager) Create(t models.Template) (models.Template, error) { if t.IsDefault { t.Type = TypeEmailOutgoing } - if _, err := m.q.InsertTemplate.Exec(t.Name, t.Body, t.IsDefault, t.Subject, t.Type); err != nil { + var result models.Template + if err := m.q.InsertTemplate.Get(&result, t.Name, t.Body, t.IsDefault, t.Subject, t.Type); err != nil { if dbutil.IsUniqueViolationError(err) && t.IsDefault { - return envelope.NewError(envelope.GeneralError, m.i18n.T("template.defaultTemplateAlreadyExists"), nil) + return models.Template{}, envelope.NewError(envelope.GeneralError, m.i18n.T("template.defaultTemplateAlreadyExists"), nil) } m.lo.Error("error inserting template", "error", err) - return envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.template}"), nil) + return models.Template{}, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.template}"), nil) } - return nil + return result, nil } // GetAll returns all templates by type. diff --git a/internal/view/queries.sql b/internal/view/queries.sql index 77b80db..fcf9450 100644 --- a/internal/view/queries.sql +++ b/internal/view/queries.sql @@ -8,7 +8,8 @@ FROM views WHERE user_id = $1; -- name: insert-view INSERT INTO views (name, filters, user_id) -VALUES ($1, $2, $3); +VALUES ($1, $2, $3) +RETURNING *; -- name: delete-view DELETE FROM views @@ -18,3 +19,4 @@ WHERE id = $1; UPDATE views SET name = $2, filters = $3, updated_at = NOW() WHERE id = $1 +RETURNING * diff --git a/internal/view/view.go b/internal/view/view.go index 26a24f7..14ad226 100644 --- a/internal/view/view.go +++ b/internal/view/view.go @@ -77,21 +77,23 @@ func (v *Manager) GetUsersViews(userID int) ([]models.View, error) { } // Create creates a new view. -func (v *Manager) Create(name string, filter []byte, userID int) error { - if _, err := v.q.InsertView.Exec(name, filter, userID); err != nil { +func (v *Manager) Create(name string, filter []byte, userID int) (models.View, error) { + var createdView models.View + if err := v.q.InsertView.Get(&createdView, name, filter, userID); err != nil { v.lo.Error("error inserting view", "error", err) - return envelope.NewError(envelope.GeneralError, v.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.view}"), nil) + return models.View{}, envelope.NewError(envelope.GeneralError, v.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.view}"), nil) } - return nil + return createdView, nil } // Update updates a view by id. -func (v *Manager) Update(id int, name string, filter []byte) error { - if _, err := v.q.UpdateView.Exec(id, name, filter); err != nil { +func (v *Manager) Update(id int, name string, filter []byte) (models.View, error) { + var updatedView models.View + if err := v.q.UpdateView.Get(&updatedView, id, name, filter); err != nil { v.lo.Error("error updating view", "error", err) - return envelope.NewError(envelope.GeneralError, v.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.view}"), nil) + return models.View{}, envelope.NewError(envelope.GeneralError, v.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.view}"), nil) } - return nil + return updatedView, nil } // Delete deletes a view by ID. diff --git a/internal/webhook/models/models.go b/internal/webhook/models/models.go index 98a638a..194334d 100644 --- a/internal/webhook/models/models.go +++ b/internal/webhook/models/models.go @@ -15,7 +15,7 @@ type Webhook struct { Name string `db:"name" json:"name"` URL string `db:"url" json:"url"` Events pq.StringArray `db:"events" json:"events"` - Secret string `db:"secret" json:"secret,omitempty"` + Secret string `db:"secret" json:"secret"` IsActive bool `db:"is_active" json:"is_active"` } diff --git a/internal/webhook/queries.sql b/internal/webhook/queries.sql index f751460..fb075e4 100644 --- a/internal/webhook/queries.sql +++ b/internal/webhook/queries.sql @@ -64,7 +64,7 @@ INSERT INTO webhooks (name, url, events, secret, is_active) VALUES ($1, $2, $3, $4, $5) -RETURNING id; +RETURNING *; -- name: update-webhook UPDATE @@ -77,7 +77,8 @@ SET is_active = $6, updated_at = NOW() WHERE - id = $1; + id = $1 +RETURNING *; -- name: delete-webhook DELETE FROM @@ -92,4 +93,5 @@ SET is_active = NOT is_active, updated_at = NOW() WHERE - id = $1; + id = $1 +RETURNING *; diff --git a/internal/webhook/webhook.go b/internal/webhook/webhook.go index 3da5aa1..8c030e8 100644 --- a/internal/webhook/webhook.go +++ b/internal/webhook/webhook.go @@ -127,25 +127,26 @@ func (m *Manager) Get(id int) (models.Webhook, error) { } // Create creates a new webhook. -func (m *Manager) Create(webhook models.Webhook) (int, error) { - var id int - if err := m.q.InsertWebhook.Get(&id, webhook.Name, webhook.URL, pq.Array(webhook.Events), webhook.Secret, webhook.IsActive); err != nil { +func (m *Manager) Create(webhook models.Webhook) (models.Webhook, error) { + var result models.Webhook + if err := m.q.InsertWebhook.Get(&result, webhook.Name, webhook.URL, pq.Array(webhook.Events), webhook.Secret, webhook.IsActive); err != nil { if dbutil.IsUniqueViolationError(err) { - return 0, envelope.NewError(envelope.ConflictError, m.i18n.Ts("globals.messages.errorAlreadyExists", "name", "webhook"), nil) + return models.Webhook{}, envelope.NewError(envelope.ConflictError, m.i18n.Ts("globals.messages.errorAlreadyExists", "name", "webhook"), nil) } m.lo.Error("error inserting webhook", "error", err) - return 0, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorCreating", "name", "webhook"), nil) + return models.Webhook{}, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorCreating", "name", "webhook"), nil) } - return id, nil + return result, nil } // Update updates a webhook by ID. -func (m *Manager) Update(id int, webhook models.Webhook) error { - if _, err := m.q.UpdateWebhook.Exec(id, webhook.Name, webhook.URL, pq.Array(webhook.Events), webhook.Secret, webhook.IsActive); err != nil { +func (m *Manager) Update(id int, webhook models.Webhook) (models.Webhook, error) { + var result models.Webhook + if err := m.q.UpdateWebhook.Get(&result, id, webhook.Name, webhook.URL, pq.Array(webhook.Events), webhook.Secret, webhook.IsActive); err != nil { m.lo.Error("error updating webhook", "error", err) - return envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorUpdating", "name", "webhook"), nil) + return models.Webhook{}, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorUpdating", "name", "webhook"), nil) } - return nil + return result, nil } // Delete deletes a webhook by ID. @@ -158,12 +159,13 @@ func (m *Manager) Delete(id int) error { } // Toggle toggles the active status of a webhook by ID. -func (m *Manager) Toggle(id int) error { - if _, err := m.q.ToggleWebhook.Exec(id); err != nil { +func (m *Manager) Toggle(id int) (models.Webhook, error) { + var result models.Webhook + if err := m.q.ToggleWebhook.Get(&result, id); err != nil { m.lo.Error("error toggling webhook", "error", err) - return envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorUpdating", "name", "webhook"), nil) + return models.Webhook{}, envelope.NewError(envelope.GeneralError, m.i18n.Ts("globals.messages.errorUpdating", "name", "webhook"), nil) } - return nil + return result, nil } // SendTestWebhook sends a test webhook to the specified webhook ID.