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>
/// <param name="Envelope">Contract envelope metadata.</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="TenantId">Tenant scope identifier.</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(
IdentityContractEnvelope Envelope,
string SubjectId,
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(
request.Envelope,
request.SubjectId,
"tenant-default",
"active");
request.TenantId,
"active",
$"{request.SubjectId}:{request.TenantId}:token",
1800,
true);
return Task.FromResult<IdentityUserRecord?>(record);
}

View File

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