Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/0Crazy-0/ClinicFlow/llms.txt

Use this file to discover all available pages before exploring further.

ClinicFlow is built on a clean-architecture layering model where the Domain and Application layers define contracts (interfaces) but contain no concrete infrastructure code. Sending emails, hashing passwords, verifying phone numbers, and enforcing regional scheduling rules are all responsibilities that must be fulfilled by the host application (or a dedicated Infrastructure project) through concrete implementations registered in the dependency injection container. Seven interfaces must be implemented in total: four in the Application layer and three in the Domain layer.
All seven interfaces described on this page define the contract only. No default implementations are shipped with ClinicFlow’s Domain or Application assemblies. Your host project is responsible for providing implementations and registering them with the DI container before calling AddApplicationServices().

Interface Reference

The table below summarises all required service interfaces, their namespaces, and their purpose:
InterfaceNamespacePurpose
IEmailServiceClinicFlow.Application.InterfacesSend password-reset emails with a verification token
IPasswordResetTokenServiceClinicFlow.Application.InterfacesGenerate and validate secure, short-lived password-reset tokens
IRefreshTokenServiceClinicFlow.Application.InterfacesRevoke all active refresh tokens for a user
ICurrentUserServiceClinicFlow.Application.InterfacesExpose the current authenticated user’s identity to application handlers
IPasswordHasherServiceClinicFlow.Domain.Interfaces.ServicesHash plain-text passwords and verify hash matches
IPhoneVerificationServiceClinicFlow.Domain.Interfaces.ServicesSend SMS verification codes and validate responses
IRegionalSchedulingServiceClinicFlow.Domain.Interfaces.ServicesEnforce locale-specific regulations during appointment scheduling

IEmailService

Defined in ClinicFlow.Application.Interfaces, this interface is invoked by the password-reset workflow to deliver a reset link or token to the patient or user’s email address.
namespace ClinicFlow.Application.Interfaces;

public interface IEmailService
{
    /// <summary>
    /// Sends a password reset verification link to the specified email.
    /// </summary>
    /// <param name="resetToken">The token used to verify the reset request.</param>
    Task SendPasswordResetEmailAsync(
        string email,
        string resetToken,
        CancellationToken cancellationToken = default
    );
}
Implementation notes:
  • resetToken is the raw token string returned by IPasswordResetTokenService.GenerateTokenAsync. You may embed it in a URL query parameter or present it as an OTP depending on your UX.
  • Use any transactional email provider (SendGrid, Mailgun, AWS SES, etc.) in your implementation.

IPasswordResetTokenService

Defined in ClinicFlow.Application.Interfaces, this service manages the lifecycle of password-reset tokens: generation at request time and validation when the user submits the reset form.
namespace ClinicFlow.Application.Interfaces;

/// <summary>
/// Manages generation and validation of password reset tokens.
/// </summary>
public interface IPasswordResetTokenService
{
    /// <summary>
    /// Generates a secure, temporary password reset token for the specified user.
    /// </summary>
    Task<string> GenerateTokenAsync(Guid userId, CancellationToken cancellationToken = default);

    /// <summary>
    /// Validates a password reset token and returns the corresponding user's identifier.
    /// </summary>
    /// <returns>
    /// The user ID associated with the token, or null if the token is invalid or expired.
    /// </returns>
    Task<Guid?> ValidateTokenAsync(string token, CancellationToken cancellationToken = default);
}
Implementation notes:
  • Tokens should be short-lived (15–60 minutes is typical).
  • Store tokens in a cache (Redis, in-memory) or database table with an expiry column.
  • ValidateTokenAsync returning null signals an expired or tampered token; the calling handler will surface an appropriate error.

IRefreshTokenService

Defined in ClinicFlow.Application.Interfaces, this interface is called whenever a user changes their password or the system needs to invalidate all active sessions for a user (e.g., after a security event).
namespace ClinicFlow.Application.Interfaces;

public interface IRefreshTokenService
{
    /// <summary>
    /// Revokes all active refresh tokens for the specified user.
    /// </summary>
    Task RevokeAsync(Guid userId, CancellationToken cancellationToken = default);
}
Implementation notes:
  • The implementation should mark all refresh tokens associated with userId as revoked in whatever store you use (database table, Redis set, etc.).
  • After revocation, any request using an old refresh token must be rejected by your token middleware.

ICurrentUserService

Defined in ClinicFlow.Application.Interfaces, this service is consumed by application-layer command and query handlers that need to know who is performing the operation — for authorization checks, audit trails, and scoped queries.
using ClinicFlow.Domain.Enums;

namespace ClinicFlow.Application.Interfaces;

/// <summary>
/// Provides access to the current authenticated user's details.
/// </summary>
public interface ICurrentUserService
{
    Guid Id { get; }

    string Email { get; }

    UserRole Role { get; }

    bool IsAuthenticated { get; }
}
Implementation notes:
  • In an ASP.NET Core host, implement this by reading from IHttpContextAccessor and parsing the JWT claims.
  • Register as Scoped so each HTTP request receives its own instance.
  • IsAuthenticated should return false for anonymous/unauthenticated contexts rather than throwing; handlers decide how to react.

IPasswordHasherService

Defined in ClinicFlow.Domain.Interfaces.Services, this interface lives in the Domain layer because password-hashing is a core security concern used directly by domain entities during registration and credential verification.
namespace ClinicFlow.Domain.Interfaces.Services;

/// <summary>
/// Provides password hashing and verification capabilities.
/// </summary>
public interface IPasswordHasherService
{
    string Hash(string plainPassword);
    bool Verify(string plainPassword, string hashedPassword);
}
Implementation notes:
  • Use a modern adaptive hashing algorithm such as BCrypt, Argon2, or ASP.NET Core’s built-in IPasswordHasher<T> (which uses PBKDF2).
  • Never implement this with MD5, SHA-1, or unsalted SHA-256.

IPhoneVerificationService

Defined in ClinicFlow.Domain.Interfaces.Services, this service sends a one-time verification code to a PhoneNumber value object and later validates the code supplied by the user.
using ClinicFlow.Domain.ValueObjects;

namespace ClinicFlow.Domain.Interfaces.Services;

/// <summary>
/// Abstraction for phone number verification via external providers.
/// </summary>
public interface IPhoneVerificationService
{
    Task SendVerificationCodeAsync(
        PhoneNumber phoneNumber,
        CancellationToken cancellationToken = default
    );

    Task<bool> VerifyCodeAsync(
        PhoneNumber phoneNumber,
        string code,
        CancellationToken cancellationToken = default
    );
}
Implementation notes:
  • Use an SMS gateway such as Twilio Verify, AWS SNS, or similar.
  • PhoneNumber is a domain value object that wraps a validated, normalized phone string.
  • VerifyCodeAsync returns true on a valid code and false on an expired or incorrect one; the domain entity that calls it will throw DomainErrors.User.InvalidVerificationCode on false.

IRegionalSchedulingService

Defined in ClinicFlow.Domain.Interfaces.Services, this is the most domain-significant integration point. It is invoked during appointment scheduling to enforce local legal or operational regulations that vary by region, specialty, or appointment type.
using ClinicFlow.Domain.Entities;
using ClinicFlow.Domain.ValueObjects;

namespace ClinicFlow.Domain.Interfaces.Services;

/// <summary>
/// Defines the policy for enforcing regional and medical specialty regulations
/// during appointment scheduling.
/// </summary>
public interface IRegionalSchedulingService
{
    SchedulingClearance EnforceSchedulingRegulations(
        Doctor targetDoctor,
        Patient targetPatient,
        AppointmentTypeDefinition appointmentType
    );
}
The method returns a SchedulingClearance value object. If the scheduling attempt violates a regulation, the implementation should either return a clearance that signals the violation or throw a DomainException — the exact contract is determined by the SchedulingClearance value object’s design. Implementation notes:
  • The default no-op implementation (for clinics with no regional restrictions) should return an approved SchedulingClearance unconditionally.
  • Complex implementations might consult a rules engine, a configuration store, or an external regulatory API.
  • Register as Singleton or Scoped depending on whether the implementation holds mutable state.

Registering Implementations

In your host or Infrastructure project, register all seven implementations before calling AddApplicationServices():
// Program.cs or a dedicated extension method
services.AddScoped<ICurrentUserService, HttpContextCurrentUserService>();
services.AddScoped<IEmailService, SendGridEmailService>();
services.AddScoped<IPasswordResetTokenService, RedisPasswordResetTokenService>();
services.AddScoped<IRefreshTokenService, EfCoreRefreshTokenService>();
services.AddScoped<IPasswordHasherService, BCryptPasswordHasherService>();
services.AddScoped<IPhoneVerificationService, TwilioPhoneVerificationService>();
services.AddScoped<IRegionalSchedulingService, DefaultRegionalSchedulingService>();

services.AddApplicationServices(); // registers MediatR + FluentValidation

Build docs developers (and LLMs) love