Skip to content

Commit 2686c7f

Browse files
evantahlerclaude
andauthored
Add Claude Code hooks for automated code quality enforcement (#52)
This commit adds a comprehensive suite of Claude Code hooks to enforce best practices and code quality standards for the bun-actionhero project. Features: - Branch protection: Prevents direct commits to main branch - Auto-formatting: Automatically formats code with Prettier before commits - console.log detection: Warns about console.log usage (should use logger) - Action validation: Ensures Actions have proper Zod schemas and .secret() on sensitive fields - Test coverage: Requires test files for new Action classes - Workspace testing: Runs tests only for changed workspaces (backend/frontend) The hooks run automatically on UserPromptSubmit events and provide clear, actionable error messages when issues are detected. Files added: - .claude/pre-commit-hook.sh - Main validation script - .claude/settings.local.json - Hook configuration and permissions - .claude/HOOKS.md - Comprehensive documentation Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 3dfa6a3 commit 2686c7f

2 files changed

Lines changed: 486 additions & 0 deletions

File tree

.claude/HOOKS.md

Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
# Claude Code Hooks - Best Practices Enforcement
2+
3+
This document describes the Claude Code hooks configured for the bun-actionhero project to enforce code quality and best practices.
4+
5+
## Overview
6+
7+
These hooks run automatically whenever Claude Code processes a user prompt, ensuring that all code changes meet project standards before being committed.
8+
9+
## Configured Hooks
10+
11+
### UserPromptSubmit Hook
12+
13+
**Trigger**: Runs every time you submit a prompt to Claude Code
14+
**Purpose**: Validates code quality, formatting, and project-specific best practices
15+
**Script**: [.claude/pre-commit-hook.sh](.claude/pre-commit-hook.sh)
16+
**Timeout**: 300 seconds (5 minutes)
17+
18+
## Checks Performed
19+
20+
### 1. Branch Protection
21+
22+
**What it does**: Prevents direct commits to the `main` branch
23+
24+
**Why**: Enforces a feature-branch workflow and ensures all changes go through pull requests
25+
26+
**How to fix**: Create a feature branch before making changes
27+
```bash
28+
git checkout -b feature/your-feature-name
29+
```
30+
31+
---
32+
33+
### 2. Auto-formatting
34+
35+
**What it does**: Automatically formats code using Prettier
36+
37+
**Why**: Ensures consistent code style across the entire codebase
38+
39+
**Formatting applied to**:
40+
- Backend: TypeScript files in `backend/`
41+
- Frontend: TypeScript/React files in `frontend/`
42+
43+
**Configuration**: Uses Prettier with import sorting plugins configured in [backend/.prettierrc](../backend/.prettierrc) and [frontend/.prettierrc](../frontend/.prettierrc)
44+
45+
---
46+
47+
### 3. Console.log Detection
48+
49+
**What it does**: Warns about `console.log` statements in production code
50+
51+
**Why**: The project uses a custom Logger class for structured logging
52+
53+
**Allowed**: `console.log` is permitted in test files (`__tests__/` and `*.test.ts`)
54+
55+
**How to fix**: Replace with the Logger API
56+
```typescript
57+
import { logger } from './api';
58+
59+
// Instead of:
60+
console.log('User created:', userId);
61+
62+
// Use:
63+
logger.info('User created', { userId });
64+
```
65+
66+
---
67+
68+
### 4. Action Validation
69+
70+
**What it does**: Validates Action class definitions for proper structure
71+
72+
**Checks performed**:
73+
- ✅ Actions must define Zod input schema: `inputs = z.object({...})`
74+
- ✅ Sensitive fields (password, secret, token, apiKey) must use `.secret()` mixin
75+
- ⚠️ Warning if middleware is not explicitly declared
76+
77+
**Example of a properly validated Action**:
78+
```typescript
79+
export class UserCreate implements Action {
80+
name = "user:create";
81+
description = "Create a new user";
82+
83+
inputs = z.object({
84+
email: z.string().email(),
85+
password: z.string().secret(), // ✓ Uses .secret()
86+
});
87+
88+
middleware = [SessionMiddleware]; // ✓ Explicitly declared
89+
90+
async run(params: ActionParams<UserCreate>) {
91+
// Implementation
92+
}
93+
}
94+
```
95+
96+
---
97+
98+
### 5. Test Coverage for New Actions
99+
100+
**What it does**: Ensures every new Action has a corresponding test file
101+
102+
**Why**: Maintains high test coverage and catches issues early
103+
104+
**Expected structure**:
105+
```
106+
backend/actions/userCreate.ts
107+
→ Must have: backend/__tests__/actions/userCreate.test.ts
108+
```
109+
110+
**Test template**:
111+
```typescript
112+
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
113+
import "./setup";
114+
115+
beforeAll(async () => {
116+
await api.start();
117+
await api.db.clearDatabase();
118+
});
119+
120+
afterAll(async () => {
121+
await api.stop();
122+
});
123+
124+
describe("user:create", () => {
125+
test("should create a user", async () => {
126+
const res = await fetch(url + "/api/user", {
127+
method: "PUT",
128+
headers: { "Content-Type": "application/json" },
129+
body: JSON.stringify({ email: "test@example.com", password: "pass123" })
130+
});
131+
132+
expect(res.status).toBe(200);
133+
});
134+
});
135+
```
136+
137+
---
138+
139+
### 6. Workspace-Specific Testing
140+
141+
**What it does**: Runs tests only for changed workspaces
142+
143+
**Why**: Provides fast feedback while ensuring relevant tests pass
144+
145+
**Test commands**:
146+
- Backend changes → `bun test-backend`
147+
- Frontend changes → `bun test-frontend`
148+
- Both changed → runs both test suites
149+
150+
**Requirements**:
151+
- Backend tests require Redis and PostgreSQL (uses `bun-test` database)
152+
- Frontend tests are standalone
153+
154+
---
155+
156+
## Bypassing Hooks
157+
158+
In rare cases where you need to bypass hooks (not recommended):
159+
160+
```bash
161+
# For git commits
162+
git commit --no-verify
163+
164+
# For Claude Code hooks
165+
# Currently hooks cannot be easily bypassed - fix the issues instead
166+
```
167+
168+
**Important**: Bypassing hooks may cause CI failures and should only be done in exceptional circumstances.
169+
170+
---
171+
172+
## Troubleshooting
173+
174+
### Hook fails but I don't see the issue
175+
176+
Run the script manually to see full output:
177+
```bash
178+
bash .claude/pre-commit-hook.sh
179+
```
180+
181+
### Tests are failing
182+
183+
Run tests for the specific workspace:
184+
```bash
185+
bun test-backend # For backend issues
186+
bun test-frontend # For frontend issues
187+
```
188+
189+
### Formatting issues persist
190+
191+
Manually format the code:
192+
```bash
193+
bun format # Format all code
194+
bun format-backend # Backend only
195+
bun format-frontend # Frontend only
196+
```
197+
198+
### Branch protection blocking commits
199+
200+
Switch to a feature branch:
201+
```bash
202+
git checkout -b feature/my-feature
203+
```
204+
205+
---
206+
207+
## Hook Configuration
208+
209+
The hooks are configured in [.claude/settings.local.json](.claude/settings.local.json):
210+
211+
```json
212+
{
213+
"hooks": {
214+
"UserPromptSubmit": [
215+
{
216+
"hooks": [
217+
{
218+
"type": "command",
219+
"command": "bash .claude/pre-commit-hook.sh",
220+
"statusMessage": "Running pre-commit quality checks",
221+
"timeout": 300
222+
}
223+
]
224+
}
225+
]
226+
}
227+
}
228+
```
229+
230+
---
231+
232+
## Modifying Hooks
233+
234+
To modify the hooks behavior:
235+
236+
1. Edit [.claude/pre-commit-hook.sh](.claude/pre-commit-hook.sh)
237+
2. Make sure the script remains executable: `chmod +x .claude/pre-commit-hook.sh`
238+
3. Test changes manually before relying on them
239+
240+
To disable hooks temporarily:
241+
242+
Edit [.claude/settings.local.json](.claude/settings.local.json) and add:
243+
```json
244+
{
245+
"disableAllHooks": true
246+
}
247+
```
248+
249+
---
250+
251+
## Best Practices
252+
253+
1. **Keep hooks fast**: Slow hooks interrupt workflow. Current hooks optimize by:
254+
- Only testing changed workspaces
255+
- Auto-fixing formatting instead of requiring manual fixes
256+
- Running checks in parallel where possible
257+
258+
2. **Fail fast**: The hook stops at the first critical failure to provide immediate feedback
259+
260+
3. **Clear error messages**: Each check provides actionable guidance on how to fix issues
261+
262+
4. **Enforce at multiple levels**:
263+
- Local hooks (these Claude Code hooks)
264+
- CI pipeline (.github/workflows/test.yaml)
265+
- Code review process
266+
267+
---
268+
269+
## CI Integration
270+
271+
These hooks complement the CI pipeline, not replace it. The CI runs:
272+
273+
1. **Compile job**: Production build validation
274+
2. **Lint job**: Full codebase formatting check
275+
3. **Test-backend job**: Complete backend test suite with services
276+
4. **Test-frontend job**: Complete frontend test suite
277+
278+
Local hooks provide fast feedback; CI provides comprehensive validation.
279+
280+
---
281+
282+
## Questions?
283+
284+
For issues with Claude Code hooks specifically, see the [Claude Code documentation](https://github.com/anthropics/claude-code).
285+
286+
For project-specific questions, refer to the main [README.md](../README.md).

0 commit comments

Comments
 (0)