skills/code-quality/SKILL.md
Code quality review checklist and enforcement guide. KISS, DRY, YAGNI principles plus concrete code smells and their fixes. Use before marking any task complete.
npx skillsauth add a2mus/ecc-antigravity code-qualityInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Run through this before considering any feature done:
i, j)except: pass)# WRONG — over-engineered
class LayerProcessorFactory:
def create_processor(self, strategy_type: str) -> LayerProcessor:
if strategy_type == "simple":
return SimpleLayerProcessor(SimpleStrategy())
...
# CORRECT — solve the actual problem
def process_layer(layer: QgsVectorLayer) -> list[dict]:
return [feature.attributes() for feature in layer.getFeatures()]
# WRONG — duplicated validation logic
def process_file(path):
if not path.exists():
raise FileNotFoundError(path)
...
def load_config(path):
if not path.exists():
raise FileNotFoundError(path)
...
# CORRECT — extract to shared function
def require_file(path: Path) -> Path:
if not path.exists():
raise FileNotFoundError(f"Required file not found: {path}")
return path
def process_file(path): require_file(path); ...
def load_config(path): require_file(path); ...
# WRONG — building for imagined future requirements
class DataProcessor:
def process(self, data, strategy=None, plugin=None,
validator=None, transformer=None): # nobody asked for this
...
# CORRECT — solve TODAY's problem
def process_data(data: list[dict]) -> list[dict]:
return [transform(item) for item in data if is_valid(item)]
# SMELL
def handle_request(request):
if request:
if request.user:
if request.user.is_authenticated:
if request.data:
return process(request.data)
# FIX
def handle_request(request):
if not request:
return None
if not request.user or not request.user.is_authenticated:
raise PermissionError("Authentication required")
if not request.data:
raise ValueError("Request data is required")
return process(request.data)
# SMELL
if layer.featureCount() > 50000:
use_chunked_processing()
# FIX
MAX_FEATURES_IN_MEMORY = 50_000
if layer.featureCount() > MAX_FEATURES_IN_MEMORY:
use_chunked_processing()
# SMELL — a 80-line function doing 5 things
def process_and_export_layer(layer, output_path, format, crs, fields):
# validate ...
# transform ...
# reproject ...
# filter fields ...
# export ...
# FIX — each step is its own focused function
def process_and_export_layer(layer, output_path, format, crs, fields):
validated = validate_layer(layer)
reprojected = reproject_to(validated, crs)
filtered = select_fields(reprojected, fields)
export_layer(filtered, output_path, format)
# SMELL — the list is shared between calls!
def add_item(item, items=[]):
items.append(item)
return items
# FIX
def add_item(item, items=None):
if items is None:
items = []
items.append(item)
return items
refactor: extract validate_layer helperdevelopment
Test-Driven Development workflow. Enforces RED → GREEN → REFACTOR cycle with 80% coverage gate. Use for all new features and bug fixes.
testing
Security audit checklist and workflow. Run before commits, PRs, or deploying. Covers secrets detection, input validation, OWASP Top 10, and dependency scanning.
tools
Research-before-coding workflow. Search for existing tools, libraries, and patterns before writing custom code. Use whenever adding new functionality.
development
Comprehensive Python idioms, best practices, and patterns. Covers dataclasses, type hints, async, error handling, testing, and QGIS-specific patterns.