using System.Data.Common; using EntitlementDAL.DTOs; using GB5Shared.DTO.Framework.Login; namespace EntitlementDAL.Interfaces; public interface IClientRefreshTokenDAL { Task GetByIdAsync(int clientRefreshTokenId, LoginDTO login, CancellationToken ct); Task GetByTokenHashAsync(string tokenHash, LoginDTO login, CancellationToken ct); Task SaveAsync(ClientRefreshTokenDTO dto, LoginDTO login, DbTransaction tx, CancellationToken ct); /// Sets RevokedOn=now and ReplacedByTokenId (pass null when cascade-killing a chain /// descendant that was never itself exchanged for anything, non-null when this is a normal /// rotation linking the old token to the new one it was exchanged for). Task RevokeAsync(int clientRefreshTokenId, int? replacedByTokenId, LoginDTO login, DbTransaction tx, CancellationToken ct); /// Walks the ReplacedByTokenId chain forward starting from the token AFTER /// clientRefreshTokenId (i.e. excludes clientRefreshTokenId itself), one PK lookup per hop — /// a recursive CTE would need dialect-specific syntax (Postgres requires WITH RECURSIVE, SQL /// Server just WITH), which would break this module's single-SQL-text-for-both-engines /// convention. Returns every descendant found, revoked or not — deciding which of them are /// "still active" and therefore need revoking is a BLL-level judgment call, not a DAL /// concern. Task> GetChainDescendantsAsync(int clientRefreshTokenId, LoginDTO login, CancellationToken ct); }