Skip to content

Commit d540be4

Browse files
Initial commit
0 parents  commit d540be4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+3824
-0
lines changed

.claude/CLAUDE.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# CLAUDE.md
2+
3+
Этот файл содержит контекст для Claude Code при работе с проектом.
4+
5+
## О проекте
6+
7+
**Chat API Microservice** — FastAPI сервис для LLM-чатов с проектами, историей и Notion интеграцией.
8+
9+
## Команды
10+
11+
```bash
12+
# Запуск сервера
13+
uv run uvicorn app.main:app --reload
14+
15+
# Тесты
16+
OTEL_SDK_DISABLED=true uv run pytest tests/ -v
17+
18+
# Линтер
19+
uv run ruff check app/ tests/ --fix
20+
21+
# Type checker
22+
uv run mypy app/ --ignore-missing-imports
23+
24+
# Все проверки
25+
uv run ruff check app/ tests/ --fix && uv run mypy app/ --ignore-missing-imports && OTEL_SDK_DISABLED=true uv run pytest tests/ -v
26+
```
27+
28+
## Структура
29+
30+
```
31+
app/
32+
├── main.py # FastAPI app factory с lifespan
33+
├── api.py # API routes /api/v1
34+
├── logger.py # Structlog + OpenTelemetry
35+
├── core/
36+
│ ├── config.py # Pydantic Settings
37+
│ ├── db.py # SQLModel database
38+
│ ├── health.py # Health endpoint
39+
│ └── llm_client.py # OpenRouter client
40+
├── models/ # SQLModel entities
41+
├── schemas/ # API request/response
42+
├── services/ # ChatService
43+
├── integrations/ # Notion, BehaviorManager
44+
├── behavior/ # Behavior models
45+
└── observability/ # OpenTelemetry tracing
46+
```
47+
48+
## Ключевые файлы
49+
50+
- `app/main.py` — точка входа, lifespan context manager
51+
- `app/api.py` — все API endpoints
52+
- `app/core/config.py` — Settings с SettingsConfigDict
53+
- `app/core/llm_client.py` — OpenRouterClient
54+
- `app/services/chat_service.py` — бизнес-логика чатов
55+
56+
## Стек
57+
58+
- Python 3.11+
59+
- FastAPI + Pydantic v2
60+
- SQLModel (SQLAlchemy + Pydantic)
61+
- OpenTelemetry (traces, logs, metrics)
62+
- OpenRouter (LLM)
63+
- uv (package manager)
64+
65+
## Конвенции
66+
67+
- Pydantic v2: `model_config = SettingsConfigDict(...)` вместо `class Config`
68+
- Datetime: `datetime.now(UTC)` вместо `datetime.utcnow()`
69+
- FastAPI: lifespan context manager вместо `@app.on_event`
70+
- Тесты: `OTEL_SDK_DISABLED=true` для отключения трейсинга
71+
72+
## Связанные репозитории
73+
74+
- `app-crewai-cluster` — CrewAI агенты (отдельный сервис)
75+
- `app-release` — Helm charts и GitOps

.claude/settings.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"permissions": {
3+
"deny": [
4+
"Read(context/**)",
5+
"Read(*.pem)",
6+
"Read(*.key)",
7+
"Read(**/secrets/**)"
8+
],
9+
"ask": [
10+
"Bash(docker build:*)",
11+
"Bash(curl:*)"
12+
],
13+
"allow": [
14+
"Bash(uv run:*)",
15+
"Bash(uv sync:*)",
16+
"Bash(uv add:*)",
17+
"Bash(pytest:*)",
18+
"Bash(python:*)",
19+
"Bash(ruff:*)",
20+
"Bash(mypy:*)",
21+
"Bash(uvicorn:*)",
22+
"Bash(wc:*)",
23+
"Bash(ls:*)",
24+
"Bash(find:*)",
25+
"Bash(docker logs:*)"
26+
]
27+
},
28+
"sandbox": {
29+
"enabled": true,
30+
"autoAllowBashIfSandboxed": true,
31+
"excludedCommands": ["docker"]
32+
},
33+
"env": {
34+
"CLAUDE_CODE_ENABLE_TELEMETRY": "0"
35+
}
36+
}

.env.example

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# =============================================================================
2+
# Chat API Configuration
3+
# =============================================================================
4+
5+
# -----------------------------------------------------------------------------
6+
# LLM Provider (OpenRouter)
7+
# -----------------------------------------------------------------------------
8+
OPENROUTER_API_KEY=sk-or-v1-...
9+
OPENROUTER_MODEL=anthropic/claude-opus-4
10+
OPENROUTER_API_URL=https://openrouter.ai/api/v1/chat/completions
11+
OPENROUTER_HTTP_REFERER=https://your-app.com
12+
OPENROUTER_X_TITLE=Chat API
13+
14+
# Legacy (if using LiteLLM proxy or OpenAI directly)
15+
OPENAI_API_KEY=
16+
LLM_API_URL=http://localhost:4000
17+
CHAT_MODEL=openai/gpt-4.1
18+
19+
# -----------------------------------------------------------------------------
20+
# Database
21+
# -----------------------------------------------------------------------------
22+
# SQLite (default for local dev)
23+
DATABASE_URL=sqlite:///db.sqlite3
24+
25+
# PostgreSQL (docker-compose)
26+
POSTGRES_USER=chatuser
27+
POSTGRES_PASSWORD=changeme
28+
POSTGRES_DB=chatdb
29+
# DATABASE_URL=postgresql://chatuser:changeme@localhost:5432/chatdb
30+
31+
# -----------------------------------------------------------------------------
32+
# Notion Integration (optional)
33+
# -----------------------------------------------------------------------------
34+
NOTION_TOKEN=
35+
NOTION_PAGE_ID=
36+
37+
# -----------------------------------------------------------------------------
38+
# OpenTelemetry (observability)
39+
# -----------------------------------------------------------------------------
40+
OTEL_SERVICE_NAME=chat-api
41+
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
42+
ENVIRONMENT=development
43+
44+
# Kubernetes metadata (auto-populated in K8s)
45+
K8S_POD_NAME=
46+
K8S_NAMESPACE=
47+
K8S_NODE_NAME=
48+
K8S_DEPLOYMENT_NAME=
49+
50+
# Disable OTEL for local dev/testing
51+
# OTEL_SDK_DISABLED=true
52+
53+
# -----------------------------------------------------------------------------
54+
# Application
55+
# -----------------------------------------------------------------------------
56+
PROJECT_NAME=ChatMicroservice

.github/workflows/release.yaml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Build and Release
2+
on:
3+
push:
4+
branches: [main]
5+
paths:
6+
- 'app/**'
7+
- 'Dockerfile'
8+
- 'pyproject.toml'
9+
- '.github/workflows/release.yaml'
10+
- '.releaserc.json'
11+
12+
jobs:
13+
build-and-release:
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: write
17+
packages: write
18+
steps:
19+
- uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
22+
token: ${{ secrets.GITHUB_TOKEN }}
23+
24+
- name: Get Next Version
25+
id: version
26+
uses: cycjimmy/semantic-release-action@v4
27+
with:
28+
semantic_version: 21
29+
dry_run: true
30+
env:
31+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32+
33+
- name: Semantic Release
34+
id: semantic
35+
if: steps.version.outputs.new_release_version
36+
uses: cycjimmy/semantic-release-action@v4
37+
with:
38+
semantic_version: 21
39+
env:
40+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
41+
42+
- name: Log in to GitHub Container Registry
43+
if: steps.semantic.outputs.new_release_published == 'true'
44+
uses: docker/login-action@v3
45+
with:
46+
registry: ghcr.io
47+
username: ${{ github.actor }}
48+
password: ${{ secrets.GITHUB_TOKEN }}
49+
50+
- name: Build and push Docker image
51+
if: steps.semantic.outputs.new_release_published == 'true'
52+
uses: docker/build-push-action@v5
53+
with:
54+
context: .
55+
push: true
56+
tags: |
57+
ghcr.io/justgithubaccount/chat-api:latest
58+
ghcr.io/justgithubaccount/chat-api:${{ github.sha }}
59+
ghcr.io/justgithubaccount/chat-api:${{ steps.semantic.outputs.new_release_version }}

.github/workflows/test.yaml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Python Tests
2+
on:
3+
pull_request:
4+
paths: ['app/**', 'tests/**', 'pyproject.toml']
5+
jobs:
6+
test:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v4
10+
- name: Install uv
11+
uses: astral-sh/setup-uv@v4
12+
- name: Set up Python
13+
run: uv python install 3.11
14+
- name: Install dependencies
15+
run: uv sync --dev
16+
- name: Run tests
17+
env:
18+
OTEL_SDK_DISABLED: true
19+
run: uv run pytest --cov=app tests/
20+
- name: Type check
21+
run: uv run mypy app --ignore-missing-imports
22+
- name: Lint
23+
run: uv run ruff check app

.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
__pycache__/
2+
*.py[cod]
3+
.env
4+
.venv/
5+
venv/
6+
*.egg-info/
7+
dist/
8+
build/
9+
.pytest_cache/
10+
.mypy_cache/
11+
.ruff_cache/
12+
.coverage
13+
htmlcov/
14+
*.sqlite3

.releaserc.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"branches": ["main"],
3+
"plugins": [
4+
[
5+
"@semantic-release/commit-analyzer",
6+
{
7+
"releaseRules": [
8+
{"type": "feat", "release": "minor"},
9+
{"type": "fix", "release": "patch"},
10+
{"type": "perf", "release": "patch"},
11+
{"type": "revert", "release": "patch"},
12+
{"type": "docs", "release": "patch"},
13+
{"type": "refactor", "release": "patch"},
14+
{"type": "ci", "release": "patch"},
15+
{"type": "chore", "release": "patch"},
16+
{"breaking": true, "release": "major"}
17+
]
18+
}
19+
],
20+
"@semantic-release/release-notes-generator",
21+
"@semantic-release/github"
22+
]
23+
}

Dockerfile

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
FROM python:3.11-slim
2+
3+
# Install uv for fast dependency management
4+
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
5+
6+
WORKDIR /app
7+
8+
# Copy dependency files first (cache layer)
9+
COPY pyproject.toml uv.lock ./
10+
11+
# Install dependencies (no dev)
12+
RUN uv sync --frozen --no-dev
13+
14+
# Copy application code
15+
COPY ./app ./app
16+
17+
# Expose port
18+
EXPOSE 8000
19+
20+
# Run with uv
21+
CMD ["uv", "run", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Yevgeny Kulikov
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

0 commit comments

Comments
 (0)