Skip to content

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

pre-commit autoupdate
pre-commit install --install-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:

[tool.ruff.lint.isort]
known-first-party = ["rag_solution", "core", "auth", "vectordbs"]

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

๐Ÿ”„ 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:

  1. Update central config (pyproject.toml or .eslintrc.json)
  2. Update pre-commit hooks (.pre-commit-config.yaml)
  3. Update CI/CD workflow (.github/workflows/01-lint.yml)
  4. Update Makefile (add new make targets)
  5. Update this documentation
  6. Test all three layers (local, pre-commit, CI/CD)

Remember: One change, three updates!