133 lines
4.7 KiB
Python
133 lines
4.7 KiB
Python
"""
|
|
Documents draft-open endpoint
|
|
|
|
This file provides a single, isolated endpoint to fetch the documents list
|
|
and minimal claim metadata for a given claim_id. It is implemented as a
|
|
separate router to avoid touching existing document/claim routes.
|
|
"""
|
|
from fastapi import APIRouter, HTTPException, Query
|
|
from fastapi.responses import RedirectResponse
|
|
from ..config import settings
|
|
import logging
|
|
import json
|
|
from typing import Any, Dict
|
|
from ..services.database import db
|
|
|
|
router = APIRouter(prefix="/api/v1/documents-draft", tags=["DocumentsDraft"])
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@router.get("/open/{claim_id}")
|
|
async def open_documents_draft(claim_id: str):
|
|
"""
|
|
Return minimal draft info focused on documents for the given claim_id.
|
|
|
|
Response:
|
|
{
|
|
"success": True,
|
|
"claim_id": "...",
|
|
"session_token": "...",
|
|
"status_code": "...",
|
|
"documents_required": [...],
|
|
"documents_meta": [...],
|
|
"documents_count": 3,
|
|
"created_at": "...",
|
|
"updated_at": "..."
|
|
}
|
|
"""
|
|
try:
|
|
query = """
|
|
SELECT
|
|
id,
|
|
payload->>'claim_id' AS claim_id,
|
|
session_token,
|
|
status_code,
|
|
payload->'documents_required' AS documents_required,
|
|
payload->'documents_meta' AS documents_meta,
|
|
created_at,
|
|
updated_at
|
|
FROM clpr_claims
|
|
WHERE (payload->>'claim_id' = $1 OR id::text = $1)
|
|
ORDER BY updated_at DESC
|
|
LIMIT 1
|
|
"""
|
|
|
|
row = await db.fetch_one(query, claim_id)
|
|
if not row:
|
|
raise HTTPException(status_code=404, detail=f"Draft not found: {claim_id}")
|
|
|
|
# Normalize JSONB fields which may be strings
|
|
def parse_json_field(val: Any):
|
|
if val is None:
|
|
return []
|
|
if isinstance(val, str):
|
|
try:
|
|
return json.loads(val)
|
|
except Exception:
|
|
return []
|
|
return val if isinstance(val, list) else []
|
|
|
|
documents_required = parse_json_field(row.get("documents_required"))
|
|
documents_meta = parse_json_field(row.get("documents_meta"))
|
|
|
|
result = {
|
|
"success": True,
|
|
"claim_id": row.get("claim_id") or str(row.get("id")),
|
|
"session_token": row.get("session_token"),
|
|
"status_code": row.get("status_code"),
|
|
"documents_required": documents_required,
|
|
"documents_meta": documents_meta,
|
|
"documents_count": len(documents_required),
|
|
"created_at": row.get("created_at").isoformat() if row.get("created_at") else None,
|
|
"updated_at": row.get("updated_at").isoformat() if row.get("updated_at") else None,
|
|
}
|
|
|
|
return result
|
|
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
logger.exception("Failed to open documents draft")
|
|
raise HTTPException(status_code=500, detail=f"Error opening documents draft: {str(e)}")
|
|
|
|
|
|
|
|
@router.get("/open/launch/{claim_id}")
|
|
async def launch_documents_draft(
|
|
claim_id: str,
|
|
target: str = Query("miniapp", description="Where to open: 'miniapp' or 'max'"),
|
|
bot_name: str | None = Query(None, description="MAX bot name (required if target=max)"),
|
|
):
|
|
"""
|
|
Convenience launcher:
|
|
- target=miniapp (default) -> redirects to our miniapp URL with claim_id
|
|
https://miniapp.clientright.ru/hello?claim_id=...
|
|
- target=max -> redirects to MAX deep link:
|
|
https://max.ru/{bot_name}?startapp={claim_id}
|
|
This endpoint only redirects; it does not change persisted data.
|
|
"""
|
|
try:
|
|
# ensure claim exists
|
|
query = "SELECT 1 FROM clpr_claims WHERE (payload->>'claim_id' = $1 OR id::text = $1) LIMIT 1"
|
|
row = await db.fetch_one(query, claim_id)
|
|
if not row:
|
|
raise HTTPException(status_code=404, detail=f"Draft not found: {claim_id}")
|
|
|
|
if target == "max":
|
|
bot = bot_name or getattr(settings, "MAX_BOT_NAME", None)
|
|
if not bot:
|
|
raise HTTPException(status_code=400, detail="bot_name is required when target=max")
|
|
# claim_id is UUID with allowed chars (hex + hyphens) - OK for startapp
|
|
url = f"https://max.ru/{bot}?startapp={claim_id}"
|
|
return RedirectResponse(url)
|
|
else:
|
|
# default: open miniapp directly (hosted at /hello)
|
|
url = f"https://miniapp.clientright.ru/hello?claim_id={claim_id}"
|
|
return RedirectResponse(url)
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
logger.exception("Failed to launch documents draft")
|
|
raise HTTPException(status_code=500, detail=f"Error launching documents draft: {str(e)}")
|
|
|