Compare commits

...

10 Commits

Author SHA1 Message Date
Pradeep Kumar
f7a89ad5f9 align system-dashboard with Source enums
assumption taken that system dashbard is just one which is going
tobe ai-o11y-overview page. (there is going to be a unique Name in
dashboard which would help us handle other system dashbaords)

no seeding code part present in this pr.
2026-05-26 11:39:18 +05:30
Pradeep Kumar
00f4e40f84 change from QP to path param
address review comment to add source as path param instead of QP
and a little refactor
2026-05-25 21:37:16 +05:30
Pradeep Kumar
05a4fa0d6b address review comments after using existing paths.
fix migration number 78  to 79
drop id in reset path, and refactor
use locking for system dashboard as well.
2026-05-25 21:37:16 +05:30
Pradeep Kumar
9b3d07ce15 use existing dashboards path
as discussed on the pr conversations, we are now using existing
dashboards path and most of the existing methods.

- GET /api/v1/dashboards?source=<src>
- POST /api/v1/dashboards/{id}/reset
Update works same it just bypass the lock/unlock check

Behavior of seeding remains intact
2026-05-25 21:37:16 +05:30
Pradeep Kumar
d66d510ad7 fix migration not by by FK toggle
used similar pattern as 029_drop_groups.

tested in local env with without data in both dashboard and
public_dashboard
2026-05-25 21:37:16 +05:30
Pradeep Kumar
d854a85f0c fix migration
after testing with data in public_dashboard migration failed.
fixed with Alter table.
2026-05-25 21:37:16 +05:30
Pradeep Kumar
b4fd65036b add userid instead of empty string or 'system' & fix migration
comment out storing default value, only add column
2026-05-25 21:37:16 +05:30
Pradeep Kumar
7ac77c6fcf address review comments 2026-05-25 21:37:16 +05:30
Pradeep Kumar
5e17e1f5c9 removes ai_o11y_overview.json containing default value
this removes default values for dashbaord data for system source

only thing changed is removal of file and not storing anything
at seed time .
will handle this in diff pr.
2026-05-25 21:37:16 +05:30
Pradeep Kumar
bd350c8f10 address review comments 2026-05-25 21:37:16 +05:30
8 changed files with 96 additions and 7 deletions

View File

@@ -228,6 +228,10 @@ func (module *module) Update(ctx context.Context, orgID valuer.UUID, id valuer.U
return module.pkgDashboardModule.Update(ctx, orgID, id, updatedBy, data, diff)
}
func (module *module) ResetSystemDashboard(ctx context.Context, orgID valuer.UUID, updatedBy string) (*dashboardtypes.Dashboard, error) {
return module.pkgDashboardModule.ResetSystemDashboard(ctx, orgID, updatedBy)
}
func (module *module) LockUnlock(ctx context.Context, orgID valuer.UUID, id valuer.UUID, updatedBy string, isAdmin bool, lock bool) error {
return module.pkgDashboardModule.LockUnlock(ctx, orgID, id, updatedBy, isAdmin, lock)
}

View File

@@ -41,6 +41,8 @@ type Module interface {
List(ctx context.Context, orgID valuer.UUID) ([]*dashboardtypes.Dashboard, error)
Update(ctx context.Context, orgID valuer.UUID, id valuer.UUID, updatedBy string, data dashboardtypes.UpdatableDashboard, diff int) (*dashboardtypes.Dashboard, error)
ResetSystemDashboard(ctx context.Context, orgID valuer.UUID, updatedBy string) (*dashboardtypes.Dashboard, error)
LockUnlock(ctx context.Context, orgID valuer.UUID, id valuer.UUID, updatedBy string, isAdmin bool, lock bool) error
@@ -74,4 +76,6 @@ type Handler interface {
LockUnlock(http.ResponseWriter, *http.Request)
Delete(http.ResponseWriter, *http.Request)
ResetSystemDashboard(http.ResponseWriter, *http.Request)
}

View File

@@ -185,6 +185,32 @@ func (handler *handler) LockUnlock(rw http.ResponseWriter, r *http.Request) {
}
// ResetSystemDashboard resets the org's system dashboard to its default.
func (handler *handler) ResetSystemDashboard(rw http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
defer cancel()
claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil {
render.Error(rw, err)
return
}
orgID, err := valuer.NewUUID(claims.OrgID)
if err != nil {
render.Error(rw, err)
return
}
dashboard, err := handler.module.ResetSystemDashboard(ctx, orgID, claims.Email)
if err != nil {
render.Error(rw, err)
return
}
render.Success(rw, http.StatusOK, dashboard)
}
func (handler *handler) Delete(rw http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
defer cancel()

View File

@@ -66,6 +66,15 @@ func (module *module) Get(ctx context.Context, orgID valuer.UUID, id valuer.UUID
return dashboardtypes.NewDashboardFromStorableDashboard(storableDashboard), nil
}
func (module *module) GetSystemDashboard(ctx context.Context, orgID valuer.UUID) (*dashboardtypes.Dashboard, error) {
storableDashboard, err := module.store.GetSystemDashboard(ctx, orgID)
if err != nil {
return nil, err
}
return dashboardtypes.NewDashboardFromStorableDashboard(storableDashboard), nil
}
func (module *module) List(ctx context.Context, orgID valuer.UUID) ([]*dashboardtypes.Dashboard, error) {
storableDashboards, err := module.store.List(ctx, orgID)
if err != nil {
@@ -94,8 +103,7 @@ func (module *module) Update(ctx context.Context, orgID valuer.UUID, id valuer.U
return nil, err
}
err = dashboard.Update(ctx, updatableDashboard, updatedBy, diff)
if err != nil {
if err := dashboard.Update(ctx, updatableDashboard, updatedBy, diff); err != nil {
return nil, err
}
@@ -104,14 +112,32 @@ func (module *module) Update(ctx context.Context, orgID valuer.UUID, id valuer.U
return nil, err
}
err = module.store.Update(ctx, orgID, storableDashboard)
if err != nil {
if err := module.store.Update(ctx, orgID, storableDashboard); err != nil {
return nil, err
}
return dashboard, nil
}
func (module *module) ResetSystemDashboard(ctx context.Context, orgID valuer.UUID, updatedBy string) (*dashboardtypes.Dashboard, error) {
existing, err := module.GetSystemDashboard(ctx, orgID)
if err != nil {
return nil, err
}
defaults, err := dashboardtypes.NewDefaultSystemDashboard(orgID)
if err != nil {
return nil, err
}
existingID, err := valuer.NewUUID(existing.ID)
if err != nil {
return nil, err
}
return module.Update(ctx, orgID, existingID, updatedBy, defaults.Data, 0)
}
func (module *module) LockUnlock(ctx context.Context, orgID valuer.UUID, id valuer.UUID, updatedBy string, isAdmin bool, lock bool) error {
dashboard, err := module.Get(ctx, orgID, id)
if err != nil {
@@ -153,8 +179,7 @@ func (module *module) Delete(ctx context.Context, orgID valuer.UUID, id valuer.U
return errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, "dashboard is locked, please unlock the dashboard to be delete it")
}
err = module.store.Delete(ctx, orgID, id)
if err != nil {
if err := module.store.Delete(ctx, orgID, id); err != nil {
return err
}

View File

@@ -63,6 +63,23 @@ func (store *store) Get(ctx context.Context, orgID valuer.UUID, id valuer.UUID)
return storableDashboard, nil
}
func (store *store) GetSystemDashboard(ctx context.Context, orgID valuer.UUID) (*dashboardtypes.StorableDashboard, error) {
storableDashboard := new(dashboardtypes.StorableDashboard)
err := store.
sqlstore.
BunDBCtx(ctx).
NewSelect().
Model(storableDashboard).
Where("org_id = ?", orgID).
Where("source = ?", dashboardtypes.SourceSystem.StringValue()).
Limit(1).
Scan(ctx)
if err != nil {
return nil, store.sqlstore.WrapNotFoundErrf(err, errors.CodeNotFound, "system dashboard doesn't exist")
}
return storableDashboard, nil
}
func (store *store) GetPublic(ctx context.Context, dashboardID string) (*dashboardtypes.StorablePublicDashboard, error) {
storable := new(dashboardtypes.StorablePublicDashboard)
err := store.
@@ -153,7 +170,7 @@ func (store *store) ListPublic(ctx context.Context, orgID valuer.UUID) ([]*dashb
func (store *store) Update(ctx context.Context, orgID valuer.UUID, storableDashboard *dashboardtypes.StorableDashboard) error {
_, err := store.
sqlstore.
BunDB().
BunDBCtx(ctx).
NewUpdate().
Model(storableDashboard).
WherePK().

View File

@@ -511,6 +511,7 @@ func (aH *APIHandler) RegisterRoutes(router *mux.Router, am *middleware.AuthZ) {
router.HandleFunc("/api/v1/dashboards/{id}", am.EditAccess(aH.Signoz.Handlers.Dashboard.Update)).Methods(http.MethodPut)
router.HandleFunc("/api/v1/dashboards/{id}", am.EditAccess(aH.Signoz.Handlers.Dashboard.Delete)).Methods(http.MethodDelete)
router.HandleFunc("/api/v1/dashboards/{id}/lock", am.EditAccess(aH.Signoz.Handlers.Dashboard.LockUnlock)).Methods(http.MethodPut)
router.HandleFunc("/api/v1/dashboards/system/reset", am.AdminAccess(aH.Signoz.Handlers.Dashboard.ResetSystemDashboard)).Methods(http.MethodPost)
router.HandleFunc("/api/v2/variables/query", am.ViewAccess(aH.queryDashboardVarsV2)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/explorer/views", am.ViewAccess(aH.Signoz.Handlers.SavedView.List)).Methods(http.MethodGet)

View File

@@ -0,0 +1,10 @@
package dashboardtypes
import (
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/valuer"
)
func NewDefaultSystemDashboard(orgID valuer.UUID) (*Dashboard, error) {
return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "no defaults registered for system dashboard")
}

View File

@@ -13,6 +13,8 @@ type Store interface {
Get(context.Context, valuer.UUID, valuer.UUID) (*StorableDashboard, error)
GetSystemDashboard(context.Context, valuer.UUID) (*StorableDashboard, error)
GetPublic(context.Context, string) (*StorablePublicDashboard, error)
GetDashboardByOrgsAndPublicID(context.Context, []string, string) (*StorableDashboard, error)