Initial commit
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using RobotNet10.MapEditor.Shared.DTOs.Node;
|
||||
using RobotNet10.MapEditor.Shared.DTOs.Requests;
|
||||
using RobotNet10.MapEditor.Shared.DTOs.Responses;
|
||||
using RobotNet10.MapEditor.Shared.DTOs.Station;
|
||||
using RobotNet10.MapManager.Services;
|
||||
|
||||
namespace RobotNet10.MapManager.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Controller for managing stations
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("api/stations")]
|
||||
[Authorize]
|
||||
public class StationsController(
|
||||
IStationService stationService,
|
||||
ILogger<StationsController> logger) : ControllerBase
|
||||
{
|
||||
private readonly IStationService _stationService = stationService;
|
||||
private readonly ILogger<StationsController> _logger = logger;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new station
|
||||
/// </summary>
|
||||
/// <param name="request">Station creation request</param>
|
||||
/// <returns>Created station</returns>
|
||||
[HttpPost]
|
||||
[ProducesResponseType(typeof(StationDto), 201)]
|
||||
[ProducesResponseType(400)]
|
||||
public async Task<ActionResult<StationDto>> CreateStation([FromBody] CreateStationRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var station = await _stationService.CreateAsync(request);
|
||||
var dto = MapToDto(station);
|
||||
|
||||
return CreatedAtAction(
|
||||
nameof(GetStation),
|
||||
new { stationId = station.Id },
|
||||
dto);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Failed to create station: {StationId}", request.StationId);
|
||||
return BadRequest(CreateErrorResponse(ex.Message, "VALIDATION_ERROR"));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all stations for a layout level
|
||||
/// </summary>
|
||||
/// <param name="layoutLevelId">Layout level ID</param>
|
||||
/// <returns>List of stations with interaction nodes</returns>
|
||||
[HttpGet("level/{layoutLevelId}")]
|
||||
[ProducesResponseType(typeof(List<StationDto>), 200)]
|
||||
public async Task<ActionResult<List<StationDto>>> GetStationsByLevel(Guid layoutLevelId)
|
||||
{
|
||||
var stations = await _stationService.GetStationsByLevelAsync(layoutLevelId, includeInteractionNodes: true);
|
||||
var dtos = stations.Select(MapToDto).ToList();
|
||||
|
||||
return Ok(dtos);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get station by ID
|
||||
/// </summary>
|
||||
/// <param name="stationId">Station database ID</param>
|
||||
/// <returns>Station details with interaction nodes</returns>
|
||||
[HttpGet("{stationId}")]
|
||||
[ProducesResponseType(typeof(StationDto), 200)]
|
||||
[ProducesResponseType(404)]
|
||||
public async Task<ActionResult<StationDto>> GetStation(Guid stationId)
|
||||
{
|
||||
var station = await _stationService.GetByIdAsync(stationId, includeInteractionNodes: true);
|
||||
|
||||
if (station == null)
|
||||
{
|
||||
return NotFound(CreateErrorResponse($"Station with ID '{stationId}' not found", "STATION_NOT_FOUND"));
|
||||
}
|
||||
|
||||
return Ok(MapToDto(station));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update station
|
||||
/// </summary>
|
||||
/// <param name="stationId">Station database ID</param>
|
||||
/// <param name="request">Update request</param>
|
||||
/// <returns>Updated station</returns>
|
||||
[HttpPut("{stationId}")]
|
||||
[ProducesResponseType(typeof(StationDto), 200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
public async Task<ActionResult<StationDto>> UpdateStation(
|
||||
Guid stationId,
|
||||
[FromBody] UpdateStationRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var station = await _stationService.UpdateAsync(stationId, request);
|
||||
|
||||
return Ok(MapToDto(station));
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
if (_logger.IsEnabled(LogLevel.Warning)) _logger.LogWarning(ex, "Failed to update station: {StationId}", stationId);
|
||||
|
||||
if (ex.Message.Contains("not found"))
|
||||
return NotFound(CreateErrorResponse(ex.Message, "STATION_NOT_FOUND"));
|
||||
|
||||
return BadRequest(CreateErrorResponse(ex.Message, "VALIDATION_ERROR"));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delete station
|
||||
/// Deletes station and cascade deletes interaction nodes (but NOT the linked nodes)
|
||||
/// </summary>
|
||||
/// <param name="stationId">Station database ID</param>
|
||||
/// <returns>No content on success</returns>
|
||||
[HttpDelete("{stationId}")]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(404)]
|
||||
public async Task<IActionResult> DeleteStation(Guid stationId)
|
||||
{
|
||||
var deleted = await _stationService.DeleteAsync(stationId);
|
||||
|
||||
if (!deleted)
|
||||
{
|
||||
return NotFound(CreateErrorResponse($"Station with ID '{stationId}' not found", "STATION_NOT_FOUND"));
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
// Helper method to map entity to DTO
|
||||
private static StationDto MapToDto(Data.Station station)
|
||||
{
|
||||
return new StationDto
|
||||
{
|
||||
Id = station.Id,
|
||||
LevelId = station.LevelId,
|
||||
StationId = station.StationId,
|
||||
StationName = station.StationName,
|
||||
StationDescription = station.StationDescription,
|
||||
StationHeight = station.StationHeight,
|
||||
X = station.X,
|
||||
Y = station.Y,
|
||||
Theta = station.Theta,
|
||||
InteractionNodes = station.InteractionNodes?.Select(sin => new StationInteractionNodeDto
|
||||
{
|
||||
Id = sin.Id,
|
||||
StationId = sin.StationId,
|
||||
NodeId = sin.NodeId,
|
||||
Node = sin.Node != null ? new NodeDto
|
||||
{
|
||||
Id = sin.Node.Id,
|
||||
NodeId = sin.Node.NodeId,
|
||||
NodeName = sin.Node.NodeName,
|
||||
X = sin.Node.X,
|
||||
Y = sin.Node.Y,
|
||||
VehicleProperties = sin.Node.VehicleProperties?.Select(vp => new NodeVehiclePropertyDto
|
||||
{
|
||||
Id = vp.Id,
|
||||
VehicleTypeId = vp.VehicleTypeId,
|
||||
Theta = vp.Theta,
|
||||
Actions = vp.Actions
|
||||
}).ToList()
|
||||
} : null
|
||||
}).ToList()
|
||||
};
|
||||
}
|
||||
|
||||
private static ErrorResponseDto CreateErrorResponse(
|
||||
string error,
|
||||
string? errorCode = null,
|
||||
Dictionary<string, object>? details = null)
|
||||
{
|
||||
return new ErrorResponseDto
|
||||
{
|
||||
Error = error,
|
||||
ErrorCode = errorCode,
|
||||
Details = details
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user