This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Hi.Events is an open-source event management and ticketing platform with a Laravel backend and React frontend, using Domain-Driven Design (DDD).
Commands must be executed in the backend docker container:
cd docker/development
docker compose -f docker-compose.dev.yml exec backend php artisan migrate
docker compose -f docker-compose.dev.yml exec backend php artisan generate-domain-objects
docker compose -f docker-compose.dev.yml exec backend php artisan test
docker compose -f docker-compose.dev.yml exec backend php artisan test --filter=TestName
docker compose -f docker-compose.dev.yml exec backend php artisan test --testsuite=Unit
docker compose -f docker-compose.dev.yml exec backend ./vendor/bin/pint --testcd frontend
yarn install
yarn dev:ssr # Development server
yarn build # SSR build
yarn messages:extract # Extract translatable strings
yarn messages:compile # Compile translations
npx tsc --noEmit # TypeScript validationcd docker/development
./start-dev.sh # Unsigned SSL certs
./start-dev.sh --certs=signed # Signed certs with mkcert- Request flow: Action → Handler → Domain Service → Repository
- Handlers can use repositories directly when a service would be overkill
- No Eloquent in handlers or services — Eloquent belongs in repositories only
- Favour composition over inheritance
- Keep code clean, but don't be dogmatic about it
- ALWAYS wrap all translatable strings in
__()helper - Domain Objects are auto-generated via
php artisan generate-domain-objects- never edit manually - Always create unit tests for new features in
backend/tests/Unit/ - DON'T add comments unless absolutely necessary
- ALWAYS sanitize user-provided content with
HtmlPurifierServicebefore storing, especially content rendered as HTML
- Use Spatie Laravel Data package for all new DTOs
- ALWAYS extend
BaseDataObject, notBaseDTO - ALWAYS favor DTOs over arrays when returning multiple values from services
- Always extend
BaseAction.php - ALWAYS use BaseAction response methods:
resourceResponse(),jsonResponse(),errorResponse(),deletedResponse(), etc. Never useresponse()->json()ornew JsonResponse()directly - Always use
isActionAuthorizedfor non-public endpoints - DON'T create actions handling multiple entity types with optional parameters - create separate, focused actions instead
- DO use base classes to share common validation and logic
- DON'T use generic exceptions like
InvalidArgumentExceptionandRuntimeException - DO use custom exceptions (e.g.,
EmailTemplateValidationException,ResourceConflictException) - DO catch custom exceptions in actions and convert to
ValidationException::withMessages()or appropriate error responses
- Favour existing repository methods over creating bespoke ones. E.g., use
findFirstWhere(['event_id' => $eventId])instead of creatingfindByEventId
- DO use auto-incrementing integer IDs (
$table->id()), not UUIDs - Use anonymous class syntax for migrations
- Status enums go in
backend/app/DomainObjects/Status/ - Other enums go in
backend/app/DomainObjects/Enums/
- DON'T use
RefreshDatabase- useDatabaseTransactionsinstead - Unit tests extend Laravel's TestCase, not PHPUnit's TestCase
- Use Mockery for mocking
- This is a SSR app - ensure safe usage of
windowanddocumentobjects - Favour using existing components over creating new ones
- DON'T include unnecessary React imports
- ALWAYS add translations when adding new user-facing strings - use Lingui
tfunction orTranscomponent - IMMEDIATELY after adding translatable strings, add translations for all supported languages (use
/translationsskill for the workflow)
- Use React Query for all API interactions
- Query example:
frontend/src/queries/useGetCapacityAssignment.ts - Mutation example:
frontend/src/mutations/useCreateAffiliate.ts
- Use Mantine UI components for UI elements
- Prefer SCSS modules over Mantine layout components for layout styling
- DON'T use
showNotificationfrom@mantine/notifications - DO use
showSuccess,showErrorfromfrontend/src/utilites/notifications.tsx - DO use
useFormErrorResponseHandlerfromfrontend/src/hooks/useFormErrorResponseHandler.tsxfor validation errors - DO handle errors in parent components, not in reusable components
- Create migration:
php artisan make:migration create_XXX_table - Run migration:
php artisan migrate - Regenerate Domain Objects:
php artisan generate-domain-objects
- Frontend:
cd frontend && npx tsc --noEmit - Backend:
docker compose -f docker-compose.dev.yml exec backend php artisan test --testsuite=Unit