Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Axiom Laravel Package

mattkingshott/axiom

Axiom is a Laravel package by Matt Kingshott for defining business rules as reusable, testable classes. It offers a fluent API for validating models against domain invariants, keeping complex application logic clean and organized. It integrates with Laravel's validation and testing tools.

View on GitHub
Deep Wiki
Context7

Getting Started

This release adds a Vietnamese citizen rule (12‑digit CCCD, plus legacy 9‑digit CMND) to the package's family of national‑identifier validators. Nothing else in the integration story changes.

  1. composer update and confirm you land on v3.2.1 — country rules in this package have historically been added without a major bump, so pin the minor if you rely on rule behaviour.
  2. Look first at src/Rules/ (the new Vietnamese rule class) and the package service provider — it is usually where rule aliases and the translation namespace are registered.
  3. Check the README's rule table for the exact string alias and constructor signature; the Vietnamese rule is typically available both as new VietnameseCitizenId() and as a string rule after the provider boots.
  4. First use case — a registration or KYC FormRequest:
public function rules(): array
{
    return [
        'full_name'   => ['required', 'string', 'max:255'],
        'citizen_id'  => ['required', 'string', new VietnameseCitizenId()],
    ];
}

If you already had a hand‑rolled regex:/^\d{12}$/, swap it in the same commit — you get structural validation (province code, birth‑date segment, gender/century digit) for free.

Implementation Patterns

Inline in FormRequests. The common case: one rule object on one field. Keep the field as string — never integer — and pair it with required/nullable as appropriate.

Conditional by country. For multi‑market apps, don't branch inside the FormRequest body; compose rules so only the matching rule runs:

'national_id' => [
    'required',
    'string',
    Rule::when($this->country === 'VN', [new VietnameseCitizenId()]),
    Rule::when($this->country === 'JP', [new JapaneseMyNumber()]),
],

Normalise before you validate. Users paste IDs with spaces, dots, and non‑breaking spaces. Use prepareForValidation() to strip separators so the rule sees a clean string, and so the value you persist matches what you validated:

protected function prepareForValidation(): void
{
    $this->merge([
        'citizen_id' => preg_replace('/[\s.\-]/u', '', (string) $this->citizen_id),
    ]);
}

Custom messages and attributes. Publish the package translations (or override messages() on the FormRequest) so the failure reads "Số CCCD không hợp lệ" rather than the raw rule key. Attribute names matter here — users see "citizen_id" otherwise.

Testing. Use datasets rather than one happy‑path test. Keep a small fixture set of valid CCCDs (including one issued post‑2000, to exercise the century/gender digit), plus invalids: 11 digits, 13 digits, wrong province prefix, impossible YYMMDD segment.

Storage and DTOs. Persist as string(12) (or string(20) if you must also hold legacy CMNDs). When mapping to an API resource, echo the ID back as a string and mask it in list views — validation rules don't protect you from leaking PII.

Gotchas and Tips

  • Never cast to int. 12‑digit IDs exceed 32‑bit and lose a leading zero on a 9‑digit CMND. Use string in migrations, casts, and JSON. This is the single most common post‑integration bug.
  • CCCD vs CMND. The Vietnamese rule generally accepts the modern 12‑digit format; if your dataset still contains 9‑digit CMNDs, check the rule's constructor for a lenient/legacy flag before you assume both pass. Validate against your real data distribution, not the docs.
  • Structural ≠ checksum. These rules validate the ID's shape (province code, encoded birth date, century/gender digit). They do not prove the ID exists. If your compliance requirements demand more, that is a separate lookup — don't let the rule's presence imply verification.
  • Reject future birth dates. The encoded YYMMDD segment is only as good as the rule's implementation. Add a domain‑level sanity check (holder is ≥ 14 years old for KYC) on top; the rule won't know your business thresholds.
  • String alias timing. If you reference the rule by string alias, make sure the service provider is registered before your validator runs. In long‑running workers (Octane, queue consumers) configuration is cached at boot — clear bootstrap/cache after upgrading, or a newly added alias won't resolve.
  • Version pinning. New country rules land in patch/minor releases here. If your CI runs composer update with a caret constraint, a fresh rule can appear mid‑sprint; pin to ~3.2.0 for production branches.
  • Debugging failures. When a valid‑looking ID fails, dump the normalised value rather than the raw input — nine times out of ten it's a stray character or a trim you forgot, not the rule.
  • Extension point. If the Vietnamese rule is close but not exact for your market (e.g. you need to accept both 9‑ and 12‑digit forms with different error messages), extend the rule class and override the message, rather than duplicating the regex in your app.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource