Files
EnvelopeGenerator/EnvelopeGenerator.Infrastructure/UserPreferencesService.cs
TekH 2e634361c5 Add user preferences management via distributed cache
Introduced `UserPreferencesDto` to represent UI preferences,
including theme, dark mode, and grid layouts. Added the
`IUserPreferencesService` interface and implemented it in
`UserPreferencesService` to manage preferences stored in
the distributed cache (`dbo.TBDD_CACHE`).

Registered `UserPreferencesService` in dependency injection
and added a NuGet reference for `Microsoft.Extensions.Caching.Abstractions`.

Created `UserPreferencesController` with `GET` and `PUT`
endpoints to retrieve and save user preferences. Validated
theme names in the `PUT` endpoint.

Updated `Program.cs` to ensure proper service registration.
2026-09-02 12:35:19 +02:00

42 lines
1.6 KiB
C#

#if NET
using System.Text.Json;
using Microsoft.Extensions.Caching.Distributed;
using EnvelopeGenerator.Application.Common.Dto;
using EnvelopeGenerator.Application.Common.Interfaces.Services;
namespace EnvelopeGenerator.Infrastructure;
/// <summary>
/// Implements user preferences storage using the distributed cache (dbo.TBDD_CACHE).
/// No DB schema changes required — uses the existing SQL Server distributed cache table.
/// Cache key schema: "signflow.user-preferences:{username}"
/// Expiration: indefinite (no TTL) — preferences persist until explicitly overwritten.
/// </summary>
public sealed class UserPreferencesService(IDistributedCache cache) : IUserPreferencesService
{
private const string KeyPrefix = "signflow.user-preferences:";
private static string BuildKey(string username) => $"{KeyPrefix}{username}";
/// <inheritdoc />
public async Task<UserPreferencesDto> GetAsync(string username, CancellationToken ct = default)
{
var json = await cache.GetStringAsync(BuildKey(username), ct);
if (json is null)
return new UserPreferencesDto();
return JsonSerializer.Deserialize<UserPreferencesDto>(json) ?? new UserPreferencesDto();
}
/// <inheritdoc />
public async Task SaveAsync(string username, UserPreferencesDto preferences, CancellationToken ct = default)
{
var json = JsonSerializer.Serialize(preferences);
// No expiration — preferences are stored indefinitely.
await cache.SetStringAsync(BuildKey(username), json, new DistributedCacheEntryOptions(), ct);
}
}
#endif