Code Style¶
Python (Backend)¶
Formatter and Linter¶
The backend uses Ruff for both formatting and linting.
Configuration: backend/pyproject.toml
[tool.ruff]
target-version = "py311"
line-length = 100
[tool.ruff.lint]
select = ["E", "W", "F", "I", "UP", "B", "SIM", "RUF"]
ignore = ["E501", "B008", "RUF012"]
[tool.ruff.lint.per-file-ignores]
"app/main.py" = ["E402"]
[tool.ruff.lint.isort]
known-first-party = ["app"]
[tool.ruff.format]
quote-style = "double"
Rules¶
| Code | Category | Description |
|---|---|---|
E |
pycodestyle errors | Basic style errors |
W |
pycodestyle warnings | Style warnings |
F |
pyflakes | Logical errors, unused imports |
I |
isort | Import sorting |
UP |
pyupgrade | Python version upgrades |
B |
flake8-bugbear | Common bug patterns |
SIM |
flake8-simplify | Code simplification |
RUF |
Ruff-specific | Ruff's own rules |
Commands¶
# Format code
make fmt
# Check linting (no auto-fix)
make lint-backend
Key Conventions¶
- Line length: 100 characters
- Quotes: Double quotes (
") - Imports: Sorted by isort (stdlib → third-party → local)
- Type hints: Use modern syntax (
list[str]notList[str],str | NonenotOptional[str]) - Async: Use
async/awaitfor all I/O operations
TypeScript (Frontend)¶
Linter¶
The frontend uses ESLint with the Next.js configuration.
Configuration: frontend/eslint.config.mjs
import { defineConfig, globalIgnores } from "eslint/config";
import nextVitals from "eslint-config-next/core-web-vitals";
import nextTs from "eslint-config-next/typescript";
const eslintConfig = defineConfig([
...nextVitals,
...nextTs,
{
rules: {
"@typescript-eslint/no-unused-vars": [
"warn",
{ argsIgnorePattern: "^_" },
],
},
},
globalIgnores([
".next/**",
"out/**",
"build/**",
"next-env.d.ts",
"src/lib/generated/**",
]),
]);
export default eslintConfig;
Commands¶
# Lint frontend
make lint-frontend
# Type check
make typecheck
Key Conventions¶
- Strict TypeScript: Enabled in
tsconfig.json - ESLint: Core Web Vitals + TypeScript rules
- Imports: Use absolute imports from
@/(maps tosrc/)
Auto-Generated Code¶
Files in frontend/src/lib/generated/ are auto-generated from the backend OpenAPI spec.
Warning
Do not edit files in src/lib/generated/ manually. They are overwritten by make generate-api.
To regenerate after backend model changes:
# With backend running
make generate-api
General Conventions¶
- Commit messages: Use conventional format —
feat:,fix:,docs:,kb:, etc. - Branch names: Descriptive with prefixes —
feat/,fix/,docs/,kb/ - Run
make checkbefore committing to catch lint, type, and test issues early