Files
AdPlatform-Server/Management/Controllers/Admin/AdminClientUsersController.cs
2026-03-14 13:50:09 -07:00

85 lines
3.3 KiB
C#

using Management.Data;
using Management.Security;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;
namespace Management.Controllers.Admin;
/// <summary>
/// Client-planet user management — tbClientUser / tbClientUserRole.
/// No admin-plane concepts here whatsoever.
///
/// ENDPOINTS:
/// GET /api/admin/client-users - List client users
/// GET /api/admin/client-users/{userId} - Get single user
/// PUT /api/admin/client-users/{userId} - Update display name / status
/// DELETE /api/admin/client-users/{userId} - Deactivate
/// POST /api/admin/client-users/{userId}/link - Link to a client
/// DELETE /api/admin/client-users/{userId}/link/{clientId} - Unlink from a client
/// </summary>
[ApiController]
[Route("api/admin/client-users")]
public sealed class AdminClientUsersController : AdminControllerBase
{
private const string Proc = "spClientUsers";
public AdminClientUsersController(SqlService sql, ClientContext client, ILogger<AdminClientUsersController> log)
: base(sql, client, log) { }
[HttpPost("list")]
public Task<IActionResult> List([FromBody] JsonElement body, CancellationToken ct)
=> CallProc(Proc, "list", body.ToString(), ct);
[HttpGet("{userId}")]
public Task<IActionResult> Get(string userId, CancellationToken ct)
=> CallProc(Proc, "get", new { userId }, ct);
[HttpPut("{userId}")]
public Task<IActionResult> Update(string userId, [FromBody] JsonElement body, CancellationToken ct)
{
Logger.LogInformation("[ClientUsers] Update {Id} by {User}", userId, Client.Email);
return CallProc(Proc, "update", new
{
userId,
displayName = Str(body, "displayName"),
status = Str(body, "status")
}, ct);
}
[HttpDelete("{userId}")]
public Task<IActionResult> Deactivate(string userId, CancellationToken ct)
{
Logger.LogWarning("[ClientUsers] Deactivate {Id} by {User}", userId, Client.Email);
return CallProc(Proc, "deactivate", new { userId }, ct);
}
[HttpPost("{userId}/link")]
public Task<IActionResult> LinkToClient(string userId, [FromBody] JsonElement body, CancellationToken ct)
{
var clientId = Str(body, "clientId");
if (string.IsNullOrWhiteSpace(clientId))
return Task.FromResult(ValidationError("clientId is required"));
Logger.LogInformation("[ClientUsers] Link user {UserId} → client {ClientId} by {User}",
userId, clientId, Client.Email);
return CallProc(Proc, "linkToClient", new
{
userId,
clientId,
role = Str(body, "role") ?? "User"
}, ct);
}
[HttpDelete("{userId}/link/{clientId}")]
public Task<IActionResult> UnlinkFromClient(string userId, string clientId, CancellationToken ct)
{
Logger.LogInformation("[ClientUsers] Unlink user {UserId} from client {ClientId} by {User}",
userId, clientId, Client.Email);
return CallProc(Proc, "unlinkFromClient", new { userId, clientId }, ct);
}
private static string? Str(JsonElement el, string key) =>
el.TryGetProperty(key, out var p) && p.ValueKind == JsonValueKind.String ? p.GetString() : null;
}