
Brewcode:Standards Review
- 18 installs
- 29 repo stars
- Updated August 2, 2026
- kochetkov-ma/claude-brewcode
Perform code quality reviews and enforce project-specific coding standards via Brewcode
About
Brewcode skill for automated code quality reviews and standards checking. Solo developers use this to enforce consistent coding standards and catch quality issues before merging or shipping code.
- Code review automation
- Standards enforcement
- Quality gates
Brewcode:Standards Review by the numbers
- 18 all-time installs (skills.sh)
- Ranked #748 of 1,352 Code Review & Quality skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/kochetkov-ma/claude-brewcode --skill brewcodestandards-reviewAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 18 |
|---|---|
| repo stars | ★ 29 |
| Last updated | August 2, 2026 |
| Repository | kochetkov-ma/claude-brewcode ↗ |
What it does
Perform code quality reviews and enforce project-specific coding standards via Brewcode
Who is it for?
Developers enforcing code standards
When should I use this skill?
Code review and quality checks
Files
Standards Review
Review Priorities
| Priority | Source | Focus |
|---|---|---|
| 1 | Existing code | Search FIRST, import instead of creating |
| 2 | CLAUDE.md | Project standards, conventions, patterns |
| 3 | rules/*.md | Strict rules with numbers — check ALL [avoid#N], [bp#N] |
| 4 | references/{stack}.md | Stack-specific guidelines from this skill |
---
Phase 0: User Confirmation
BEFORE any analysis, ask the user using AskUserQuestion tool:
"Run /simplify at the end for an additional review pass (efficiency, concurrency, hot-paths)? This will increase execution time."| Option | Value |
|---|---|
| A | "Yes - run /simplify after report" |
| B | "No - standards review only" |
Remember the answer. If "Yes" - execute Phase 7 after Phase 6. If "No" - stop after Phase 6.
---
Input
| Input | Example | Action |
|---|---|---|
| Empty | /standards-review | Branch vs main/master |
| Commit | abc123 | Single commit |
| Folder | src/main/java/... | Folder contents |
Arguments: $ARGUMENTS
Phase 1: Detect Tech Stack
Check project root for stack indicators:
| Files Present | Stack | Reference |
|---|---|---|
pom.xml, build.gradle, build.gradle.kts | Java/Kotlin | references/java-kotlin.md |
package.json with react/typescript | TypeScript/React | references/typescript-react.md |
pyproject.toml, setup.py, requirements.txt | Python | references/python.md |
ACTION: When stack confirmed → READ references/{stack}.md (relative to this skill directory) and use as expert guidelines.Multi-stack: If multiple detected, read ALL matching references, process each separately.
Unknown stack: Use only project's .claude/rules/ — skip stack reference.
Phase 2: Get Files
Based on detected stack, use appropriate patterns:
| Stack | Patterns | Command |
|---|---|---|
| Java/Kotlin | *.java, *.kt | git diff --name-only ... -- '*.java' '*.kt' |
| TypeScript/React | *.ts, *.tsx, *.js, *.jsx | git diff --name-only ... -- '*.ts' '*.tsx' |
| Python | *.py | git diff --name-only ... -- '*.py' |
Commands by input type:
# Commit
git diff --name-only {COMMIT}^..{COMMIT} -- {PATTERNS} | head -50
# Branch (auto-detect main/master)
MAIN=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo "main")
git diff --name-only ${MAIN}...HEAD -- {PATTERNS} | head -50
# Folder
find {FOLDER} -type f \( {FIND_PATTERNS} \) | head -50Phase 3: Load Context
| Source | Files | Condition |
|---|---|---|
| Stack reference | references/{stack}.md | Based on Phase 1 detection |
| Project rules | .claude/rules/avoid.md, .claude/rules/best-practice.md, .claude/rules/*-avoid.md, .claude/rules/*-best-practice.md, .claude/rules/*.md | May not exist |
| Project standards | CLAUDE.md, .claude/CLAUDE.md | May not exist |
Search-First Protocol
Before reviewing code: identify new utilities/helpers/patterns/abstractions → search via grepai_search, check common locations → decide based on similarity.
Common Locations by Stack:
| Stack | Search Paths |
|---|---|
| Java/Kotlin | **/util/, **/common/, **/shared/, **/core/ |
| TypeScript/React | **/components/common/, **/shared/, **/hooks/, **/utils/ |
| Python | **/utils/, **/common/, **/lib/, **/helpers/ |
Similarity Decision Matrix:
| Similarity | Decision | Action |
|---|---|---|
| 90-100% | REUSE | Import existing |
| 70-89% | EXTEND | Add params/config to existing |
| 50-69% | CONSIDER | Evaluate effort vs benefit |
| <50% | KEEP_NEW | Justified new code |
Dynamic Agent Resolution
Before spawning expert agents, check for project team agents:
1. If .claude/teams/ exists — read team.md for agent roster with domains 2. If team has code-quality/standards domain agents — prefer over generic reviewer/Explore 3. Priority: team agent > project agent > plugin agent > system agent 4. If agent refuses (Task Acceptance Protocol) — re-delegate to suggested colleague (max 2 retries)
Always fall back to plugin agents when no project agents match the task domain.
Phase 4: Expert Analysis
Step 4.1: Group Files by Type
From Phase 2 file list, group by pattern matching:
Java/Kotlin:
| Group | Pattern | Focus |
|---|---|---|
| entities | **/entity/*.java, **/model/*.kt | Entity suffix, DI, Lombok |
| services | **/service/*.java, **/service/*.kt | Stream API, constructor injection |
| tests | **/*Test.java, **/*Test.kt | AssertJ, BDD comments, no logs |
| build | pom.xml, build.gradle, build.gradle.kts | Dependencies, plugins, versions |
TypeScript/React:
| Group | Pattern | Focus |
|---|---|---|
| styles | **/styles.ts, **/*.styled.ts | Theme tokens, no hardcoded colors |
| components | **/*.tsx | Hooks, functional components |
| tests | **/*.test.tsx, **/*.spec.ts | Jest patterns, coverage |
| build | package.json, tsconfig*.json, vite.config.*, webpack.config.* | Dependencies, scripts, bundler config |
Python:
| Group | Pattern | Focus |
|---|---|---|
| modules | **/*.py (non-test) | Type hints, docstrings |
| tests | **/test_*.py, **/*_test.py | pytest patterns |
| configs | **/config*.py, **/settings*.py | Environment handling |
| build | pyproject.toml, setup.py, setup.cfg, requirements*.txt | Dependencies, tool configs |
Step 4.2: Spawn Experts (haiku per group)
For each non-empty group, spawn parallel haiku agent:
Template:
Task(subagent_type="Explore", model="haiku", prompt="
## Standards Review - {EXPERT_TYPE}
**Stack:** {STACK}
**SEARCH-FIRST:** Use grepai_search for finding existing code before flagging duplicates.
**Files:** {FILE_LIST}
**Project Rules:**
{RULES_CONTENT}
**Stack Guidelines:**
{STACK_REFERENCE_CONTENT}
**Output JSON:**
{
\"changes\": [{
\"location\": \"file:15-20\",
\"description\": \"...\",
\"existing\": \"path/to/similar|null\",
\"reuse\": \"REUSE|EXTEND|CONSIDER|KEEP_NEW\",
\"rating\": \"good|warning|bad\"
}],
\"violations\": [{
\"file\": \"path\",
\"line\": 42,
\"rule\": \"avoid#5|best-practice#3|stack:entity-suffix\",
\"issue\": \"...\",
\"fix\": \"...\",
\"severity\": \"error|warning|info\"
}]
}
")---
Phase 5: Validation (sonnet)
Task(subagent_type="reviewer", model="sonnet", prompt="
Validate EACH finding from expert analysis.
Read actual code at file:line locations.
Verify rule actually applies in context.
**Findings:** {AGGREGATED_JSON}
**Output:** [
{\"id\": \"1\", \"verdict\": \"CONFIRM|REJECT\", \"reason\": \"...\"}
]
")Phase 6: Report
Create Report Directory
TIMESTAMP=$(date +"%Y%m%d-%H%M%S")
REPORT_DIR=".claude/reports/${TIMESTAMP}_standards-review"
mkdir -p "${REPORT_DIR}"REPORT.md Structure
# Standards Review Report
**Generated:** {TIMESTAMP}
**Stack:** {DETECTED_STACK}
**Scope:** {INPUT_TYPE} - {INPUT_VALUE}
**Files Reviewed:** {COUNT}
## Summary
| Category | Count | Severity |
|----------|-------|----------|
| Violations | X | Y errors, Z warnings |
| Reuse Opportunities | X | - |
| Good Patterns | X | - |
## Violations
### Errors
| File | Line | Rule | Issue | Fix |
|------|------|------|-------|-----|
| path | 42 | avoid#5 | Description | Suggested fix |
### Warnings
| File | Line | Rule | Issue | Fix |
|------|------|------|-------|-----|
## Reuse Opportunities
| New Code | Existing | Similarity | Action |
|----------|----------|------------|--------|
| path:15-20 | util/X.java | 85% | EXTEND |
## Good Patterns Found
| File | Pattern | Description |
|------|---------|-------------|
| path | stream-api | Proper use of Stream API |
## Reuse Statistics
| Metric | Value |
|--------|-------|
| Total new code blocks | X |
| Reusable (>70%) | Y |
| Reuse rate | Z% |
## Legend
**Severity:** error (must fix), warning (should fix), info (consider)
**Reuse:** REUSE (import), EXTEND (modify existing), CONSIDER (evaluate), KEEP_NEW (justified)
**Rating:** good (exemplary), warning (suboptimal), bad (violation)Phase 7: Simplify Pass (conditional)
Execute ONLY if user answered "Yes" in Phase 0.
After Phase 6 report is written, invoke:
Skill(skill="simplify", args="{INPUT_VALUE}")Where {INPUT_VALUE} is the same scope used in this review (commit, branch, or folder from Phase 2).
If user answered "No" in Phase 0 - skip this phase entirely.
Error Handling
| Condition | Action |
|---|---|
| No files found | Exit: "No files to review for {SCOPE}" |
| >50 files | Warn user, suggest narrowing scope |
| Unknown stack | Continue with project rules only |
| No rules found | Continue with stack reference only |
| All compliant | Report: "All code compliant with standards" |
MIT License
Copyright (c) 2025-2026 Maxim Kochetkov (kochetkov-ma)
https://github.com/kochetkov-ma/claude-brewcode
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Standards Review
Analyzes code changes for project standards compliance, detects duplicate code that can be replaced with existing utilities, and highlights exemplary patterns. Automatically detects your tech stack and applies the right set of rules.
Quick Start
/brewcode:standards-reviewReviews all changes on your current branch compared to main.
Modes
| Mode | How to trigger | What it does |
|---|---|---|
| Branch diff | /brewcode:standards-review | Compares current branch to main/master, reviews all changed files |
| Single commit | /brewcode:standards-review abc123f | Reviews files changed in the specified commit |
| Folder scan | /brewcode:standards-review src/main/java | Reviews all source files in the given directory |
| Custom focus | /brewcode:standards-review -p "check error handling" | Adds a custom analysis prompt on top of standard checks |
| With simplify | Answer "Yes" when prompted at start | Runs an extra /simplify pass for efficiency, concurrency, and hot-path analysis |
Examples
Good Usage
# Review branch before opening a PR
/brewcode:standards-review
# Review a specific commit after a colleague's push
/brewcode:standards-review d8c8e69
# Review an entire module after refactoring
/brewcode:standards-review src/components
# Focus on security concerns in authentication code
/brewcode:standards-review src/auth -p "focus on security and input validation"
# Review Python tests folder for test quality
/brewcode:standards-review tests/Common Mistakes
# Reviewing generated or vendored code -- produces noise, not actionable findings
/brewcode:standards-review node_modules
/brewcode:standards-review src/generated
# Reviewing the entire repo on a long-lived branch -- too many files, suggest narrowing scope
# (the skill warns you when >50 files are detected)
/brewcode:standards-review /
# Running without any project rules or CLAUDE.md -- the skill still works
# but findings will be limited to stack-specific guidelines onlyWhat It Checks
Standards compliance -- validates code against three layers of rules:
- Project rules from
.claude/rules/*.md(numberedavoid#N,best-practice#N) - Project conventions from
CLAUDE.md - Stack-specific guidelines from built-in reference files
Duplicate detection -- uses grepai_search to find existing utilities, helpers, and patterns before flagging new code. Similarity scoring determines the recommendation:
| Similarity | Recommendation | Meaning |
|---|---|---|
| 90-100% | REUSE | Import the existing code directly |
| 70-89% | EXTEND | Add parameters or configuration to the existing code |
| 50-69% | CONSIDER | Evaluate whether refactoring is worth the effort |
| <50% | KEEP_NEW | New code is justified |
Pattern recognition -- identifies good patterns worth replicating across the codebase.
Supported stacks:
| Stack | Detected by | File groups analyzed |
|---|---|---|
| Java/Kotlin | pom.xml, build.gradle, build.gradle.kts | entities, services, tests, build configs |
| TypeScript/React | package.json with react/typescript | styles, components, tests, build configs |
| Python | pyproject.toml, setup.py, requirements.txt | modules, tests, configs, build files |
Multi-stack projects are supported -- each stack is processed separately.
Output
A structured REPORT.md is saved to .claude/reports/{timestamp}_standards-review/ containing:
- Summary table -- violation counts by severity, reuse opportunities, good patterns found
- Violations -- grouped by severity (error, warning, info) with file, line, rule reference, and suggested fix
- Reuse opportunities -- new code mapped to existing code with similarity percentages
- Good patterns -- exemplary code worth emulating
- Reuse statistics -- total new code blocks, reusable percentage, overall reuse rate
Severity levels: error (must fix), warning (should fix), info (consider).
Tips
- Run before opening a PR to catch standards issues early -- the branch diff mode is designed for exactly this workflow.
- If the skill detects more than 50 files, narrow the scope to a specific folder or commit to get more focused results.
- Answer "Yes" to the simplify prompt when reviewing performance-sensitive code -- the extra pass analyzes efficiency, concurrency, and hot-path optimizations.
- Make sure
grepaiis configured for your project (/brewcode:grepai) to get accurate duplicate detection results.
Documentation
Full docs: standards-review
Java/Kotlin Standards Reference
Standards for Java/Kotlin enterprise projects.
File Patterns
| Type | Patterns |
|---|---|
| Source | *.java, *.kt, *.kts |
| Build | pom.xml, build.gradle, build.gradle.kts |
| Tests | *Test.java, *Test.kt, *IT.java |
| Config | application.yml, application.properties |
Naming Conventions
Classes
| Type | Convention | Example | Verdict |
|---|---|---|---|
| Entity | *Entity suffix | UserEntity, OrderEntity | ✅ REQ |
| DTO Response | *Response suffix | UserResponse, OrderListResponse | ✅ REQ |
| DTO Request | *Request suffix | CreateUserRequest | ✅ REQ |
| Repository | *Repository suffix | UserRepository | ✅ REQ |
| Service | *Service suffix | UserService, OrderService | ✅ REQ |
| Controller | *Controller suffix | UserController | ✅ REQ |
Methods
| Pattern | Example | Status |
|---|---|---|
| Verbs for actions | createUser, findById | ✅ |
| Boolean prefix | isActive, hasPermission, canEdit | ✅ |
| Stream operations | toUserResponse, mapToEntity | ✅ |
Dependency Injection
| Rule | Evidence | Verdict |
|---|---|---|
| Constructor injection only | Spring recommends, testability | ✅ REQ |
@RequiredArgsConstructor + final fields | Lombok best practice | ✅ REQ |
No field injection (@Autowired on field) | Harder to test, hidden deps | ❌ VIOL |
Pattern:
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository; // final + constructor
private final EmailService emailService;
}Stream API & Functional Style
| Rule | Evidence | Verdict |
|---|---|---|
| Prefer Stream API over loops | Declarative, readable | ✅ REQ |
| Method references over lambdas | User::getName vs u -> u.getName() | ✅ PREF |
| No side effects in streams | Functional purity | ✅ REQ |
collect(Collectors.toList()) → toList() | Java 16+ | ✅ PREF |
Violations:
// ❌ Imperative loop
List<String> names = new ArrayList<>();
for (User user : users) {
names.add(user.getName());
}
// ✅ Stream API
List<String> names = users.stream()
.map(User::getName)
.toList();Immutability
| Pattern | Usage | Verdict |
|---|---|---|
final fields | All fields unless mutation required | ✅ REQ |
List.of(), Set.of(), Map.of() | Immutable collections | ✅ PREF |
@Value (Lombok) | Immutable DTOs | ✅ PREF |
@Builder | Complex object construction | ✅ PREF |
Library Usage Priority
Check existing libraries before writing utility code.
| Priority | Library | Common APIs |
|---|---|---|
| 1 | JDK | Objects, Optional, String, Math, Arrays, Collections, Files, Path |
| 2 | Apache Commons | StringUtils, CollectionUtils, Validate, FileUtils, IOUtils |
| 3 | Guava | Preconditions, Strings, Iterables, Lists, Maps, Multimap |
Common JDK Utilities: Null check → Objects.requireNonNull(x, "msg"), Empty → str.isBlank() / collection.isEmpty(), Null-safe equals → Objects.equals(a, b), Optional chain → Optional.ofNullable(x).map(...).orElse(...)
Lombok Annotations
| Annotation | Usage | Verdict |
|---|---|---|
@Slf4j | Logging | ✅ REQ |
@RequiredArgsConstructor | DI | ✅ REQ |
@Builder | Complex objects | ✅ PREF |
@Value | Immutable DTOs | ✅ PREF |
@Data | Mutable entities only | ⚠️ CAUTION |
@Getter/@Setter | Fine-grained control | ✅ OK |
Logging
| Rule | Evidence | Verdict |
|---|---|---|
Use @Slf4j | Lombok, SLF4J facade | ✅ REQ |
No System.out.println() | Not production-ready | ❌ VIOL |
| No logs in tests | Clutter, slow | ❌ VIOL |
| Main code: warn/error only | Performance | ✅ PREF |
| Parameterized logging | log.info("User: {}", userId) | ✅ REQ |
Test Patterns
Structure
| Rule | Pattern | Verdict |
|---|---|---|
| BDD comments | // GIVEN, // WHEN, // THEN | ✅ REQ |
@DisplayName on methods | Readable test names | ✅ REQ |
No @DisplayName on class | Redundant | ✅ PREF |
| No Javadoc in tests | Unnecessary | ✅ REQ |
AssertJ
| Pattern | Status |
|---|---|
.as("description") on every assertion | ✅ REQ |
assertThat(x).isEqualTo(y) | ✅ Specific value |
assertThat(list).hasSize(5) | ✅ Specific count |
assertThat(x).isNotNull() | ❌ Too weak |
assertThat(x).isNotEmpty() | ❌ Too weak |
assertThat(x).isGreaterThanOrEqualTo(0) | ❌ Too weak |
allSatisfy() over forEach | ✅ REQ |
extracting().contains(tuple()) | ✅ For collections |
Violations:
// ❌ Too weak
assertThat(result).isNotNull();
assertThat(list).isNotEmpty();
// ✅ Specific
assertThat(result).isEqualTo(expected);
assertThat(list).hasSize(3);No Conditionals
| Rule | Evidence | Verdict |
|---|---|---|
No if in tests | Unpredictable paths | ❌ VIOL |
| Assert preconditions first | Then unconditional assert | ✅ REQ |
// ❌ Conditional assertion
if (list.size() > 1) {
assertThat(list.get(1)).isEqualTo(expected);
}
// ✅ Assert precondition, then assert
assertThat(list).as("precondition").hasSizeGreaterThan(1);
assertThat(list.get(1)).as("second element").isEqualTo(expected);Kotlin-Specific
| Pattern | Usage | Verdict |
|---|---|---|
data class for DTOs | Immutable by default | ✅ REQ |
| Extension functions | Utility methods | ✅ PREF |
?.let {} over null checks | Idiomatic | ✅ PREF |
Duration conversion | 1.seconds.toJavaDuration() | ✅ REQ |
when over if-else chains | Exhaustive matching | ✅ PREF |
Spring Boot Patterns
| Pattern | Description | Verdict |
|---|---|---|
@Transactional on service | Not repository | ✅ REQ |
ResponseEntity<T> in controller | Proper HTTP responses | ✅ REQ |
@Valid on request body | Input validation | ✅ REQ |
| Profile-specific config | application-{profile}.yml | ✅ REQ |
SQL in Code
| Rule | Evidence | Verdict |
|---|---|---|
| No comments in SQL strings | Clutter logs | ✅ REQ |
Use .formatted() | Java 15+ string formatting | ✅ PREF |
| Named parameters | :paramName in JPA | ✅ REQ |
Common Violations Summary
| # | Violation | Fix |
|---|---|---|
| 1 | Missing Entity suffix | Add Entity to JPA entities |
| 2 | Field injection | Use constructor injection |
| 3 | Loop instead of Stream | Convert to Stream API |
| 4 | System.out.println | Use @Slf4j |
| 5 | Missing .as() in test | Add description to assertion |
| 6 | isNotNull() assertion | Use specific value assertion |
| 7 | if in test | Assert precondition first |
| 8 | Writing utility that exists | Check JDK/Commons/Guava |
| 9 | Logs in tests | Remove all logging |
| 10 | @Autowired on field | Constructor injection |
Tools
| Tool | Purpose |
|---|---|
| Maven/Gradle | Build |
| Spring Boot | Framework |
| JUnit 5 | Testing |
| AssertJ | Assertions |
| Mockito | Mocking |
| Lombok | Boilerplate |
| WireMock | HTTP mocking |
Python Standards Reference
Standards for modern Python projects.
File Patterns
| Type | Patterns |
|---|---|
| Source | *.py |
| Tests | test_*.py, *_test.py, **/tests/*.py |
| Config | pyproject.toml, setup.py, setup.cfg, requirements.txt |
| Types | py.typed, *.pyi |
Type Hints
Required Annotations
| Location | Requirement | Verdict |
|---|---|---|
| Function parameters | All params typed | ✅ REQ |
| Function returns | Return type annotated | ✅ REQ |
| Class attributes | Typed in __init__ or class body | ✅ REQ |
| Module-level vars | Type annotation | ✅ PREF |
Pattern:
# ✅ Fully typed
def process_user(user_id: int, options: dict[str, Any] | None = None) -> User:
...
# ❌ Missing types
def process_user(user_id, options=None):
...Common Type Patterns
| Need | Type | Example |
|---|---|---|
| Optional | `X | None` |
| List | list[X] | items: list[str] |
| Dict | dict[K, V] | mapping: dict[str, int] |
| Callable | Callable[[Args], Return] | handler: Callable[[int], str] |
| Any dict | dict[str, Any] | Config objects |
| Union | `X | Y` |
Python 3.10+: UseX | YoverUnion[X, Y],list[X]overList[X]
Docstrings
Required Locations
| Location | Requirement | Verdict |
|---|---|---|
| Modules | Module-level docstring | ✅ REQ |
| Public classes | Class docstring | ✅ REQ |
| Public functions | Function docstring | ✅ REQ |
Private (_*) | Optional | ⚠️ PREF |
Format (Google Style)
def fetch_user(user_id: int, include_profile: bool = False) -> User | None:
"""Fetch user by ID from database.
Args:
user_id: The unique identifier of the user.
include_profile: Whether to include full profile data.
Returns:
User object if found, None otherwise.
Raises:
DatabaseError: If database connection fails.
"""Naming Conventions
| Type | Convention | Example |
|---|---|---|
| Modules | snake_case | user_service.py |
| Classes | PascalCase | UserService |
| Functions | snake_case | get_user_by_id |
| Constants | UPPER_SNAKE | MAX_RETRIES |
| Private | _prefix | _internal_method |
| Protected | __prefix | __mangled_name |
Imports
Order (isort)
| Order | Type | Example |
|---|---|---|
| 1 | Standard library | import os, from pathlib import Path |
| 2 | Third-party | import requests, from pydantic import BaseModel |
| 3 | Local | from .models import User, from myapp.utils import ... |
Style
| Rule | Evidence | Verdict |
|---|---|---|
| Absolute imports | Clarity | ✅ PREF |
| One import per line | Readability | ✅ PREF |
| No wildcard imports | Namespace pollution | ❌ VIOL |
| Group by package | Organization | ✅ REQ |
# ✅ Good
from collections.abc import Callable, Iterable
from pathlib import Path
import httpx
from pydantic import BaseModel, Field
from myapp.models import User
from myapp.utils import validate
# ❌ Bad
from os import *
from myapp.utils import validate, parse, format, convert, transformClasses
Dataclasses
| Rule | Evidence | Verdict |
|---|---|---|
Use @dataclass for data | Less boilerplate | ✅ PREF |
frozen=True for immutable | Thread safety | ✅ PREF |
| Pydantic for validation | Input validation | ✅ PREF |
# ✅ Dataclass
from dataclasses import dataclass
@dataclass(frozen=True)
class User:
id: int
name: str
email: str | None = None
# ✅ Pydantic (with validation)
from pydantic import BaseModel, EmailStr
class UserCreate(BaseModel):
name: str
email: EmailStrNo __init__ Boilerplate
| Pattern | When | Example |
|---|---|---|
@dataclass | Simple data containers | Most DTOs |
pydantic.BaseModel | Validation needed | API inputs |
attrs | Advanced features | Complex models |
Error Handling
Exceptions
| Rule | Evidence | Verdict |
|---|---|---|
| Custom exceptions | Clear error types | ✅ PREF |
| Specific catch | No bare except: | ✅ REQ |
| Chain exceptions | raise X from e | ✅ REQ |
| Context managers | Resource cleanup | ✅ REQ |
# ✅ Specific exception handling
try:
user = fetch_user(user_id)
except UserNotFoundError:
logger.warning(f"User {user_id} not found")
raise
except DatabaseError as e:
raise ServiceError("Database unavailable") from e
# ❌ Bare except
try:
...
except: # Catches everything including KeyboardInterrupt
passTesting
pytest Patterns
| Rule | Evidence | Verdict |
|---|---|---|
| pytest over unittest | Modern, less boilerplate | ✅ PREF |
| Fixtures for setup | Reusable, composable | ✅ REQ |
| Parametrize for variants | DRY testing | ✅ PREF |
conftest.py for shared | Fixture organization | ✅ REQ |
Structure
# test_user_service.py
import pytest
from myapp.services import UserService
class TestUserService:
"""Tests for UserService."""
def test_get_user_returns_user_when_exists(self, user_service: UserService, sample_user: User):
# GIVEN
user_id = sample_user.id
# WHEN
result = user_service.get_user(user_id)
# THEN
assert result is not None
assert result.id == user_id
assert result.name == sample_user.name
def test_get_user_returns_none_when_not_found(self, user_service: UserService):
# GIVEN
nonexistent_id = 99999
# WHEN
result = user_service.get_user(nonexistent_id)
# THEN
assert result is NoneAssertions
| Pattern | Usage | Verdict |
|---|---|---|
assert x == expected | Equality | ✅ |
assert x is None | None check | ✅ |
pytest.raises(Error) | Exception testing | ✅ REQ |
pytest.approx(x) | Float comparison | ✅ REQ |
Logging
| Rule | Evidence | Verdict |
|---|---|---|
Use logging module | Standard, configurable | ✅ REQ |
No print() in prod | Not production-ready | ❌ VIOL |
| Lazy formatting | log.info("User: %s", user_id) | ✅ PREF |
| Logger per module | logging.getLogger(__name__) | ✅ REQ |
# ✅ Proper logging
import logging
logger = logging.getLogger(__name__)
def process(data: dict) -> None:
logger.info("Processing data: %s", data.get("id"))
# ...
logger.error("Failed to process: %s", error, exc_info=True)
# ❌ Print statements
def process(data):
print(f"Processing {data}")Code Style
Line Length & Formatting
| Tool | Purpose | Config |
|---|---|---|
| Black | Formatting | pyproject.toml |
| Ruff | Linting (fast) | pyproject.toml |
| isort | Import sorting | pyproject.toml |
| mypy | Type checking | pyproject.toml |
Comprehensions
| Pattern | When | Verdict |
|---|---|---|
| List comprehension | Simple transforms | ✅ PREF |
| Generator expression | Large/lazy iteration | ✅ PREF |
map()/filter() | Simple function application | ✅ OK |
| Multi-line for complex | >1 condition/transform | ✅ OK |
# ✅ Simple comprehension
names = [user.name for user in users if user.active]
# ✅ Generator for large data
active_ids = (user.id for user in users if user.active)
# ✅ Multi-line for complex
results = [
transform(item)
for item in items
if item.valid
if item.score > threshold
]Common Violations Summary
| # | Violation | Fix |
|---|---|---|
| 1 | Missing type hints | Add parameter and return types |
| 2 | No docstring | Add Google-style docstring |
| 3 | Bare except: | Catch specific exceptions |
| 4 | print() in production | Use logging module |
| 5 | Wildcard import | Import specific names |
| 6 | Missing from e in reraise | Chain exceptions properly |
| 7 | Mutable default argument | Use None + conditional |
| 8 | No __init__.py | Add for package recognition |
| 9 | Union[X, Y] on 3.10+ | Use `X |
| 10 | No type: ignore comment | Fix type error or add explanation |
Search Locations
| Type | Paths |
|---|---|
| Utils | **/utils/, **/helpers/, **/lib/ |
| Models | **/models/, **/schemas/, **/entities/ |
| Services | **/services/, **/core/ |
| Tests | **/tests/, test_*.py |
| Config | **/config/, **/settings/ |
Dependency Management
| Tool | Config File | Verdict |
|---|---|---|
| Poetry | pyproject.toml | ✅ PREF |
| pip-tools | requirements.in → requirements.txt | ✅ OK |
| pip | requirements.txt | ⚠️ BASIC |
Tools
| Tool | Purpose |
|---|---|
| pip/poetry | Package management |
| pytest | Testing |
| mypy | Type checking |
| Black | Formatting |
| Ruff | Fast linting |
| isort | Import sorting |
| coverage | Test coverage |
TypeScript/React Standards Reference
Standards for TypeScript/React projects.
File Patterns
| Type | Patterns |
|---|---|
| Components | *.tsx, *.jsx |
| Logic | *.ts, *.js |
| Styles | *.styled.ts, **/styles.ts, *.css, *.scss |
| Tests | *.test.tsx, *.spec.ts, **/__tests__/* |
| Config | package.json, tsconfig.json, .eslintrc* |
Component Patterns
Functional Components Only
| Rule | Evidence | Verdict |
|---|---|---|
| Functional components | React 18+ standard | ✅ REQ |
| No class components | Legacy pattern | ❌ VIOLATION |
| Arrow functions for components | Consistent style | ✅ PREF |
Pattern:
// ✅ Functional component
const UserCard: React.FC<UserCardProps> = ({ user, onEdit }) => {
return <div>{user.name}</div>;
};
// ❌ Class component
class UserCard extends React.Component { ... }Component Structure
| Order | Section |
|---|---|
| 1 | Type definitions (Props, State) |
| 2 | Component declaration |
| 3 | Hooks (useState, useEffect, custom) |
| 4 | Handlers (event handlers, callbacks) |
| 5 | Render helpers (if needed) |
| 6 | Return JSX |
Hooks
Built-in Hooks
| Hook | Usage | Common Mistakes |
|---|---|---|
useState | Local state | Over-using for derived state |
useEffect | Side effects | Missing cleanup, deps array |
useMemo | Expensive calculations | Premature optimization |
useCallback | Stable callbacks | Over-using everywhere |
useRef | DOM refs, mutable values | Using for state |
Custom Hooks
| Rule | Evidence | Verdict |
|---|---|---|
| Extract reusable logic | DRY principle | ✅ REQ |
use* prefix | React convention | ✅ REQ |
| Return object for >2 values | Destructuring clarity | ✅ PREF |
Check existing hooks before creating: hooks/ or **/hooks/ directories, use*.ts files, grepai_search for similar functionality
Styling
Theme Tokens
| Rule | Evidence | Verdict |
|---|---|---|
| Use theme tokens | Consistency, theming | ✅ REQ |
| No hardcoded colors | #fff, rgb() | ❌ VIOLATION |
| No hardcoded spacing | 8px, 16px | ❌ VIOLATION |
| No hardcoded fonts | Arial, 16px | ❌ VIOLATION |
Violations:
// ❌ Hardcoded values
const Button = styled.button`
color: #3498db;
padding: 8px 16px;
font-size: 14px;
`;
// ✅ Theme tokens
const Button = styled.button`
color: ${({ theme }) => theme.colors.primary};
padding: ${({ theme }) => theme.spacing.sm} ${({ theme }) => theme.spacing.md};
font-size: ${({ theme }) => theme.typography.body.size};
`;Styled Components
| Rule | Evidence | Verdict |
|---|---|---|
| Colocate styles | Component-scoped | ✅ PREF |
| Extend base components | Reuse patterns | ✅ REQ |
Check Components/Common/ | Avoid duplication | ✅ REQ |
TypeScript
Type Safety
| Rule | Evidence | Verdict |
|---|---|---|
| Explicit prop types | Type safety | ✅ REQ |
No any type | Type erasure | ❌ VIOLATION |
unknown over any | Safe narrowing | ✅ PREF |
| Interface for objects | Extensible | ✅ PREF |
| Type for unions/primitives | Clarity | ✅ PREF |
Common Patterns
// ✅ Props interface
interface UserCardProps {
user: User;
onEdit?: (id: string) => void;
isLoading?: boolean;
}
// ✅ Discriminated unions
type ApiResponse<T> =
| { status: 'success'; data: T }
| { status: 'error'; error: string };
// ❌ Avoid any
const handleData = (data: any) => { ... }
// ✅ Use unknown + narrowing
const handleData = (data: unknown) => {
if (isUser(data)) { ... }
};State Management
Local vs Global
| Scope | Solution | When |
|---|---|---|
| Component | useState | UI state, form inputs |
| Subtree | Context + useReducer | Theme, auth, localized state |
| Global | Redux/Zustand/Jotai | Cross-cutting, cached data |
Avoid Prop Drilling
| Depth | Solution |
|---|---|
| 2-3 levels | Props OK |
| 4+ levels | Context or state management |
Testing
Jest + React Testing Library
| Rule | Evidence | Verdict |
|---|---|---|
| Test behavior, not implementation | RTL philosophy | ✅ REQ |
| Query by role/label | Accessibility | ✅ PREF |
screen over destructure | Clarity | ✅ PREF |
userEvent over fireEvent | Realistic events | ✅ PREF |
Queries Priority:
| Priority | Query | When |
|---|---|---|
| 1 | getByRole | Buttons, inputs, headings |
| 2 | getByLabelText | Form fields |
| 3 | getByText | Static text |
| 4 | getByTestId | Last resort |
Test Structure
describe('UserCard', () => {
it('renders user name', () => {
// GIVEN
const user = { id: '1', name: 'John' };
// WHEN
render(<UserCard user={user} />);
// THEN
expect(screen.getByText('John')).toBeInTheDocument();
});
});Performance
Memoization
| Pattern | When | Verdict |
|---|---|---|
React.memo | Expensive render, stable props | ✅ AS NEEDED |
useMemo | Expensive calculations | ✅ AS NEEDED |
useCallback | Stable callback for child | ✅ AS NEEDED |
Avoid premature optimization. Profile first, optimize second.
Code Splitting
| Pattern | Usage |
|---|---|
React.lazy() | Route-level splitting |
| Dynamic imports | Feature modules |
| Suspense boundaries | Loading states |
Common Violations Summary
| # | Violation | Fix |
|---|---|---|
| 1 | Hardcoded colors | Use theme tokens |
| 2 | Class component | Convert to functional |
| 3 | Missing TypeScript types | Add explicit types |
| 4 | any type | Use unknown or specific type |
| 5 | Duplicate styled component | Check Common/, extend existing |
| 6 | Missing useEffect cleanup | Return cleanup function |
| 7 | Prop drilling >3 levels | Use Context |
| 8 | Testing implementation | Test behavior/output |
| 9 | No error boundary | Add for async components |
| 10 | Inline function in render | Extract to useCallback |
Search Locations
| Type | Paths |
|---|---|
| Common components | **/components/common/, **/components/shared/ |
| Hooks | **/hooks/, **/use*.ts |
| Utils | **/utils/, **/helpers/ |
| Types | **/types/, **/*.types.ts |
| Styles/Theme | **/theme/, **/styles/ |
Function Declaration Style
| Pattern | Usage | Verdict |
|---|---|---|
| Arrow function | Components, callbacks | ✅ PREF |
| Function declaration | Hoisted utilities | ✅ OK |
| Consistent per file | Pick one style | ✅ REQ |
Import Order
| Order | Type |
|---|---|
| 1 | React |
| 2 | External libraries |
| 3 | Internal modules (absolute) |
| 4 | Relative imports |
| 5 | Styles/assets |
Tools
| Tool | Purpose |
|---|---|
| npm/yarn/pnpm | Package management |
| TypeScript | Type safety |
| ESLint | Linting |
| Prettier | Formatting |
| Jest | Testing |
| React Testing Library | Component testing |
| Storybook | Component docs |