feat(handlers): dispatch pending events after transaction commit

All generic CRUD handlers now call events.DispatchPending(s) after
s.Commit() and events.CleanupPending(s) on rollback paths. This is
preparation for switching model methods from events.Dispatch to
events.DispatchOnCommit.

Refs #2315
This commit is contained in:
kolaente
2026-03-02 09:10:24 +01:00
parent 564573bdd5
commit 217a481162
5 changed files with 33 additions and 0 deletions

View File

@@ -22,6 +22,7 @@ import (
"net/http"
"code.vikunja.io/api/pkg/db"
"code.vikunja.io/api/pkg/events"
"code.vikunja.io/api/pkg/log"
"code.vikunja.io/api/pkg/models"
"code.vikunja.io/api/pkg/modules/auth"
@@ -68,10 +69,12 @@ func (c *WebHandler) CreateWeb(ctx *echo.Context) error {
canCreate, err := currentStruct.CanCreate(s, currentAuth)
if err != nil {
_ = s.Rollback()
events.CleanupPending(s)
return err
}
if !canCreate {
_ = s.Rollback()
events.CleanupPending(s)
log.Warningf("Tried to create while not having the permissions for it (User: %v)", currentAuth)
return echo.NewHTTPError(http.StatusForbidden, "Forbidden")
}
@@ -80,13 +83,17 @@ func (c *WebHandler) CreateWeb(ctx *echo.Context) error {
err = currentStruct.Create(s, currentAuth)
if err != nil {
_ = s.Rollback()
events.CleanupPending(s)
return err
}
err = s.Commit()
if err != nil {
events.CleanupPending(s)
return err
}
events.DispatchPending(s)
return ctx.JSON(http.StatusCreated, currentStruct)
}

View File

@@ -22,6 +22,7 @@ import (
"net/http"
"code.vikunja.io/api/pkg/db"
"code.vikunja.io/api/pkg/events"
"code.vikunja.io/api/pkg/log"
"code.vikunja.io/api/pkg/models"
"code.vikunja.io/api/pkg/modules/auth"
@@ -67,10 +68,12 @@ func (c *WebHandler) DeleteWeb(ctx *echo.Context) error {
canDelete, err := currentStruct.CanDelete(s, currentAuth)
if err != nil {
_ = s.Rollback()
events.CleanupPending(s)
return err
}
if !canDelete {
_ = s.Rollback()
events.CleanupPending(s)
log.Warningf("Tried to delete while not having the permissions for it (User: %v)", currentAuth)
return echo.NewHTTPError(http.StatusForbidden, "Forbidden")
}
@@ -78,13 +81,17 @@ func (c *WebHandler) DeleteWeb(ctx *echo.Context) error {
err = currentStruct.Delete(s, currentAuth)
if err != nil {
_ = s.Rollback()
events.CleanupPending(s)
return err
}
err = s.Commit()
if err != nil {
events.CleanupPending(s)
return err
}
events.DispatchPending(s)
return ctx.JSON(http.StatusOK, message{"Successfully deleted."})
}

View File

@@ -26,6 +26,7 @@ import (
vconfig "code.vikunja.io/api/pkg/config"
"code.vikunja.io/api/pkg/db"
"code.vikunja.io/api/pkg/events"
"code.vikunja.io/api/pkg/log"
"code.vikunja.io/api/pkg/models"
"code.vikunja.io/api/pkg/modules/auth"
@@ -105,6 +106,7 @@ func (c *WebHandler) ReadAllWeb(ctx *echo.Context) error {
result, resultCount, numberOfItems, err := currentStruct.ReadAll(s, currentAuth, search, pageNumber, perPageNumber)
if err != nil {
_ = s.Rollback()
events.CleanupPending(s)
return err
}
@@ -127,9 +129,12 @@ func (c *WebHandler) ReadAllWeb(ctx *echo.Context) error {
err = s.Commit()
if err != nil {
events.CleanupPending(s)
return err
}
events.DispatchPending(s)
// Ensure we return an empty array instead of null when there are no results.
// We need to use reflection here because a nil slice wrapped in an interface{}
// is not equal to nil (the interface contains a nil value but is not nil itself).

View File

@@ -23,6 +23,7 @@ import (
"strconv"
"code.vikunja.io/api/pkg/db"
"code.vikunja.io/api/pkg/events"
"code.vikunja.io/api/pkg/log"
"code.vikunja.io/api/pkg/models"
"code.vikunja.io/api/pkg/modules/auth"
@@ -63,10 +64,12 @@ func (c *WebHandler) ReadOneWeb(ctx *echo.Context) error {
canRead, maxPermission, err := currentStruct.CanRead(s, currentAuth)
if err != nil {
_ = s.Rollback()
events.CleanupPending(s)
return err
}
if !canRead {
_ = s.Rollback()
events.CleanupPending(s)
log.Warningf("Tried to read while not having the permissions for it (User: %v)", currentAuth)
return echo.NewHTTPError(http.StatusForbidden, "You don't have the permission to see this")
}
@@ -75,6 +78,7 @@ func (c *WebHandler) ReadOneWeb(ctx *echo.Context) error {
err = currentStruct.ReadOne(s, currentAuth)
if err != nil {
_ = s.Rollback()
events.CleanupPending(s)
return err
}
@@ -86,8 +90,11 @@ func (c *WebHandler) ReadOneWeb(ctx *echo.Context) error {
err = s.Commit()
if err != nil {
events.CleanupPending(s)
return err
}
events.DispatchPending(s)
return ctx.JSON(http.StatusOK, currentStruct)
}

View File

@@ -22,6 +22,7 @@ import (
"net/http"
"code.vikunja.io/api/pkg/db"
"code.vikunja.io/api/pkg/events"
"code.vikunja.io/api/pkg/log"
"code.vikunja.io/api/pkg/models"
"code.vikunja.io/api/pkg/modules/auth"
@@ -68,10 +69,12 @@ func (c *WebHandler) UpdateWeb(ctx *echo.Context) error {
canUpdate, err := currentStruct.CanUpdate(s, currentAuth)
if err != nil {
_ = s.Rollback()
events.CleanupPending(s)
return err
}
if !canUpdate {
_ = s.Rollback()
events.CleanupPending(s)
log.Warningf("Tried to update while not having the permissions for it (User: %v)", currentAuth)
return echo.NewHTTPError(http.StatusForbidden, "Forbidden")
}
@@ -80,13 +83,17 @@ func (c *WebHandler) UpdateWeb(ctx *echo.Context) error {
err = currentStruct.Update(s, currentAuth)
if err != nil {
_ = s.Rollback()
events.CleanupPending(s)
return err
}
err = s.Commit()
if err != nil {
events.CleanupPending(s)
return err
}
events.DispatchPending(s)
return ctx.JSON(http.StatusOK, currentStruct)
}