-- ============================================================ -- spAdminUsers: User management -- ============================================================ CREATE OR ALTER PROCEDURE [dbo].[spAdminUsers] @action VARCHAR(50), @rqst NVARCHAR(MAX), @resp NVARCHAR(MAX) OUTPUT AS BEGIN SET NOCOUNT ON; DECLARE @j NVARCHAR(MAX) = ISNULL(@rqst, N'{}'); ------------------------------------------------------------------------ -- ACTION: create ------------------------------------------------------------------------ IF @action = 'create' BEGIN DECLARE @cEmail NVARCHAR(256) = NULLIF(JSON_VALUE(@j, '$.email'), ''); DECLARE @cDisplayName NVARCHAR(256) = NULLIF(JSON_VALUE(@j, '$.displayName'), ''); DECLARE @cClientId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.clientId')); DECLARE @cRole VARCHAR(30) = ISNULL(NULLIF(JSON_VALUE(@j, '$.role'), ''), 'User'); IF @cEmail IS NULL BEGIN SET @resp = N'{"ok":false,"error":"email is required"}'; RETURN; END IF EXISTS (SELECT 1 FROM dbo.tbUser WHERE usrEmail = @cEmail) BEGIN SET @resp = N'{"ok":false,"error":"User with this email already exists"}'; RETURN; END IF @cClientId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM dbo.tbClient WHERE cltId = @cClientId) BEGIN SET @resp = N'{"ok":false,"error":"Client not found"}'; RETURN; END DECLARE @cUserId UNIQUEIDENTIFIER = NEWID(); DECLARE @cEntraSub NVARCHAR(100) = 'pending-' + CAST(@cUserId AS NVARCHAR(50)); INSERT INTO dbo.tbUser (usrId, usrEntraSub, usrProvider, usrSubject, usrEmail, usrDisplayName, usrStatus) VALUES (@cUserId, @cEntraSub, 'Pending', @cEntraSub, @cEmail, @cDisplayName, 'Active'); IF @cClientId IS NOT NULL BEGIN INSERT INTO dbo.tbUserClientRole (ucrUsrId, ucrCltId, ucrRole) VALUES (@cUserId, @cClientId, @cRole); END SET @resp = ( SELECT CAST(1 AS BIT) AS ok, @cUserId AS userId, @cEmail AS email, @cDisplayName AS displayName, @cClientId AS clientId, @cRole AS [role] FOR JSON PATH, WITHOUT_ARRAY_WRAPPER ); RETURN; END ------------------------------------------------------------------------ -- ACTION: get ------------------------------------------------------------------------ IF @action = 'get' BEGIN DECLARE @gId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.userId')); IF @gId IS NULL BEGIN SET @resp = N'{"ok":false,"error":"userId is required"}'; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.tbUser WHERE usrId = @gId) BEGIN SET @resp = N'{"ok":false,"error":"User not found"}'; RETURN; END SET @resp = ( SELECT CAST(1 AS BIT) AS ok, u.usrId AS userId, u.usrEmail AS email, u.usrDisplayName AS displayName, u.usrStatus AS status, u.usrCreatedUtc AS createdAt, ( SELECT c.cltId AS clientId, c.cltName AS clientName, r.ucrRole AS [role] FROM dbo.tbUserClientRole r JOIN dbo.tbClient c ON c.cltId = r.ucrCltId WHERE r.ucrUsrId = u.usrId FOR JSON PATH ) AS clients FROM dbo.tbUser u WHERE u.usrId = @gId FOR JSON PATH, WITHOUT_ARRAY_WRAPPER ); RETURN; END ------------------------------------------------------------------------ -- ACTION: list ------------------------------------------------------------------------ IF @action = 'list' BEGIN DECLARE @lStatus VARCHAR(20) = NULLIF(JSON_VALUE(@j, '$.status'), ''); DECLARE @lClientId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.clientId')); DECLARE @lPage INT = ISNULL(TRY_CAST(JSON_VALUE(@j, '$.page') AS INT), 1); DECLARE @lPageSize INT = ISNULL(TRY_CAST(JSON_VALUE(@j, '$.pageSize') AS INT), 50); DECLARE @users NVARCHAR(MAX); SELECT @users = ( SELECT u.usrId AS userId, u.usrEmail AS email, u.usrDisplayName AS displayName, u.usrStatus AS status, u.usrCreatedUtc AS createdAt, ( SELECT c.cltId AS clientId, c.cltName AS clientName, r.ucrRole AS [role] FROM dbo.tbUserClientRole r JOIN dbo.tbClient c ON c.cltId = r.ucrCltId WHERE r.ucrUsrId = u.usrId FOR JSON PATH ) AS clients FROM dbo.tbUser u WHERE (@lStatus IS NULL OR u.usrStatus = @lStatus) AND (@lClientId IS NULL OR EXISTS ( SELECT 1 FROM dbo.tbUserClientRole WHERE ucrUsrId = u.usrId AND ucrCltId = @lClientId )) ORDER BY u.usrEmail OFFSET (@lPage - 1) * @lPageSize ROWS FETCH NEXT @lPageSize ROWS ONLY FOR JSON PATH ); DECLARE @lTotal INT; SELECT @lTotal = COUNT(*) FROM dbo.tbUser u WHERE (@lStatus IS NULL OR u.usrStatus = @lStatus) AND (@lClientId IS NULL OR EXISTS ( SELECT 1 FROM dbo.tbUserClientRole WHERE ucrUsrId = u.usrId AND ucrCltId = @lClientId )); SET @resp = ( SELECT CAST(1 AS BIT) AS ok, JSON_QUERY(ISNULL(@users, '[]')) AS users, @lTotal AS totalCount, @lPage AS page, @lPageSize AS pageSize FOR JSON PATH, WITHOUT_ARRAY_WRAPPER ); RETURN; END ------------------------------------------------------------------------ -- ACTION: update ------------------------------------------------------------------------ IF @action = 'update' BEGIN DECLARE @uId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.userId')); DECLARE @uDisplayName NVARCHAR(256) = NULLIF(JSON_VALUE(@j, '$.displayName'), ''); DECLARE @uStatus VARCHAR(20) = NULLIF(JSON_VALUE(@j, '$.status'), ''); IF @uId IS NULL BEGIN SET @resp = N'{"ok":false,"error":"userId is required"}'; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.tbUser WHERE usrId = @uId) BEGIN SET @resp = N'{"ok":false,"error":"User not found"}'; RETURN; END UPDATE dbo.tbUser SET usrDisplayName = ISNULL(@uDisplayName, usrDisplayName), usrStatus = ISNULL(@uStatus, usrStatus) WHERE usrId = @uId; SET @resp = ( SELECT CAST(1 AS BIT) AS ok, usrId AS userId, usrEmail AS email, usrDisplayName AS displayName, usrStatus AS status FROM dbo.tbUser WHERE usrId = @uId FOR JSON PATH, WITHOUT_ARRAY_WRAPPER ); RETURN; END ------------------------------------------------------------------------ -- ACTION: delete (soft delete) ------------------------------------------------------------------------ IF @action = 'delete' BEGIN DECLARE @dId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.userId')); IF @dId IS NULL BEGIN SET @resp = N'{"ok":false,"error":"userId is required"}'; RETURN; END UPDATE dbo.tbUser SET usrStatus = 'Inactive' WHERE usrId = @dId; SET @resp = (SELECT CAST(1 AS BIT) AS ok, @@ROWCOUNT AS rowsAffected FOR JSON PATH, WITHOUT_ARRAY_WRAPPER); RETURN; END ------------------------------------------------------------------------ -- ACTION: linkToClient ------------------------------------------------------------------------ IF @action = 'linkToClient' BEGIN DECLARE @luUserId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.userId')); DECLARE @luClientId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.clientId')); DECLARE @luRole VARCHAR(30) = ISNULL(NULLIF(JSON_VALUE(@j, '$.role'), ''), 'User'); IF @luUserId IS NULL OR @luClientId IS NULL BEGIN SET @resp = N'{"ok":false,"error":"userId and clientId are required"}'; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.tbUser WHERE usrId = @luUserId) BEGIN SET @resp = N'{"ok":false,"error":"User not found"}'; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.tbClient WHERE cltId = @luClientId) BEGIN SET @resp = N'{"ok":false,"error":"Client not found"}'; RETURN; END IF EXISTS (SELECT 1 FROM dbo.tbUserClientRole WHERE ucrUsrId = @luUserId AND ucrCltId = @luClientId) BEGIN UPDATE dbo.tbUserClientRole SET ucrRole = @luRole WHERE ucrUsrId = @luUserId AND ucrCltId = @luClientId; SET @resp = (SELECT CAST(1 AS BIT) AS ok, 'updated' AS action, @luRole AS [role] FOR JSON PATH, WITHOUT_ARRAY_WRAPPER); RETURN; END INSERT INTO dbo.tbUserClientRole (ucrUsrId, ucrCltId, ucrRole) VALUES (@luUserId, @luClientId, @luRole); SET @resp = (SELECT CAST(1 AS BIT) AS ok, 'created' AS action, @luRole AS [role] FOR JSON PATH, WITHOUT_ARRAY_WRAPPER); RETURN; END ------------------------------------------------------------------------ -- ACTION: unlinkFromClient ------------------------------------------------------------------------ IF @action = 'unlinkFromClient' BEGIN DECLARE @ruUserId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.userId')); DECLARE @ruClientId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.clientId')); IF @ruUserId IS NULL OR @ruClientId IS NULL BEGIN SET @resp = N'{"ok":false,"error":"userId and clientId are required"}'; RETURN; END DELETE FROM dbo.tbUserClientRole WHERE ucrUsrId = @ruUserId AND ucrCltId = @ruClientId; SET @resp = (SELECT CAST(1 AS BIT) AS ok, @@ROWCOUNT AS rowsAffected FOR JSON PATH, WITHOUT_ARRAY_WRAPPER); RETURN; END SET @resp = N'{"ok":false,"error":"Unknown action"}'; END GO