This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Verbs is a Laravel package that provides event sourcing capabilities. It focuses on developer experience, following Laravel conventions, and minimizing boilerplate.
- Never use
privateorreadonlykeywords - Never use strict types
- Values are
snake_case - Anything callable is
camelCase(even if it's a variable) - Paths are
kebab-case(URLs, files, etc) - Only apply docblocks where they provide useful IDE/static analysis value
The project uses Pest PHP for testing. Key testing patterns:
// Use Verbs::fake() to prevent database writes during tests
Verbs::fake();
// Use Verbs::commitImmediately() for integration tests
Verbs::commitImmediately();
// Create test states using factories
CustomerState::factory()->id($id)->create();-
Events: Immutable records of what happened in the system
- Base class:
src/Event.php— events extendThunk\Verbs\Event - Can implement
boot(),authorize(),validate(),apply(), andhandle()methods
- Base class:
-
States: Aggregate event data over time
- Base classes:
src/State.phpandsrc/SingletonState.php— states extendThunk\Verbs\State - Use
#[StateId]attribute to specify which event property contains the state ID
- Base classes:
-
Storage: Three-table structure
verb_events: All events with metadataverb_snapshots: State snapshots for performanceverb_state_events: Event-to-state mappings
src/: Main package source codeAttributes/: PHP 8 attributes for configurationCommands/: Artisan commandsContracts/: InterfacesEvents/: Framework-dispatched events (e.g.VerbsStateInitialized)Facades/: Laravel facadesLifecycle/: Broker, dispatcher, queue, state manager, and the default event/snapshot storesModels/: Eloquent models for storageSupport/: Utilities and helpers
tests/: Pest tests organized by featureexamples/: Complete example implementations (Bank, Cart, etc.)
- Event Lifecycle: boot -> authorize → validate → apply → handle
- Attribute Usage:
#[StateId],#[AppliesToState],#[AppliesToChildState] - Serialization: Custom normalizers in
src/Support/Normalization/ - Replay Safety: Use
#[Once]annotations andVerbs::unlessReplaying()for side effects
- Follow Laravel package conventions
- Use Pest for all new tests
- Run
composer formatbefore committing - Ensure compatibility with PHP 8.1+ and Laravel 10.x, 11.x, 12.x
- Test against SQLite, MySQL, and PostgreSQL when modifying storage logic