Code Quality Standards¶
Overview¶
RAG Modulo enforces consistent code quality through centralized linting configuration across all development environments. This ensures that code quality checks are identical whether you're developing locally, running pre-commit hooks, or in CI/CD pipelines.
๐ฏ Design Principle: Single Source of Truth¶
All linting configurations reference a central configuration file to maintain consistency:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ SINGLE SOURCE OF TRUTH โ
โ โ
โ Backend: backend/pyproject.toml โ
โ Frontend: frontend/.eslintrc.json โ
โ frontend/.prettierrc.json โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โ Referenced by
โ
โโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโ
โ โ โ
โผ โผ โผ
โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ
โ Local โ โ Pre- โ โ CI/CD โ
โ Dev โ โ Commit โ โ Pipeline โ
โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ
๐ Linting Tool Versions (Updated: 2025-10-08)¶
| Tool | Version | Purpose | Blocking |
|---|---|---|---|
| Ruff | 0.14.0 | Python linting & formatting | โ Yes |
| MyPy | 1.15.0 | Python type checking | โ ๏ธ Informational |
| Pylint | 3.3.8+ | Python code quality | โ ๏ธ Informational |
| Pydocstyle | 6.3.0+ | Python docstring style | โ ๏ธ Informational |
| ESLint | (react-app) | TypeScript/JavaScript linting | โ Yes |
| Prettier | Latest | Code formatting | โ Yes |
๐๏ธ Architecture: Three Enforcement Layers¶
graph TB
subgraph "Layer 1: Local Development"
A1[Developer writes code]
A2[IDE shows linting errors]
A3[make lint]
A4[Fix issues]
end
subgraph "Layer 2: Pre-Commit Hooks"
B1[git commit]
B2[Pre-commit hook runs]
B3{All checks pass?}
B4[Auto-fix if possible]
B5[Commit blocked]
B6[Commit succeeds]
end
subgraph "Layer 3: CI/CD Pipeline"
C1[Push to GitHub]
C2[GitHub Actions triggers]
C3[Parallel linting jobs]
C4[Blocking checks]
C5[Informational checks]
C6{All blocking pass?}
C7[PR approved]
C8[PR blocked]
end
A1 --> A2
A2 --> A3
A3 --> A4
A4 --> B1
B1 --> B2
B2 --> B3
B3 -->|No| B4
B4 --> B5
B3 -->|Yes| B6
B5 -.Fix.-> A1
B6 --> C1
C1 --> C2
C2 --> C3
C3 --> C4
C3 --> C5
C4 --> C6
C6 -->|Yes| C7
C6 -->|No| C8
C8 -.Fix.-> A1 ๐ Backend Python Linting Rules¶
Configuration Location¶
Central Config: backend/pyproject.toml
Scope¶
All Python files in: - โ
backend/rag_solution/ (main application) - โ
backend/vectordbs/ (vector database abstractions) - โ
backend/core/ (core utilities) - โ
backend/auth/ (authentication) - โ
backend/tests/ (test suite)
Ruff Configuration¶
[tool.ruff]
target-version = "py312"
line-length = 120
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"F", # pyflakes
"I", # isort (import sorting)
"W", # pycodestyle warnings
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"UP", # pyupgrade
"N", # pep8-naming
"Q", # flake8-quotes
"SIM", # flake8-simplify
"ARG", # flake8-unused-arguments
"PIE", # flake8-pie
"TID", # flake8-tidy-imports
"RUF", # Ruff-specific rules
]
[tool.ruff.lint.isort]
known-first-party = ["rag_solution", "core", "auth", "vectordbs"]
Import Sorting Rules (isort via Ruff)¶
Imports are sorted in this order:
"""Module docstring."""
# 1. Standard library
import json
import logging
from typing import Any
# 2. Third-party libraries
from fastapi import APIRouter, Depends
from pydantic import BaseModel
from sqlalchemy.orm import Session
# 3. First-party (our code)
from core.config import Settings
from rag_solution.services.my_service import MyService
Type Checking (MyPy)¶
[tool.mypy]
python_version = "3.12"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
๐จ Frontend TypeScript/JavaScript Linting¶
Configuration Location¶
- ESLint:
frontend/.eslintrc.json - Prettier:
frontend/.prettierrc.json(if added)
Scope¶
All TypeScript and JavaScript files in: - โ
frontend/src/ (React application) - โ
frontend/public/ (static assets)
ESLint Rules¶
{
"extends": [
"react-app",
"react-app/jest"
],
"rules": {
"no-console": ["warn", { "allow": ["warn", "error"] }],
"no-unused-vars": "warn",
"@typescript-eslint/no-unused-vars": ["warn", {
"argsIgnorePattern": "^_"
}],
"react-hooks/exhaustive-deps": "warn"
}
}
๐ Command Reference¶
Local Development¶
# Backend linting
make lint # Run all backend linting
make lint-ruff # Ruff only (fast)
make lint-mypy # Type checking
make lint-pylint # Code quality
make fix-all # Auto-fix issues
# Frontend linting
cd frontend
npm run lint # ESLint check
npm run format:check # Prettier check
npm run format # Auto-fix formatting
Pre-Commit Hooks¶
# Install hooks (one-time setup)
pre-commit install
# Run manually
pre-commit run --all-files
# Run on specific files
pre-commit run --files backend/rag_solution/router/*.py
# Update hook versions
pre-commit autoupdate
CI/CD Pipeline¶
Automatically runs on: - All pull requests to main - All pushes to main
Workflow: .github/workflows/01-lint.yml
๐ Linting Checklist Matrix¶
| Check | Layer 1: Local | Layer 2: Pre-commit | Layer 3: CI/CD | Blocking |
|---|---|---|---|---|
| Backend | ||||
| Ruff (Lint + Format) | make lint-ruff | โ Auto-runs | โ Combined job | โ Yes |
| MyPy | make lint-mypy | โ On push only | โ Parallel job | โ ๏ธ No |
| Pylint | make lint-pylint | โ Manual | โ Parallel job | โ ๏ธ No |
| Pydocstyle | Manual | โ Manual | โ Parallel job | โ ๏ธ No |
| Frontend | ||||
| ESLint | npm run lint | โ Auto-runs | โ Parallel job | โ Yes |
| Prettier | npm run format:check | โ Auto-runs | โ Parallel job | โ Yes |
| Config Files | ||||
| YAML Lint | Manual | โ Auto-runs | โ Parallel job | โ Yes |
| JSON Lint | Manual | โ Auto-runs | โ Parallel job | โ Yes |
| TOML Lint | Manual | โ Auto-runs | โ Parallel job | โ Yes |
๐ง Configuration Files Reference¶
rag_modulo/
โโโ .pre-commit-config.yaml # Pre-commit hook configuration
โโโ .github/workflows/
โ โโโ 01-lint.yml # CI/CD linting workflow
โโโ Makefile # Local development commands
โโโ backend/
โ โโโ pyproject.toml # โญ Backend linting central config
โโโ frontend/
โโโ .eslintrc.json # โญ Frontend ESLint config
โโโ .prettierrc.json # โญ Frontend Prettier config (TBD)
๐ฏ Blocking vs. Informational Checks¶
Blocking Checks (Must Pass)¶
These block PR merges and commits:
- โ Ruff (linting + formatting combined)
- โ ESLint (TypeScript/JavaScript)
- โ Prettier (formatting)
- โ YAML/JSON/TOML syntax
Informational Checks (Advisory)¶
These show warnings but don't block:
- โ ๏ธ MyPy (type checking - 150+ errors being addressed)
- โ ๏ธ Pylint (code quality suggestions)
- โ ๏ธ Pydocstyle (docstring completeness)
Why? We're progressively improving type coverage and documentation. These checks provide guidance without blocking development.
๐จ Common Issues & Solutions¶
Issue: Pre-commit hook fails but local lint passes¶
Cause: Different Ruff versions Solution: Update pre-commit hooks
Issue: Import order differs between local and CI¶
Cause: Missing known-first-party configuration Solution: Ensure backend/pyproject.toml includes all first-party packages:
Issue: MyPy fails in CI but not locally¶
Cause: Missing type stubs or dependencies Solution: Check tool.poetry.group.dev.dependencies includes all types-* packages
Issue: Linting is too slow¶
Solutions: 1. Run only Ruff (fast): make lint-ruff 2. Skip MyPy locally: SKIP_MYPY=1 make lint 3. Use pre-commit on changed files only: pre-commit run
๐ Related Documentation¶
๐ Version History¶
| Date | Version | Changes |
|---|---|---|
| 2025-10-08 | v2.0 | Centralized config, Ruff 0.14.0, all backend files |
| 2025-09-30 | v1.1 | Added frontend linting |
| 2025-09-01 | v1.0 | Initial linting standards |
๐ค Contributing¶
When adding new linting rules:
- Update central config (
pyproject.tomlor.eslintrc.json) - Update pre-commit hooks (
.pre-commit-config.yaml) - Update CI/CD workflow (
.github/workflows/01-lint.yml) - Update Makefile (add new make targets)
- Update this documentation
- Test all three layers (local, pre-commit, CI/CD)
Remember: One change, three updates!