refactor(thalos-dal): keep repository technical

This commit is contained in:
José René White Enciso 2026-02-24 05:26:54 -06:00
parent f7f0e787b6
commit 16e5e0a68a
7 changed files with 52 additions and 10 deletions

View File

@ -0,0 +1,13 @@
# Thalos DAL Domain Alignment
## Goal
Align DAL with thalos-domain abstractions while keeping DAL technical.
## DAL Responsibilities
- Identity persistence and retrieval
- Technical data translation
- Provider/repository boundaries
## Prohibited
- Identity policy decision ownership
- Service orchestration concerns

View File

@ -0,0 +1,6 @@
# Thalos DAL Port Alignment Map
## Alignment Areas
- DAL read/write ports map to domain contracts.
- Technical DTO translation remains in DAL adapters.
- Domain policy semantics are not reimplemented in DAL.

View File

@ -0,0 +1,6 @@
# Thalos DAL Technical Mapping Rules
## Rules
- Mapping logic remains technical and deterministic.
- No policy evaluation branching in DAL mapping layer.
- Correlation and metadata pass-through remains unchanged.

View File

@ -5,4 +5,5 @@ namespace Thalos.DAL.Contracts;
/// </summary> /// </summary>
/// <param name="Envelope">Contract envelope metadata.</param> /// <param name="Envelope">Contract envelope metadata.</param>
/// <param name="SubjectId">Identity subject identifier.</param> /// <param name="SubjectId">Identity subject identifier.</param>
public sealed record IdentityUserLookupRequest(IdentityContractEnvelope Envelope, string SubjectId); /// <param name="TenantId">Tenant identifier.</param>
public sealed record IdentityUserLookupRequest(IdentityContractEnvelope Envelope, string SubjectId, string TenantId);

View File

@ -7,8 +7,14 @@ namespace Thalos.DAL.Contracts;
/// <param name="SubjectId">Identity subject identifier.</param> /// <param name="SubjectId">Identity subject identifier.</param>
/// <param name="TenantId">Tenant scope identifier.</param> /// <param name="TenantId">Tenant scope identifier.</param>
/// <param name="Status">Current user status.</param> /// <param name="Status">Current user status.</param>
/// <param name="Token">Persisted token projection for subject/tenant.</param>
/// <param name="ExpiresInSeconds">Persisted token expiration in seconds.</param>
/// <param name="ContextSatisfied">Persisted policy context projection.</param>
public sealed record IdentityUserRecord( public sealed record IdentityUserRecord(
IdentityContractEnvelope Envelope, IdentityContractEnvelope Envelope,
string SubjectId, string SubjectId,
string TenantId, string TenantId,
string Status); string Status,
string Token,
int ExpiresInSeconds,
bool ContextSatisfied);

View File

@ -20,8 +20,11 @@ public sealed class InMemoryUserDataProvider : IUserDataProvider
var record = new IdentityUserRecord( var record = new IdentityUserRecord(
request.Envelope, request.Envelope,
request.SubjectId, request.SubjectId,
"tenant-default", request.TenantId,
"active"); "active",
$"{request.SubjectId}:{request.TenantId}:token",
1800,
true);
return Task.FromResult<IdentityUserRecord?>(record); return Task.FromResult<IdentityUserRecord?>(record);
} }

View File

@ -15,15 +15,19 @@ public sealed class IdentityRepository(
IdentityTokenLookupRequest request, IdentityTokenLookupRequest request,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
var userRequest = new IdentityUserLookupRequest(request.Envelope, request.SubjectId); var userRequest = new IdentityUserLookupRequest(request.Envelope, request.SubjectId, request.TenantId);
var userRecord = await userDataProvider.ReadUserAsync(userRequest, cancellationToken); var userRecord = await userDataProvider.ReadUserAsync(userRequest, cancellationToken);
if (userRecord is null) if (userRecord is null)
{ {
return null; return null;
} }
var token = $"{request.SubjectId}:{request.TenantId}:token"; return new IdentityTokenRecord(
return new IdentityTokenRecord(request.Envelope, request.SubjectId, request.TenantId, token, 1800); request.Envelope,
request.SubjectId,
request.TenantId,
userRecord.Token,
userRecord.ExpiresInSeconds);
} }
/// <inheritdoc /> /// <inheritdoc />
@ -31,15 +35,18 @@ public sealed class IdentityRepository(
IdentityPolicyLookupRequest request, IdentityPolicyLookupRequest request,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
var userRequest = new IdentityUserLookupRequest(request.Envelope, request.SubjectId); var userRequest = new IdentityUserLookupRequest(request.Envelope, request.SubjectId, request.TenantId);
var userRecord = await userDataProvider.ReadUserAsync(userRequest, cancellationToken); var userRecord = await userDataProvider.ReadUserAsync(userRequest, cancellationToken);
if (userRecord is null) if (userRecord is null)
{ {
return null; return null;
} }
var contextSatisfied = string.Equals(userRecord.Status, "active", StringComparison.OrdinalIgnoreCase); return new IdentityPolicyRecord(
return new IdentityPolicyRecord(request.Envelope, request.SubjectId, request.PermissionCode, contextSatisfied); request.Envelope,
request.SubjectId,
request.PermissionCode,
userRecord.ContextSatisfied);
} }
/// <inheritdoc /> /// <inheritdoc />