using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Options; using System.Text.Json; using EnvelopeGenerator.API.Options; using EnvelopeGenerator.Domain.Constants; namespace EnvelopeGenerator.API.Controllers; /// /// Manages cached data for receivers using distributed cache. /// [ApiController] [Route("api/[controller]")] [Authorize(Policy = AuthPolicy.Receiver)] public class CacheController( IDistributedCache cache, IOptions cacheOptions) : ControllerBase { private const string SignatureCacheKeyPrefix = "signature:91751687-8ae6-4777-bf5f-b8846085e62e:"; /// /// Stores a receiver's signature in cache for the specified envelope. /// [HttpPost("SignatureCapture/{envelopeKey}")] public async Task SaveSignature( string envelopeKey, [FromBody] SignatureCacheRequest request, CancellationToken cancel) { var cacheKey = $"{SignatureCacheKeyPrefix}{envelopeKey}"; var json = JsonSerializer.Serialize(request); var options = cacheOptions.Value.SignatureCacheExpiration.HasValue ? new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = cacheOptions.Value.SignatureCacheExpiration.Value } : null; await cache.SetStringAsync(cacheKey, json, options ?? new DistributedCacheEntryOptions(), cancel); return Ok(); } /// /// Retrieves a cached signature for the specified envelope. /// [HttpGet("SignatureCapture/{envelopeKey}")] public async Task GetSignature(string envelopeKey, CancellationToken cancel) { var cacheKey = $"{SignatureCacheKeyPrefix}{envelopeKey}"; var json = await cache.GetStringAsync(cacheKey, cancel); if (json is null) return NotFound(); var signature = JsonSerializer.Deserialize(json); return Ok(signature); } /// /// Deletes a cached signature for the specified envelope. /// [HttpDelete("SignatureCapture/{envelopeKey}")] public async Task DeleteSignature(string envelopeKey, CancellationToken cancel) { var cacheKey = $"{SignatureCacheKeyPrefix}{envelopeKey}"; await cache.RemoveAsync(cacheKey, cancel); return Ok(); } } /// /// Request model for caching signature data. /// public sealed record SignatureCacheRequest( string? DataUrl, string? FullName, string? Position, string? Place);