Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## О проекте

**Chat API Microservice** — FastAPI сервис для LLM-чатов с проектами, историей и Notion интеграцией.
**Chat API Microservice** — FastAPI сервис для LLM-чатов с проектами, историей и опциональной загрузкой behavior из Notion.

## Команды

Expand All @@ -15,14 +15,17 @@ uv run uvicorn app.main:app --reload
# Тесты
OTEL_SDK_DISABLED=true uv run pytest tests/ -v

# Линтер
# Линтер (не изменяет файлы)
uv run ruff check app/ tests/

# Явное применение исправлений Ruff
uv run ruff check app/ tests/ --fix

# Type checker
uv run mypy app/ --ignore-missing-imports

# Все проверки
uv run ruff check app/ tests/ --fix && uv run mypy app/ --ignore-missing-imports && OTEL_SDK_DISABLED=true uv run pytest tests/ -v
task check
```

## Структура
Expand All @@ -36,8 +39,7 @@ app/
│ ├── config.py # Pydantic Settings
│ ├── db.py # SQLModel database
│ ├── health.py # Health endpoint
│ ├── llm_client.py # OpenRouter client
│ └── project_memory.py # In-memory fallback
│ └── llm_client.py # OpenRouter client
├── models/
│ ├── chat.py # Chat models
│ └── db_models.py # SQLModel entities
Expand Down Expand Up @@ -76,7 +78,7 @@ app/
- uv (package manager)
- structlog (logging)
- httpx (HTTP client)
- notion-client (Notion API)
- httpx + PyYAML (опциональная Notion/behavior интеграция)

## Конвенции

Expand All @@ -85,6 +87,8 @@ app/
- FastAPI: lifespan context manager вместо `@app.on_event`
- Тесты: `OTEL_SDK_DISABLED=true` для отключения трейсинга
- Логирование: `enrich_context(event="name").info("message")`
- SQLModel — единственное хранилище проектов и истории; in-memory fallback отсутствует
- NotionClient/BehaviorManager — опциональная заготовка, по умолчанию не подключена

## Связанные репозитории

Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ jobs:
id-token: write
attestations: write
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
node-version: '22.22.0'
cache: 'npm'

- name: Install dependencies
Expand All @@ -50,15 +50,15 @@ jobs:

- name: Log in to GitHub Container Registry
if: steps.semantic.outputs.new_release_published == 'true'
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push Docker image
if: steps.semantic.outputs.new_release_published == 'true'
uses: docker/build-push-action@v5
uses: docker/build-push-action@v7
with:
context: .
push: true
Expand Down
33 changes: 27 additions & 6 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,43 @@ on:
- 'app/**'
- 'tests/**'
- 'Dockerfile'
- 'docker-compose.yml'
- 'Taskfile.yaml'
- 'pyproject.toml'
- 'uv.lock'
- 'package.json'
- 'package-lock.json'
- '.claude/CLAUDE.md'
- '.github/workflows/test.yaml'
- '.github/workflows/release.yaml'
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- name: Install uv
uses: astral-sh/setup-uv@v4
uses: astral-sh/setup-uv@v10.3.2
- name: Set up Python
run: uv python install 3.11
- name: Install dependencies
run: uv sync --dev
run: uv sync --locked --dev
- name: Run tests
env:
OTEL_SDK_DISABLED: true
run: uv run pytest --cov=app tests/
- name: Type check
run: uv run mypy app --ignore-missing-imports
- name: Lint
run: uv run ruff check app
run: uv run ruff check app tests

- name: Validate Compose configuration
run: docker compose config --quiet

container:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: actions/checkout@v7
- uses: docker/setup-buildx-action@v4
- name: Build runtime image
uses: docker/build-push-action@v6
with:
Expand All @@ -41,3 +50,15 @@ jobs:
tags: app-poly-gitops-fastapi:test
- name: Verify offline runtime startup
run: tests/test_container_runtime.sh app-poly-gitops-fastapi:test

release-toolchain:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v4
with:
node-version: '22.22.0'
cache: npm
- run: npm ci
- name: Reject critical release-toolchain advisories
run: npm audit --audit-level=critical
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ Project history is written only after the model returns successfully and include
the submitted messages, assistant reply, timestamp, and available trace/span IDs.
Provider failures return HTTP `502` and are not added to project history.

The SQLModel database is the only project and history store. The behavior
models, lightweight Notion HTTP client, `BehaviorManager`, and
`/api/v1/behavior/schema` are optional integration scaffolding: the default app
does not load a behavior document, so the endpoint intentionally returns `404`.

## Getting started

Requirements: Python 3.11+ and [uv](https://docs.astral.sh/uv/).
Expand Down Expand Up @@ -51,10 +56,14 @@ docker run --rm -p 8000:8000 --env-file .env chat-api
OTEL_SDK_DISABLED=true uv run pytest tests/ -v
uv run ruff check app tests
uv run mypy app --ignore-missing-imports
docker compose config --quiet
docker build -t app-poly-gitops-fastapi:test .
bash tests/test_container_runtime.sh app-poly-gitops-fastapi:test
~~~

The equivalent non-mutating aggregate is `task check`. `task lint:fix` is the
explicit source-modifying lint command.

The CI workflow runs the Python checks and verifies that the built container
starts without external services. Releases from `main` publish versioned images
to GitHub Container Registry.
Expand Down
8 changes: 6 additions & 2 deletions Taskfile.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ tasks:
# Linting
lint:
desc: Run ruff linter
cmd: uv run ruff check app/ tests/

lint:fix:
desc: Apply safe Ruff fixes
cmd: uv run ruff check app/ tests/ --fix

typecheck:
Expand All @@ -39,7 +43,7 @@ tasks:
# Dependencies
sync:
desc: Sync dependencies
cmd: uv sync
cmd: uv sync --locked --dev

# Docker
docker:build:
Expand All @@ -48,4 +52,4 @@ tasks:

docker:run:
desc: Run Docker container
cmd: docker run -p 8000:8000 --env-file .env chat-api:local
cmd: docker run --rm -p 8000:8000 --env-file .env chat-api:local
2 changes: 0 additions & 2 deletions app/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

from .core.db import get_session
from .core.llm_client import LLMProviderError
from .core.project_memory import ProjectMemory
from .integrations.behavior_manager import BehaviorManager
from .models import ChatHistory, ChatHistoryDB, Project, StoredChatMessage
from .schemas import (
Expand All @@ -28,7 +27,6 @@
tags=["chat"]
)

memory = ProjectMemory()
meter = metrics.get_meter(__name__)
chat_counter = meter.create_counter("chat_requests_total")

Expand Down
64 changes: 0 additions & 64 deletions app/core/project_memory.py

This file was deleted.

8 changes: 7 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ services:
ports:
- "8000:8000"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
test:
- CMD
- .venv/bin/python
- -c
- >-
import json, urllib.request;
assert json.load(urllib.request.urlopen('http://127.0.0.1:8000/health', timeout=5)) == {'status': 'ok'}
interval: 30s
timeout: 10s
retries: 3
Expand Down
Loading
Loading