Skip to content

Latest commit

 

History

History
122 lines (102 loc) · 4.62 KB

File metadata and controls

122 lines (102 loc) · 4.62 KB

validators

Tier: Foundational · Status: Full · Java original: firefly-common-validators · .NET project: FireflyFramework.Validators

Overview

validators is the canonical input-validation tier — pure functions that return nil on success or an error wrapping validators.ErrInvalid with a human-readable reason on failure. Every function is allocation-free for the success path and safe for concurrent use.

Coverage:

Validator What it checks
ValidateIBAN ISO 13616 mod-97 + per-country length (76 country codes ship in the table)
ValidateBIC ISO 9362 — 8 or 11 alnum chars
ValidateLuhn Luhn checksum (credit cards, IMEI, SIN)
ValidateCreditCard Luhn + length 12..19
ValidatePhoneE164 +<country><subscriber>, 8..16 chars
ValidateCurrency ISO 4217 — 3 uppercase letters
ValidateEmail RFC 5322 syntactic
ValidatePassword Configurable policy (length, upper, lower, digit, symbol)
ValidateSortCode UK 6-digit sort code (XXXXXX or XX-XX-XX)
ValidateBSB AU 6-digit Bank-State-Branch
ValidateSSN US Social Security Number
ValidateVAT EU-style VAT (CC + 2..12 alnum)
ValidateDNI Spanish DNI with letter checksum
ValidateNIE Spanish NIE (X/Y/Z prefix variant)
ValidateNIF Spanish NIF (DNI ∪ NIE)

Why pure functions?

The .NET port uses validation attributes ([ValidIban]); Java uses Jakarta Bean Validation annotations. Go has no annotation runtime, so struct tags + a third-party library would be the closest equivalent — but every adapter introduces a different set of trade-offs. By exposing the validators as plain functions returning error, services can:

  • Call them directly from CQRS handler Validate() methods.
  • Adapt them to go-playground/validator/v10 custom tags in three lines of code.
  • Combine them via errors.Join for multi-field validation.

Public surface

var ErrInvalid = errors.New("firefly/validators: invalid")

func ValidateIBAN(s string) error
func ValidateBIC(s string) error
func ValidateLuhn(s string) error
func ValidateCreditCard(s string) error
func ValidatePhoneE164(s string) error
func ValidateCurrency(s string) error
func ValidateEmail(s string) error
func ValidatePassword(s string, p PasswordPolicy) error
func ValidateSortCode(s string) error
func ValidateBSB(s string) error
func ValidateSSN(s string) error
func ValidateVAT(s string) error
func ValidateDNI(s string) error
func ValidateNIE(s string) error
func ValidateNIF(s string) error

type PasswordPolicy struct {
    MinLength    int
    RequireUpper bool
    RequireLower bool
    RequireDigit bool
    RequireSym   bool
}
func DefaultPasswordPolicy() PasswordPolicy

var IBANCountryLengths map[string]int

Quick start

import (
    "errors"
    "github.com/fireflyframework/fireflyframework-go/validators"
    "github.com/fireflyframework/fireflyframework-go/kernel"
)

type RegisterCmd struct {
    Email    string
    Password string
    IBAN     string
}

func (c RegisterCmd) Validate() error {
    var errs []error
    if err := validators.ValidateEmail(c.Email); err != nil {
        errs = append(errs, fmt.Errorf("email: %w", err))
    }
    if err := validators.ValidatePassword(c.Password, validators.DefaultPasswordPolicy()); err != nil {
        errs = append(errs, fmt.Errorf("password: %w", err))
    }
    if err := validators.ValidateIBAN(c.IBAN); err != nil {
        errs = append(errs, fmt.Errorf("iban: %w", err))
    }
    if len(errs) > 0 {
        return kernel.NewValidation(errors.Join(errs...).Error())
    }
    return nil
}

Testing

cd validators
go test ./...

Suite includes mod-97 round-trips on canonical IBAN test vectors (GB, DE, FR, ES), Luhn against a known-good and known-bad pair, DNI checksum letter table, and password-policy boundary cases.