- GeradoresService: cada tipo passa a ser um IGenerator (NIF, NIPC, NISS, CC, passaporte, IBAN, NIB, cartões, referência MB, pessoa, telefone, código postal, email, matrícula, EAN, UUID) registado em GeneratorRegistry; remove DAL/EF - GeradoresWS: minimal APIs em /api/v1 com OpenAPI + Scalar e health check - UnitTest: testes de ida e volta, valores conhecidos, detecção e API - geradoresfe: UI construída a partir dos metadados da API, validador livre, exportação CSV/JSON/TXT, nginx com API_UPSTREAM configurável - Docker, docker-compose e Jenkinsfile actualizados Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
68 lines
2.7 KiB
C#
68 lines
2.7 KiB
C#
using GeradoresService.Core;
|
|
|
|
namespace GeradoresService.Generators.Contactos;
|
|
|
|
/// <summary>Números de telefone portugueses (Plano Nacional de Numeração). Apenas formato.</summary>
|
|
public sealed class TelefoneGenerator : GeneratorBase
|
|
{
|
|
private static readonly string[] MobilePrefixes = ["91", "92", "93", "96"];
|
|
|
|
public override string Id => "telefone";
|
|
public override string Name => "Telefone";
|
|
public override string Category => Categories.Contactos;
|
|
public override string Description => "Telemóvel ou telefone fixo português.";
|
|
public override bool HasChecksum => false;
|
|
|
|
public override IReadOnlyList<GeneratorOption> Options =>
|
|
[
|
|
Option("tipo", "Tipo", "movel", ("movel", "Telemóvel"), ("fixo", "Fixo"), ("qualquer", "Qualquer")),
|
|
Option("formato", "Formato", "nacional",
|
|
("nacional", "912 345 678"), ("internacional", "+351 912 345 678"), ("compacto", "912345678")),
|
|
];
|
|
|
|
public override GeneratedItem Generate(GeneratorContext context)
|
|
{
|
|
var tipo = context.Option(Options[0]);
|
|
if (tipo == "qualquer")
|
|
tipo = context.Random.Next(2) == 0 ? "movel" : "fixo";
|
|
|
|
var number = tipo == "movel"
|
|
? context.Pick(MobilePrefixes) + context.Digits(7)
|
|
: "2" + (1 + context.Random.Next(9)) + context.Digits(7);
|
|
|
|
return new GeneratedItem(Format(number, context.Option(Options[1])));
|
|
}
|
|
|
|
private static string Format(string n, string formato) => formato switch
|
|
{
|
|
"compacto" => n,
|
|
"internacional" => $"+351 {n[..3]} {n[3..6]} {n[6..]}",
|
|
_ => $"{n[..3]} {n[3..6]} {n[6..]}",
|
|
};
|
|
|
|
public override ValidationResult Validate(string value)
|
|
{
|
|
var n = Checksums.Clean(value).Replace("(", "").Replace(")", "");
|
|
if (n.StartsWith("+351")) n = n[4..];
|
|
else if (n.StartsWith("00351")) n = n[5..];
|
|
|
|
if (n.Length != 9 || !Checksums.AllDigits(n))
|
|
return ValidationResult.WrongFormat("Um número português tem 9 dígitos (opcionalmente com +351).");
|
|
|
|
var tipo = n switch
|
|
{
|
|
['9', '1' or '2' or '3' or '6', ..] => "telemóvel",
|
|
['2', ..] => "fixo",
|
|
['3', '0', ..] => "VoIP nómada",
|
|
['8', '0', '0', ..] => "número verde (gratuito)",
|
|
['8', '0', '8', ..] => "número azul (custo partilhado)",
|
|
['7', '0', '7', ..] or ['7', '6', '0', ..] => "número de valor acrescentado",
|
|
_ => null,
|
|
};
|
|
|
|
return tipo is null
|
|
? ValidationResult.WrongFormat("O prefixo não corresponde a um número português conhecido.")
|
|
: ValidationResult.Valid(Format(n, "internacional"), $"Número português válido ({tipo}).", [$"Tipo: {tipo}"]);
|
|
}
|
|
}
|