Skip to content

feat(domain): introduce typed verification exceptions and replace message-based mapping#10

Open
Maatify wants to merge 6 commits intomainfrom
migrate-domain-exceptions-2990851230226549379
Open

feat(domain): introduce typed verification exceptions and replace message-based mapping#10
Maatify wants to merge 6 commits intomainfrom
migrate-domain-exceptions-2990851230226549379

Conversation

@Maatify
Copy link
Copy Markdown
Owner

@Maatify Maatify commented Mar 19, 2026

This PR fully strictly migrates maatify/verification from legacy RuntimeException and string-based parsing (str_contains) mapping to deterministic Typed Domain Exceptions, preserving all security atomic guarantees and tests.

Changes

  • Added Typed Domain Exceptions inside src/Domain/Exception/.
  • Removed RuntimeException from VerificationCodeGenerator and RedisRateLimiter.
  • Upgraded VerificationCodeRepositoryInterface::markUsed to return a VerificationUseResult object wrapping a VerificationUseStatus enum (replacing the boolean). This securely provides specific failure reasons post-atomic failure.
  • Updated VerificationCodeValidator to map the explicit VerificationUseStatus into the newly created Typed Domain Exceptions.
  • Completely eliminated mapValidationException and mapGenerationException in VerificationService.php, replacing them with explicit catch blocks of Domain exceptions.
  • Updated all test mocks to appropriately throw Domain exceptions instead of string messages.

PR created automatically by Jules for task 2990851230226549379 started by @Maatify

- Added explicit domain exceptions for all verification failure cases
- Replaced RuntimeException usage with deterministic typed exceptions
- Replaced `bool` return on repository with `VerificationUseResult` containing `VerificationUseStatus`
- Updated validator to throw granular Typed Domain Exceptions (e.g., VerificationCodeExpiredException)
- Preserved all atomic guarantees via post-update DB lookups

refactor(application): replace message-based mapping with typed exception handling

- Removed `str_contains` mapping logic from Application Service
- Catch Typed Domain Exceptions explicitly from the Domain Layer
- Updated tests to throw `DomainException` to test mapping correctness

Co-authored-by: Maatify <130119162+Maatify@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

google-labs-jules bot and others added 5 commits March 19, 2026 00:16
…yped Domain Exceptions

- Updated `VerificationServiceTest.php` to use fully qualified `\Maatify\Verification\Domain\Exception\...` classes in `willThrowException` mocks.
- This resolves CI failures caused by the previous tests still throwing generic `RuntimeException`s which the refactored `VerificationService` no longer catches.

Co-authored-by: Maatify <130119162+Maatify@users.noreply.github.com>
…ions

- Refactored `MarkUsedAtomicTest` to assert against `VerificationUseResult` instead of a boolean return.
- Refactored `ValidateAttemptsExhaustedTest`, `ValidateExpiredCodeTest`, `ValidateReplayAttackTest`, and `ValidateWrongCodeTest` to use `$this->expectException` for the newly implemented explicitly typed Domain Exceptions.
- Ensured database state assertions in integration tests run inside `finally` blocks to verify behavior after exceptions are thrown.
- All integration tests now pass correctly against the updated architectural contracts (Option B).

Co-authored-by: Maatify <130119162+Maatify@users.noreply.github.com>
…in exceptions

- Updated `ValidationRaceTest` child process logic to explicitly catch `VerificationDomainException` and exit with code `1` (expected failure), preventing the test from misinterpreting domain validation failures as unhandled errors.
- Fixed `PdoVerificationCodeRepository::markUsed` to properly foresee and return `ATTEMPTS_EXCEEDED` on the exact attempt that hits `max_attempts`, ensuring `ValidateAttemptsExhaustedTest` correctly expects `VerificationAttemptsExceededException` instead of `InvalidVerificationCodeException`.

Co-authored-by: Maatify <130119162+Maatify@users.noreply.github.com>
- Fixed `VerificationService.php` throwing Application exceptions with extraneous parameters (removed `0, $e`).
- Fixed `PdoVerificationCodeRepository.php` accessing offsets on `mixed` by using `is_array` checks and explicit PHPDoc type assertions for database row elements (`status`, `expires_at`, `attempts`, `max_attempts`).
- Ensured `composer analyse` (PHPStan max level) passes with 0 errors.

Co-authored-by: Maatify <130119162+Maatify@users.noreply.github.com>
…omic

- Refactored `PdoVerificationCodeRepository::markUsed()` to use a database transaction with `SELECT ... FOR UPDATE` row-level locking.
- Replaced the post-failure lookup (which introduced TOCTOU race conditions) with a deterministic, fully-isolated state evaluation prior to the `UPDATE`.
- The method now safely returns the precise `VerificationUseStatus` (e.g., EXPIRED, ATTEMPTS_EXCEEDED, INVALID_CODE, SUCCESS) within a single atomic operational boundary without allowing concurrent modifications.

Co-authored-by: Maatify <130119162+Maatify@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant