From 989f439655931ed37cdb6222ab05b05f89537f21 Mon Sep 17 00:00:00 2001 From: Dave Earley Date: Mon, 6 Apr 2026 21:58:36 +0100 Subject: [PATCH] Add AI development guidelines, CLAUDE.md, and improve contribution docs - Add CLAUDE.md with project conventions, architecture flow, and dev guidelines - Add translations skill (.claude/skills/translations/SKILL.md) - Add AGENTS.md and .cursorrules pointing to CLAUDE.md - Add .github/copilot-instructions.md pointing to CLAUDE.md - Update PR template with structured sections and closure warning - Update CONTRIBUTING.md with AI bot requirements and prior-discussion policy - Remove CLAUDE.md from .gitignore Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/skills/translations/SKILL.md | 64 +++++++++++++ .cursorrules | 1 + .github/copilot-instructions.md | 1 + .github/pull_request_template.md | 19 ++-- .gitignore | 1 - AGENTS.md | 1 + CLAUDE.md | 130 +++++++++++++++++++++++++++ CONTRIBUTING.md | 10 +++ 8 files changed, 219 insertions(+), 8 deletions(-) create mode 100644 .claude/skills/translations/SKILL.md create mode 100644 .cursorrules create mode 100644 .github/copilot-instructions.md create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/.claude/skills/translations/SKILL.md b/.claude/skills/translations/SKILL.md new file mode 100644 index 0000000000..532b1c1b10 --- /dev/null +++ b/.claude/skills/translations/SKILL.md @@ -0,0 +1,64 @@ +--- +name: translations +description: Frontend translation workflow using Lingui - extracting, adding, and compiling translations for all supported languages +--- + +# Frontend Translation Workflow (Lingui) + +IMPORTANT: Always update translations as you develop features. When adding new translatable strings, immediately add translations for all supported languages. + +## Core Commands + +```bash +cd frontend + +# Extract translatable strings (use --clean for accurate counts) +yarn messages:extract --clean + +# Compile translations for production +yarn messages:compile + +# Check for untranslated strings +cd scripts && ./list_untranslated_strings.sh +``` + +## Process + +1. **Extract**: `yarn messages:extract --clean` +2. **Check**: Look at the output table for missing translation counts +3. **Add translations**: Update the `.po` files for each language +4. **Verify**: Run extract again to confirm 0 missing +5. **Compile**: `yarn messages:compile` + +## Adding Translations + +Add entries to each locale's `.po` file in `frontend/src/locales/`: + +```po +#: src/path/to/component.tsx:123 +msgid "Your English String" +msgstr "Translated String" +``` + +## Supported Languages + +| Code | Language | +|------|----------| +| en | English (source - no translation needed) | +| de | Deutsch | +| es | Espanol | +| fr | Francais | +| pt | Portugues | +| pt-br | Portugues do Brasil | +| it | Italiano | +| nl | Nederlands | +| zh-cn | Simplified Chinese | +| zh-hk | Traditional Chinese (HK) | +| vi | Tieng Viet | +| ru | Russian (currently untranslated) | + +## Troubleshooting + +- **Counts seem wrong**: Use `--clean` flag to remove obsolete entries +- **Translation not appearing**: Run `yarn messages:compile` after adding +- **Syntax errors**: Check for proper escaping of quotes in `.po` files diff --git a/.cursorrules b/.cursorrules new file mode 100644 index 0000000000..f9c142c9a6 --- /dev/null +++ b/.cursorrules @@ -0,0 +1 @@ +See [CLAUDE.md](./CLAUDE.md) for project conventions and development guidelines. diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000000..cd2ce4facd --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1 @@ +See [CLAUDE.md](../CLAUDE.md) for project conventions and development guidelines. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 8c16b2d628..c3bb20bce4 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,13 +1,18 @@ -Thank you for creating a PR! We appreciate your contribution to Hi.Events. +> â„šī¸ Thank you for your contribution! We really appreciate it. However, please note that PRs that do not follow the [contribution guidelines](https://github.com/HiEventsDev/hi.events/blob/develop/CONTRIBUTING.md) will be closed without review. Non-trivial changes require prior discussion via an issue or discussion thread. PRs with empty or unedited descriptions will also be closed. +> +> Please delete everything above this line, then fill in the sections below. -To make the process as smooth as possible, please ensure you've read the [contributing guidelines](https://github.com/HiEventsDev/hi.events/blob/develop/CONTRIBUTING.md) before proceeding. +--- -Please include a summary of the changes and the issue being fixed or the feature being added. The more detail, the better! +## What changes I've made + +## Why I've made these changes + +## How I've tested these changes ## Checklist -- [ ] I have read the contributing guidelines. -- [ ] My code is of good quality and follows the coding standards of the project. +- [ ] I have read the [contributing guidelines](https://github.com/HiEventsDev/hi.events/blob/develop/CONTRIBUTING.md). +- [ ] My code follows the coding standards of the project. - [ ] I have tested my changes, and they work as expected. - -Thank you for your contribution! 🎉 +- [x] I understand that this PR will be closed if I do not follow the [contributor guidelines](https://github.com/HiEventsDev/hi.events/blob/develop/CONTRIBUTING.md) and if this PR template is left unedited. diff --git a/.gitignore b/.gitignore index 385ebec7a2..eda9758bce 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,6 @@ backend/.env docker/all-in-one/.env docker-compose.override.yml todo.md -CLAUDE.md /prompts/** /prompts diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..f9c142c9a6 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1 @@ +See [CLAUDE.md](./CLAUDE.md) for project conventions and development guidelines. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000000..f283207d7f --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,130 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +Hi.Events is an open-source event management and ticketing platform with a Laravel backend and React frontend, using Domain-Driven Design (DDD). + +## Key Commands + +### Backend (Laravel) + +Commands must be executed in the `backend` docker container: + +```bash +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 --test +``` + +### Frontend (React + Vite) - SSR Only + +```bash +cd 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 validation +``` + +### Docker Development + +```bash +cd docker/development +./start-dev.sh # Unsigned SSL certs +./start-dev.sh --certs=signed # Signed certs with mkcert +``` + +## Development Guidelines + +### Backend + +#### Architecture Flow +- 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 + +#### General Standards +- **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 `HtmlPurifierService` before storing, especially content rendered as HTML + +#### DTOs +- Use Spatie Laravel Data package for all new DTOs +- **ALWAYS** extend `BaseDataObject`, not `BaseDTO` +- **ALWAYS** favor DTOs over arrays when returning multiple values from services + +#### HTTP Actions +- Always extend `BaseAction.php` +- **ALWAYS** use BaseAction response methods: `resourceResponse()`, `jsonResponse()`, `errorResponse()`, `deletedResponse()`, etc. Never use `response()->json()` or `new JsonResponse()` directly +- Always use `isActionAuthorized` for 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 + +#### Exception Handling +- **DON'T** use generic exceptions like `InvalidArgumentException` and `RuntimeException` +- **DO** use custom exceptions (e.g., `EmailTemplateValidationException`, `ResourceConflictException`) +- **DO** catch custom exceptions in actions and convert to `ValidationException::withMessages()` or appropriate error responses + +#### Repository Pattern +- Favour existing repository methods over creating bespoke ones. E.g., use `findFirstWhere(['event_id' => $eventId])` instead of creating `findByEventId` + +#### Database & Migrations +- **DO** use auto-incrementing integer IDs (`$table->id()`), not UUIDs +- Use anonymous class syntax for migrations + +#### Enums +- Status enums go in `backend/app/DomainObjects/Status/` +- Other enums go in `backend/app/DomainObjects/Enums/` + +#### Testing +- **DON'T** use `RefreshDatabase` - use `DatabaseTransactions` instead +- Unit tests extend Laravel's TestCase, not PHPUnit's TestCase +- Use Mockery for mocking + +### Frontend + +#### General Standards +- This is a SSR app - ensure safe usage of `window` and `document` objects +- 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 `t` function or `Trans` component +- **IMMEDIATELY** after adding translatable strings, add translations for all supported languages (use `/translations` skill for the workflow) + +#### Data Fetching +- Use React Query for all API interactions +- Query example: `frontend/src/queries/useGetCapacityAssignment.ts` +- Mutation example: `frontend/src/mutations/useCreateAffiliate.ts` + +#### UI & Styling +- Use Mantine UI components for UI elements +- Prefer SCSS modules over Mantine layout components for layout styling + +#### Error Handling +- **DON'T** use `showNotification` from `@mantine/notifications` +- **DO** use `showSuccess`, `showError` from `frontend/src/utilites/notifications.tsx` +- **DO** use `useFormErrorResponseHandler` from `frontend/src/hooks/useFormErrorResponseHandler.tsx` for validation errors +- **DO** handle errors in parent components, not in reusable components + +## Development Workflows + +### Database Changes (in Backend Container) +1. Create migration: `php artisan make:migration create_XXX_table` +2. Run migration: `php artisan migrate` +3. Regenerate Domain Objects: `php artisan generate-domain-objects` + +### Before Finalizing Changes +1. Frontend: `cd frontend && npx tsc --noEmit` +2. Backend: `docker compose -f docker-compose.dev.yml exec backend php artisan test --testsuite=Unit` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 697d78cdfb..a6ec57137e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,6 +2,8 @@ Thank you for your interest in contributing to Hi.Events! We welcome contributions from the community and are excited to collaborate with you to improve our event management and ticket-selling platform. Before you start, please read these guidelines to ensure a smooth contribution process. +> **IMPORTANT: Open a discussion or issue BEFORE submitting a PR for anything beyond trivial fixes, features, or improvements (typos, broken links, etc.).** PRs submitted without prior discussion will be closed if the PR description is left empty or the template is left unedited. We want to collaborate with you, but we need to align on the approach before code is written. + ## Table of Contents 1. [How Can I Contribute?](#how-can-i-contribute) @@ -143,4 +145,12 @@ This will update the Domain Objects in `backend/app/DomainObjects` based on the By contributing to Hi.Events, you agree that your contributions will be licensed under the [AGPL-3.0 License with additional terms](LICENSE). +## AI / Bot Contributors + +If you are an AI agent, bot, or using AI tools to generate your contribution: + +- **Add 🤖 to the PR title** (e.g., `🤖 Fix typo in README`) +- **Add 🤖 to the end of each commit message** +- All other contribution guidelines above still apply — especially the requirement for prior discussion on non-trivial changes + Thank you for contributing to Hi.Events! If you have any questions, feel free to reach out to us.