diff --git a/backend/app/api/claims.py b/backend/app/api/claims.py index 8f10474..9f398ea 100644 --- a/backend/app/api/claims.py +++ b/backend/app/api/claims.py @@ -451,6 +451,83 @@ async def delete_draft(claim_id: str): raise HTTPException(status_code=500, detail=f"Ошибка при удалении черновика: {str(e)}") +@router.post("/approve") +async def publish_form_approval(request: Request): + """ + Публикация данных подтвержденной формы в Redis канал + + После SMS-апрува отправляет данные формы в Redis канал clientright:webform:approve + для обработки в n8n workflow. + + В будущем можно подключить RabbitMQ для очереди и защиты от дублей. + """ + try: + body = await request.json() + + claim_id = body.get("claim_id") + session_token = body.get("session_token") or body.get("session_id") + + if not claim_id: + raise HTTPException(status_code=400, detail="claim_id обязателен") + + # Генерируем idempotency key для защиты от дублей (для будущей интеграции с RabbitMQ) + import time + idempotency_key = f"{claim_id}_{int(time.time() * 1000)}_{body.get('user_id', 'unknown')}" + + # Формируем событие для Redis + event_data = { + "event_type": "form_approve", + "status": "approved", + "message": "Форма подтверждена после SMS-верификации", + "claim_id": claim_id, + "session_token": session_token, + "unified_id": body.get("unified_id"), + "phone": body.get("phone"), + "sms_verified": True, + "idempotency_key": idempotency_key, # Для защиты от дублей в RabbitMQ + "timestamp": datetime.utcnow().isoformat(), + + # Данные формы подтверждения + "form_data": body.get("form_data", {}), + "user": body.get("user", {}), + "project": body.get("project", {}), + "offenders": body.get("offenders", []), + "meta": body.get("meta", {}), + + # Оригинальные данные для сравнения + "original_data": body.get("original_data", {}), + } + + # Публикуем в Redis канал clientright:webform:approve + channel = "clientright:webform:approve" + event_json = json.dumps(event_data, ensure_ascii=False) + await redis_service.publish(channel, event_json) + + logger.info( + f"📢 Form approval published to {channel}", + extra={ + "claim_id": claim_id, + "idempotency_key": idempotency_key, + }, + ) + + return { + "success": True, + "channel": channel, + "idempotency_key": idempotency_key, + "message": "Данные формы отправлены на обработку", + } + + except HTTPException: + raise + except Exception as e: + logger.exception("❌ Failed to publish form approval") + raise HTTPException( + status_code=500, + detail=f"Ошибка при отправке данных формы: {str(e)}", + ) + + @router.get("/{claim_id}") async def get_claim(claim_id: str): """Получить информацию о заявке по ID""" @@ -541,83 +618,6 @@ async def load_wizard_data(claim_id: str): raise HTTPException(status_code=500, detail=f"Ошибка при загрузке данных визарда: {str(e)}") -@router.post("/approve") -async def publish_form_approval(request: Request): - """ - Публикация данных подтвержденной формы в Redis канал - - После SMS-апрува отправляет данные формы в Redis канал clientright:webform:approve - для обработки в n8n workflow. - - В будущем можно подключить RabbitMQ для очереди и защиты от дублей. - """ - try: - body = await request.json() - - claim_id = body.get("claim_id") - session_token = body.get("session_token") or body.get("session_id") - - if not claim_id: - raise HTTPException(status_code=400, detail="claim_id обязателен") - - # Генерируем idempotency key для защиты от дублей (для будущей интеграции с RabbitMQ) - import time - idempotency_key = f"{claim_id}_{int(time.time() * 1000)}_{body.get('user_id', 'unknown')}" - - # Формируем событие для Redis - event_data = { - "event_type": "form_approve", - "status": "approved", - "message": "Форма подтверждена после SMS-верификации", - "claim_id": claim_id, - "session_token": session_token, - "unified_id": body.get("unified_id"), - "phone": body.get("phone"), - "sms_verified": True, - "idempotency_key": idempotency_key, # Для защиты от дублей в RabbitMQ - "timestamp": datetime.utcnow().isoformat(), - - # Данные формы подтверждения - "form_data": body.get("form_data", {}), - "user": body.get("user", {}), - "project": body.get("project", {}), - "offenders": body.get("offenders", []), - "meta": body.get("meta", {}), - - # Оригинальные данные для сравнения - "original_data": body.get("original_data", {}), - } - - # Публикуем в Redis канал clientright:webform:approve - channel = "clientright:webform:approve" - event_json = json.dumps(event_data, ensure_ascii=False) - await redis_service.publish(channel, event_json) - - logger.info( - f"📢 Form approval published to {channel}", - extra={ - "claim_id": claim_id, - "idempotency_key": idempotency_key, - }, - ) - - return { - "success": True, - "channel": channel, - "idempotency_key": idempotency_key, - "message": "Данные формы отправлены на обработку", - } - - except HTTPException: - raise - except Exception as e: - logger.exception("❌ Failed to publish form approval") - raise HTTPException( - status_code=500, - detail=f"Ошибка при отправке данных формы: {str(e)}", - ) - - @router.post("/description") async def publish_ticket_form_description(payload: TicketFormDescriptionRequest): """