SF-74: Domain/Application — UserPreferences DTO, interface, Sender role constant

This commit is contained in:
2026-09-03 14:57:21 +02:00
parent 7fc2c14f9c
commit 0fdfe991ea
3 changed files with 23 additions and 5 deletions

View File

@@ -3,7 +3,7 @@ namespace EnvelopeGenerator.Application.Common.Dto;
/// <summary> /// <summary>
/// Represents a user's UI preferences stored in the distributed cache (dbo.TBDD_CACHE). /// Represents a user's UI preferences stored in the distributed cache (dbo.TBDD_CACHE).
/// </summary> /// </summary>
public sealed class UserPreferencesDto public sealed record UserPreferencesDto
{ {
/// <summary> /// <summary>
/// The active DevExpress theme name. /// The active DevExpress theme name.
@@ -23,4 +23,17 @@ public sealed class UserPreferencesDto
/// Values are opaque JSON strings produced by DxGrid.SaveLayoutAsync(). /// Values are opaque JSON strings produced by DxGrid.SaveLayoutAsync().
/// </summary> /// </summary>
public Dictionary<string, string> GridLayouts { get; set; } = new(); public Dictionary<string, string> GridLayouts { get; set; } = new();
/// <summary>
/// The authenticated user's display name ("{GivenName} {Surname}").
/// Populated by the server on GET responses from JWT claims.
/// NOT persisted in cache — injected at read time by UserPreferencesController.
/// Ignored on PUT requests.
/// </summary>
public string? DisplayName { get; set; }
/// <summary>
///
/// </summary>
public static UserPreferencesDto Default { get; } = new UserPreferencesDto();
} }

View File

@@ -14,16 +14,16 @@ public interface IUserPreferencesService
/// Always returns a valid object — never throws, never returns null. /// Always returns a valid object — never throws, never returns null.
/// Returns defaults if no entry exists in cache. /// Returns defaults if no entry exists in cache.
/// </summary> /// </summary>
/// <param name="username">The sender's username (ClaimTypes.Name from JWT).</param> /// <param name="id"></param>
/// <param name="ct">Cancellation token.</param> /// <param name="ct">Cancellation token.</param>
Task<UserPreferencesDto> GetAsync(string username, CancellationToken ct = default); Task<UserPreferencesDto> GetOrCreateAsync(string id, CancellationToken ct = default);
/// <summary> /// <summary>
/// Persists the given preferences for the user in the distributed cache. /// Persists the given preferences for the user in the distributed cache.
/// Failures are non-fatal and silently ignored. /// Failures are non-fatal and silently ignored.
/// </summary> /// </summary>
/// <param name="username">The sender's username (ClaimTypes.Name from JWT).</param> /// <param name="id"></param>
/// <param name="preferences">The preferences to persist.</param> /// <param name="preferences">The preferences to persist.</param>
/// <param name="ct">Cancellation token.</param> /// <param name="ct">Cancellation token.</param>
Task SaveAsync(string username, UserPreferencesDto preferences, CancellationToken ct = default); Task SaveAsync(string id, UserPreferencesDto preferences, CancellationToken ct = default);
} }

View File

@@ -1,5 +1,6 @@
#if NETFRAMEWORK #if NETFRAMEWORK
using System; using System;
using System.Collections.Generic;
#endif #endif
namespace EnvelopeGenerator.Domain.Constants namespace EnvelopeGenerator.Domain.Constants
@@ -15,7 +16,11 @@ namespace EnvelopeGenerator.Domain.Constants
public static class Receiver public static class Receiver
{ {
public const string TFA = "EGReceiverTFA"; public const string TFA = "EGReceiverTFA";
[Obsolete("Use Receiver.Authorized")]
public const string Full = "EGReceiver"; public const string Full = "EGReceiver";
public static readonly IReadOnlyList<string> Authorized = new[] { "receiver", "EGReceiver" };
} }
public const string Sender = "EGSender"; public const string Sender = "EGSender";