using Backend.Interface; using Microsoft.AspNetCore.Mvc; namespace Backend.Controllers { [ApiController] [Route("api/annotations")] public sealed class AnnotationController : ControllerBase { private readonly IAnnotationStore _store; public AnnotationController(IAnnotationStore store) { _store = store; } [HttpGet("fetch")] public async Task Fetch( [FromQuery] string user, [FromQuery] string symbol, CancellationToken cancellationToken = default) { if (string.IsNullOrWhiteSpace(user)) return BadRequest("User cannot be empty."); if (string.IsNullOrWhiteSpace(symbol)) return BadRequest("Symbol cannot be empty."); var json = await _store.GetAsync( user.Trim(), symbol.Trim().ToUpperInvariant(), cancellationToken); if (json is null) return Ok("[]"); return Content(json, "application/json"); } [HttpPost("save")] public async Task Save( [FromQuery] string user, [FromQuery] string symbol, CancellationToken cancellationToken = default) { if (string.IsNullOrWhiteSpace(user)) return BadRequest("User cannot be empty."); if (string.IsNullOrWhiteSpace(symbol)) return BadRequest("Symbol cannot be empty."); using var reader = new StreamReader(Request.Body); string body = await reader.ReadToEndAsync(cancellationToken); if (string.IsNullOrWhiteSpace(body)) return BadRequest("Request body cannot be empty."); await _store.UpsertAsync( user.Trim(), symbol.Trim().ToUpperInvariant(), body, cancellationToken); return Ok(new { success = true }); } [HttpDelete("delete")] public async Task Delete( [FromQuery] string user, [FromQuery] string symbol, CancellationToken cancellationToken = default) { if (string.IsNullOrWhiteSpace(user)) return BadRequest("User cannot be empty."); if (string.IsNullOrWhiteSpace(symbol)) return BadRequest("Symbol cannot be empty."); await _store.DeleteAsync( user.Trim(), symbol.Trim().ToUpperInvariant(), cancellationToken); return Ok(new { success = true }); } } }