85 lines
3.3 KiB
C#
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;
|
|
}
|