|
| 1 | +# AGENTS.md - AI Coding Agent Guidelines |
| 2 | + |
| 3 | +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). |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +- **Language**: PHP 8.2+ |
| 8 | +- **Purpose**: Validate Ecuadorian Cedula and RUC numbers |
| 9 | +- **Structure**: Single main class library with comprehensive test suite |
| 10 | +- **License**: MIT |
| 11 | + |
| 12 | +## Project Structure |
| 13 | + |
| 14 | +``` |
| 15 | +ec-validador-cedula-ruc/ |
| 16 | +├── src/ |
| 17 | +│ └── ValidadorEc.php # Main library class (single file) |
| 18 | +├── tests/ |
| 19 | +│ ├── TestCase.php # Base test class with setUp() |
| 20 | +│ ├── CedulaValidationTest.php |
| 21 | +│ ├── NaturalPersonRucValidationTest.php |
| 22 | +│ ├── PrivateCompanyRucValidationTest.php |
| 23 | +│ ├── PublicCompanyRucValidationTest.php |
| 24 | +│ ├── StaticMethodsTest.php |
| 25 | +│ └── UniversalValidationTest.php |
| 26 | +├── composer.json |
| 27 | +├── phpunit.xml |
| 28 | +└── readme.md |
| 29 | +``` |
| 30 | + |
| 31 | +--- |
| 32 | + |
| 33 | +## Build / Lint / Test Commands |
| 34 | + |
| 35 | +### Install Dependencies |
| 36 | +```bash |
| 37 | +composer install |
| 38 | +``` |
| 39 | + |
| 40 | +### Run All Tests |
| 41 | +```bash |
| 42 | +./vendor/bin/phpunit |
| 43 | +``` |
| 44 | + |
| 45 | +### Run Tests with Detailed Output |
| 46 | +```bash |
| 47 | +./vendor/bin/phpunit --testdox |
| 48 | +``` |
| 49 | + |
| 50 | +### Run a Single Test File |
| 51 | +```bash |
| 52 | +./vendor/bin/phpunit tests/CedulaValidationTest.php |
| 53 | +``` |
| 54 | + |
| 55 | +### Run a Single Test Method |
| 56 | +```bash |
| 57 | +./vendor/bin/phpunit --filter test_valid_cedulas |
| 58 | +``` |
| 59 | + |
| 60 | +### Run Tests for a Specific Class |
| 61 | +```bash |
| 62 | +./vendor/bin/phpunit --filter CedulaValidationTest |
| 63 | +``` |
| 64 | + |
| 65 | +### Run Tests with Coverage |
| 66 | +```bash |
| 67 | +./vendor/bin/phpunit --coverage-text |
| 68 | +``` |
| 69 | + |
| 70 | +### No Build Step Required |
| 71 | +This is a library - no compilation or build process needed. |
| 72 | + |
| 73 | +### No Linter Configured |
| 74 | +Follow existing code style patterns. No PHP-CS-Fixer or PHPStan configuration exists. |
| 75 | + |
| 76 | +--- |
| 77 | + |
| 78 | +## Code Style Guidelines |
| 79 | + |
| 80 | +### Language |
| 81 | +- **All code and comments must be in English** |
| 82 | +- Use clear, descriptive names that explain intent |
| 83 | + |
| 84 | +### PHP Version Features |
| 85 | +- Target PHP 8.2+ features |
| 86 | +- Use `declare(strict_types=1)` at the top of every file |
| 87 | +- Use `final class` for non-extendable classes |
| 88 | +- Use `match` expressions where appropriate |
| 89 | + |
| 90 | +### File Header Pattern |
| 91 | +```php |
| 92 | +<?php |
| 93 | + |
| 94 | +declare(strict_types=1); |
| 95 | + |
| 96 | +namespace Tavo; |
| 97 | + |
| 98 | +use InvalidArgumentException; |
| 99 | +``` |
| 100 | + |
| 101 | +### Imports |
| 102 | +- One class per `use` statement (no grouped imports) |
| 103 | +- Import only what you use |
| 104 | +- Order: PHP built-in classes first, then external packages |
| 105 | + |
| 106 | +### Naming Conventions |
| 107 | + |
| 108 | +| Element | Convention | Example | |
| 109 | +|---------|------------|---------| |
| 110 | +| Class | PascalCase | `ValidadorEc` | |
| 111 | +| Public method | camelCase | `validateCedula()`, `getError()` | |
| 112 | +| Private method | camelCase | `performCedulaValidation()` | |
| 113 | +| Property | camelCase | `$documentType`, `$error` | |
| 114 | +| Constants | SCREAMING_SNAKE_CASE | `TYPE_CEDULA`, `MODULO_10` | |
| 115 | +| Test methods | snake_case with `test_` prefix | `test_valid_cedulas()` | |
| 116 | + |
| 117 | +### Type Declarations |
| 118 | +- Always use return type declarations |
| 119 | +- Always use property type declarations |
| 120 | +- Use PHPDoc for complex types (arrays, generics): |
| 121 | + ```php |
| 122 | + /** @var list<int> */ |
| 123 | + private const COEFFICIENTS = [2, 1, 2, 1, 2, 1, 2, 1, 2]; |
| 124 | + ``` |
| 125 | + |
| 126 | +### Class Organization |
| 127 | +Organize class members in this order with section headers: |
| 128 | + |
| 129 | +```php |
| 130 | +final class ValidadorEc |
| 131 | +{ |
| 132 | + // Constants (public first, then private) |
| 133 | + public const TYPE_CEDULA = 'cedula'; |
| 134 | + private const FOREIGN_RESIDENT_CODE = 30; |
| 135 | + |
| 136 | + // Properties |
| 137 | + private string $error = ''; |
| 138 | + |
| 139 | + // ==================== Static Methods ==================== |
| 140 | + public static function validateCedula(string $number): bool { } |
| 141 | + |
| 142 | + // ==================== Instance Methods ==================== |
| 143 | + public function validate(string $number): bool { } |
| 144 | + |
| 145 | + // ==================== Internal Validation Methods ==================== |
| 146 | + private function performValidation(): bool { } |
| 147 | + |
| 148 | + // ==================== Helper Methods ==================== |
| 149 | + private function extractDigits(): array { } |
| 150 | +} |
| 151 | +``` |
| 152 | + |
| 153 | +### Error Handling Pattern |
| 154 | +The library uses a specific pattern: internal methods throw exceptions, public methods catch and store errors. |
| 155 | + |
| 156 | +```php |
| 157 | +// Internal methods throw InvalidArgumentException |
| 158 | +private function assertValidProvinceCode(int $code): void |
| 159 | +{ |
| 160 | + if (!$isValid) { |
| 161 | + throw new InvalidArgumentException('Province code must be between 1 and 24, or 30'); |
| 162 | + } |
| 163 | +} |
| 164 | + |
| 165 | +// Public methods catch exceptions and store error message |
| 166 | +public function validateCedula(string $number = ''): bool |
| 167 | +{ |
| 168 | + try { |
| 169 | + $this->assertValidInitialFormat($number, 10); |
| 170 | + $this->performCedulaValidation($number); |
| 171 | + } catch (InvalidArgumentException $e) { |
| 172 | + $this->error = $e->getMessage(); |
| 173 | + return false; |
| 174 | + } |
| 175 | + return true; |
| 176 | +} |
| 177 | + |
| 178 | +// Error accessible via getter |
| 179 | +public function getError(): string |
| 180 | +{ |
| 181 | + return $this->error; |
| 182 | +} |
| 183 | +``` |
| 184 | + |
| 185 | +--- |
| 186 | + |
| 187 | +## Testing Guidelines |
| 188 | + |
| 189 | +### Test File Naming |
| 190 | +- Test files: `{Feature}Test.php` (e.g., `CedulaValidationTest.php`) |
| 191 | +- Extend `Tavo\Tests\TestCase` |
| 192 | + |
| 193 | +### Test Method Naming |
| 194 | +- Use snake_case with `test_` prefix |
| 195 | +- Be descriptive: `test_invalid_cedula_with_wrong_check_digit()` |
| 196 | + |
| 197 | +### Test Structure |
| 198 | +```php |
| 199 | +<?php |
| 200 | + |
| 201 | +declare(strict_types=1); |
| 202 | + |
| 203 | +namespace Tavo\Tests; |
| 204 | + |
| 205 | +final class CedulaValidationTest extends TestCase |
| 206 | +{ |
| 207 | + // ==================== Section Name ==================== |
| 208 | + |
| 209 | + public function test_descriptive_name(): void |
| 210 | + { |
| 211 | + $this->assertFalse($this->validator->validateCedula('1234567890')); |
| 212 | + $this->assertEquals('Expected error message', $this->validator->getError()); |
| 213 | + } |
| 214 | +} |
| 215 | +``` |
| 216 | + |
| 217 | +### Base TestCase |
| 218 | +The `TestCase` class provides a `$this->validator` instance via `setUp()`: |
| 219 | +```php |
| 220 | +protected function setUp(): void |
| 221 | +{ |
| 222 | + $this->validator = new ValidadorEc(); |
| 223 | +} |
| 224 | +``` |
| 225 | + |
| 226 | +--- |
| 227 | + |
| 228 | +## CI/CD |
| 229 | + |
| 230 | +GitHub Actions runs tests on PHP 8.2, 8.3, and 8.4. |
| 231 | + |
| 232 | +Ensure all tests pass before committing: |
| 233 | +```bash |
| 234 | +./vendor/bin/phpunit --testdox |
| 235 | +``` |
| 236 | + |
| 237 | +--- |
| 238 | + |
| 239 | +## Common Patterns |
| 240 | + |
| 241 | +### Adding a New Validation Type |
| 242 | +1. Add public constant for the type |
| 243 | +2. Add private validation method |
| 244 | +3. Add public method that catches exceptions and stores errors |
| 245 | +4. Add static wrapper method if appropriate |
| 246 | +5. Add comprehensive tests |
| 247 | + |
| 248 | +### Modifying Validation Logic |
| 249 | +1. Update the private validation method |
| 250 | +2. Update or add tests to cover the change |
| 251 | +3. Run full test suite to check for regressions |
0 commit comments