# Implementation Plan: Async Backend Refactoring

**Branch**: `032-translate-requests-httpx` | **Date**: 2026-06-04 | **Spec**: [spec.md](./spec.md) | **Status**: ✅ Implemented
**Input**: Feature specification from `/specs/032-translate-requests-httpx/spec.md`

## Status

**Реализовано**. Полный рефакторинг backend на асинхронный неблокирующий ввод-вывод.

Полный рефакторинг backend на асинхронный неблокирующий ввод-вывод. Big-bang замена синхронного `requests.Session` на `httpx.AsyncClient` в центральном `APIClient`, слияние sync `SupersetClient` и `AsyncSupersetClient` в единый асинхронный клиент, перевод всех 13 миксинов SupersetClient на async, замена `time.sleep` на `asyncio.sleep` во всех поллинг-циклах, обёртка блокирующих операций БД и файлового I/O в `run_blocking` (bounded executors), полный переход Task Manager'а с `ThreadPoolExecutor` на `asyncio.create_task`. Фронтенд не меняется.

## Technical Context

**Language/Version**: Python 3.9+ (backend, canonical — ADR-0001 note: Python 3.13+ preferred but 3.9+ is the minimum supported), TypeScript (frontend Svelte 5 runes-only)
**Primary Dependencies**: FastAPI 0.126, SQLAlchemy, APScheduler 3.11, httpx 0.28 (already present), anyio 4.12 (already present)
**New Dependencies**: pytest-httpx (test mocking), aiofiles (optional — file I/O), aiosmtplib (optional — SMTP)
**Storage**: PostgreSQL 16 (unchanged — DB operations via asyncio.to_thread)
**Testing**: pytest (backend), pytest-httpx (new), pytest-asyncio (existing)
**Target Platform**: Linux server (Docker), single uvicorn worker
**Project Type**: web application backend (FastAPI REST + WebSocket)
**Performance Goals**: <100ms p95 для лёгких запросов во время тяжёлых операций; конкурентность 3+ тяжёлых запросов при 1 worker
**Constraints**: API-контракты неизменны; все тесты проходят; нулевые утечки соединений; обратная совместимость WebSocket-логирования
**Scale/Scope**: ~16 файлов, ~45 блокирующих вызовов, 1 uvicorn worker, 20 одновременных соединений к Superset (семафор)

## Constitution Check

*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*

| # | Principle | Status | Justification |
|---|-----------|--------|---------------|
| I | Semantic Contract First | ✅ PASS | Все изменённые функции получат/обновят C3-C4 контракты. Новый `AsyncAPIClient` — C4 с @PRE/@POST/@SIDE_EFFECT. |
| II | Decision Memory | ✅ PASS | ADR-0011 будет создан с записью rejected-путей (aiohttp, multiprocessing, async SQLAlchemy). @RATIONALE/@REJECTED в каждом C4+ контракте. |
| III | External Orchestrator | ✅ PASS | Топология не меняется. ss-tools остаётся внешним оркестратором над Superset. |
| IV | Module Discipline | ✅ PASS | `network.py` (542 строки) → Tombstone. `async_network.py` (<400 строк) — canonical async client, расширяется семафором. `SupersetAuthCache` уже выделен. |
| V | RBAC Enforcement | ✅ PASS | Проверки прав не затрагиваются. Ручки сохраняют `Depends(has_permission(...))`. |
| VI | Frontend Svelte 5 Runes Only | ✅ N/A | Фронтенд не меняется. |
| VII | Test-Driven for C3+ | ✅ PASS | Тесты на конкурентность (asyncio.gather + pytest_httpx) написаны для всех C3+ контрактов. |

## Project Structure

### Documentation (this feature)

```text
specs/032-translate-requests-httpx/
├── plan.md              # This file
├── research.md          # Phase 0 output
├── data-model.md        # Phase 1 output
├── quickstart.md        # Phase 1 output
├── contracts/           # Phase 1 output
│   └── modules.md       # GRACE contracts for new/changed modules
└── tasks.md             # Phase 2 output (/speckit.tasks)
```

### Source Code (repository root — files touched)

```text
backend/
├── src/
│   ├── core/
│   │   ├── utils/
│   │   │   ├── network.py           → Tombstone (sync APIClient replaced)
│   │   │   └── async_network.py      → extended: semaphore + pool config added
│   │   │   ├── fileio.py            → async wrappers for file operations
│   │   │   └── superset_compilation_adapter.py → async migration
│   │   ├── superset_client/
│   │   │   ├── _base.py             → merged with AsyncSupersetClient
│   │   │   ├── async_superset_client.py → absorbed into _base.py
│   │   │   └── _mixins/*.py         → all 13 mixins become async
│   │   └── task_manager/
│   │       ├── manager.py           → ThreadPoolExecutor → asyncio.create_task
│   │       ├── lifecycle.py         → async lifecycle
│   │       └── event_bus.py         → async WebSocket logging
│   ├── api/routes/
│   │   ├── dashboards/_detail_routes.py → async SupersetClient
│   │   └── translate/*.py           → already async def, now truly non-blocking
│   ├── plugins/
│   │   ├── translate/
│   │   │   ├── _llm_http.py         → httpx.AsyncClient
│   │   │   ├── preview_llm_client.py → httpx.AsyncClient
│   │   │   ├── superset_executor.py → async execute + asyncio.sleep
│   │   │   ├── _run_source.py       → async chart data fetch
│   │   │   └── preview_executor.py  → async sample row fetch
│   │   ├── backup.py                → async SupersetClient + file I/O
│   │   ├── git_plugin.py            → asyncio.to_thread for shutil + git
│   │   ├── llm_analysis/plugin.py   → async dashboard logs fetch
│   │   └── storage/plugin.py        → asyncio.to_thread for file ops
│   └── services/
│       ├── notifications/providers.py → aiosmtplib + httpx
│       └── git/_base.py             → asyncio.to_thread for git/file ops
└── tests/                            → pytest_httpx replaces requests_mock
```

## Complexity Tracking

| Violation | Why Needed | Simpler Alternative Rejected Because |
|-----------|------------|-------------------------------------|
| `network.py` > 400 строк (542) | Центральный HTTP-клиент со всей логикой аутентификации, пагинации, загрузки файлов | `network.py` → Tombstone. `async_network.py` (уже существует, <400 строк) — canonical async client. `SupersetAuthCache` уже выделен и переиспользуется обоими клиентами. |
| Task Manager рефакторинг | Переход с ThreadPoolExecutor на asyncio.create_task требует изменения lifecycle и event_bus | Оставить ThreadPoolExecutor — rejected, т.к. задачи должны разделять event loop для конкурентности |
