-
Notifications
You must be signed in to change notification settings - Fork 1
Rewrite CLAUDE.md with architecture docs #59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -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%. | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a discrepancy between the documented mutation testing target and the actual configuration. This file states the target MSI is 88%, while
Suggested change
|
||||||
|
|
||||||
| ## CI | ||||||
|
|
||||||
| GitHub Actions runs the test matrix against PHP 8.3, 8.4, and 8.5 with vulnerability scanning (osv-scanner + Enlightn). | ||||||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The description "Stricter trim" for the
trimmethod is misleading. The implementation inStringManipulation.phpis a simple wrapper around PHP's nativetrim()function and does not provide any additional strictness. To ensure the documentation is accurate, I recommend updating the purpose to reflect its actual behavior.