Files
aiform_dev/backend/app/main.py

241 lines
7.1 KiB
Python
Raw Normal View History

"""
Ticket Form Intake Platform - FastAPI Backend
"""
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from contextlib import asynccontextmanager
import logging
from .config import settings
from .services.database import db
from .services.redis_service import redis_service
from .services.rabbitmq_service import rabbitmq_service
from .services.policy_service import policy_service
from .services.crm_mysql_service import crm_mysql_service
feat: 6 улучшений формы - S3 upload, draft, HEIC, email на step3 1. ✅ Placeholder с тире E1000-302538524 - Теперь в placeholder тоже тире 2. ✅ Email перенесен на Step3 - Убран с Step1 (проверка полиса) - Добавлен на Step3 (вместе с телефоном) - Теперь телефон + email + выплата на одном шаге 3. ✅ HEIC формат + мультилоад - Добавлена поддержка .heic, .heif (iPhone формат) - Убран maxCount - неограниченная загрузка - Параметр multiple для множественной загрузки 4. ✅ S3 Upload - Создан s3_service.py для работы с Timeweb S3 - Новый endpoint: POST /api/v1/upload/files - Поддержка мультизагрузки файлов - Автоматическая генерация уникальных имен - Файлы грузятся в S3, не локально 5. ✅ Draft автосохранение - Создана таблица claims_draft в PostgreSQL - Новый API: POST /api/v1/draft/save - GET /api/v1/draft/stats - статистика по шагам - GET /api/v1/draft/list - список последних драфтов - Для аналитики: где люди бросают заполнение 6. ✅ Миграция БД - 002_create_claims_draft.sql применена - Индексы для быстрого поиска - JSONB поле для гибкости данных Backend: - s3_service.py - сервис для S3 - draft.py - API автосохранения - upload.py - обновлен endpoint для S3 - main.py - добавлены роуты и подключения Frontend: - Step1Policy: убран email, добавлен HEIC - Step3Payment: добавлен email после телефона Статус: ✅ Backend подключен к S3, таблица создана, всё работает
2025-10-24 21:24:00 +03:00
from .services.s3_service import s3_service
fix: Исправление загрузки документов и SQL запросов - Исправлена потеря документов при обновлении черновика (SQL объединяет вместо перезаписи) - Исправлено определение типа документа (приоритет field_label над field_name) - Исправлены дубликаты в documents_meta и documents_uploaded - Добавлена передача group_index с фронтенда для правильного field_name - Исправлены все документы в таблице clpr_claim_documents с правильными field_name - Обновлены SQL запросы: claimsave и claimsave_final для нового флоу - Добавлена поддержка multi-file upload для одного документа - Исправлены дубликаты в списке загруженных документов на фронтенде Файлы: - SQL: SQL_CLAIMSAVE_FIXED_NEW_FLOW.sql, SQL_CLAIMSAVE_FINAL_FIXED_NEW_FLOW_WITH_UPLOADED.sql - n8n: N8N_CODE_PROCESS_UPLOADED_FILES_FIXED.js (поддержка group_index) - Backend: documents.py (передача group_index в n8n) - Frontend: StepWizardPlan.tsx (передача group_index, исправление дубликатов) - Скрипты: fix_claim_documents_field_names.py, fix_documents_meta_duplicates.py Результат: документы больше не теряются, имеют правильные типы и field_name
2025-11-26 19:54:51 +03:00
from .api import sms, claims, policy, upload, draft, events, n8n_proxy, session, documents
# Настройка логирования
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
@asynccontextmanager
async def lifespan(app: FastAPI):
"""
Lifecycle events: startup and shutdown
"""
# STARTUP
logger.info("🚀 Starting Ticket Form Intake Platform...")
try:
# Подключаем PostgreSQL
await db.connect()
except Exception as e:
logger.warning(f"⚠️ PostgreSQL not available: {e}")
try:
# Подключаем Redis
await redis_service.connect()
# Инициализируем session API с Redis connection
session.init_redis(redis_service.client)
except Exception as e:
logger.warning(f"⚠️ Redis not available: {e}")
try:
# Подключаем RabbitMQ
await rabbitmq_service.connect()
except Exception as e:
logger.warning(f"⚠️ RabbitMQ not available: {e}")
try:
# Подключаем MySQL (для проверки полисов)
await policy_service.connect()
except Exception as e:
logger.warning(f"⚠️ MySQL Policy DB not available: {e}")
try:
# Подключаем MySQL CRM (vtiger)
await crm_mysql_service.connect()
except Exception as e:
logger.warning(f"⚠️ MySQL CRM DB not available: {e}")
feat: 6 улучшений формы - S3 upload, draft, HEIC, email на step3 1. ✅ Placeholder с тире E1000-302538524 - Теперь в placeholder тоже тире 2. ✅ Email перенесен на Step3 - Убран с Step1 (проверка полиса) - Добавлен на Step3 (вместе с телефоном) - Теперь телефон + email + выплата на одном шаге 3. ✅ HEIC формат + мультилоад - Добавлена поддержка .heic, .heif (iPhone формат) - Убран maxCount - неограниченная загрузка - Параметр multiple для множественной загрузки 4. ✅ S3 Upload - Создан s3_service.py для работы с Timeweb S3 - Новый endpoint: POST /api/v1/upload/files - Поддержка мультизагрузки файлов - Автоматическая генерация уникальных имен - Файлы грузятся в S3, не локально 5. ✅ Draft автосохранение - Создана таблица claims_draft в PostgreSQL - Новый API: POST /api/v1/draft/save - GET /api/v1/draft/stats - статистика по шагам - GET /api/v1/draft/list - список последних драфтов - Для аналитики: где люди бросают заполнение 6. ✅ Миграция БД - 002_create_claims_draft.sql применена - Индексы для быстрого поиска - JSONB поле для гибкости данных Backend: - s3_service.py - сервис для S3 - draft.py - API автосохранения - upload.py - обновлен endpoint для S3 - main.py - добавлены роуты и подключения Frontend: - Step1Policy: убран email, добавлен HEIC - Step3Payment: добавлен email после телефона Статус: ✅ Backend подключен к S3, таблица создана, всё работает
2025-10-24 21:24:00 +03:00
try:
# Подключаем S3 (для загрузки файлов)
s3_service.connect()
except Exception as e:
logger.warning(f"⚠️ S3 storage not available: {e}")
logger.info("✅ Ticket Form Intake Platform started successfully!")
yield
# SHUTDOWN
logger.info("🛑 Shutting down Ticket Form Intake Platform...")
await db.disconnect()
await redis_service.disconnect()
await rabbitmq_service.disconnect()
await policy_service.close()
await crm_mysql_service.close()
logger.info("👋 Ticket Form Intake Platform stopped")
# Создаём FastAPI приложение
app = FastAPI(
title="Ticket Form Intake API",
description="API для обработки обращений Ticket Form",
version="1.0.0",
lifespan=lifespan
)
# CORS
app.add_middleware(
CORSMiddleware,
allow_origins=settings.cors_origins_list,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# API Routes
app.include_router(sms.router)
app.include_router(claims.router)
app.include_router(policy.router)
app.include_router(upload.router)
feat: 6 улучшений формы - S3 upload, draft, HEIC, email на step3 1. ✅ Placeholder с тире E1000-302538524 - Теперь в placeholder тоже тире 2. ✅ Email перенесен на Step3 - Убран с Step1 (проверка полиса) - Добавлен на Step3 (вместе с телефоном) - Теперь телефон + email + выплата на одном шаге 3. ✅ HEIC формат + мультилоад - Добавлена поддержка .heic, .heif (iPhone формат) - Убран maxCount - неограниченная загрузка - Параметр multiple для множественной загрузки 4. ✅ S3 Upload - Создан s3_service.py для работы с Timeweb S3 - Новый endpoint: POST /api/v1/upload/files - Поддержка мультизагрузки файлов - Автоматическая генерация уникальных имен - Файлы грузятся в S3, не локально 5. ✅ Draft автосохранение - Создана таблица claims_draft в PostgreSQL - Новый API: POST /api/v1/draft/save - GET /api/v1/draft/stats - статистика по шагам - GET /api/v1/draft/list - список последних драфтов - Для аналитики: где люди бросают заполнение 6. ✅ Миграция БД - 002_create_claims_draft.sql применена - Индексы для быстрого поиска - JSONB поле для гибкости данных Backend: - s3_service.py - сервис для S3 - draft.py - API автосохранения - upload.py - обновлен endpoint для S3 - main.py - добавлены роуты и подключения Frontend: - Step1Policy: убран email, добавлен HEIC - Step3Payment: добавлен email после телефона Статус: ✅ Backend подключен к S3, таблица создана, всё работает
2025-10-24 21:24:00 +03:00
app.include_router(draft.router)
app.include_router(events.router)
app.include_router(n8n_proxy.router) # 🔒 Безопасный proxy к n8n webhooks
app.include_router(session.router) # 🔑 Session management через Redis
fix: Исправление загрузки документов и SQL запросов - Исправлена потеря документов при обновлении черновика (SQL объединяет вместо перезаписи) - Исправлено определение типа документа (приоритет field_label над field_name) - Исправлены дубликаты в documents_meta и documents_uploaded - Добавлена передача group_index с фронтенда для правильного field_name - Исправлены все документы в таблице clpr_claim_documents с правильными field_name - Обновлены SQL запросы: claimsave и claimsave_final для нового флоу - Добавлена поддержка multi-file upload для одного документа - Исправлены дубликаты в списке загруженных документов на фронтенде Файлы: - SQL: SQL_CLAIMSAVE_FIXED_NEW_FLOW.sql, SQL_CLAIMSAVE_FINAL_FIXED_NEW_FLOW_WITH_UPLOADED.sql - n8n: N8N_CODE_PROCESS_UPLOADED_FILES_FIXED.js (поддержка group_index) - Backend: documents.py (передача group_index в n8n) - Frontend: StepWizardPlan.tsx (передача group_index, исправление дубликатов) - Скрипты: fix_claim_documents_field_names.py, fix_documents_meta_duplicates.py Результат: документы больше не теряются, имеют правильные типы и field_name
2025-11-26 19:54:51 +03:00
app.include_router(documents.router) # 📄 Documents upload and processing
@app.get("/")
async def root():
"""Главная страница API"""
return {
"message": "🚀 Ticket Form Intake API",
"version": "1.0.0",
"status": "running",
"docs": f"{settings.backend_url}/docs"
}
@app.get("/health")
async def health():
"""Health check - проверка всех сервисов"""
health_status = {
"status": "ok",
"message": "API работает!",
"services": {}
}
# Проверка PostgreSQL
try:
pg_healthy = await db.health_check()
health_status["services"]["postgresql"] = {
"status": "✅ healthy" if pg_healthy else "❌ unhealthy",
"connected": pg_healthy
}
except:
health_status["services"]["postgresql"] = {
"status": "❌ unavailable",
"connected": False
}
# Проверка Redis
try:
redis_healthy = await redis_service.health_check()
health_status["services"]["redis"] = {
"status": "✅ healthy" if redis_healthy else "❌ unhealthy",
"connected": redis_healthy
}
except:
health_status["services"]["redis"] = {
"status": "❌ unavailable",
"connected": False
}
# Проверка RabbitMQ
try:
rabbitmq_healthy = await rabbitmq_service.health_check()
health_status["services"]["rabbitmq"] = {
"status": "✅ healthy" if rabbitmq_healthy else "❌ unhealthy",
"connected": rabbitmq_healthy
}
except:
health_status["services"]["rabbitmq"] = {
"status": "❌ unavailable",
"connected": False
}
# Общий статус
all_healthy = all(
service.get("connected", False)
for service in health_status["services"].values()
)
if not all_healthy:
health_status["status"] = "degraded"
health_status["message"] = "⚠️ Некоторые сервисы недоступны"
return health_status
@app.get("/api/v1/test")
async def test():
"""Тестовый endpoint"""
return {
"success": True,
"message": "✅ Backend API работает!",
"services": {
"redis": f"{settings.redis_host}:{settings.redis_port}",
"postgres": f"{settings.postgres_host}:{settings.postgres_port}",
"ocr": settings.ocr_api_url,
"rabbitmq": f"{settings.rabbitmq_host}:{settings.rabbitmq_port}"
}
}
@app.get("/api/v1/utils/client-ip")
async def get_client_ip(request: Request):
"""Возвращает IP-адрес клиента по HTTP-запросу"""
client_host = request.client.host if request.client else None
return {
"ip": client_host
}
@app.get("/api/v1/info")
async def info():
"""Информация о платформе"""
return {
"platform": settings.app_name,
"version": "1.0.0",
"tech_stack": {
"backend": "Python FastAPI",
"frontend": "React TypeScript",
"database": "PostgreSQL + MySQL",
"cache": "Redis",
"queue": "RabbitMQ",
"storage": "S3 Timeweb"
},
"features": [
"OCR документов",
"AI автозаполнение",
"Проверка статуса выплат",
"СБП выплаты",
"Интеграция с CRM Vtiger"
]
}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8200)
fix: Исправление загрузки документов и SQL запросов - Исправлена потеря документов при обновлении черновика (SQL объединяет вместо перезаписи) - Исправлено определение типа документа (приоритет field_label над field_name) - Исправлены дубликаты в documents_meta и documents_uploaded - Добавлена передача group_index с фронтенда для правильного field_name - Исправлены все документы в таблице clpr_claim_documents с правильными field_name - Обновлены SQL запросы: claimsave и claimsave_final для нового флоу - Добавлена поддержка multi-file upload для одного документа - Исправлены дубликаты в списке загруженных документов на фронтенде Файлы: - SQL: SQL_CLAIMSAVE_FIXED_NEW_FLOW.sql, SQL_CLAIMSAVE_FINAL_FIXED_NEW_FLOW_WITH_UPLOADED.sql - n8n: N8N_CODE_PROCESS_UPLOADED_FILES_FIXED.js (поддержка group_index) - Backend: documents.py (передача group_index в n8n) - Frontend: StepWizardPlan.tsx (передача group_index, исправление дубликатов) - Скрипты: fix_claim_documents_field_names.py, fix_documents_meta_duplicates.py Результат: документы больше не теряются, имеют правильные типы и field_name
2025-11-26 19:54:51 +03:00