docs: add full project documentation
- Architecture: overview, 7 ADR, tech stack - Principles: code-style, git-workflow, security - API contracts: auth, profile, tests, admin endpoints - Database schema: tables, relationships, indexes - LLM strategy: prompts, fallback, validation, Qwen 2.5 14B - Onboarding: setup, Docker, .env template - Progress: roadmap, changelog - Agents: context, backend instructions Made-with: Cursor
This commit is contained in:
189
principles/code-style.md
Normal file
189
principles/code-style.md
Normal file
@@ -0,0 +1,189 @@
|
||||
# Code style
|
||||
|
||||
## Языковые соглашения
|
||||
|
||||
| Что | Язык |
|
||||
| ----- | ------ |
|
||||
| Код (переменные, функции, комментарии) | Английский |
|
||||
| Коммиты | Английский (conventional commits) |
|
||||
| Документация | Русский |
|
||||
|
||||
## Общие правила
|
||||
|
||||
- **TypeScript strict mode** — всегда. `any` запрещён, допускается только с явным комментарием-обоснованием
|
||||
- **`console.log` в production-коде запрещён** — только через Pino logger
|
||||
- **Форматтер: Prettier** — конфиг фиксирован в репо, не обсуждается
|
||||
- **Линтер: ESLint** — strict + security plugin
|
||||
- **Тесты: Vitest** — минимум 70% покрытие на сервисном слое
|
||||
|
||||
## Prettier
|
||||
|
||||
```json
|
||||
{
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "all",
|
||||
"printWidth": 100,
|
||||
"endOfLine": "lf"
|
||||
}
|
||||
```
|
||||
|
||||
```text
|
||||
// .prettierignore
|
||||
dist/
|
||||
node_modules/
|
||||
*.sql
|
||||
```
|
||||
|
||||
## ESLint (backend)
|
||||
|
||||
Flat config (ESLint 9+):
|
||||
|
||||
```bash
|
||||
npm install -D \
|
||||
eslint \
|
||||
@eslint/js \
|
||||
typescript-eslint \
|
||||
eslint-plugin-import \
|
||||
eslint-plugin-security \
|
||||
eslint-config-prettier
|
||||
```
|
||||
|
||||
```ts
|
||||
// eslint.config.ts
|
||||
import js from '@eslint/js'
|
||||
import tseslint from 'typescript-eslint'
|
||||
import security from 'eslint-plugin-security'
|
||||
import importPlugin from 'eslint-plugin-import'
|
||||
|
||||
export default tseslint.config(
|
||||
js.configs.recommended,
|
||||
...tseslint.configs.recommended,
|
||||
{
|
||||
plugins: { security, import: importPlugin },
|
||||
rules: {
|
||||
'@typescript-eslint/no-explicit-any': 'warn',
|
||||
'@typescript-eslint/explicit-function-return-type': 'warn',
|
||||
'security/detect-object-injection': 'warn',
|
||||
'import/order': ['error', { 'newlines-between': 'always' }],
|
||||
'no-console': 'warn',
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## ESLint (frontend)
|
||||
|
||||
Дополнительно к базовому конфигу:
|
||||
|
||||
```bash
|
||||
npm install -D \
|
||||
eslint-plugin-react \
|
||||
eslint-plugin-react-hooks \
|
||||
eslint-plugin-jsx-a11y
|
||||
```
|
||||
|
||||
- `eslint-plugin-react-hooks` — обязателен, ловит типичные ошибки с хуками
|
||||
- `eslint-plugin-jsx-a11y` — базовая доступность (a11y) в линтере
|
||||
|
||||
## TypeScript (backend)
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"strict": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
```
|
||||
|
||||
## Vitest
|
||||
|
||||
```bash
|
||||
npm install -D vitest @vitest/coverage-v8
|
||||
```
|
||||
|
||||
```ts
|
||||
// vitest.config.ts
|
||||
import { defineConfig } from 'vitest/config'
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
globals: true,
|
||||
environment: 'node',
|
||||
coverage: {
|
||||
provider: 'v8',
|
||||
reporter: ['text', 'lcov'],
|
||||
thresholds: { lines: 70 },
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Frontend использует `@testing-library/react` + `@testing-library/user-event` для компонентов.
|
||||
|
||||
## .editorconfig
|
||||
|
||||
Общий для всех репо:
|
||||
|
||||
```ini
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
```
|
||||
|
||||
## VS Code
|
||||
|
||||
```json
|
||||
// .vscode/settings.json
|
||||
{
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit"
|
||||
},
|
||||
"typescript.preferences.importModuleSpecifier": "non-relative"
|
||||
}
|
||||
```
|
||||
|
||||
Рекомендуемые расширения:
|
||||
|
||||
```json
|
||||
// .vscode/extensions.json
|
||||
{
|
||||
"recommendations": [
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
"bradlc.vscode-tailwindcss",
|
||||
"eamodio.gitlens",
|
||||
"streetsidesoftware.code-spell-checker-russian",
|
||||
"usernamehw.errorlens",
|
||||
"ms-azuretools.vscode-docker",
|
||||
"mikestead.dotenv"
|
||||
]
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user