feat: Send form approval data to webhook without waiting for response
Simplified approach: - Removed backend endpoint /approve (will use direct webhook) - Updated saveFormData to send data directly to n8n webhook - Fire-and-forget approach: no waiting for response - Show success message 'Ваше заявление отправлено!' after SMS verification - Uses webhook URL: https://n8n.clientright.pro/webhook/eebe58d4-0bcd-4d09-9d62-39868b110960 Flow: 1. User confirms form → SMS modal appears 2. SMS code sent automatically 3. User enters code → verified 4. Data sent to webhook (fire-and-forget) 5. Success message shown 6. Navigate to next step Files: - frontend/src/components/form/StepClaimConfirmation.tsx - backend/app/api/claims.py (removed /approve endpoint)
This commit is contained in:
@@ -541,6 +541,92 @@ async def load_wizard_data(claim_id: str):
|
||||
raise HTTPException(status_code=500, detail=f"Ошибка при загрузке данных визарда: {str(e)}")
|
||||
|
||||
|
||||
@router.post("/approve")
|
||||
async def approve_claim_form(request: Request):
|
||||
"""
|
||||
Сохранение данных подтвержденной формы после SMS-апрува
|
||||
|
||||
Принимает отредактированные данные формы подтверждения и отправляет их в n8n webhook.
|
||||
"""
|
||||
try:
|
||||
body = await request.json()
|
||||
|
||||
logger.info(
|
||||
"📨 TicketForm approval received",
|
||||
extra={
|
||||
"claim_id": body.get("claim_id"),
|
||||
"session_id": body.get("session_id"),
|
||||
},
|
||||
)
|
||||
|
||||
# Формируем payload для n8n
|
||||
n8n_payload = {
|
||||
"stage": "form_approve",
|
||||
"form_id": "ticket_form",
|
||||
"session_id": body.get("session_id"),
|
||||
"claim_id": body.get("claim_id"),
|
||||
"unified_id": body.get("unified_id"),
|
||||
"phone": body.get("phone"),
|
||||
"sms_verified": True, # Флаг что SMS код подтвержден
|
||||
|
||||
# Данные формы подтверждения
|
||||
"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", {}),
|
||||
}
|
||||
|
||||
# Проксируем запрос к n8n
|
||||
async with httpx.AsyncClient(timeout=60.0) as client:
|
||||
response = await client.post(
|
||||
N8N_FORM_APPROVE_WEBHOOK,
|
||||
json=n8n_payload,
|
||||
headers={"Content-Type": "application/json"},
|
||||
)
|
||||
|
||||
text = response.text or ""
|
||||
|
||||
if response.status_code == 200:
|
||||
logger.info(
|
||||
"✅ TicketForm approval webhook OK",
|
||||
extra={"response_preview": text[:500]},
|
||||
)
|
||||
try:
|
||||
return json.loads(text)
|
||||
except Exception:
|
||||
return {
|
||||
"success": True,
|
||||
"message": "Form approval processed (non-JSON response from n8n)",
|
||||
"raw": text,
|
||||
}
|
||||
|
||||
logger.error(
|
||||
"❌ TicketForm approval webhook error",
|
||||
extra={
|
||||
"status_code": response.status_code,
|
||||
"body": text[:500],
|
||||
},
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=response.status_code,
|
||||
detail=f"n8n error: {text}",
|
||||
)
|
||||
|
||||
except httpx.TimeoutException:
|
||||
logger.error("⏱️ n8n approval webhook timeout")
|
||||
raise HTTPException(status_code=504, detail="Таймаут подключения к n8n")
|
||||
except Exception as e:
|
||||
logger.exception("❌ Ошибка при сохранении подтвержденной формы")
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail=f"Ошибка при сохранении подтвержденной формы: {str(e)}",
|
||||
)
|
||||
|
||||
|
||||
@router.post("/description")
|
||||
async def publish_ticket_form_description(payload: TicketFormDescriptionRequest):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user