using GermanApp.Domain.Interfaces; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace GermanApp.Presentation.Controllers; /// /// API controller for speech recognition using Vosk. /// This is part of the Presentation layer. /// [ApiController] [Route("api/[controller]")] [Authorize] public class SpeechController : ControllerBase { private readonly IVoskService _voskService; public SpeechController(IVoskService voskService) { _voskService = voskService; } /// /// Recognizes speech from audio bytes. /// /// Audio recognition request /// Cancellation token /// Recognized text [HttpPost("recognize")] [RequestSizeLimit(10_000_000)] // 10MB limit [RequestFormLimits(MultipartBodyLengthLimit = 10_000_000)] public async Task RecognizeSpeech( [FromForm] SpeechRecognitionRequest request, CancellationToken cancellationToken = default) { if (request?.Audio == null || request.Audio.Length == 0) return BadRequest("Audio data is required"); try { var result = await _voskService.RecognizeSpeechAsync( request.Audio, request.SampleRate, request.Hint, cancellationToken); return Ok(new SpeechRecognitionResponse(result)); } catch (TimeoutException ex) { return StatusCode(504, new { Error = ex.Message }); } catch (Exception ex) { return StatusCode(500, new { Error = ex.Message }); } } /// /// Tests the speech recognition service. /// /// Health check result [HttpGet("health")] [AllowAnonymous] public async Task HealthCheck(CancellationToken cancellationToken = default) { try { var isHealthy = await _voskService.TestModelAsync(cancellationToken); return Ok(new { Healthy = isHealthy }); } catch (Exception ex) { return StatusCode(500, new { Error = ex.Message }); } } /// /// Gets information about the current Vosk model. /// /// Model information [HttpGet("model-info")] [AllowAnonymous] public async Task GetModelInfo(CancellationToken cancellationToken = default) { try { var (modelName, modelPath) = await _voskService.GetModelInfoAsync(); return Ok(new { ModelName = modelName, ModelPath = modelPath }); } catch (Exception ex) { return StatusCode(500, new { Error = ex.Message }); } } } /// /// Request DTO for speech recognition. /// public record SpeechRecognitionRequest( byte[] Audio, int SampleRate = 16000, string? Hint = null); /// /// Response DTO for speech recognition. /// public record SpeechRecognitionResponse(string Text);