package classes import ( "context" "git.golem15.com/golem15/summercms/modules/backpack" "git.golem15.com/golem15/summercms/modules/lagoon" "git.golem15.com/golem15/summercms/modules/pact" "gorm.io/gorm" ) // Guard names the plugin's pact.MCPSubjectChanged events carry: the frontend // user guard this plugin provides and the admin's guard (for the backend // side of an account link). const ( SubjectGuardUser = "user" SubjectGuardBackend = "backend" ) // FireSubjectChanged fires one *pact.MCPSubjectChanged (guard, user id, // kind) through the application's event bus at once, so the MCP endpoint // re-lists the subject's tools or ends its sessions. A missing application // or bus, or a zero id, is a no-op; a listener's error is logged and never // returned, so the write that caused the event never fails because of it // (every MCP request re-checks anyway). func FireSubjectChanged(ctx context.Context, app *backpack.App, guard string, userID uint, kind string) { if app == nil || app.Events == nil || userID == 0 || kind == "" { return } if ctx == nil { ctx = context.Background() } event := &pact.MCPSubjectChanged{Guard: guard, UserID: userID, Kind: kind} if err := app.Events.Fire(ctx, event); err != nil { pluginLog.WarnContext(ctx, "golem15.user: subject changed listener failed", "guard", guard, "user_id", userID, "kind", kind, "err", err) } } // FireSubjectChangedAfterCommit is FireSubjectChanged once the write // transaction tx commits (lagoon.AfterCommit), so a listener that reads the // database sees the change; nothing is fired when the transaction rolls // back. A nil tx fires at once. ctx must be the context the transaction // runs under (the one cabana hands a hook or an action). func FireSubjectChangedAfterCommit(ctx context.Context, app *backpack.App, tx *gorm.DB, guard string, userID uint, kind string) { if app == nil || app.Events == nil || userID == 0 || kind == "" { return } if tx == nil { FireSubjectChanged(ctx, app, guard, userID, kind) return } lagoon.AfterCommit(ctx, tx, func(ctx context.Context, _ *gorm.DB) { FireSubjectChanged(ctx, app, guard, userID, kind) }) }