This document provides guidelines for AI coding agents working on the ec-validador-cedula-ruc project, a PHP library for validating Ecuadorian identification documents (Cedula and RUC).
- Language: PHP 8.2+
- Purpose: Validate Ecuadorian Cedula and RUC numbers
- Structure: Single main class library with comprehensive test suite
- License: MIT
ec-validador-cedula-ruc/
├── src/
│ └── ValidadorEc.php # Main library class (single file)
├── tests/
│ ├── TestCase.php # Base test class with setUp()
│ ├── CedulaValidationTest.php
│ ├── NaturalPersonRucValidationTest.php
│ ├── PrivateCompanyRucValidationTest.php
│ ├── PublicCompanyRucValidationTest.php
│ ├── StaticMethodsTest.php
│ └── UniversalValidationTest.php
├── composer.json
├── phpunit.xml
└── readme.md
composer install./vendor/bin/phpunit./vendor/bin/phpunit --testdox./vendor/bin/phpunit tests/CedulaValidationTest.php./vendor/bin/phpunit --filter test_valid_cedulas./vendor/bin/phpunit --filter CedulaValidationTest./vendor/bin/phpunit --coverage-textThis is a library - no compilation or build process needed.
Follow existing code style patterns. No PHP-CS-Fixer or PHPStan configuration exists.
- All code and comments must be in English
- Use clear, descriptive names that explain intent
- Target PHP 8.2+ features
- Use
declare(strict_types=1)at the top of every file - Use
final classfor non-extendable classes - Use
matchexpressions where appropriate
<?php
declare(strict_types=1);
namespace Tavo;
use InvalidArgumentException;- One class per
usestatement (no grouped imports) - Import only what you use
- Order: PHP built-in classes first, then external packages
| Element | Convention | Example |
|---|---|---|
| Class | PascalCase | ValidadorEc |
| Public method | camelCase | validateCedula(), getError() |
| Private method | camelCase | performCedulaValidation() |
| Property | camelCase | $documentType, $error |
| Constants | SCREAMING_SNAKE_CASE | TYPE_CEDULA, MODULO_10 |
| Test methods | snake_case with test_ prefix |
test_valid_cedulas() |
- Always use return type declarations
- Always use property type declarations
- Use PHPDoc for complex types (arrays, generics):
/** @var list<int> */ private const COEFFICIENTS = [2, 1, 2, 1, 2, 1, 2, 1, 2];
Organize class members in this order with section headers:
final class ValidadorEc
{
// Constants (public first, then private)
public const TYPE_CEDULA = 'cedula';
private const FOREIGN_RESIDENT_CODE = 30;
// Properties
private string $error = '';
// ==================== Static Methods ====================
public static function validateCedula(string $number): bool { }
// ==================== Instance Methods ====================
public function validate(string $number): bool { }
// ==================== Internal Validation Methods ====================
private function performValidation(): bool { }
// ==================== Helper Methods ====================
private function extractDigits(): array { }
}The library uses a specific pattern: internal methods throw exceptions, public methods catch and store errors.
// Internal methods throw InvalidArgumentException
private function assertValidProvinceCode(int $code): void
{
if (!$isValid) {
throw new InvalidArgumentException('Province code must be between 1 and 24, or 30');
}
}
// Public methods catch exceptions and store error message
public function validateCedula(string $number = ''): bool
{
try {
$this->assertValidInitialFormat($number, 10);
$this->performCedulaValidation($number);
} catch (InvalidArgumentException $e) {
$this->error = $e->getMessage();
return false;
}
return true;
}
// Error accessible via getter
public function getError(): string
{
return $this->error;
}- Test files:
{Feature}Test.php(e.g.,CedulaValidationTest.php) - Extend
Tavo\Tests\TestCase
- Use snake_case with
test_prefix - Be descriptive:
test_invalid_cedula_with_wrong_check_digit()
<?php
declare(strict_types=1);
namespace Tavo\Tests;
final class CedulaValidationTest extends TestCase
{
// ==================== Section Name ====================
public function test_descriptive_name(): void
{
$this->assertFalse($this->validator->validateCedula('1234567890'));
$this->assertEquals('Expected error message', $this->validator->getError());
}
}The TestCase class provides a $this->validator instance via setUp():
protected function setUp(): void
{
$this->validator = new ValidadorEc();
}GitHub Actions runs tests on PHP 8.2, 8.3, and 8.4.
Ensure all tests pass before committing:
./vendor/bin/phpunit --testdox- Add public constant for the type
- Add private validation method
- Add public method that catches exceptions and stores errors
- Add static wrapper method if appropriate
- Add comprehensive tests
- Update the private validation method
- Update or add tests to cover the change
- Run full test suite to check for regressions