File size: 5,380 Bytes
31f2a28
 
 
df5cfe3
31f2a28
 
 
 
 
 
 
 
df5cfe3
31f2a28
 
df5cfe3
 
31f2a28
 
df5cfe3
31f2a28
df5cfe3
 
 
 
31f2a28
 
 
 
df5cfe3
 
 
 
 
 
 
 
 
 
31f2a28
 
df5cfe3
 
 
 
 
 
31f2a28
 
df5cfe3
 
 
31f2a28
 
df5cfe3
31f2a28
df5cfe3
31f2a28
 
 
df5cfe3
 
31f2a28
 
 
 
 
 
df5cfe3
 
31f2a28
 
 
 
 
df5cfe3
31f2a28
 
df5cfe3
 
 
31f2a28
 
df5cfe3
 
31f2a28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
df5cfe3
31f2a28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
df5cfe3
 
 
 
31f2a28
 
 
 
 
 
 
 
df5cfe3
 
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import os
import hashlib
import secrets
from typing import Optional, Dict, Any, List
from dotenv import load_dotenv
from supabase import create_client, Client

load_dotenv()

SUPABASE_URL = os.getenv("SUPABASE_URL")
SUPABASE_SERVICE_KEY = os.getenv("SUPABASE_SERVICE_KEY")

supabase: Optional[Client] = create_client(SUPABASE_URL, SUPABASE_SERVICE_KEY) if SUPABASE_URL and SUPABASE_SERVICE_KEY else None

def hash_key(api_key: str) -> str:
    """Calculeaza SHA-256 pentru API key."""
    return hashlib.sha256(api_key.strip().encode('utf-8')).hexdigest()

def verify_api_key_db(api_key: str) -> Optional[Dict[str, Any]]:
    """Valideaza cheia, verifica planul si incrementeaza cota de utilizare."""
    if not supabase:
        print("[DB Warning]: Supabase client not initialized. Bypassing auth.")
        return {"quota_exceeded": False, "plan": "free", "org_id": None, "project_id": None}

    if not api_key:
        return None

    hashed_key = hash_key(api_key)

    try:
        response = supabase.table("api_keys") \
            .select("id, org_id, is_active, plan, monthly_limit, current_usage") \
            .eq("key_hash", hashed_key) \
            .eq("is_active", True) \
            .limit(1) \
            .execute()

        if not response.data:
            return None

        key_record = response.data[0]
        current_usage = key_record.get("current_usage", 0)
        monthly_limit = key_record.get("monthly_limit", 500)
        plan = key_record.get("plan", "free")

        # Verificare cota
        if current_usage >= monthly_limit:
            return {
                "quota_exceeded": True,
                "usage": current_usage,
                "limit": monthly_limit,
                "plan": plan
            }

        # Incrementare sigura
        supabase.table("api_keys") \
            .update({"current_usage": current_usage + 1}) \
            .eq("id", key_record["id"]) \
            .execute()

        # Obtinere proiect asociat
        project_id = None
        proj_res = supabase.table("projects") \
            .select("id") \
            .eq("org_id", key_record["org_id"]) \
            .limit(1) \
            .execute()

        if proj_res.data:
            project_id = proj_res.data[0]["id"]

        return {
            "quota_exceeded": False,
            "org_id": key_record["org_id"],
            "project_id": project_id,
            "plan": plan
        }

    except Exception as e:
        print(f"[DB Auth Error]: {e}")
        return None

def save_evaluation_to_db(project_id: str, report_data: Dict[str, Any]) -> Optional[str]:
    """Salveaza asincron raportul complet si incidentele de securitate in Supabase."""
    if not supabase or not project_id or not report_data:
        return None

    try:
        summary = report_data.get("executive_summary", {})
        results = report_data.get("results", [])

        eval_run_payload = {
            "project_id": project_id,
            "health_rating": str(summary.get("health_rating", "F")),
            "success_rate": float(summary.get("success_rate_percentage", 0.0)),
            "mean_drift": float(summary.get("mean_drift", 0.0)) if "mean_drift" in summary else 0.0,
            "total_tokens": sum(r.get("total_tokens", 0) for r in results),
            "estimated_cost_usd": sum(r.get("estimated_cost_usd", 0.0) for r in results),
            "narrative_report": report_data.get("narrative_report", "")
        }

        run_res = supabase.table("eval_runs").insert(eval_run_payload).execute()
        if not run_res.data:
            return None

        eval_run_id = run_res.data[0]["id"]

        for session in results:
            session_payload = {
                "eval_run_id": eval_run_id,
                "session_id": str(session.get("session_id", "unknown")),
                "status": session.get("status", "STABLE"),
                "max_drift": float(session.get("max_drift_detected", 0.0)),
                "mean_drift": float(session.get("mean_drift", 0.0)),
                "enriched_graph": session.get("enriched_graph", {})
            }

            session_res = supabase.table("session_trajectories").insert(session_payload).execute()
            if session_res.data:
                session_db_id = session_res.data[0]["id"]
                failures = session.get("failures", [])
                if failures:
                    failure_payloads = [
                        {
                            "session_trajectory_id": session_db_id,
                            "failure_type": f.get("failure_type", "UNKNOWN"),
                            "from_node": str(f.get("from_node", "")),
                            "to_node": str(f.get("to_node", "")),
                            "reason": str(f.get("reason", "")),
                            "details": str(f.get("details", "")) if f.get("details") else None
                        } for f in failures
                    ]
                    supabase.table("failure_incidents").insert(failure_payloads).execute()

        print(f"[Supabase Sync]: Eval Run [{eval_run_id}] salvat cu succes.")
        return eval_run_id

    except Exception as e:
        print(f"[Supabase Sync Error]: {e}")
        return None