- Add release-gate.yml: 11-job pipeline (lint, tests, Docker build/smoke, Trivy scan, dep audit, audit checks, e2e API+UI, PR summary comment) - Fix CI double-trigger on release branches (push + PR) - Add CODE_OF_CONDUCT.md, SECURITY.md, PR template - Add docs: git-workflow, architecture (ADR), release, operations, community - Add profiles/fastapi-vue for automated audit checks - Add docs/PROCESSES.md: index of 19 available processes
3.2 KiB
3.2 KiB
Coding Standards
Conventions for writing consistent, readable code across the Docling Studio codebase.
Python (Backend — document-parser/)
Tooling
| Tool | Purpose | Config |
|---|---|---|
| Ruff | Linting + formatting | ruff.toml / pyproject.toml |
| pytest | Testing | pytest.ini / pyproject.toml |
| mypy (optional) | Type checking | — |
Naming
| Element | Convention | Example |
|---|---|---|
| Modules | snake_case |
analysis_repo.py |
| Classes | PascalCase |
AnalysisJob, DocumentConverter |
| Functions / methods | snake_case |
create_analysis() |
| Constants | UPPER_SNAKE_CASE |
MAX_CONCURRENT_ANALYSES |
| Private | _leading_underscore |
_build_converter() |
Style Rules
- Max function length: 30 lines (soft limit — justify longer ones)
- Max file length: 300 lines (split into modules if exceeded)
- Imports: standard library → third-party → local, separated by blank lines
- Type hints on all public functions
- Docstrings only on non-obvious public APIs (don't state the obvious)
- No
# type: ignorewithout a comment explaining why
Architecture Rules
- Domain layer (
domain/): zero imports fromapi/,persistence/,infra/ - Persistence layer (
persistence/): only imports fromdomain/ - API layer (
api/): never imports frompersistence/directly — goes throughservices/ - Services (
services/): orchestrate, don't implement — delegate to domain and infra
TypeScript / Vue (Frontend — frontend/src/)
Tooling
| Tool | Purpose | Config |
|---|---|---|
| ESLint | Linting | .eslintrc.* |
| Prettier | Formatting | .prettierrc |
| vue-tsc | Type checking | tsconfig.json |
| Vitest | Testing | vitest.config.ts |
Naming
| Element | Convention | Example |
|---|---|---|
| Components | PascalCase.vue |
BboxOverlay.vue |
| Composables | useCamelCase.ts |
usePagination.ts |
| Stores | camelCase.ts |
analysisStore.ts |
| Types / Interfaces | PascalCase |
AnalysisJob, BboxRect |
| Constants | UPPER_SNAKE_CASE |
DEFAULT_PAGE_SIZE |
| CSS classes | kebab-case |
.bbox-overlay |
data-e2e attributes |
kebab-case |
data-e2e="upload-zone" |
Style Rules
- Composition API only (
<script setup lang="ts">) — no Options API - One component per file
- Props defined with
defineProps<T>()(type-based, not runtime) - Emits defined with
defineEmits<T>() - Pinia stores: one per feature, in the feature directory
- No global state outside Pinia
- API calls only in
api.tsfiles (never in components or stores directly)
API Contract
- Frontend sends/receives camelCase (Pydantic
alias_generator) - Backend uses snake_case internally
pages_jsonis an exception — contains raw snake_case fromdataclasses.asdict()
Karate (E2E — e2e/)
See e2e/CONVENTIONS.md for detailed rules.
Key points:
- Use
data-e2eselectors, never CSS classes - Use
retry()/waitFor(), neverThread.sleep()ordelay() - Setup via API, verify via UI, cleanup via API
- Tag tests:
@critical,@ui,@smoke,@regression,@e2e