2026-01-28 11:55:25 -06:00

108 lines
3.4 KiB
C#

using CharacterApi.Models;
using CharacterApi.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
namespace CharacterApi.Controllers;
[ApiController]
[Route("api/[controller]")]
public class CharactersController : ControllerBase
{
private readonly CharacterStore _characters;
private readonly LocationsClient _locations;
public CharactersController(CharacterStore characters, LocationsClient locations)
{
_characters = characters;
_locations = locations;
}
[HttpPost]
[Authorize(Roles = "USER,SUPER")]
public async Task<IActionResult> Create([FromBody] CreateCharacterRequest req)
{
if (string.IsNullOrWhiteSpace(req.Name))
return BadRequest("Name required");
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
if (string.IsNullOrWhiteSpace(userId))
return Unauthorized();
var character = new Character
{
OwnerUserId = userId,
Name = req.Name.Trim(),
Coord = new Coord { X = 0, Y = 0 },
CreatedUtc = DateTime.UtcNow
};
await _characters.CreateAsync(character);
return Ok(character);
}
[HttpGet]
[Authorize(Roles = "USER,SUPER")]
public async Task<IActionResult> ListMine()
{
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
if (string.IsNullOrWhiteSpace(userId))
return Unauthorized();
var characters = await _characters.GetForOwnerAsync(userId);
return Ok(characters);
}
[HttpDelete("{id}")]
[Authorize(Roles = "USER,SUPER")]
public async Task<IActionResult> Delete(string id)
{
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
if (string.IsNullOrWhiteSpace(userId))
return Unauthorized();
var allowAnyOwner = User.IsInRole("SUPER");
var deleted = await _characters.DeleteForOwnerAsync(id, userId, allowAnyOwner);
if (!deleted)
return NotFound();
return Ok("Deleted");
}
[HttpPut("{id}/move")]
[Authorize(Roles = "USER,SUPER")]
public async Task<IActionResult> Move(string id, [FromBody] MoveCharacterRequest req, CancellationToken ct)
{
if (req?.Coord is null)
return BadRequest("Coord required");
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
if (string.IsNullOrWhiteSpace(userId))
return Unauthorized();
var allowAnyOwner = User.IsInRole("SUPER");
var existing = await _characters.GetForOwnerByIdAsync(id, userId, allowAnyOwner);
if (existing is null)
return NotFound();
var presence = await _locations.UpdatePresenceAsync(id, req.Coord, ct);
if (!presence.Ok)
{
var message = string.IsNullOrWhiteSpace(presence.Body)
? "Location presence update failed"
: presence.Body;
return StatusCode((int)presence.Status, message);
}
var updated = await _characters.UpdateCoordAsync(id, userId, allowAnyOwner, req.Coord);
if (!updated)
{
await _locations.UpdatePresenceAsync(id, existing.Coord, ct);
return StatusCode(500, "Failed to update character coord");
}
return Ok("Moved");
}
}