diff --git a/docs/architecture/thalos-dal-map.puml b/docs/architecture/thalos-dal-map.puml
index e7060de..89bb78d 100644
--- a/docs/architecture/thalos-dal-map.puml
+++ b/docs/architecture/thalos-dal-map.puml
@@ -2,6 +2,13 @@
skinparam packageStyle rectangle
package "thalos-dal" {
+ class IdentityPolicyLookupRequest
+ class IdentityPolicyRecord
+ class IdentityTokenLookupRequest
+ class IdentityTokenRecord
+ class IdentityPermissionSetLookupRequest
+ class IdentityPermissionRecord
+ interface IIdentityDalGrpcContractAdapter
interface IUserDataProvider
interface IRoleDataProvider
interface IPermissionDataProvider
@@ -10,12 +17,20 @@ package "thalos-dal" {
interface IIdentityRepository
interface IDalDependencyHealthCheck
+ IIdentityDalGrpcContractAdapter --> IdentityPolicyLookupRequest
+ IIdentityDalGrpcContractAdapter --> IdentityTokenLookupRequest
IIdentityRepository --> IUserDataProvider
IIdentityRepository --> IRoleDataProvider
IIdentityRepository --> IPermissionDataProvider
IIdentityRepository --> IModuleDataProvider
IIdentityRepository --> ITenantDataProvider
IIdentityRepository --> IDalDependencyHealthCheck
+ IIdentityRepository --> IdentityPolicyLookupRequest
+ IIdentityRepository --> IdentityPolicyRecord
+ IIdentityRepository --> IdentityTokenLookupRequest
+ IIdentityRepository --> IdentityTokenRecord
+ IIdentityRepository --> IdentityPermissionSetLookupRequest
+ IIdentityRepository --> IdentityPermissionRecord
}
package "thalos-service" as ThalosService
diff --git a/docs/dal/identity-persistence-strategy.md b/docs/dal/identity-persistence-strategy.md
index 38f96d5..5186cdb 100644
--- a/docs/dal/identity-persistence-strategy.md
+++ b/docs/dal/identity-persistence-strategy.md
@@ -5,8 +5,10 @@
- DAL repository boundaries coordinate identity aggregate persistence operations.
- Dependency health checks are defined inside DAL boundaries.
- Storage and cache dependencies are modeled in DAL-owned contracts.
+- gRPC translation stays at adapter interfaces and does not include persistence implementation.
## Constraints
- Identity persistence concerns do not leak to non-Thalos repositories.
- Service layer consumes DAL boundaries without owning persistence details.
+- This stage defines contracts and ports only; no datastore implementation is introduced.
diff --git a/docs/dal/identity-provider-boundaries.md b/docs/dal/identity-provider-boundaries.md
index 717246f..f57bc23 100644
--- a/docs/dal/identity-provider-boundaries.md
+++ b/docs/dal/identity-provider-boundaries.md
@@ -7,9 +7,12 @@
- `IPermissionDataProvider`: permission aggregate provider boundary.
- `IModuleDataProvider`: module aggregate provider boundary.
- `ITenantDataProvider`: tenant aggregate provider boundary.
+- `IIdentityRepository`: DAL composition boundary for policy, token, and permission-set reads.
+- `IIdentityDalGrpcContractAdapter`: gRPC translation boundary for DAL contracts.
## Rules
- Providers isolate datastore-specific behavior.
- Provider boundaries remain internal to Thalos DAL.
+- DAL interfaces expose only transport-neutral contracts and read ports.
- Identity abstractions remain Thalos-owned.
diff --git a/src/Thalos.DAL/Adapters/IIdentityDalGrpcContractAdapter.cs b/src/Thalos.DAL/Adapters/IIdentityDalGrpcContractAdapter.cs
new file mode 100644
index 0000000..e2609cf
--- /dev/null
+++ b/src/Thalos.DAL/Adapters/IIdentityDalGrpcContractAdapter.cs
@@ -0,0 +1,38 @@
+using Thalos.DAL.Contracts;
+using Thalos.DAL.Grpc;
+
+namespace Thalos.DAL.Adapters;
+
+///
+/// Defines adapter boundary for dal gRPC contract translation.
+///
+public interface IIdentityDalGrpcContractAdapter
+{
+ ///
+ /// Maps transport-neutral policy lookup request into gRPC contract shape.
+ ///
+ /// Policy lookup request contract.
+ /// gRPC policy contract shape.
+ IdentityPolicyDalGrpcContract ToGrpcPolicyRequest(IdentityPolicyLookupRequest request);
+
+ ///
+ /// Maps gRPC policy contract into transport-neutral policy lookup request.
+ ///
+ /// gRPC policy contract shape.
+ /// Policy lookup request contract.
+ IdentityPolicyLookupRequest FromGrpcPolicyRequest(IdentityPolicyDalGrpcContract contract);
+
+ ///
+ /// Maps transport-neutral token lookup request into gRPC contract shape.
+ ///
+ /// Token lookup request contract.
+ /// gRPC token contract shape.
+ IdentityTokenDalGrpcContract ToGrpcTokenRequest(IdentityTokenLookupRequest request);
+
+ ///
+ /// Maps gRPC token contract into transport-neutral token lookup request.
+ ///
+ /// gRPC token contract shape.
+ /// Token lookup request contract.
+ IdentityTokenLookupRequest FromGrpcTokenRequest(IdentityTokenDalGrpcContract contract);
+}
diff --git a/src/Thalos.DAL/Contracts/DalDependencyHealthStatus.cs b/src/Thalos.DAL/Contracts/DalDependencyHealthStatus.cs
new file mode 100644
index 0000000..fc098a0
--- /dev/null
+++ b/src/Thalos.DAL/Contracts/DalDependencyHealthStatus.cs
@@ -0,0 +1,12 @@
+namespace Thalos.DAL.Contracts;
+
+///
+/// Contract representing dal dependency health status.
+///
+/// Contract envelope metadata.
+/// Indicates whether dependencies are healthy.
+/// Dependency boundaries included in health probe.
+public sealed record DalDependencyHealthStatus(
+ IdentityContractEnvelope Envelope,
+ bool IsHealthy,
+ IReadOnlyList DependencyNames);
diff --git a/src/Thalos.DAL/Contracts/IdentityContractEnvelope.cs b/src/Thalos.DAL/Contracts/IdentityContractEnvelope.cs
new file mode 100644
index 0000000..7a03817
--- /dev/null
+++ b/src/Thalos.DAL/Contracts/IdentityContractEnvelope.cs
@@ -0,0 +1,8 @@
+namespace Thalos.DAL.Contracts;
+
+///
+/// Defines transport-neutral envelope metadata for thalos dal contract messages.
+///
+/// Contract schema version.
+/// Correlation identifier for cross-layer tracing.
+public sealed record IdentityContractEnvelope(string ContractVersion, string CorrelationId);
diff --git a/src/Thalos.DAL/Contracts/IdentityModuleLookupRequest.cs b/src/Thalos.DAL/Contracts/IdentityModuleLookupRequest.cs
new file mode 100644
index 0000000..b9808af
--- /dev/null
+++ b/src/Thalos.DAL/Contracts/IdentityModuleLookupRequest.cs
@@ -0,0 +1,8 @@
+namespace Thalos.DAL.Contracts;
+
+///
+/// Request contract for module aggregate lookup.
+///
+/// Contract envelope metadata.
+/// Tenant scope identifier.
+public sealed record IdentityModuleLookupRequest(IdentityContractEnvelope Envelope, string TenantId);
diff --git a/src/Thalos.DAL/Contracts/IdentityModuleRecord.cs b/src/Thalos.DAL/Contracts/IdentityModuleRecord.cs
new file mode 100644
index 0000000..5938def
--- /dev/null
+++ b/src/Thalos.DAL/Contracts/IdentityModuleRecord.cs
@@ -0,0 +1,9 @@
+namespace Thalos.DAL.Contracts;
+
+///
+/// Contract representing persisted module metadata for tenant scope.
+///
+/// Contract envelope metadata.
+/// Module code identifier.
+/// Indicates whether module is enabled.
+public sealed record IdentityModuleRecord(IdentityContractEnvelope Envelope, string ModuleCode, bool IsEnabled);
diff --git a/src/Thalos.DAL/Contracts/IdentityPermissionRecord.cs b/src/Thalos.DAL/Contracts/IdentityPermissionRecord.cs
new file mode 100644
index 0000000..8ee10f2
--- /dev/null
+++ b/src/Thalos.DAL/Contracts/IdentityPermissionRecord.cs
@@ -0,0 +1,12 @@
+namespace Thalos.DAL.Contracts;
+
+///
+/// Contract representing a persisted permission grant for identity scope.
+///
+/// Contract envelope metadata.
+/// Permission code identifier.
+/// Role code that grants the permission.
+public sealed record IdentityPermissionRecord(
+ IdentityContractEnvelope Envelope,
+ string PermissionCode,
+ string SourceRoleCode);
diff --git a/src/Thalos.DAL/Contracts/IdentityPermissionSetLookupRequest.cs b/src/Thalos.DAL/Contracts/IdentityPermissionSetLookupRequest.cs
new file mode 100644
index 0000000..d41d316
--- /dev/null
+++ b/src/Thalos.DAL/Contracts/IdentityPermissionSetLookupRequest.cs
@@ -0,0 +1,12 @@
+namespace Thalos.DAL.Contracts;
+
+///
+/// Request contract for identity permission set lookup.
+///
+/// Contract envelope metadata.
+/// Identity subject identifier.
+/// Tenant scope identifier.
+public sealed record IdentityPermissionSetLookupRequest(
+ IdentityContractEnvelope Envelope,
+ string SubjectId,
+ string TenantId);
diff --git a/src/Thalos.DAL/Contracts/IdentityPolicyLookupRequest.cs b/src/Thalos.DAL/Contracts/IdentityPolicyLookupRequest.cs
new file mode 100644
index 0000000..c6a338c
--- /dev/null
+++ b/src/Thalos.DAL/Contracts/IdentityPolicyLookupRequest.cs
@@ -0,0 +1,14 @@
+namespace Thalos.DAL.Contracts;
+
+///
+/// Request contract for identity policy context lookup.
+///
+/// Contract envelope metadata.
+/// Identity subject identifier.
+/// Tenant scope identifier.
+/// Permission code to evaluate.
+public sealed record IdentityPolicyLookupRequest(
+ IdentityContractEnvelope Envelope,
+ string SubjectId,
+ string TenantId,
+ string PermissionCode);
diff --git a/src/Thalos.DAL/Contracts/IdentityPolicyRecord.cs b/src/Thalos.DAL/Contracts/IdentityPolicyRecord.cs
new file mode 100644
index 0000000..4a47f3e
--- /dev/null
+++ b/src/Thalos.DAL/Contracts/IdentityPolicyRecord.cs
@@ -0,0 +1,14 @@
+namespace Thalos.DAL.Contracts;
+
+///
+/// Response contract representing persisted identity policy context.
+///
+/// Contract envelope metadata.
+/// Identity subject identifier.
+/// Permission code evaluated.
+/// Indicates whether policy context is satisfied.
+public sealed record IdentityPolicyRecord(
+ IdentityContractEnvelope Envelope,
+ string SubjectId,
+ string PermissionCode,
+ bool ContextSatisfied);
diff --git a/src/Thalos.DAL/Contracts/IdentityRoleLookupRequest.cs b/src/Thalos.DAL/Contracts/IdentityRoleLookupRequest.cs
new file mode 100644
index 0000000..277c4de
--- /dev/null
+++ b/src/Thalos.DAL/Contracts/IdentityRoleLookupRequest.cs
@@ -0,0 +1,9 @@
+namespace Thalos.DAL.Contracts;
+
+///
+/// Request contract for role aggregate lookup.
+///
+/// Contract envelope metadata.
+/// Identity subject identifier.
+/// Tenant scope identifier.
+public sealed record IdentityRoleLookupRequest(IdentityContractEnvelope Envelope, string SubjectId, string TenantId);
diff --git a/src/Thalos.DAL/Contracts/IdentityRoleRecord.cs b/src/Thalos.DAL/Contracts/IdentityRoleRecord.cs
new file mode 100644
index 0000000..023ab8c
--- /dev/null
+++ b/src/Thalos.DAL/Contracts/IdentityRoleRecord.cs
@@ -0,0 +1,9 @@
+namespace Thalos.DAL.Contracts;
+
+///
+/// Contract representing a persisted identity role assignment.
+///
+/// Contract envelope metadata.
+/// Role code identifier.
+/// Tenant scope identifier.
+public sealed record IdentityRoleRecord(IdentityContractEnvelope Envelope, string RoleCode, string TenantId);
diff --git a/src/Thalos.DAL/Contracts/IdentityTenantLookupRequest.cs b/src/Thalos.DAL/Contracts/IdentityTenantLookupRequest.cs
new file mode 100644
index 0000000..531e2b4
--- /dev/null
+++ b/src/Thalos.DAL/Contracts/IdentityTenantLookupRequest.cs
@@ -0,0 +1,8 @@
+namespace Thalos.DAL.Contracts;
+
+///
+/// Request contract for tenant aggregate lookup.
+///
+/// Contract envelope metadata.
+/// Tenant scope identifier.
+public sealed record IdentityTenantLookupRequest(IdentityContractEnvelope Envelope, string TenantId);
diff --git a/src/Thalos.DAL/Contracts/IdentityTenantRecord.cs b/src/Thalos.DAL/Contracts/IdentityTenantRecord.cs
new file mode 100644
index 0000000..2009b25
--- /dev/null
+++ b/src/Thalos.DAL/Contracts/IdentityTenantRecord.cs
@@ -0,0 +1,14 @@
+namespace Thalos.DAL.Contracts;
+
+///
+/// Contract representing persisted tenant metadata.
+///
+/// Contract envelope metadata.
+/// Tenant scope identifier.
+/// Tenant code identifier.
+/// Indicates whether tenant is active.
+public sealed record IdentityTenantRecord(
+ IdentityContractEnvelope Envelope,
+ string TenantId,
+ string TenantCode,
+ bool IsActive);
diff --git a/src/Thalos.DAL/Contracts/IdentityTokenLookupRequest.cs b/src/Thalos.DAL/Contracts/IdentityTokenLookupRequest.cs
new file mode 100644
index 0000000..034118d
--- /dev/null
+++ b/src/Thalos.DAL/Contracts/IdentityTokenLookupRequest.cs
@@ -0,0 +1,9 @@
+namespace Thalos.DAL.Contracts;
+
+///
+/// Request contract for identity token record lookup.
+///
+/// Contract envelope metadata.
+/// Identity subject identifier.
+/// Tenant scope identifier.
+public sealed record IdentityTokenLookupRequest(IdentityContractEnvelope Envelope, string SubjectId, string TenantId);
diff --git a/src/Thalos.DAL/Contracts/IdentityTokenRecord.cs b/src/Thalos.DAL/Contracts/IdentityTokenRecord.cs
new file mode 100644
index 0000000..e932ff4
--- /dev/null
+++ b/src/Thalos.DAL/Contracts/IdentityTokenRecord.cs
@@ -0,0 +1,16 @@
+namespace Thalos.DAL.Contracts;
+
+///
+/// Response contract representing token issuance persistence data.
+///
+/// Contract envelope metadata.
+/// Identity subject identifier.
+/// Tenant scope identifier.
+/// Issued access token value.
+/// Token expiration in seconds.
+public sealed record IdentityTokenRecord(
+ IdentityContractEnvelope Envelope,
+ string SubjectId,
+ string TenantId,
+ string Token,
+ int ExpiresInSeconds);
diff --git a/src/Thalos.DAL/Contracts/IdentityUserLookupRequest.cs b/src/Thalos.DAL/Contracts/IdentityUserLookupRequest.cs
new file mode 100644
index 0000000..8e6d4e4
--- /dev/null
+++ b/src/Thalos.DAL/Contracts/IdentityUserLookupRequest.cs
@@ -0,0 +1,8 @@
+namespace Thalos.DAL.Contracts;
+
+///
+/// Request contract for user aggregate lookup.
+///
+/// Contract envelope metadata.
+/// Identity subject identifier.
+public sealed record IdentityUserLookupRequest(IdentityContractEnvelope Envelope, string SubjectId);
diff --git a/src/Thalos.DAL/Contracts/IdentityUserRecord.cs b/src/Thalos.DAL/Contracts/IdentityUserRecord.cs
new file mode 100644
index 0000000..aa364ac
--- /dev/null
+++ b/src/Thalos.DAL/Contracts/IdentityUserRecord.cs
@@ -0,0 +1,14 @@
+namespace Thalos.DAL.Contracts;
+
+///
+/// Contract representing a persisted identity user aggregate.
+///
+/// Contract envelope metadata.
+/// Identity subject identifier.
+/// Tenant scope identifier.
+/// Current user status.
+public sealed record IdentityUserRecord(
+ IdentityContractEnvelope Envelope,
+ string SubjectId,
+ string TenantId,
+ string Status);
diff --git a/src/Thalos.DAL/Contracts/ThalosDalPackageContract.cs b/src/Thalos.DAL/Contracts/ThalosDalPackageContract.cs
new file mode 100644
index 0000000..6857a0b
--- /dev/null
+++ b/src/Thalos.DAL/Contracts/ThalosDalPackageContract.cs
@@ -0,0 +1,15 @@
+using Core.Blueprint.Common.Contracts;
+
+namespace Thalos.DAL.Contracts;
+
+///
+/// Defines package descriptor metadata for thalos dal contracts.
+///
+public sealed class ThalosDalPackageContract : IBlueprintPackageContract
+{
+ ///
+ public BlueprintPackageDescriptor Descriptor { get; } = new(
+ "Thalos.DAL.Contracts",
+ PackageVersionPolicy.Minor,
+ ["Core.Blueprint.Common"]);
+}
diff --git a/src/Thalos.DAL/Grpc/IdentityPolicyDalGrpcContract.cs b/src/Thalos.DAL/Grpc/IdentityPolicyDalGrpcContract.cs
new file mode 100644
index 0000000..2a705e7
--- /dev/null
+++ b/src/Thalos.DAL/Grpc/IdentityPolicyDalGrpcContract.cs
@@ -0,0 +1,9 @@
+namespace Thalos.DAL.Grpc;
+
+///
+/// Defines minimal gRPC contract shape for identity policy dal adapter translation.
+///
+/// Identity subject identifier.
+/// Tenant scope identifier.
+/// Permission code to evaluate.
+public sealed record IdentityPolicyDalGrpcContract(string SubjectId, string TenantId, string PermissionCode);
diff --git a/src/Thalos.DAL/Grpc/IdentityTokenDalGrpcContract.cs b/src/Thalos.DAL/Grpc/IdentityTokenDalGrpcContract.cs
new file mode 100644
index 0000000..40e8c6f
--- /dev/null
+++ b/src/Thalos.DAL/Grpc/IdentityTokenDalGrpcContract.cs
@@ -0,0 +1,8 @@
+namespace Thalos.DAL.Grpc;
+
+///
+/// Defines minimal gRPC contract shape for identity token dal adapter translation.
+///
+/// Identity subject identifier.
+/// Tenant scope identifier.
+public sealed record IdentityTokenDalGrpcContract(string SubjectId, string TenantId);
diff --git a/src/Thalos.DAL/Health/IDalDependencyHealthCheck.cs b/src/Thalos.DAL/Health/IDalDependencyHealthCheck.cs
index f2f3606..387d57e 100644
--- a/src/Thalos.DAL/Health/IDalDependencyHealthCheck.cs
+++ b/src/Thalos.DAL/Health/IDalDependencyHealthCheck.cs
@@ -1,3 +1,5 @@
+using Thalos.DAL.Contracts;
+
namespace Thalos.DAL.Health;
///
@@ -5,4 +7,10 @@ namespace Thalos.DAL.Health;
///
public interface IDalDependencyHealthCheck
{
+ ///
+ /// Probes dependency health for DAL-owned providers.
+ ///
+ /// Cancellation token.
+ /// Health status contract for DAL dependency boundaries.
+ Task CheckAsync(CancellationToken cancellationToken = default);
}
diff --git a/src/Thalos.DAL/Providers/IModuleDataProvider.cs b/src/Thalos.DAL/Providers/IModuleDataProvider.cs
index 60014eb..74c8a1e 100644
--- a/src/Thalos.DAL/Providers/IModuleDataProvider.cs
+++ b/src/Thalos.DAL/Providers/IModuleDataProvider.cs
@@ -1,3 +1,5 @@
+using Thalos.DAL.Contracts;
+
namespace Thalos.DAL.Providers;
///
@@ -5,4 +7,13 @@ namespace Thalos.DAL.Providers;
///
public interface IModuleDataProvider
{
+ ///
+ /// Reads module capability metadata for tenant scope.
+ ///
+ /// Module lookup request contract.
+ /// Cancellation token.
+ /// Module records matching lookup scope.
+ Task> ReadModulesAsync(
+ IdentityModuleLookupRequest request,
+ CancellationToken cancellationToken = default);
}
diff --git a/src/Thalos.DAL/Providers/IPermissionDataProvider.cs b/src/Thalos.DAL/Providers/IPermissionDataProvider.cs
index 61c9c0b..ac95fe6 100644
--- a/src/Thalos.DAL/Providers/IPermissionDataProvider.cs
+++ b/src/Thalos.DAL/Providers/IPermissionDataProvider.cs
@@ -1,3 +1,5 @@
+using Thalos.DAL.Contracts;
+
namespace Thalos.DAL.Providers;
///
@@ -5,4 +7,13 @@ namespace Thalos.DAL.Providers;
///
public interface IPermissionDataProvider
{
+ ///
+ /// Reads permission grants for subject and tenant scope.
+ ///
+ /// Permission lookup request contract.
+ /// Cancellation token.
+ /// Permission grant records matching lookup scope.
+ Task> ReadPermissionsAsync(
+ IdentityPermissionSetLookupRequest request,
+ CancellationToken cancellationToken = default);
}
diff --git a/src/Thalos.DAL/Providers/IRoleDataProvider.cs b/src/Thalos.DAL/Providers/IRoleDataProvider.cs
index 4910e3e..739afa4 100644
--- a/src/Thalos.DAL/Providers/IRoleDataProvider.cs
+++ b/src/Thalos.DAL/Providers/IRoleDataProvider.cs
@@ -1,3 +1,5 @@
+using Thalos.DAL.Contracts;
+
namespace Thalos.DAL.Providers;
///
@@ -5,4 +7,13 @@ namespace Thalos.DAL.Providers;
///
public interface IRoleDataProvider
{
+ ///
+ /// Reads identity role records for subject and tenant scope.
+ ///
+ /// Role lookup request contract.
+ /// Cancellation token.
+ /// Role records matching the lookup scope.
+ Task> ReadRolesAsync(
+ IdentityRoleLookupRequest request,
+ CancellationToken cancellationToken = default);
}
diff --git a/src/Thalos.DAL/Providers/ITenantDataProvider.cs b/src/Thalos.DAL/Providers/ITenantDataProvider.cs
index 976f57c..50d0b46 100644
--- a/src/Thalos.DAL/Providers/ITenantDataProvider.cs
+++ b/src/Thalos.DAL/Providers/ITenantDataProvider.cs
@@ -1,3 +1,5 @@
+using Thalos.DAL.Contracts;
+
namespace Thalos.DAL.Providers;
///
@@ -5,4 +7,13 @@ namespace Thalos.DAL.Providers;
///
public interface ITenantDataProvider
{
+ ///
+ /// Reads tenant scope metadata for identity policy and token decisions.
+ ///
+ /// Tenant lookup request contract.
+ /// Cancellation token.
+ /// Tenant record when found; otherwise null.
+ Task ReadTenantAsync(
+ IdentityTenantLookupRequest request,
+ CancellationToken cancellationToken = default);
}
diff --git a/src/Thalos.DAL/Providers/IUserDataProvider.cs b/src/Thalos.DAL/Providers/IUserDataProvider.cs
index 5afd2d8..2a1eff6 100644
--- a/src/Thalos.DAL/Providers/IUserDataProvider.cs
+++ b/src/Thalos.DAL/Providers/IUserDataProvider.cs
@@ -1,3 +1,5 @@
+using Thalos.DAL.Contracts;
+
namespace Thalos.DAL.Providers;
///
@@ -5,4 +7,13 @@ namespace Thalos.DAL.Providers;
///
public interface IUserDataProvider
{
+ ///
+ /// Reads an identity user record by subject identifier.
+ ///
+ /// User lookup request contract.
+ /// Cancellation token.
+ /// User record when found; otherwise null.
+ Task ReadUserAsync(
+ IdentityUserLookupRequest request,
+ CancellationToken cancellationToken = default);
}
diff --git a/src/Thalos.DAL/Repositories/IIdentityRepository.cs b/src/Thalos.DAL/Repositories/IIdentityRepository.cs
index 2b1c317..228b436 100644
--- a/src/Thalos.DAL/Repositories/IIdentityRepository.cs
+++ b/src/Thalos.DAL/Repositories/IIdentityRepository.cs
@@ -1,3 +1,5 @@
+using Thalos.DAL.Contracts;
+
namespace Thalos.DAL.Repositories;
///
@@ -5,4 +7,33 @@ namespace Thalos.DAL.Repositories;
///
public interface IIdentityRepository
{
+ ///
+ /// Reads token issuance record data for a subject and tenant scope.
+ ///
+ /// Token lookup request contract.
+ /// Cancellation token.
+ /// Token record when found; otherwise null.
+ Task ReadIdentityTokenAsync(
+ IdentityTokenLookupRequest request,
+ CancellationToken cancellationToken = default);
+
+ ///
+ /// Reads policy context data required for authorization checks.
+ ///
+ /// Policy lookup request contract.
+ /// Cancellation token.
+ /// Policy record when found; otherwise null.
+ Task ReadIdentityPolicyAsync(
+ IdentityPolicyLookupRequest request,
+ CancellationToken cancellationToken = default);
+
+ ///
+ /// Reads permission set data for subject and tenant scope.
+ ///
+ /// Permission set lookup request contract.
+ /// Cancellation token.
+ /// Permission records for the requested scope.
+ Task> ReadPermissionSetAsync(
+ IdentityPermissionSetLookupRequest request,
+ CancellationToken cancellationToken = default);
}
diff --git a/src/Thalos.DAL/Thalos.DAL.csproj b/src/Thalos.DAL/Thalos.DAL.csproj
index 6c3a887..04a4bbc 100644
--- a/src/Thalos.DAL/Thalos.DAL.csproj
+++ b/src/Thalos.DAL/Thalos.DAL.csproj
@@ -4,4 +4,7 @@
enable
enable
+
+
+
diff --git a/tests/Thalos.DAL.UnitTests/BoundaryShapeTests.cs b/tests/Thalos.DAL.UnitTests/BoundaryShapeTests.cs
index 21c50dd..7e36d03 100644
--- a/tests/Thalos.DAL.UnitTests/BoundaryShapeTests.cs
+++ b/tests/Thalos.DAL.UnitTests/BoundaryShapeTests.cs
@@ -1,6 +1,7 @@
using Thalos.DAL.Health;
using Thalos.DAL.Providers;
using Thalos.DAL.Repositories;
+using System.Reflection;
namespace Thalos.DAL.UnitTests;
@@ -22,4 +23,26 @@ public class BoundaryShapeTests
Assert.True(typeof(IIdentityRepository).IsInterface);
Assert.True(typeof(IDalDependencyHealthCheck).IsInterface);
}
+
+ [Fact]
+ public void IdentityRepository_WhenReflected_ExposesContractMethodsOnly()
+ {
+ var methods = typeof(IIdentityRepository).GetMethods(BindingFlags.Public | BindingFlags.Instance);
+ var methodNames = methods.Select(method => method.Name).OrderBy(name => name).ToArray();
+
+ Assert.Equal(
+ ["ReadIdentityPolicyAsync", "ReadIdentityTokenAsync", "ReadPermissionSetAsync"],
+ methodNames);
+ }
+
+ [Fact]
+ public void ProviderBoundaries_WhenReflected_ExposeReadOnlyMethods()
+ {
+ Assert.Equal("ReadUserAsync", typeof(IUserDataProvider).GetMethods().Single().Name);
+ Assert.Equal("ReadRolesAsync", typeof(IRoleDataProvider).GetMethods().Single().Name);
+ Assert.Equal("ReadPermissionsAsync", typeof(IPermissionDataProvider).GetMethods().Single().Name);
+ Assert.Equal("ReadModulesAsync", typeof(IModuleDataProvider).GetMethods().Single().Name);
+ Assert.Equal("ReadTenantAsync", typeof(ITenantDataProvider).GetMethods().Single().Name);
+ Assert.Equal("CheckAsync", typeof(IDalDependencyHealthCheck).GetMethods().Single().Name);
+ }
}
diff --git a/tests/Thalos.DAL.UnitTests/ContractShapeTests.cs b/tests/Thalos.DAL.UnitTests/ContractShapeTests.cs
new file mode 100644
index 0000000..58949ba
--- /dev/null
+++ b/tests/Thalos.DAL.UnitTests/ContractShapeTests.cs
@@ -0,0 +1,44 @@
+using Core.Blueprint.Common.Contracts;
+using Thalos.DAL.Contracts;
+
+namespace Thalos.DAL.UnitTests;
+
+public class ContractShapeTests
+{
+ [Fact]
+ public void IdentityPolicyLookupRequest_WhenCreated_StoresTransportNeutralData()
+ {
+ var envelope = new IdentityContractEnvelope("1.0.0", "corr-123");
+ var request = new IdentityPolicyLookupRequest(envelope, "user-1", "tenant-1", "identity.token.issue");
+
+ Assert.Equal("1.0.0", request.Envelope.ContractVersion);
+ Assert.Equal("corr-123", request.Envelope.CorrelationId);
+ Assert.Equal("user-1", request.SubjectId);
+ Assert.Equal("tenant-1", request.TenantId);
+ Assert.Equal("identity.token.issue", request.PermissionCode);
+ }
+
+ [Fact]
+ public void IdentityTokenRecord_WhenCreated_StoresTransportNeutralData()
+ {
+ var envelope = new IdentityContractEnvelope("1.0.0", "corr-123");
+ var record = new IdentityTokenRecord(envelope, "user-1", "tenant-1", "token-xyz", 1800);
+
+ Assert.Equal("1.0.0", record.Envelope.ContractVersion);
+ Assert.Equal("corr-123", record.Envelope.CorrelationId);
+ Assert.Equal("user-1", record.SubjectId);
+ Assert.Equal("tenant-1", record.TenantId);
+ Assert.Equal("token-xyz", record.Token);
+ Assert.Equal(1800, record.ExpiresInSeconds);
+ }
+
+ [Fact]
+ public void ThalosDalPackageContract_WhenCreated_UsesBlueprintDescriptorContract()
+ {
+ IBlueprintPackageContract contract = new ThalosDalPackageContract();
+
+ Assert.Equal("Thalos.DAL.Contracts", contract.Descriptor.PackageId);
+ Assert.Equal(PackageVersionPolicy.Minor, contract.Descriptor.VersionPolicy);
+ Assert.Contains("Core.Blueprint.Common", contract.Descriptor.DependencyPackageIds);
+ }
+}