tavo1987/laravel-ec-validator
Laravel validation rules for Ecuadorian identification documents, letting you verify cédula and RUC numbers with ready-made rules and checksum checks so forms and APIs accept only correctly formatted IDs.
Architecture fit. The package is architecturally well-behaved and idiomatic Laravel. It ships a single auto-discovered service provider (EcValidatorServiceProvider), registers a custom validator via Validator::resolver() in boot(), and exposes four string rules (ecuador:ci, ecuador:ruc, ecuador:ruc_spub, ecuador:ruc_spriv). There are no migrations, no published config, no queues, no I/O, and no global state beyond the validator resolver itself. Validation logic is delegated to a sibling library (tavo1987/ec-validador-cedula-ruc ^2.0), so the Laravel layer is a thin adapter — a good separation of concerns, and one we could replicate ourselves if needed.
The fit is narrow but real: this only makes sense for a Laravel application serving the Ecuadorian market where Cédula/RUC capture happens (onboarding, KYC, invoicing, supplier registration). If we run non-PHP services (Node admin, Python data pipeline) that must apply the same rules, this package does not help them — the algorithm gets duplicated and diverges.
Integration feasibility. High. composer require tavo1987/laravel-ec-validator and use the rule strings in FormRequests. Realistic effort is well under a day for a working integration. The interesting work is not installation, it is establishing confidence in correctness and deciding how hard we bind to the package.
Technical risk. The dominant risk here is supply chain and correctness confidence, not code quality:
Error rather than an InvalidArgumentException or a validation failure. In production that becomes an unhandled 500 rather than a validation message, and Error is a class most framework error handlers and our own catch (Exception) blocks will not catch. This is the single most concerning implementation detail and it should be verified and, if confirmed, wrapped or patched.Validator::resolver() is a process-wide override. Any other package using the same pattern is a last-one-wins collision that silently disables these rules. Must be verified against the actual dependency set.^2.0. A 3.0 release is a breaking change we do not control.Key questions to resolve before committing:
Validator::resolver()?My recommendation: treat this as buy-to-learn, then decide. The Ecuadorian validation algorithm is small and well-specified (modulus checks over province code, entity type, and check digit). A one-to-two-day in-house reimplementation with the golden test set is a credible alternative that eliminates a two-deep dependency chain and the Error-throwing behavior entirely. The package is a fast way to get a correct reference implementation and test corpus; it is not obviously the right thing to run in production permanently.
Stack fit. Compatible if we are on Laravel 11 or 12 with PHP 8.2+. If the target application is on Laravel 10 or PHP 8.1, the package is blocked as-is and the choice collapses to fork-and-repin or reimplement. Confirm the platform version before anything else — this is the first gate.
Migration path. Greenfield adoption is trivial. The realistic case is replacing an existing regex:^[0-9]{10}$-style check, and that must not be a hard cutover:
Compatibility and containment. Two containment measures are non-negotiable regardless of which implementation wins:
ecuador:ci and friends appear in FormRequests across the codebase. Introduce a single in-house rule class (e.g. Rules\EcuadorianId) that internally delegates to the package or to our own implementation. This makes a vendor swap, a fork, or a full replacement a one-file change and gives us one place to normalize input and localize messages.Error cannot escape as a 500. Either patch via fork or guard at the rule boundary.Accept the global Validator::resolver() behavior only after confirming no other package competes for it; if there is a conflict, the wrapper approach plus a Laravel-native Rule object may be preferable to the string-rule registration entirely.
Sequencing.
| Step | Activity | Exit criterion |
|---|---|---|
| 1 | Platform check (PHP/Laravel versions, existing validators) | Go / no-go on the package as-is |
| 2 | Spike in a branch + build golden dataset of real (anonymized) IDs | All four rule types behave as expected; edge cases documented |
| 3 | Verify failure modes: bad parameter, malformed input, resolver collision | No path yields a 500 |
| 4 | Build/comparison exercise: ~1–2 days to reimplement against the golden set | Build-vs-buy decision with evidence, not vibes |
| 5 | Ship the in-house wrapper rule | Single integration point in the codebase |
| 6 | Shadow-run, then cut over | Zero unexplained disagreements |
Step 4 is the one most teams skip. Given the size of the domain logic and the supply-chain profile here, it is cheap insurance and it doubles as our contingency plan if the maintainer goes dark.
Maintenance. Ongoing effort is genuinely low — the package is a stable adapter over a stable algorithm — but it is not zero and it is not under our control. Laravel major releases (L13, L14) will require a maintainer release; the current constraint ^11.0|^12.0 guarantees a hard stop at the next major unless someone publishes an update. Plan on an annual review and hold a documented fork-and-repin contingency. Budget roughly a day a year, plus the tail risk of an unplanned fork if a Laravel upgrade lands before the maintainer acts.
Support. Community-only, no SLA, one maintainer, minimal issue history. Internal documentation is the actual support mechanism: record the rule semantics, the RUC sub-type distinctions, the golden test set, and the escalation path (fork → reimplement). Any engineer touching onboarding, KYC, or invoicing must know the wrapper exists and that the dependency is thin.
Scaling. A non-issue. Validation is pure CPU work measured in microseconds with no network, disk, or database access. It is safe in high-volume paths including bulk import — a million-row CSV import will not be meaningfully slower. The only scaling consideration is keeping it out of database query construction; it belongs in request/import validation, never in a query builder callback.
Failure modes. Ranked by expected pain:
Error on a bad rule parameter — a 500 instead of a validation message. Trivially triggered by a typo during a refactor; this is the one to fix before shipping.^2.0 minor of the core library changing behavior under us, or an unmaintained package blocking a framework upgrade.Mitigation across the board: instrument it. Emit a counter per rule and outcome (pass/fail) and alert on rate discontinuities. A sudden shift in ecuador:ruc rejection rate is the earliest and often only signal that a library release, a data-entry change, or a client rollout has broken something.
Ramp-up. Low. One engineer, a few hours to productivity, with the real learning being Ecuadorian domain knowledge (the difference between a natural-person RUC, a public-company RUC, and a private-company RUC, and why they need separate rules) rather than anything about the package API. That domain knowledge is the durable asset — capture it in the wrapper's tests, not in tribal memory.
How can I help you explore Laravel packages today?