Sube carpetas API, API.Tests, Application y Domain del Backend
This commit is contained in:
+30
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
|
||||
namespace Application.Utils.Constants.Validation;
|
||||
|
||||
/// <summary>
|
||||
/// Validates that a string is a plausible Argentine phone number.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter)]
|
||||
public sealed class ArgentinePhoneNumberAttribute : ValidationAttribute
|
||||
{
|
||||
protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
|
||||
{
|
||||
if (value is not string phone || string.IsNullOrWhiteSpace(phone))
|
||||
{
|
||||
return ValidationResult.Success;
|
||||
}
|
||||
|
||||
string trimmed = phone.Trim();
|
||||
bool hasOnlyAllowedChars = trimmed.All(c => char.IsDigit(c) || c is '+' or ' ' or '(' or ')' or '-');
|
||||
int digitCount = trimmed.Count(char.IsDigit);
|
||||
|
||||
return hasOnlyAllowedChars && digitCount == 10
|
||||
? ValidationResult.Success
|
||||
: new ValidationResult(
|
||||
ErrorMessage ?? ValidationPatterns.PhoneNumberError,
|
||||
[validationContext.MemberName ?? string.Empty]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Application.Utils.Constants.Validation;
|
||||
|
||||
/// <summary>
|
||||
/// Field length limits shared by every division-name-accepting request DTO and entity configuration.
|
||||
/// </summary>
|
||||
public static class DivisionFieldLengths
|
||||
{
|
||||
public const int NameMaxLength = 100;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Application.Utils.Constants.Validation;
|
||||
|
||||
/// <summary>
|
||||
/// Validates that a DateTime birth date is at least minimumYears years in the past, meaning the person is at least that many years old today.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter)]
|
||||
public sealed class MinimumAgeAttribute(int minimumYears) : ValidationAttribute
|
||||
{
|
||||
private readonly int _minimumYears = minimumYears;
|
||||
|
||||
protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
|
||||
{
|
||||
if (value is not DateTime birthDate)
|
||||
{
|
||||
return ValidationResult.Success;
|
||||
}
|
||||
|
||||
DateTime cutoff = DateTime.UtcNow.Date.AddYears(-_minimumYears);
|
||||
|
||||
return birthDate.Date <= cutoff
|
||||
? ValidationResult.Success
|
||||
: new ValidationResult(
|
||||
ErrorMessage ?? $"El jugador debe tener al menos {_minimumYears} años.",
|
||||
[validationContext.MemberName ?? string.Empty]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace Application.Utils.Constants.Validation;
|
||||
|
||||
/// <summary>
|
||||
/// Field length limits shared by CreatePlayerRequest and UpdatePlayerRequest, so the two stay in sync.
|
||||
/// </summary>
|
||||
public static class PlayerFieldLengths
|
||||
{
|
||||
public const int NameMaxLength = 70;
|
||||
public const int DocumentNumberMaxLength = 15;
|
||||
public const int PhoneNumberMaxLength = 15;
|
||||
public const int SocialSecurityMaxLength = 100;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace Application.Utils.Constants.Validation;
|
||||
|
||||
/// <summary>
|
||||
/// Field length limits shared across the player sanction request DTOs, so they stay in sync.
|
||||
/// </summary>
|
||||
public static class SanctionFieldLengths
|
||||
{
|
||||
/// <summary>
|
||||
/// Max length of the short sanction description on Create and Update requests.
|
||||
/// </summary>
|
||||
public const int DescriptionMaxLength = 255;
|
||||
|
||||
/// <summary>
|
||||
/// Min length of the free-text appeal reason / resolution notes.
|
||||
/// </summary>
|
||||
public const int LongTextMinLength = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Max length of the free-text appeal reason / resolution notes.
|
||||
/// </summary>
|
||||
public const int LongTextMaxLength = 1000;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Application.Utils.Constants.Validation;
|
||||
|
||||
/// <summary>
|
||||
/// Field length limits shared by CreateSeasonRequest and UpdateSeasonRequest, so the two stay in sync.
|
||||
/// </summary>
|
||||
public static class SeasonFieldLengths
|
||||
{
|
||||
public const int NameMaxLength = 100;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace Application.Utils.Constants.Validation;
|
||||
|
||||
/// <summary>
|
||||
/// Field length limits shared across the account and user request DTOs, so they stay in sync.
|
||||
/// </summary>
|
||||
public static class UserFieldLengths
|
||||
{
|
||||
public const int UsernameMinLength = 3;
|
||||
public const int UsernameMaxLength = 50;
|
||||
public const int PasswordMinLength = 8;
|
||||
public const int PhoneMaxLength = 15;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
namespace Application.Utils.Constants.Validation;
|
||||
|
||||
/// <summary>
|
||||
/// Shared validation regex patterns kept in one place so every request DTO and the frontend validators enforce the exact same plausible contact-field rules.
|
||||
/// </summary>
|
||||
public static class ValidationPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Plausible phone number: only digits, spaces, plus, hyphen and parentheses, containing between 8 and 15 digits.
|
||||
/// </summary>
|
||||
public const string PhoneNumber = @"^(?=(?:\D*\d){8,15}\D*$)[+\d\s()-]+$";
|
||||
|
||||
/// <summary>
|
||||
/// Human-facing message for a phone number that fails the pattern.
|
||||
/// </summary>
|
||||
public const string PhoneNumberError = "Invalid phone number format.";
|
||||
|
||||
/// <summary>
|
||||
/// A player's DNI or document number: digits only, 6 to 15 of them.
|
||||
/// </summary>
|
||||
public const string DocumentNumber = @"^\d{6,15}$";
|
||||
|
||||
/// <summary>
|
||||
/// Human-facing message for a document number that fails the pattern.
|
||||
/// </summary>
|
||||
public const string DocumentNumberError = "El documento debe contener solo números.";
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Application.Utils.Constants.Validation;
|
||||
|
||||
/// <summary>
|
||||
/// Field length limits shared by CreateVenueRequest and UpdateVenueRequest, so the two stay in sync.
|
||||
/// </summary>
|
||||
public static class VenueFieldLengths
|
||||
{
|
||||
public const int NameMaxLength = 50;
|
||||
public const int AddressMaxLength = 200;
|
||||
}
|
||||
Reference in New Issue
Block a user