File size: 3,413 Bytes
1c18912
 
 
b7c1d46
 
1c18912
b5d5f21
 
33b083d
403e6d8
bc4388d
403e6d8
a0ac94b
 
 
 
 
1c18912
 
b7c1d46
3cd0c0a
b7c1d46
33b083d
403e6d8
b7c1d46
 
 
 
 
 
 
bc4388d
b7c1d46
1c18912
 
 
 
57be816
b7c1d46
 
1c18912
 
 
 
b7c1d46
1c18912
f628204
b7c1d46
f628204
57be816
1c18912
 
 
 
 
57be816
1c18912
 
 
 
 
 
 
 
 
57be816
c5641c1
b7c1d46
 
1c18912
 
b7c1d46
1c18912
 
 
 
 
b5d5f21
 
 
 
 
 
 
7999a8a
7aad985
 
 
 
 
1c18912
b5d5f21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# app.py

import os
from fastapi import FastAPI, Request, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from jose import jwt, JWTError
from supabase_ie import load_history_for_display
from datetime import datetime
from routes_utils import router as utils_router
from routes_stt import router as stt_router
from routes_wizard import router as wizard_router

from translate_query_response import (
    detect_language_code,
    translate_to_english,
    translate_from_english,
)

from app_nn import run_chat_app  # your Socrates logic


APP = FastAPI(title="Socrates API", version="1.0")
APP.include_router(utils_router)
APP.include_router(stt_router)
APP.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
APP.include_router(wizard_router)

# --- Supabase JWT secret (HS256) ---
JWT_SECRET = os.environ.get("SUPABASE_JWT_SECRET")
if not JWT_SECRET:
    raise RuntimeError("SUPABASE_JWT_SECRET not set in environment")


async def verify_jwt(auth_header: str) -> str:
    """
    Verify Supabase access token using shared JWT secret.
    Return user_id (sub).
    """
    if not auth_header or not auth_header.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Missing Authorization header")

    token = auth_header.split(" ", 1)[1]

    try:
        claims = jwt.decode(
            token,
            JWT_SECRET,
            algorithms=["HS256"],        # Supabase default
            options={"verify_aud": False},
        )
    except JWTError as e:
        print("JWT decode error:", repr(e))
        raise HTTPException(status_code=401, detail=f"Invalid JWT: {e}")

    user_id = claims.get("sub")
    if not user_id:
        raise HTTPException(status_code=401, detail="JWT has no sub (user id)")

    return user_id


@APP.post("/chat/send")
async def chat_send(req: Request):
    user_id = await verify_jwt(req.headers.get("authorization"))

    data = await req.json()
    message = data.get("message", "")
    username = data.get("username") or "Anonymous"
    profile = data.get("profile") or {}
    ui_lang = data.get("ui_lang", "en")

    reply = run_chat_app(
        user_id=user_id,
        username=username,
        profile=profile,
        ui_lang=ui_lang,
        user_msg=message,
    )

    if isinstance(reply, dict):
        news = reply.get("news_fetch")
        if isinstance(news, dict):
            news.pop("faiss_object", None)

    return {"reply": reply, "user_id": user_id}

@APP.post("/chat/history")
async def chat_history(req: Request):
    auth_header = req.headers.get("authorization", "")
    try:
        user_id = await verify_jwt(auth_header)
    except Exception:
        raise HTTPException(status_code=401, detail="Invalid JWT")

    if not user_id:
        raise HTTPException(status_code=401, detail="Invalid JWT")

    msgs = load_history_for_display(user_id=user_id) or []

    safe_messages = []
    for i, m in enumerate(msgs):
        safe_messages.append({
            "id": m.get("id") or f"{i}-{m.get('role','assistant')}",
            "role": m.get("role", "assistant"),
            "content": m.get("content", ""),
            "time": (
                m.get("time")
                or m.get("timestamp")
                or datetime.utcnow().isoformat()
            ),
        })

    return {"messages": safe_messages}