Skip to content

Commit 626f419

Browse files
authored
Merge pull request #2147 from cultuurnet/claude-code-prompt
Improve Claude Code prompting
2 parents 1ab6971 + 53609a0 commit 626f419

File tree

9 files changed

+375
-77
lines changed

9 files changed

+375
-77
lines changed

.github/workflows/claude.yml

Lines changed: 5 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,17 @@ name: Claude Code
33
on:
44
issue_comment:
55
types: [created]
6-
pull_request_review_comment:
7-
types: [created]
8-
issues:
9-
types: [opened, assigned]
10-
pull_request_review:
11-
types: [submitted]
126

137
jobs:
148
claude:
15-
if: |
16-
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
17-
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
18-
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
19-
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
9+
if: contains(github.event.comment.body, '@claude')
2010
runs-on: ubuntu-latest
2111
permissions:
2212
contents: write
2313
pull-requests: write
2414
issues: write
2515
id-token: write
26-
actions: read # Required for Claude to read CI results on PRs
16+
actions: read
2717
steps:
2818
- name: Checkout repository
2919
uses: actions/checkout@v5
@@ -35,76 +25,14 @@ jobs:
3525
with:
3626
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
3727

38-
# Enable progress tracking
3928
track_progress: true
4029

41-
# Your custom review instructions
4230
prompt: |
4331
REPO: ${{ github.repository }}
4432
PR NUMBER: ${{ github.event.pull_request.number || github.event.issue.number }}
45-
46-
Review this pull request and provide inline feedback using the GitHub review system. Follow these steps:
47-
48-
1. Start a review: Use `mcp__github__create_pending_pull_request_review` to start a pending review.
49-
2. Get diff information: Use `mcp__github__get_pull_request_diff` to see the code changes and line numbers.
50-
- If the pull request has many changes, paginate the diff using the `page` and `per_page` parameters.
51-
- Example: To get the first 100 lines, call `mcp__github__get_pull_request_diff` with `per_page=100` and `page=1`. For the next 100 lines, use `page=2`, and so on.
52-
- Continue fetching pages until all changes are retrieved.
53-
3. Add inline comments: Use `mcp__github__add_comment_to_pending_review` to provide feedback on specific lines of code snippets.
54-
- **When suggesting code changes, format them as GitHub suggestion blocks so they can be committed directly:**
55-
- For single-line suggestions, use:
56-
```suggestion
57-
suggested code here
58-
```
59-
- For multi-line suggestions, use:
60-
```suggestion:-0+1
61-
suggested code here
62-
```
63-
(Adjust the numbers to match how many lines to remove and add)
64-
- Only provide suggestion blocks when you have a concrete, actionable fix
65-
- Include explanation text before or after the suggestion block
66-
4. Submit for review: Use `mcp__github__submit_pending_pull_request_review` with the event type set to "COMMENT" (not "REQUEST_CHANGES") to publish all comments for non-blocking review.
67-
68-
Focus on the following focus areas:
69-
70-
1. **Code Quality**
71-
- Clean code principles and best practices
72-
- Proper error handling and edge cases
73-
- Code readability and maintainability
74-
- **Provide suggestion blocks for improvements when possible**
75-
76-
2. **Security**
77-
- Check for potential security vulnerabilities
78-
- Validate input sanitization
79-
- Review authentication/authorization logic
80-
- **Suggest secure alternatives with suggestion blocks**
81-
82-
3. **Performance**
83-
- Identify potential performance bottlenecks
84-
- Review database queries for efficiency
85-
- Check for memory leaks or resource issues
86-
- **Offer optimized code via suggestion blocks**
87-
88-
4. **Testing**
89-
- Verify adequate test coverage
90-
- Review test quality and edge cases
91-
- Check for missing test scenarios
92-
93-
5. **Documentation**
94-
- Ensure code is properly documented
95-
- Verify README updates for new features
96-
- Check API documentation accuracy
97-
98-
Provide detailed feedback using inline comments for specific issues.
99-
Use suggestion blocks liberally to make it easy for developers to apply fixes.
100-
Use top-level comments for general observations or praise.
10133
102-
# Tools for comprehensive PR review
34+
Review this pull request following the guidelines in docs/review-guidelines.md.
35+
Provide detailed inline feedback using suggestion blocks where applicable.
36+
10337
claude_args: |
10438
--allowedTools "mcp__github__get_pull_request,mcp__github__create_pending_pull_request_review,mcp__github__add_comment_to_pending_review,mcp__github__submit_pending_pull_request_review,mcp__github__get_pull_request_diff"
105-
106-
# When track_progress is enabled:
107-
# - Creates a tracking comment with progress checkboxes
108-
# - Includes all PR context (comments, attachments, images)
109-
# - Updates progress as the review proceeds
110-
# - Marks as completed when done

CLAUDE.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# UDB3 Backend
2+
3+
UiTdatabank 3 core application - an event-sourced backend built with Broadway.
4+
5+
## Documentation
6+
7+
- [Domain](docs/domain.md) - Core domain concepts (Event, Place, Organizer, Offer)
8+
- [Architecture](docs/architecture.md) - System design, tech stack, message flow
9+
- [Coding Guidelines](docs/coding-guidelines.md) - Code style, conventions, security
10+
- [Commands](docs/commands.md) - All available make commands
11+
- [Review Guidelines](docs/review-guidelines.md) - PR review process and focus areas
12+
13+
## Acceptance Tests
14+
15+
- [General](docs/features/general.md) - Acceptance test overview

docs/architecture.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Architecture
2+
3+
UiTdatabank 3 (UDB3) is an event-sourced backend built with Broadway.
4+
5+
## Tech Stack
6+
7+
- **Language**: PHP 8.1+
8+
- **Architecture**: Event Sourcing with [Broadway](https://github.com/broadway/broadway)
9+
- **Database**: Doctrine DBAL
10+
- **Message Broker**: RabbitMQ (AMQP)
11+
- **Search**: SAPI3 (external Elasticsearch-based service)
12+
- **Cache**: Redis
13+
- **Testing**: PHPUnit (unit), Behat (acceptance)
14+
- **Quality**: PHPStan (static analysis), PHP-CS-Fixer (code style)
15+
- **Environment**: Docker with docker-compose
16+
17+
## Project Structure
18+
19+
```
20+
├── app/ # Service providers and application wiring
21+
├── src/ # Core domain code
22+
├── tests/ # PHPUnit tests (mirrors src/ structure)
23+
├── features/ # Behat acceptance tests
24+
├── docker/ # Docker configuration
25+
├── docs/ # Documentation
26+
│ └── refactor/ # Refactoring plans and progress
27+
└── vendor/ # Dependencies (never modify)
28+
```
29+
30+
## Event Sourcing with Broadway
31+
32+
- **Aggregates**: Domain objects that emit events (in `src/`)
33+
- **Projectors**: Build read models from events
34+
- **Event Bus**: Distributes events to handlers
35+
36+
## Message Flow: Domain Events to Search Indexing
37+
38+
```
39+
1. API Request (e.g., Create Event)
40+
41+
2. Command Handler processes command
42+
43+
3. Domain event created (e.g., EventCreated)
44+
45+
4. EventBus publishes event to subscribers
46+
47+
5. Projectors generate JSON-LD → emit *ProjectedToJSONLD events
48+
49+
6. AMQPPublisher sends message to RabbitMQ
50+
51+
7. External SAPI3 consumes message and indexes in Elasticsearch
52+
```
53+
54+
### AMQP Configuration
55+
56+
- **Exchange**: `udb3.x.domain-events`
57+
- **Routing**: Messages routed to `api`, `cli`, or `related` queues based on context
58+
- **Message Types**:
59+
- `application/vnd.cultuurnet.udb3-events.event-projected-to-jsonld+json`
60+
- `application/vnd.cultuurnet.udb3-events.place-projected-to-jsonld+json`
61+
- `application/vnd.cultuurnet.udb3-events.organizer-projected-to-jsonld+json`
62+
63+
### SAPI3 Integration
64+
65+
SAPI3 is an external search service (Elasticsearch-based) that:
66+
- Consumes messages from RabbitMQ
67+
- Indexes events, places, and organizers
68+
- Provides search endpoints proxied by UDB3
69+
70+
**Configuration** (in `config.php`):
71+
- Base URL: `http://search.uitdatabank.local:9000`
72+
- ES URL: `http://search.uitdatabank.local:9200/`
73+
- API Key: configured per environment
74+
75+
**Search Endpoints** (proxy to SAPI3):
76+
- `/events` - Search events
77+
- `/places` - Search places
78+
- `/organizers` - Search organizers
79+
- `/offers` - Search events and places combined
80+
81+
## Docker Services
82+
83+
| Service | Port | Purpose |
84+
|---------|------|---------|
85+
| PHP | 80 | Application |
86+
| MySQL | 3306 | Database |
87+
| Redis | 6379 | Cache |
88+
| RabbitMQ | 5672, 15672 | Message broker (AMQP, Management UI) |
89+
| Mailpit | 1025, 8025 | Email testing (SMTP, Web UI) |

docs/coding-guidelines.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# Coding Guidelines
2+
3+
## General
4+
5+
- Use `final` classes by default
6+
- Follow PSR-4 autoloading under `CultuurNet\UDB3\` namespace
7+
- Keep classes small and focused (Single Responsibility)
8+
9+
## PHP 8.1 Features
10+
11+
Use **readonly properties** with constructor promotion for immutable class properties.
12+
13+
See `src/Doctrine/DBALDatabaseConnectionChecker.php` for an example.
14+
15+
> **Note**: Do NOT use PHP 8.2 `readonly class` syntax - we're on PHP 8.1.
16+
17+
## Comments & Self-Documenting Code
18+
19+
Avoid comments in favor of self-documenting code:
20+
21+
- **Type hints**: Use typed parameters, typed properties and return types instead of docblock descriptions
22+
- **Method names**: Use descriptive, self-explaining method and function names
23+
- **Variable names**: Choose clear, meaningful variable names that convey purpose
24+
- **Class names**: Use descriptive class names that explain their responsibility
25+
- **File names**: Mirror class names for easy discoverability
26+
27+
Comments are acceptable when explaining **why** something is done (not **what**), such as workarounds for external limitations or non-obvious business rules.
28+
29+
## Naming
30+
31+
### Interfaces
32+
33+
- Descriptive name without `Interface` suffix (e.g., `DatabaseConnectionChecker`)
34+
- Implementations: Prefix with technology (e.g., `DBALDatabaseConnectionChecker`)
35+
36+
### Exceptions
37+
38+
- Descriptive name without `Exception` suffix
39+
- Name should describe what went wrong (e.g., `DocumentDoesNotExist`, `NewsArticleNotFound`)
40+
41+
## Testing
42+
43+
- Use `@test` annotation style for test methods
44+
- Mock objects use intersection types: `Connection&MockObject`
45+
- Prefer separate test methods over data providers for clarity
46+
- Test file location mirrors source: `src/Foo/Bar.php``tests/Foo/BarTest.php`
47+
48+
## Gotchas & Pitfalls
49+
50+
| Issue | Solution |
51+
|-------|----------|
52+
| Commands fail outside Docker | Use `make` commands, not direct `composer` calls |
53+
| `withConsecutive` deprecation | Avoid in new tests - use separate test methods |
54+
| Uppercase `String` type hint | Legacy code - don't "fix" these |
55+
| Tests fail after changes | Run `make ci` before committing |
56+
57+
## Restrictions
58+
59+
- **Never** modify files in `vendor/`
60+
- **Never** commit `.env` or credentials files
61+
- **Avoid** creating new service providers - extend existing ones in `app/`
62+
- **Avoid** adding dependencies without team discussion
63+
- **Always** run `make ci` before considering work complete
64+
65+
## AI Restrictions
66+
67+
- **Never** create commits - only humans commit code
68+
- **Plan** larger changes but implement step by step, waiting for human review between steps
69+
70+
## Dependency Injection
71+
72+
- Service providers in `app/` wire all dependencies
73+
- Use **constructor injection**, not service locators
74+
- Extract testable logic into separate classes with **interfaces**
75+
76+
See `src/Doctrine/DatabaseConnectionChecker.php` and `src/Doctrine/DBALDatabaseConnectionChecker.php` for an example of interface + implementation pattern.
77+
78+
## Workflow
79+
80+
- **Small commits**: One logical change per commit
81+
- A logical change can span multiple files (e.g., source code + tests, or a refactor touching several related files)
82+
- All changes in the commit should belong together and serve a single purpose
83+
- The goal is to make commits easy to review and understand
84+
- **Small pull requests**: Easier to review, faster to merge
85+
- **Feature flags**: Deploy often, enable features when ready
86+
87+
## Preferences
88+
89+
When working on this codebase, prefer:
90+
91+
- Extracting logic into testable classes with interfaces over inline implementation
92+
- Constructor injection over service locator patterns
93+
- Explicit code over clever abstractions
94+
- Integration with existing patterns over introducing new ones
95+
96+
## Security
97+
98+
### Never Commit
99+
100+
- `.env` files or environment-specific configurations
101+
- API keys, tokens, or credentials
102+
- Private keys or certificates
103+
- Database connection strings with passwords
104+
- Any hardcoded secrets
105+
106+
### Configuration
107+
108+
- Secrets belong in environment variables, not in code
109+
- Use `.env.example` or `.env.dist` for documenting required env vars (without actual values)
110+
- Configuration files with secrets should be in `.gitignore`
111+
112+
### Secure Coding
113+
114+
- No hardcoded credentials or secrets in code
115+
- No sensitive data in log statements
116+
- Validate input on user-provided data
117+
- SQL queries use parameterized statements (handled by Doctrine DBAL)
118+
- No sensitive data exposure in error messages

docs/commands.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Commands
2+
3+
> **Important**: Always use `make` commands, not direct `composer` or `vendor/bin` calls. The project runs in Docker.
4+
5+
## Environment Management
6+
7+
```bash
8+
make up # Start containers
9+
make down # Stop containers
10+
make bash # Shell into PHP container
11+
make install # Install composer dependencies
12+
make migrate # Run database migrations
13+
make init # Install + migrate (fresh setup)
14+
```
15+
16+
## Quality Assurance
17+
18+
```bash
19+
make ci # Run ALL checks (PHPStan + tests + code style)
20+
make stan # PHPStan static analysis only
21+
make test # PHPUnit tests only
22+
make cs # Code style check (dry-run)
23+
make cs-fix # Auto-fix code style issues
24+
```
25+
26+
## Unit Testing
27+
28+
```bash
29+
make test # All unit tests
30+
make test-filter filter=EventBusForwarding # Tests matching filter
31+
make test-group group=integration # Tests in specific group
32+
```
33+
34+
## Acceptance Testing (Behat)
35+
36+
```bash
37+
make feature # All feature tests
38+
make feature-tag tag=@events # Feature tests by tag
39+
make feature-tag tag=@sapi3 # SAPI3 search integration tests
40+
make feature-filter path=features/search/auth.feature # All scenarios in a file
41+
make feature-filter path=features/search/auth.feature:25 # Single scenario by line number
42+
```

docs/domain.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Domain Concepts
2+
3+
## Resources
4+
5+
UDB3 manages three main resources:
6+
7+
| Resource | Description |
8+
|----------|-------------|
9+
| **Event** | An activity happening at a specific time and place |
10+
| **Place** | A location where events can happen |
11+
| **Organizer** | The entity organizing events |
12+
13+
## Offers
14+
15+
Event and Place are collectively referred to as **Offer**. This terminology is used throughout the codebase and APIs.

0 commit comments

Comments
 (0)