Contents

Stack

  • go-playground/validator/v10
  • Shared registration: pkg/validation.Register
  • Field messages (i18n): pkg/validation.FieldMessage + pkg/i18n/locales/{tr,en}.json

HTTP and GoUI use the same validator instance / message resolution; error responses are translated by locale.

Custom tags

Registered in pkg/validation:

Tag Meaning
phone Optional phone; format check when provided
phone_required Required phone

Standard tags (required, email, min, max, uuid, …) are used directly.

Layers

  1. Transport — handler / GoUI form bind + struct tags
  2. Application — business rules (e.g. last admin cannot be deleted)
  3. Domain — entity factory / VO invariants

Transport errors return field-level messages to the user. Domain errors are mapped to problem/flash responses.

i18n

  • Default / supported: I18N_DEFAULT_LOCALE, I18N_SUPPORTED
  • Resolution order (summary): query lang → cookie → Accept-Language → user preferred_locale → default
  • When adding a new validation message, write the same key in tr and en locale files
  • Parity test: pkg/i18n/locale_parity_test.go

API error format

JSON API problem details include field errors with i18n text.
The panel shows them via flash / SweetAlert.

Upload / tabular

  • MIME allowlist: SEC_ALLOWED_UPLOAD_MIME (image, PDF, CSV, Excel)
  • Size: SEC_MAX_UPLOAD_BYTES
  • Bulk recipient parse: pkg/recipients (row validation)
  • Export: pkg/tabular

Related code

  • pkg/validation
  • internal/adapters/shared/validate.go
  • internal/adapters/http/middleware/i18n.go