Table of Contents

Class VolunteerApplicationService

Namespace
Builvero.Application.Services
Assembly
Builvero.Application.dll

Service for managing volunteer applications including creation, retrieval, status updates, and resume management.

public class VolunteerApplicationService : IVolunteerApplicationService
Inheritance
VolunteerApplicationService
Implements
Inherited Members

Remarks

This service handles the complete lifecycle of volunteer applications:

  • Creating applications with resume upload to S3
  • Retrieving applications with pagination and filtering
  • Updating application status (New, Reviewed, Accepted)
  • Generating presigned URLs for resume downloads
  • Deleting applications (GDPR compliance - right to be forgotten)
Resume files are stored in S3 and managed securely. Application deletion includes S3 cleanup for GDPR compliance.

Constructors

VolunteerApplicationService(IVolunteerApplicationRepository, IVolunteerRoleRepository, IS3Service, IEmailSender, ILogger<VolunteerApplicationService>)

Initializes a new instance of the VolunteerApplicationService class.

public VolunteerApplicationService(IVolunteerApplicationRepository applicationRepository, IVolunteerRoleRepository roleRepository, IS3Service s3Service, IEmailSender emailSender, ILogger<VolunteerApplicationService> logger)

Parameters

applicationRepository IVolunteerApplicationRepository

Repository for volunteer application data access.

roleRepository IVolunteerRoleRepository

Repository for volunteer role data access.

s3Service IS3Service

Service for S3 operations (resume upload/download/delete).

emailSender IEmailSender

Service for sending email notifications.

logger ILogger<VolunteerApplicationService>

Logger for recording operations and errors.

Methods

CreateApplicationAsync(CreateVolunteerApplicationRequest, Stream, string, string, long, CancellationToken)

Creates a new volunteer application with resume upload to S3.

public Task<VolunteerApplicationDto> CreateApplicationAsync(CreateVolunteerApplicationRequest request, Stream resumeStream, string resumeFileName, string resumeContentType, long resumeSizeBytes, CancellationToken cancellationToken = default)

Parameters

request CreateVolunteerApplicationRequest

The application request containing applicant information and role details.

resumeStream Stream

The resume file stream to upload.

resumeFileName string

The original filename of the resume.

resumeContentType string

The MIME content type of the resume file.

resumeSizeBytes long

The size of the resume file in bytes.

cancellationToken CancellationToken

Cancellation token to cancel the operation.

Returns

Task<VolunteerApplicationDto>

The created volunteer application DTO.

Remarks

This method performs the following operations:

  1. Validates that the email address is not already used
  2. Validates that the volunteer role exists and is active
  3. Validates and parses the hours per week enum value
  4. Creates the application entity with status "New"
  5. Uploads the resume file to S3 under the resumes/ prefix
  6. Saves the application to the database

The resume is uploaded to S3 with a key format: resumes/{roleId}/{applicationId}/{fileName} If S3 upload fails, an exception is thrown and the application is not saved.

Exceptions

Exception

Thrown when email already exists, role not found, role is closed, or resume upload fails.

ArgumentException

Thrown when hours per week value is invalid.

DeleteApplicationAsync(Guid, CancellationToken)

Deletes a volunteer application and its associated resume from S3 (GDPR compliance - right to be forgotten).

public Task<bool> DeleteApplicationAsync(Guid applicationId, CancellationToken cancellationToken = default)

Parameters

applicationId Guid

The unique identifier of the application to delete.

cancellationToken CancellationToken

Cancellation token to cancel the operation.

Returns

Task<bool>

True if the application was successfully deleted; otherwise, false.

Remarks

This method performs GDPR-compliant deletion:

  1. Attempts to delete the resume file from S3
  2. Deletes the application record from the database

If S3 deletion fails, the error is logged but database deletion continues to ensure GDPR compliance. This ensures that even if S3 operations fail, the personal data is removed from the database.

EmailExistsAsync(string, CancellationToken)

Checks if an email address already exists in the volunteer applications database.

public Task<bool> EmailExistsAsync(string email, CancellationToken cancellationToken = default)

Parameters

email string

The email address to check.

cancellationToken CancellationToken

Cancellation token to cancel the operation.

Returns

Task<bool>

True if an application with the email address exists; otherwise, false.

Remarks

Used for client-side validation to prevent duplicate applications with the same email address.

GetApplicationByIdAsync(Guid, CancellationToken)

Retrieves a specific volunteer application by ID.

public Task<VolunteerApplicationDto?> GetApplicationByIdAsync(Guid id, CancellationToken cancellationToken = default)

Parameters

id Guid

The unique identifier of the application to retrieve.

cancellationToken CancellationToken

Cancellation token to cancel the operation.

Returns

Task<VolunteerApplicationDto>

The application DTO if found; otherwise, null.

Remarks

Returns the application with its associated role information. Full name is HTML-encoded to prevent XSS.

GetApplicationsAsync(int, int, Guid?, string?, CancellationToken)

Retrieves a paginated list of volunteer applications with optional filtering by role and status.

public Task<(List<VolunteerApplicationDto> Applications, int TotalCount)> GetApplicationsAsync(int page, int pageSize, Guid? roleId = null, string? status = null, CancellationToken cancellationToken = default)

Parameters

page int

The page number (1-based) to retrieve.

pageSize int

The number of applications per page.

roleId Guid?

Optional role ID filter to retrieve applications for a specific role.

status string

Optional status filter (e.g., "New", "Reviewed", "Accepted"). Must match ApplicationStatus enum values (case-insensitive).

cancellationToken CancellationToken

Cancellation token to cancel the operation.

Returns

Task<(List<VolunteerApplicationDto> Applications, int TotalCount)>

A tuple containing the list of applications and the total count matching the filters.

Remarks

Applications are returned with their associated role information. Status filtering is case-insensitive and matches enum values. If no filters are provided, all applications are returned (paginated).

GetResumeDownloadUrlAsync(Guid, CancellationToken)

Generates a presigned URL for downloading a volunteer application's resume from S3.

public Task<string> GetResumeDownloadUrlAsync(Guid applicationId, CancellationToken cancellationToken = default)

Parameters

applicationId Guid

The unique identifier of the application whose resume should be downloaded.

cancellationToken CancellationToken

Cancellation token to cancel the operation.

Returns

Task<string>

A presigned URL valid for 5 minutes that can be used to download the resume.

Remarks

The presigned URL is valid for 5 minutes and provides secure, temporary access to the resume file stored in S3 without exposing the S3 bucket structure or requiring direct S3 credentials.

Exceptions

Exception

Thrown when the application is not found or the resume S3 key is missing.

UpdateApplicationStatusAsync(Guid, ApplicationStatus, CancellationToken)

Updates the status of a volunteer application.

public Task<VolunteerApplicationDto> UpdateApplicationStatusAsync(Guid applicationId, ApplicationStatus status, CancellationToken cancellationToken = default)

Parameters

applicationId Guid

The unique identifier of the application to update.

status ApplicationStatus

The new status to set. Must be one of: New, Reviewed, or Accepted.

cancellationToken CancellationToken

Cancellation token to cancel the operation.

Returns

Task<VolunteerApplicationDto>

The updated application DTO.

Remarks

Only allows status transitions to New, Reviewed, or Accepted. Rejected status is not allowed; applications should be discarded/deleted instead. Status updates are logged for audit purposes.

Exceptions

Exception

Thrown when the application is not found.

ArgumentException

Thrown when the status is Rejected (use discard/delete instead).