Add backpressure stack for agentic coding quality gates

PostToolUse hooks run after every file edit:
- Backend: ./mvnw compile (Checkstyle Google Style + javac)
- Frontend: vue-tsc --noEmit + oxlint + ESLint

Stop hook runs test suites when source files changed, blocks the
agent on failure and re-engages it to fix the issue. Output is
filtered to [ERROR] lines only for context efficiency.

Static analysis: Checkstyle (validate phase), SpotBugs (verify phase),
ArchUnit (9 hexagonal architecture rules as JUnit tests).

Fail-fast: Surefire skipAfterFailureCount=1, Vitest bail=1.
Test log noise suppressed via logback-test.xml (WARN level),
redirectTestOutputToFile, and trimStackTrace.

Existing Java sources reformatted to Google Style (2-space indent,
import order, Javadoc on public types).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-04 02:44:15 +01:00
parent a55174b323
commit a9802c2881
15 changed files with 1098 additions and 43 deletions

View File

@@ -33,13 +33,13 @@ A privacy-focused, self-hostable web app for event announcements and RSVPs. An a
## Tech stack
| Layer | Technology |
|--------------|------------------------------------------|
| Backend | Java (latest LTS), Spring Boot, Maven |
| Frontend | Vue 3, Vite, TypeScript |
| Database | PostgreSQL (external, not bundled) |
| Layer | Technology |
|--------------|--------------------------------------------|
| Backend | Java (latest LTS), Spring Boot, Maven |
| Frontend | Vue 3, Vite, TypeScript |
| Database | PostgreSQL (external, not bundled) |
| Architecture | SPA + RESTful API, hexagonal/onion backend |
| Deployment | Single Docker container |
| Deployment | Single Docker container |
## Self-hosting
@@ -89,11 +89,11 @@ The app runs at `http://localhost:8080`. Database migrations run automatically o
All configuration is done via environment variables:
| Variable | Required | Description |
|----------------------|----------|---------------------------------------------------------------------------------------------------------------------------------------|
| `DATABASE_URL` | Yes | JDBC connection string for PostgreSQL |
| `MAX_ACTIVE_EVENTS` | No | Maximum number of non-expired events. Unset = unlimited |
| `UNSPLASH_API_KEY` | No | Enables header image search via Unsplash. Images are fetched server-side and stored locally — guests never contact Unsplash |
| Variable | Required | Description |
|---------------------|----------|-----------------------------------------------------------------------------------------------------------------------------|
| `DATABASE_URL` | Yes | JDBC connection string for PostgreSQL |
| `MAX_ACTIVE_EVENTS` | No | Maximum number of non-expired events. Unset = unlimited |
| `UNSPLASH_API_KEY` | No | Enables header image search via Unsplash. Images are fetched server-side and stored locally — guests never contact Unsplash |
### Image storage
@@ -138,6 +138,57 @@ cd backend && mvn package
cd frontend && npm run build
```
## Code quality
Automated quality gates run as Claude Code hooks during AI-assisted development. They provide immediate feedback after every file edit and block the agent from finishing when tests fail.
### Backend (Java / Maven)
**After editing a `*.java` file** (PostToolUse hook):
| What | Command | Fails on |
|---------------------|------------------|----------------------------------|
| Checkstyle | `./mvnw compile` | Style violations (Google Style) |
| Java compiler | `./mvnw compile` | Compile errors |
Checkstyle enforces Google Style (2-space indent, import order, Javadoc on public types) and is bound to the `validate` phase, so it runs automatically as part of every `compile`. Covers both `src/main` and `src/test`.
**When the agent finishes** (Stop hook — only if `backend/src/` has uncommitted changes):
| What | Command | Fails on |
|---------------------|----------------|---------------------------------------|
| JUnit 5 | `./mvnw test` | Test failures (fail-fast, stops at 1) |
| ArchUnit (9 rules) | `./mvnw test` | Hexagonal architecture violations |
ArchUnit enforces hexagonal boundaries: domain must not depend on adapters, application, config, or Spring; ports must be interfaces; web and persistence adapters must not cross-depend.
**Not hooked** (run manually):
| What | Command | Fails on |
|---------------------|------------------|----------------------------------------------------|
| SpotBugs | `./mvnw verify` | Potential bugs, null dereferences, resource leaks |
### Frontend (TypeScript / Vue)
**After editing a `*.ts` or `*.vue` file** (PostToolUse hook):
| What | Command | Fails on |
|---------------------|--------------------|-----------------|
| TypeScript (strict) | `vue-tsc --noEmit` | Type errors |
| oxlint + ESLint | `oxlint`, `eslint` | Lint violations |
**When the agent finishes** (Stop hook — only if `frontend/src/` has uncommitted changes):
| What | Command | Fails on |
|---------------------|------------------------------|---------------------------------------|
| Vitest | `npm run test:unit -- --run` | Test failures (fail-fast, stops at 1) |
**Not hooked** (run manually or via editor):
| What | Command | Fails on |
|---------------------|------------------|-------------------|
| Prettier | `npm run format` | Formatting issues |
## License
GPL — see [LICENSE](LICENSE) for details.