From 35ed9a69bd8ab7d87c55b9d68803cc470a5cc908 Mon Sep 17 00:00:00 2001 From: Marjo Wenzel van Lier Date: Fri, 6 Feb 2026 10:22:03 +0100 Subject: [PATCH] docs(claude-md): Rewrite with architecture and API reference - Add Claude Code header and project overview - Consolidate Docker/local commands into single table - Add architecture section explaining trait-as-constants pattern - Add public API quick-reference table - Add static analysis levels section - Remove generic rules duplicated from global config Signed-off-by: Marjo Wenzel van Lier --- CLAUDE.md | 143 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 85 insertions(+), 58 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 9083f9d..73c476d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,58 +1,85 @@ -# StringManipulation Development Guide - -## Critical Development Rules -- **ALWAYS run all tests before committing**: `docker-compose run --rm test-all` -- **NEVER force push or use --force with git commands** -- **NEVER ignore test failures or errors** -- **ALWAYS use conventional commit messages** (feat:, fix:, chore:, etc.) -- **NEVER overwrite or amend existing commit messages** - -## Build & Testing Commands - -### Docker (Recommended - PHP 8.3 with AST extension) -**IMPORTANT**: Always use Docker for testing to ensure consistent environment with PHP 8.3 and AST extension. - -- Run all tests: `docker-compose run --rm test-all` -- Run Pest tests: `docker-compose run --rm tests ./vendor/bin/pest` -- Run single test: `docker-compose run --rm tests ./vendor/bin/pest --filter testName` -- Code style check: `docker-compose run --rm test-code-style` -- Static analysis: - - PHPStan: `docker-compose run --rm test-phpstan` - - Psalm: `docker-compose run --rm test-psalm` - - Phan: `docker-compose run --rm test-phan` -- PHP Mess Detector: `docker-compose run --rm test-phpmd` -- Mutation testing: `docker-compose run --rm test-infection` -- Code refactoring: `docker-compose run --rm test-rector` -- Linting: `docker-compose run --rm test-lint` -- Security check: `docker-compose run --rm test-security` - -### Local (Requires PHP 8.3+ with AST extension) -- Run all tests: `composer tests` -- Run Pest tests: `./vendor/bin/pest` -- Run single test: `./vendor/bin/pest --filter testName` -- Code style check: `composer test:code-style` -- Static analysis: `composer test:phpstan`, `composer test:psalm`, `composer test:phan` -- Linting: `composer test:lint` -- Mess detection: `composer test:phpmd` - -### Code Review -- CodeRabbit review: `coderabbit review --type committed --config .coderabbit.yaml --plain --base main` - - Reviews committed changes against main branch - - Uses project-specific configuration from .coderabbit.yaml - - Plain text output for terminal display - - Note: Can timeout if simout set too low; use 30 minute timeout - -## Code Style Guidelines -- PHP version: >=8.3.0 -- Strict typing required: `declare(strict_types=1);` -- Namespaces: PSR-4 `MarjovanLier\StringManipulation` -- Classes: Final, static methods preferred -- Class constants: Use typed constants (e.g., `private const array FOO = []`) -- Docblocks: Comprehensive for public methods with @param, @return and @example -- Parameter typing: Always explicit, including return types -- Type hints: Use PHP 8 attributes like `#[SensitiveParameter]` where appropriate -- Null handling: Explicit checks, optional parameters default to empty string -- Documentation: 100% method coverage with examples -- Standards: PSR guidelines with Laravel Pint (preset "per") -- Testing: Pest PHP with complete coverage -- PHPMD: Methods must not exceed 100 lines +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +High-performance PHP 8.3+ string manipulation library with zero production dependencies. Single final class (`StringManipulation`) exposing static methods optimised with pre-computed character mappings for O(1) lookups via `strtr()`. + +## Build & Test Commands + +**Always use Docker** to ensure consistent PHP 8.3 + AST extension environment. + +| Task | Docker | Local | +|------|--------|-------| +| Full pipeline | `docker-compose run --rm test-all` | `composer tests` | +| Pest tests | `docker-compose run --rm tests ./vendor/bin/pest` | `./vendor/bin/pest` | +| Single test | `docker-compose run --rm tests ./vendor/bin/pest --filter testName` | `./vendor/bin/pest --filter testName` | +| Code style check | `docker-compose run --rm test-code-style` | `composer test:code-style` | +| Code style fix | `docker-compose run --rm tests ./vendor/bin/pint` | `composer fix:code-style` | +| PHPStan | `docker-compose run --rm test-phpstan` | `composer test:phpstan` | +| Psalm | `docker-compose run --rm test-psalm` | `composer test:psalm` | +| Phan | `docker-compose run --rm test-phan` | `composer test:phan` | +| PHPMD | `docker-compose run --rm test-phpmd` | `composer test:phpmd` | +| Mutation testing | `docker-compose run --rm test-infection` | `composer test:infection` | +| Rector (dry-run) | `docker-compose run --rm test-rector` | `composer test:rector` | +| Linting | `docker-compose run --rm test-lint` | `composer test:lint` | +| Security check | `docker-compose run --rm test-security` | `composer test:vulnerabilities-check` | + +**Run the full pipeline before committing**: `docker-compose run --rm test-all` + +## Architecture + +``` +src/ +├── StringManipulation.php # Single final class, all public static methods +├── AccentNormalization.php # Trait: SEARCH_WORDS_MAPPING + ACCENT_MAPPING constants +└── UnicodeMappings.php # Trait: UTF8_ANSI2 constant +``` + +- **StringManipulation** uses two traits purely as constant containers for pre-computed character mapping arrays +- All methods are static; the class is never instantiated +- Performance comes from `strtr()` with pre-computed array constants (hash table O(1) lookups) and single-pass algorithms +- The traits exist to keep the ~600 lines of mapping data separate from the ~400 lines of logic + +### Public API (7 methods) + +| Method | Purpose | +|--------|---------| +| `searchWords(?string)` | Normalise strings for database search (lowercase, remove accents/special chars) | +| `nameFix(?string)` | Standardise surnames (handles mc/mac prefixes, van/von/de particles, hyphens) | +| `removeAccents(string)` | Strip diacritics preserving case | +| `utf8Ansi(?string)` | Convert UTF-8 to ANSI equivalents | +| `isValidDate(string, string)` | Validate date string against format with logical checks | +| `strReplace(...)` | Optimised replacement (uses `strtr()` for single-char) | +| `trim(string, string)` | Stricter trim | + +## Static Analysis Levels + +All analysers run at their strictest settings: +- **PHPStan**: Level MAX with strict rules, type-perfect, 95%+ type coverage +- **Psalm**: Level 1, taint analysis enabled, 99.95% type coverage +- **Phan**: All strict checking flags enabled, 11 quality plugins +- **PHPMD**: Max 100 lines/method, max 15 public methods/class + +## Code Conventions + +- `declare(strict_types=1)` on every file +- Final classes, static methods +- Typed constants: `private const array NAME = []` +- Comprehensive docblocks with `@param`, `@return`, `@example` on public methods +- `#[\SensitiveParameter]` attribute on parameters containing personal data +- Code style: Laravel Pint with PER (PHP Evolving Rules) preset +- South African English in documentation (organisation, colour, centre) + +## Test Organisation + +Tests live in `tests/Unit/` using Pest v4 syntax (`test('...', fn() => expect(...)->toBe(...))`). + +Tests are split by method and concern: `NameFixTest`, `NameFixEdgeCasesTest`, `NameFixNegativeFlowTest`, `NameFixSpecialCharactersTest`, etc. Bug regressions get dedicated test files (e.g., `ArrayCombineValidationBugFixTest`, `UppercaseAccentMappingBugFixTest`). + +Mutation testing target MSI: 88%. + +## CI + +GitHub Actions runs the test matrix against PHP 8.3, 8.4, and 8.5 with vulnerability scanning (osv-scanner + Enlightn).