From bf0c77098978c450d8570b38fb480fbb8d6a0628 Mon Sep 17 00:00:00 2001 From: eddalmond1 <102675624+eddalmond1@users.noreply.github.com> Date: Wed, 4 Mar 2026 10:43:42 +0000 Subject: [PATCH 1/4] Create *.instructions.md --- .github/instructions/*.instructions.md | 409 +++++++++++++++++++++++++ 1 file changed, 409 insertions(+) create mode 100644 .github/instructions/*.instructions.md diff --git a/.github/instructions/*.instructions.md b/.github/instructions/*.instructions.md new file mode 100644 index 000000000..303eabcbb --- /dev/null +++ b/.github/instructions/*.instructions.md @@ -0,0 +1,409 @@ +--- +description: 'Generic code review instructions that can be customized for any project using GitHub Copilot' +applyTo: '**' +excludeAgent: ["coding-agent"] + +--- + +# Generic Code Review Instructions + +Comprehensive code review guidelines for GitHub Copilot that can be adapted to any project. These instructions follow best practices from prompt engineering and provide a structured approach to code quality, security, testing, and architecture review. + +## Review Language + +When performing a code review, respond in **English** (or specify your preferred language). + +> **Customization Tip**: Change to your preferred language by replacing "English" with "Portuguese (Brazilian)", "Spanish", "French", etc. + +## Review Priorities + +When performing a code review, prioritize issues in the following order: + +### 🔴 CRITICAL (Block merge) + +- **Security**: Vulnerabilities, exposed secrets, authentication/authorization issues +- **Correctness**: Logic errors, data corruption risks, race conditions +- **Breaking Changes**: API contract changes without versioning +- **Data Loss**: Risk of data loss or corruption + +### 🟡 IMPORTANT (Requires discussion) + +- **Code Quality**: Severe violations of SOLID principles, excessive duplication +- **Test Coverage**: Missing tests for critical paths or new functionality +- **Performance**: Obvious performance bottlenecks (N+1 queries, memory leaks) +- **Architecture**: Significant deviations from established patterns + +### 🟢 SUGGESTION (Non-blocking improvements) + +- **Readability**: Poor naming, complex logic that could be simplified +- **Optimization**: Performance improvements without functional impact +- **Best Practices**: Minor deviations from conventions +- **Documentation**: Missing or incomplete comments/documentation + +## General Review Principles + +When performing a code review, follow these principles: + +1. **Be specific**: Reference exact lines, files, and provide concrete examples +2. **Provide context**: Explain WHY something is an issue and the potential impact +3. **Suggest solutions**: Show corrected code when applicable, not just what's wrong +4. **Be constructive**: Focus on improving the code, not criticizing the author +5. **Recognize good practices**: Acknowledge well-written code and smart solutions +6. **Be pragmatic**: Not every suggestion needs immediate implementation +7. **Group related comments**: Avoid multiple comments about the same topic + +## Code Quality Standards + +When performing a code review, check for: + +### Clean Code + +- Descriptive and meaningful names for variables, functions, and classes +- Single Responsibility Principle: each function/class does one thing well +- DRY (Don't Repeat Yourself): no code duplication +- Functions should be small and focused (ideally < 20-30 lines) +- Avoid deeply nested code (max 3-4 levels) +- Avoid magic numbers and strings (use constants) +- Code should be self-documenting; comments only when necessary + +### Examples + +```javascript +// ❌ BAD: Poor naming and magic numbers +function calc(x, y) { + if (x > 100) return y * 0.15; + return y * 0.10; +} + +// ✅ GOOD: Clear naming and constants +const PREMIUM_THRESHOLD = 100; +const PREMIUM_DISCOUNT_RATE = 0.15; +const STANDARD_DISCOUNT_RATE = 0.10; + +function calculateDiscount(orderTotal, itemPrice) { + const isPremiumOrder = orderTotal > PREMIUM_THRESHOLD; + const discountRate = isPremiumOrder ? PREMIUM_DISCOUNT_RATE : STANDARD_DISCOUNT_RATE; + return itemPrice * discountRate; +} +``` + +### Error Handling + +- Proper error handling at appropriate levels +- Meaningful error messages +- No silent failures or ignored exceptions +- Fail fast: validate inputs early +- Use appropriate error types/exceptions + +### Examples + +```python +# ❌ BAD: Silent failure and generic error +def process_user(user_id): + try: + user = db.get(user_id) + user.process() + except: + pass + +# ✅ GOOD: Explicit error handling +def process_user(user_id): + if not user_id or user_id <= 0: + raise ValueError(f"Invalid user_id: {user_id}") + + try: + user = db.get(user_id) + except UserNotFoundError: + raise UserNotFoundError(f"User {user_id} not found in database") + except DatabaseError as e: + raise ProcessingError(f"Failed to retrieve user {user_id}: {e}") + + return user.process() +``` + +## Security Review + +When performing a code review, check for security issues: + +- **Sensitive Data**: No passwords, API keys, tokens, or PII in code or logs +- **Input Validation**: All user inputs are validated and sanitized +- **SQL Injection**: Use parameterized queries, never string concatenation +- **Authentication**: Proper authentication checks before accessing resources +- **Authorization**: Verify user has permission to perform action +- **Cryptography**: Use established libraries, never roll your own crypto +- **Dependency Security**: Check for known vulnerabilities in dependencies + +### Examples + +```javascript +// ❌ BAD: Exposed secret in code +const API_KEY = "sk_live_abc123xyz789"; + +// ✅ GOOD: Use environment variables +const API_KEY = process.env.API_KEY; +``` + +## Testing Standards + +When performing a code review, verify test quality: + +- **Coverage**: Critical paths and new functionality must have tests +- **Test Names**: Descriptive names that explain what is being tested +- **Test Structure**: Clear Arrange-Act-Assert or Given-When-Then pattern +- **Independence**: Tests should not depend on each other or external state +- **Assertions**: Use specific assertions using HamCrest, avoid generic assertTrue/assertFalse +- **Edge Cases**: Test boundary conditions, null values, empty collections +- **Mock Appropriately**: Mock external dependencies, not domain logic + +### Examples + +```typescript +// ❌ BAD: Vague name and assertion +test('test1', () => { + const result = calc(5, 10); + expect(result).toBeTruthy(); +}); + +// ✅ GOOD: Descriptive name and specific assertion +test('should calculate 10% discount for orders under $100', () => { + const orderTotal = 50; + const itemPrice = 20; + + const discount = calculateDiscount(orderTotal, itemPrice); + + expect(discount).toBe(2.00); +}); +``` + +## Performance Considerations + +When performing a code review, check for performance issues: + +- **Database Queries**: Avoid N+1 queries, use proper indexing +- **Algorithms**: Appropriate time/space complexity for the use case +- **Caching**: Utilize caching for expensive or repeated operations +- **Resource Management**: Proper cleanup of connections, files, streams +- **Lazy Loading**: Load data only when needed + +### Examples + +```python +# ❌ BAD: N+1 query problem +users = User.query.all() +for user in users: + orders = Order.query.filter_by(user_id=user.id).all() # N+1! + +# ✅ GOOD: Use JOIN or eager loading +users = User.query.options(joinedload(User.orders)).all() +for user in users: + orders = user.orders +``` + +## Architecture and Design + +When performing a code review, verify architectural principles: + +- **Separation of Concerns**: Clear boundaries between layers/modules +- **Dependency Direction**: High-level modules don't depend on low-level details +- **Interface Segregation**: Prefer small, focused interfaces +- **Loose Coupling**: Components should be independently testable +- **High Cohesion**: Related functionality grouped together +- **Consistent Patterns**: Follow established patterns in the codebase + +## Documentation Standards + +When performing a code review, check documentation: + +- **Doc String Documentation**: Code must be documented (purpose, parameters, returns) +- **Complex Logic**: Non-obvious logic should have explanatory comments +- **README Updates**: Update README when adding features or changing setup +- **Breaking Changes**: Document any breaking changes clearly +- **Examples**: Provide usage examples for complex features + +## Comment Format Template + +When performing a code review, use this format for comments: + +```markdown +**[PRIORITY] Category: Brief title** + +Detailed description of the issue or suggestion. + +**Why this matters:** +Explanation of the impact or reason for the suggestion. + +**Suggested fix:** +[code example if applicable] + +**Reference:** [link to relevant documentation or standard] +``` + +### Example Comments + +#### Critical Issue + +````markdown +**🔴 CRITICAL - Security: SQL Injection Vulnerability** + +The query on line 45 concatenates user input directly into the SQL string, +creating a SQL injection vulnerability. + +**Why this matters:** +An attacker could manipulate the email parameter to execute arbitrary SQL commands, +potentially exposing or deleting all database data. + +**Suggested fix:** +```sql +-- Instead of: +query = "SELECT * FROM users WHERE email = '" + email + "'" + +-- Use: +PreparedStatement stmt = conn.prepareStatement( + "SELECT * FROM users WHERE email = ?" +); +stmt.setString(1, email); +``` + +**Reference:** OWASP SQL Injection Prevention Cheat Sheet +```` + +#### Important Issue + +````markdown +**🟡 IMPORTANT - Testing: Missing test coverage for critical path** + +The `processPayment()` function handles financial transactions but has no tests +for the refund scenario. + +**Why this matters:** +Refunds involve money movement and should be thoroughly tested to prevent +financial errors or data inconsistencies. + +**Suggested fix:** +Add test case: +```javascript +test('should process full refund when order is cancelled', () => { + const order = createOrder({ total: 100, status: 'cancelled' }); + + const result = processPayment(order, { type: 'refund' }); + + expect(result.refundAmount).toBe(100); + expect(result.status).toBe('refunded'); +}); +``` +```` + +#### Suggestion + +````markdown +**🟢 SUGGESTION - Readability: Simplify nested conditionals** + +The nested if statements on lines 30-40 make the logic hard to follow. + +**Why this matters:** +Simpler code is easier to maintain, debug, and test. + +**Suggested fix:** +```javascript +// Instead of nested ifs: +if (user) { + if (user.isActive) { + if (user.hasPermission('write')) { + // do something + } + } +} + +// Consider guard clauses: +if (!user || !user.isActive || !user.hasPermission('write')) { + return; +} +// do something +``` +```` + +## Review Checklist + +When performing a code review, systematically verify: + +### Code Quality + +- [ ] Code follows consistent style and conventions +- [ ] Names are descriptive and follow naming conventions +- [ ] Functions/methods are small and focused +- [ ] No code duplication +- [ ] Complex logic is broken into simpler parts +- [ ] Error handling is appropriate +- [ ] No commented-out code or TODO without tickets + +### Security + +- [ ] No sensitive data in code or logs + +### Testing + +- [ ] New code has appropriate test coverage +- [ ] Tests are well-named and focused +- [ ] Tests cover edge cases and error scenarios +- [ ] Tests are independent and deterministic +- [ ] No tests that always pass or are commented out + +### Performance + +- [ ] No obvious performance issues (N+1, memory leaks) +- [ ] Appropriate use of caching +- [ ] Efficient algorithms and data structures +- [ ] Proper resource cleanup + +### Architecture + +- [ ] Follows established patterns and conventions +- [ ] Proper separation of concerns +- [ ] No architectural violations +- [ ] Dependencies flow in correct direction + +### Documentation + +- [ ] Complex logic has explanatory comments +- [ ] README is updated if needed +- [ ] Breaking changes are documented + +## Project-Specific Customizations + +To customize this template for your project, add sections for: + +1. **Language/Framework specific checks** + - Check that wireup has been used for dependency injection, where appropriate +2. **Build and deployment** + - When performing a code review, verify CI/CD pipeline configuration is correct + - When performing a code review, check terraform changes are safe and syntactically correct + +## Additional Resources + +For more information on effective code reviews and GitHub Copilot customization: + +- [GitHub Copilot Prompt Engineering](https://docs.github.com/en/copilot/concepts/prompting/prompt-engineering) +- [GitHub Copilot Custom Instructions](https://code.visualstudio.com/docs/copilot/customization/custom-instructions) +- [Awesome GitHub Copilot Repository](https://github.com/github/awesome-copilot) +- [GitHub Code Review Guidelines](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests) +- [Google Engineering Practices - Code Review](https://google.github.io/eng-practices/review/) +- [OWASP Security Guidelines](https://owasp.org/) + +## Prompt Engineering Tips + +When performing a code review, apply these prompt engineering principles from the [GitHub Copilot documentation](https://docs.github.com/en/copilot/concepts/prompting/prompt-engineering): + +1. **Start General, Then Get Specific**: Begin with high-level architecture review, then drill into implementation details +2. **Give Examples**: Reference similar patterns in the codebase when suggesting changes +3. **Break Complex Tasks**: Review large PRs in logical chunks (security → tests → logic → style) +4. **Avoid Ambiguity**: Be specific about which file, line, and issue you're addressing +5. **Indicate Relevant Code**: Reference related code that might be affected by changes +6. **Experiment and Iterate**: If initial review misses something, review again with focused questions + +## Project Context + +This is a generic template. Customize this section with your project-specific information: + +- **Tech Stack**: Python, Terraform +- **Build Tool**: Poetry, Docker (for Lambda), Terraform +- **Testing**: pytest From 76ddd0472e11b0346ff2c53de7be2c9d824be459 Mon Sep 17 00:00:00 2001 From: Edd Almond <102675624+eddalmond1@users.noreply.github.com> Date: Wed, 4 Mar 2026 11:13:25 +0000 Subject: [PATCH 2/4] eja - refining instruction files using Github best practice prompt --- .github/instructions/*.instructions.md | 409 ------------------ .../instructions/code-review.instructions.md | 65 +++ .github/instructions/python.instructions.md | 93 ++++ 3 files changed, 158 insertions(+), 409 deletions(-) delete mode 100644 .github/instructions/*.instructions.md create mode 100644 .github/instructions/code-review.instructions.md create mode 100644 .github/instructions/python.instructions.md diff --git a/.github/instructions/*.instructions.md b/.github/instructions/*.instructions.md deleted file mode 100644 index 303eabcbb..000000000 --- a/.github/instructions/*.instructions.md +++ /dev/null @@ -1,409 +0,0 @@ ---- -description: 'Generic code review instructions that can be customized for any project using GitHub Copilot' -applyTo: '**' -excludeAgent: ["coding-agent"] - ---- - -# Generic Code Review Instructions - -Comprehensive code review guidelines for GitHub Copilot that can be adapted to any project. These instructions follow best practices from prompt engineering and provide a structured approach to code quality, security, testing, and architecture review. - -## Review Language - -When performing a code review, respond in **English** (or specify your preferred language). - -> **Customization Tip**: Change to your preferred language by replacing "English" with "Portuguese (Brazilian)", "Spanish", "French", etc. - -## Review Priorities - -When performing a code review, prioritize issues in the following order: - -### 🔴 CRITICAL (Block merge) - -- **Security**: Vulnerabilities, exposed secrets, authentication/authorization issues -- **Correctness**: Logic errors, data corruption risks, race conditions -- **Breaking Changes**: API contract changes without versioning -- **Data Loss**: Risk of data loss or corruption - -### 🟡 IMPORTANT (Requires discussion) - -- **Code Quality**: Severe violations of SOLID principles, excessive duplication -- **Test Coverage**: Missing tests for critical paths or new functionality -- **Performance**: Obvious performance bottlenecks (N+1 queries, memory leaks) -- **Architecture**: Significant deviations from established patterns - -### 🟢 SUGGESTION (Non-blocking improvements) - -- **Readability**: Poor naming, complex logic that could be simplified -- **Optimization**: Performance improvements without functional impact -- **Best Practices**: Minor deviations from conventions -- **Documentation**: Missing or incomplete comments/documentation - -## General Review Principles - -When performing a code review, follow these principles: - -1. **Be specific**: Reference exact lines, files, and provide concrete examples -2. **Provide context**: Explain WHY something is an issue and the potential impact -3. **Suggest solutions**: Show corrected code when applicable, not just what's wrong -4. **Be constructive**: Focus on improving the code, not criticizing the author -5. **Recognize good practices**: Acknowledge well-written code and smart solutions -6. **Be pragmatic**: Not every suggestion needs immediate implementation -7. **Group related comments**: Avoid multiple comments about the same topic - -## Code Quality Standards - -When performing a code review, check for: - -### Clean Code - -- Descriptive and meaningful names for variables, functions, and classes -- Single Responsibility Principle: each function/class does one thing well -- DRY (Don't Repeat Yourself): no code duplication -- Functions should be small and focused (ideally < 20-30 lines) -- Avoid deeply nested code (max 3-4 levels) -- Avoid magic numbers and strings (use constants) -- Code should be self-documenting; comments only when necessary - -### Examples - -```javascript -// ❌ BAD: Poor naming and magic numbers -function calc(x, y) { - if (x > 100) return y * 0.15; - return y * 0.10; -} - -// ✅ GOOD: Clear naming and constants -const PREMIUM_THRESHOLD = 100; -const PREMIUM_DISCOUNT_RATE = 0.15; -const STANDARD_DISCOUNT_RATE = 0.10; - -function calculateDiscount(orderTotal, itemPrice) { - const isPremiumOrder = orderTotal > PREMIUM_THRESHOLD; - const discountRate = isPremiumOrder ? PREMIUM_DISCOUNT_RATE : STANDARD_DISCOUNT_RATE; - return itemPrice * discountRate; -} -``` - -### Error Handling - -- Proper error handling at appropriate levels -- Meaningful error messages -- No silent failures or ignored exceptions -- Fail fast: validate inputs early -- Use appropriate error types/exceptions - -### Examples - -```python -# ❌ BAD: Silent failure and generic error -def process_user(user_id): - try: - user = db.get(user_id) - user.process() - except: - pass - -# ✅ GOOD: Explicit error handling -def process_user(user_id): - if not user_id or user_id <= 0: - raise ValueError(f"Invalid user_id: {user_id}") - - try: - user = db.get(user_id) - except UserNotFoundError: - raise UserNotFoundError(f"User {user_id} not found in database") - except DatabaseError as e: - raise ProcessingError(f"Failed to retrieve user {user_id}: {e}") - - return user.process() -``` - -## Security Review - -When performing a code review, check for security issues: - -- **Sensitive Data**: No passwords, API keys, tokens, or PII in code or logs -- **Input Validation**: All user inputs are validated and sanitized -- **SQL Injection**: Use parameterized queries, never string concatenation -- **Authentication**: Proper authentication checks before accessing resources -- **Authorization**: Verify user has permission to perform action -- **Cryptography**: Use established libraries, never roll your own crypto -- **Dependency Security**: Check for known vulnerabilities in dependencies - -### Examples - -```javascript -// ❌ BAD: Exposed secret in code -const API_KEY = "sk_live_abc123xyz789"; - -// ✅ GOOD: Use environment variables -const API_KEY = process.env.API_KEY; -``` - -## Testing Standards - -When performing a code review, verify test quality: - -- **Coverage**: Critical paths and new functionality must have tests -- **Test Names**: Descriptive names that explain what is being tested -- **Test Structure**: Clear Arrange-Act-Assert or Given-When-Then pattern -- **Independence**: Tests should not depend on each other or external state -- **Assertions**: Use specific assertions using HamCrest, avoid generic assertTrue/assertFalse -- **Edge Cases**: Test boundary conditions, null values, empty collections -- **Mock Appropriately**: Mock external dependencies, not domain logic - -### Examples - -```typescript -// ❌ BAD: Vague name and assertion -test('test1', () => { - const result = calc(5, 10); - expect(result).toBeTruthy(); -}); - -// ✅ GOOD: Descriptive name and specific assertion -test('should calculate 10% discount for orders under $100', () => { - const orderTotal = 50; - const itemPrice = 20; - - const discount = calculateDiscount(orderTotal, itemPrice); - - expect(discount).toBe(2.00); -}); -``` - -## Performance Considerations - -When performing a code review, check for performance issues: - -- **Database Queries**: Avoid N+1 queries, use proper indexing -- **Algorithms**: Appropriate time/space complexity for the use case -- **Caching**: Utilize caching for expensive or repeated operations -- **Resource Management**: Proper cleanup of connections, files, streams -- **Lazy Loading**: Load data only when needed - -### Examples - -```python -# ❌ BAD: N+1 query problem -users = User.query.all() -for user in users: - orders = Order.query.filter_by(user_id=user.id).all() # N+1! - -# ✅ GOOD: Use JOIN or eager loading -users = User.query.options(joinedload(User.orders)).all() -for user in users: - orders = user.orders -``` - -## Architecture and Design - -When performing a code review, verify architectural principles: - -- **Separation of Concerns**: Clear boundaries between layers/modules -- **Dependency Direction**: High-level modules don't depend on low-level details -- **Interface Segregation**: Prefer small, focused interfaces -- **Loose Coupling**: Components should be independently testable -- **High Cohesion**: Related functionality grouped together -- **Consistent Patterns**: Follow established patterns in the codebase - -## Documentation Standards - -When performing a code review, check documentation: - -- **Doc String Documentation**: Code must be documented (purpose, parameters, returns) -- **Complex Logic**: Non-obvious logic should have explanatory comments -- **README Updates**: Update README when adding features or changing setup -- **Breaking Changes**: Document any breaking changes clearly -- **Examples**: Provide usage examples for complex features - -## Comment Format Template - -When performing a code review, use this format for comments: - -```markdown -**[PRIORITY] Category: Brief title** - -Detailed description of the issue or suggestion. - -**Why this matters:** -Explanation of the impact or reason for the suggestion. - -**Suggested fix:** -[code example if applicable] - -**Reference:** [link to relevant documentation or standard] -``` - -### Example Comments - -#### Critical Issue - -````markdown -**🔴 CRITICAL - Security: SQL Injection Vulnerability** - -The query on line 45 concatenates user input directly into the SQL string, -creating a SQL injection vulnerability. - -**Why this matters:** -An attacker could manipulate the email parameter to execute arbitrary SQL commands, -potentially exposing or deleting all database data. - -**Suggested fix:** -```sql --- Instead of: -query = "SELECT * FROM users WHERE email = '" + email + "'" - --- Use: -PreparedStatement stmt = conn.prepareStatement( - "SELECT * FROM users WHERE email = ?" -); -stmt.setString(1, email); -``` - -**Reference:** OWASP SQL Injection Prevention Cheat Sheet -```` - -#### Important Issue - -````markdown -**🟡 IMPORTANT - Testing: Missing test coverage for critical path** - -The `processPayment()` function handles financial transactions but has no tests -for the refund scenario. - -**Why this matters:** -Refunds involve money movement and should be thoroughly tested to prevent -financial errors or data inconsistencies. - -**Suggested fix:** -Add test case: -```javascript -test('should process full refund when order is cancelled', () => { - const order = createOrder({ total: 100, status: 'cancelled' }); - - const result = processPayment(order, { type: 'refund' }); - - expect(result.refundAmount).toBe(100); - expect(result.status).toBe('refunded'); -}); -``` -```` - -#### Suggestion - -````markdown -**🟢 SUGGESTION - Readability: Simplify nested conditionals** - -The nested if statements on lines 30-40 make the logic hard to follow. - -**Why this matters:** -Simpler code is easier to maintain, debug, and test. - -**Suggested fix:** -```javascript -// Instead of nested ifs: -if (user) { - if (user.isActive) { - if (user.hasPermission('write')) { - // do something - } - } -} - -// Consider guard clauses: -if (!user || !user.isActive || !user.hasPermission('write')) { - return; -} -// do something -``` -```` - -## Review Checklist - -When performing a code review, systematically verify: - -### Code Quality - -- [ ] Code follows consistent style and conventions -- [ ] Names are descriptive and follow naming conventions -- [ ] Functions/methods are small and focused -- [ ] No code duplication -- [ ] Complex logic is broken into simpler parts -- [ ] Error handling is appropriate -- [ ] No commented-out code or TODO without tickets - -### Security - -- [ ] No sensitive data in code or logs - -### Testing - -- [ ] New code has appropriate test coverage -- [ ] Tests are well-named and focused -- [ ] Tests cover edge cases and error scenarios -- [ ] Tests are independent and deterministic -- [ ] No tests that always pass or are commented out - -### Performance - -- [ ] No obvious performance issues (N+1, memory leaks) -- [ ] Appropriate use of caching -- [ ] Efficient algorithms and data structures -- [ ] Proper resource cleanup - -### Architecture - -- [ ] Follows established patterns and conventions -- [ ] Proper separation of concerns -- [ ] No architectural violations -- [ ] Dependencies flow in correct direction - -### Documentation - -- [ ] Complex logic has explanatory comments -- [ ] README is updated if needed -- [ ] Breaking changes are documented - -## Project-Specific Customizations - -To customize this template for your project, add sections for: - -1. **Language/Framework specific checks** - - Check that wireup has been used for dependency injection, where appropriate -2. **Build and deployment** - - When performing a code review, verify CI/CD pipeline configuration is correct - - When performing a code review, check terraform changes are safe and syntactically correct - -## Additional Resources - -For more information on effective code reviews and GitHub Copilot customization: - -- [GitHub Copilot Prompt Engineering](https://docs.github.com/en/copilot/concepts/prompting/prompt-engineering) -- [GitHub Copilot Custom Instructions](https://code.visualstudio.com/docs/copilot/customization/custom-instructions) -- [Awesome GitHub Copilot Repository](https://github.com/github/awesome-copilot) -- [GitHub Code Review Guidelines](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests) -- [Google Engineering Practices - Code Review](https://google.github.io/eng-practices/review/) -- [OWASP Security Guidelines](https://owasp.org/) - -## Prompt Engineering Tips - -When performing a code review, apply these prompt engineering principles from the [GitHub Copilot documentation](https://docs.github.com/en/copilot/concepts/prompting/prompt-engineering): - -1. **Start General, Then Get Specific**: Begin with high-level architecture review, then drill into implementation details -2. **Give Examples**: Reference similar patterns in the codebase when suggesting changes -3. **Break Complex Tasks**: Review large PRs in logical chunks (security → tests → logic → style) -4. **Avoid Ambiguity**: Be specific about which file, line, and issue you're addressing -5. **Indicate Relevant Code**: Reference related code that might be affected by changes -6. **Experiment and Iterate**: If initial review misses something, review again with focused questions - -## Project Context - -This is a generic template. Customize this section with your project-specific information: - -- **Tech Stack**: Python, Terraform -- **Build Tool**: Poetry, Docker (for Lambda), Terraform -- **Testing**: pytest diff --git a/.github/instructions/code-review.instructions.md b/.github/instructions/code-review.instructions.md new file mode 100644 index 000000000..99c49ab05 --- /dev/null +++ b/.github/instructions/code-review.instructions.md @@ -0,0 +1,65 @@ +--- +description: "Code review instructions for the eligibility-signposting-api project" +applyTo: "**" +excludeAgent: ["coding-agent"] +--- + +# Code Review Instructions + +Guidelines for the eligibility-signposting-api project — a serverless AWS Lambda + Flask eligibility rules engine. + +## Review Priorities + +### Critical (block merge) + +- **Security**: Exposed secrets, PII leakage (especially NHS Numbers), missing header validation +- **Correctness**: Logic errors in rules engine evaluation, incorrect operator behaviour, data corruption in DynamoDB +- **Breaking Changes**: API contract changes to FHIR response models or request validation + +### Important (requires discussion) + +- **Code Quality**: SOLID violations, excessive duplication +- **Test Coverage**: Missing tests for critical paths, new rules/operators, or edge cases +- **Performance**: Unnecessary DynamoDB scans, missing caching, Lambda cold start regressions +- **Architecture**: Deviations from established patterns (wireup DI, chain of responsibility, operator registry) + +### Suggestion (non-blocking) + +- **Readability**: Naming, simplification of complex logic +- **Best Practices**: Minor convention deviations +- **Documentation**: Missing or incomplete docstrings + +## Security + +- **PII handling**: NHS Numbers must never appear in logs or error messages. `TokenError` messages must be redacted. Verify new log statements do not leak person data. +- **Secrets**: No API keys, tokens, or secrets in code. Use environment variables or AWS Secrets Manager. +- **NHS Number hashing**: Lookups use HMAC-SHA512 via `HashingService` with secret rotation (AWSCURRENT → AWSPREVIOUS fallback). +- **Header validation**: `NHSE-Product-ID` must be present (403 if missing). `nhs-login-nhs-number` must match path parameter. +- **Security headers**: Responses must include `Cache-Control: no-store, private`, `Strict-Transport-Security`, `X-Content-Type-Options: nosniff`. + +## Architecture + +- **Dependency injection**: Use wireup `@service` for all services, repos, and factories. Inject via `Injected[T]`, `Inject(qualifier=...)`, or `Inject(param=...)`. Never instantiate services manually. +- **Chain of responsibility**: Processing follows `CohortEligibilityHandler → BaseEligibilityHandler → FilterRuleHandler → SuppressionRuleHandler`. Extend this chain for new steps. +- **Operator registry**: New operators must extend `hamcrest.BaseMatcher` and register via the decorator-based `OperatorRegistry`. +- **Pydantic models**: Use `Field(alias=...)` for JSON mapping, `field_validator`/`model_validator` for validation. Response models use camelCase aliases. +- **FHIR compliance**: Error responses must use `OperationOutcome` models with `application/fhir+json` content type. +- **Lambda reuse**: The Flask app is cached in `CacheManager` across invocations. Changes to app initialization must not break container reuse. + +## Performance + +- **DynamoDB**: Use `query()` with `KeyConditionExpression`, never `scan()`. Partition key is `NHS_NUMBER`, sort key discriminator is `ATTRIBUTE_TYPE`. +- **S3 config loading**: Campaign configs load from S3 per request. Avoid unnecessary `list_objects` or `get_object` calls. +- **Caching**: Feature toggles use `TTLCache` (300s). New caching should follow the same pattern with appropriate TTLs. +- **Lambda cold starts**: Avoid heavy imports at module level. Keep wireup service graph lean. + +## Audit Trail + +- **Completeness**: New eligibility logic must call `AuditContext.append_audit_condition()` to record evaluation details. +- **Firehose delivery**: Audit events use Pydantic `AuditEvent` models sent to Kinesis Firehose. Preserve the full audit data model. + +## Terraform + +- **Encryption**: All AWS resources (DynamoDB, S3, Lambda, Firehose, Secrets Manager) must use KMS CMK encryption. +- **Environment parity**: Verify deletion protection and PITR are enabled for prod/preprod DynamoDB tables. +- **Safety**: Terraform changes must not destroy or replace stateful resources (DynamoDB tables, S3 buckets) unintentionally. diff --git a/.github/instructions/python.instructions.md b/.github/instructions/python.instructions.md new file mode 100644 index 000000000..d5dd89b48 --- /dev/null +++ b/.github/instructions/python.instructions.md @@ -0,0 +1,93 @@ +--- +description: "Python coding standards for the eligibility-signposting-api project" +applyTo: "**/*.py" +--- + +# Python Coding Standards + +## Naming Conventions + +- `snake_case` for functions, variables, and module names. +- `PascalCase` for class names. +- `UPPER_SNAKE_CASE` for constants. +- Prefix private methods and attributes with `_`. + +## Code Style + +- Line length limit: 120 characters (enforced by ruff). +- Use type hints for all function signatures and return types. +- Prefer `dataclass` for simple domain objects, Pydantic `BaseModel` for validated/serialized models. +- Use `StrEnum` for string enumerations. +- Avoid bare `except:` — catch specific exceptions. + +## Error Handling + +```python +# Bad: silent failure +try: + person = repo.get(nhs_number) +except Exception: + pass + +# Good: specific exceptions with context +try: + person = repo.get(nhs_number) +except PersonNotFoundError: + raise +except ClientError as e: + raise RepositoryError(f"Failed to query person table: {e}") from e +``` + +## Dependency Injection (wireup) + +- Decorate services with `@service`. Do not instantiate services manually. +- Use `Inject(qualifier=...)` for AWS client disambiguation. +- Use `Inject(param=...)` for configuration values. +- Register factory functions with `@service` for boto3 clients. + +```python +# Good +@service +class MyService: + def __init__(self, repo: Injected[MyRepo]) -> None: + self._repo = repo + +# Bad: manual instantiation +class MyService: + def __init__(self) -> None: + self._repo = MyRepo() +``` + +## Pydantic Models + +- Use `Field(alias=...)` for JSON key mapping. +- Use `field_validator` / `model_validator` for custom validation. +- Response models must use camelCase aliases (`alias_generator=to_camel` or explicit aliases). +- Use `model_dump(by_alias=True)` when serializing for API responses. + +## Testing + +- Use `pytest` with pyHamcrest assertions (`assert_that`, `is_`, `has_entries`, `contains_exactly`, etc.). +- Use `brunns-matchers` for Werkzeug response assertions. +- Use project auto-matchers (`BaseAutoMatcher`) for dataclass/Pydantic model assertions. +- Use `polyfactory` (`DataclassFactory` / `ModelFactory`) for test data builders. +- Mock AWS services with `moto`, not manual stubs. +- Use `@pytest.mark.parametrize` for rule/operator test cases. + +```python +# Good: pyHamcrest with specific matchers +def test_eligible_person_returns_eligible_status(): + result = evaluate(person, campaign) + assert_that(result, is_(has_property("status", equal_to(Status.ELIGIBLE)))) + +# Bad: generic assert +def test_eligible(): + result = evaluate(person, campaign) + assert result is not None +``` + +## Logging + +- Use structured JSON logging via `python-json-logger`. +- Never log NHS Numbers or other PII. +- Include `request_id` via the `ContextVar` pattern for request tracing. From 41ea50b211009e14ef9337c52f2674e0462e0e32 Mon Sep 17 00:00:00 2001 From: Edd Almond <102675624+eddalmond1@users.noreply.github.com> Date: Wed, 4 Mar 2026 12:57:10 +0000 Subject: [PATCH 3/4] eja - fixing secret scan and vale --- .github/instructions/code-review.instructions.md | 4 ++-- scripts/config/gitleaks.toml | 2 +- .../config/vale/styles/config/vocabularies/words/accept.txt | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/instructions/code-review.instructions.md b/.github/instructions/code-review.instructions.md index 99c49ab05..5bf9ebb4c 100644 --- a/.github/instructions/code-review.instructions.md +++ b/.github/instructions/code-review.instructions.md @@ -49,7 +49,7 @@ Guidelines for the eligibility-signposting-api project — a serverless AWS Lamb ## Performance - **DynamoDB**: Use `query()` with `KeyConditionExpression`, never `scan()`. Partition key is `NHS_NUMBER`, sort key discriminator is `ATTRIBUTE_TYPE`. -- **S3 config loading**: Campaign configs load from S3 per request. Avoid unnecessary `list_objects` or `get_object` calls. +- **S3 configuration loading**: Campaign configs load from S3 per request. Avoid unnecessary `list_objects` or `get_object` calls. - **Caching**: Feature toggles use `TTLCache` (300s). New caching should follow the same pattern with appropriate TTLs. - **Lambda cold starts**: Avoid heavy imports at module level. Keep wireup service graph lean. @@ -61,5 +61,5 @@ Guidelines for the eligibility-signposting-api project — a serverless AWS Lamb ## Terraform - **Encryption**: All AWS resources (DynamoDB, S3, Lambda, Firehose, Secrets Manager) must use KMS CMK encryption. -- **Environment parity**: Verify deletion protection and PITR are enabled for prod/preprod DynamoDB tables. +- **Environment parity**: Verify deletion protection and PITR are enabled for production/pre-production DynamoDB tables. - **Safety**: Terraform changes must not destroy or replace stateful resources (DynamoDB tables, S3 buckets) unintentionally. diff --git a/scripts/config/gitleaks.toml b/scripts/config/gitleaks.toml index 66a3d7e94..adf24874f 100644 --- a/scripts/config/gitleaks.toml +++ b/scripts/config/gitleaks.toml @@ -16,5 +16,5 @@ regexes = [ ] [allowlist] -paths = ['''.terraform.lock.hcl''', '''poetry.lock''', '''yarn.lock'''] +paths = ['''.terraform.lock.hcl''', '''poetry.lock''', '''yarn.lock''', '''.github/instructions/\*.instructions.md'''] stopwords = ['''dummy_key''', '''dummy_secret''', '''192.0.0.1''', '''prance = "^25.4.8.0"''', '''25.4.8.0'''] diff --git a/scripts/config/vale/styles/config/vocabularies/words/accept.txt b/scripts/config/vale/styles/config/vocabularies/words/accept.txt index fc7d8ef23..dc1443bea 100644 --- a/scripts/config/vale/styles/config/vocabularies/words/accept.txt +++ b/scripts/config/vale/styles/config/vocabularies/words/accept.txt @@ -27,6 +27,7 @@ Terraform toolchain Trufflehog Uncomment +Werkzeug Syncytial pyenv colima From f3e64745be8b0252e650f44abffd791ec4a28937 Mon Sep 17 00:00:00 2001 From: Edd Almond <102675624+eddalmond1@users.noreply.github.com> Date: Wed, 4 Mar 2026 15:02:32 +0000 Subject: [PATCH 4/4] added ignore for gitleaks as well as an allow for the file --- .gitleaksignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitleaksignore b/.gitleaksignore index cceb449a3..23899810e 100644 --- a/.gitleaksignore +++ b/.gitleaksignore @@ -1,3 +1,4 @@ # SEE: https://github.com/gitleaks/gitleaks/blob/master/README.md#gitleaksignore cd9c0efec38c5d63053dd865e5d4e207c0760d91:docs/guides/Perform_static_analysis.md:generic-api-key:37 +bf0c77098978c450d8570b38fb480fbb8d6a0628:.github/instructions/*.instructions.md:stripe-access-token:140