Spaces:
Sleeping
Sleeping
File size: 5,379 Bytes
7f10996 | 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 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | """
Supabase Database Helper
Saves/loads audit results in batches.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
RUN THIS SQL IN SUPABASE SQL EDITOR (one-time setup):
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
CREATE TABLE audit_runs (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
name TEXT NOT NULL,
domain TEXT NOT NULL,
total_urls INTEGER DEFAULT 0,
completed_urls INTEGER DEFAULT 0,
status TEXT DEFAULT 'running' CHECK (status IN ('running', 'paused', 'completed', 'error')),
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
summary JSONB DEFAULT '{}'::jsonb,
pending_urls JSONB DEFAULT '[]'::jsonb
);
CREATE TABLE audit_pages (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
run_id UUID REFERENCES audit_runs(id) ON DELETE CASCADE,
url TEXT NOT NULL,
result JSONB NOT NULL,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX idx_audit_pages_run_id ON audit_pages(run_id);
CREATE INDEX idx_audit_pages_url ON audit_pages(url);
CREATE INDEX idx_audit_runs_status ON audit_runs(status);
ALTER TABLE audit_runs ENABLE ROW LEVEL SECURITY;
ALTER TABLE audit_pages ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Allow all on audit_runs" ON audit_runs FOR ALL USING (true);
CREATE POLICY "Allow all on audit_pages" ON audit_pages FOR ALL USING (true);
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
"""
import json
from datetime import datetime
from supabase import create_client, Client
def get_client(url: str, key: str) -> Client:
return create_client(url, key)
# βββ Run Management βββ
def create_run(client: Client, name: str, domain: str, total_urls: int, all_urls: list) -> str:
data = {
"name": name,
"domain": domain,
"total_urls": total_urls,
"completed_urls": 0,
"status": "running",
"pending_urls": json.dumps(all_urls),
}
response = client.table("audit_runs").insert(data).execute()
return response.data[0]["id"]
def get_run(client: Client, run_id: str):
response = client.table("audit_runs").select("*").eq("id", run_id).single().execute()
return response.data
def get_all_runs(client: Client):
response = client.table("audit_runs").select("*").order("created_at", desc=True).execute()
return response.data
def update_run_status(client: Client, run_id: str, status: str, completed: int = None, summary: dict = None):
data = {"status": status, "updated_at": datetime.utcnow().isoformat()}
if completed is not None:
data["completed_urls"] = completed
if summary is not None:
data["summary"] = json.loads(json.dumps(summary, default=str))
client.table("audit_runs").update(data).eq("id", run_id).execute()
def delete_run(client: Client, run_id: str):
client.table("audit_pages").delete().eq("run_id", run_id).execute()
client.table("audit_runs").delete().eq("id", run_id).execute()
# βββ Page Results βββ
def save_batch_results(client: Client, run_id: str, batch_results: list):
rows = []
for r in batch_results:
clean = json.loads(json.dumps(r, default=str))
rows.append({"run_id": run_id, "url": r['url'], "result": clean})
for i in range(0, len(rows), 50):
chunk = rows[i:i+50]
client.table("audit_pages").insert(chunk).execute()
def get_completed_urls(client: Client, run_id: str) -> set:
urls = set()
offset = 0
page_size = 1000
while True:
response = (
client.table("audit_pages")
.select("url")
.eq("run_id", run_id)
.range(offset, offset + page_size - 1)
.execute()
)
if not response.data:
break
urls.update(p["url"] for p in response.data)
if len(response.data) < page_size:
break
offset += page_size
return urls
def get_completed_count(client: Client, run_id: str) -> int:
response = (
client.table("audit_pages")
.select("id", count="exact")
.eq("run_id", run_id)
.execute()
)
return response.count or 0
def get_all_page_results(client: Client, run_id: str) -> list:
all_pages = []
offset = 0
page_size = 500
while True:
response = (
client.table("audit_pages")
.select("url, result")
.eq("run_id", run_id)
.order("created_at", desc=False)
.range(offset, offset + page_size - 1)
.execute()
)
if not response.data:
break
all_pages.extend(response.data)
if len(response.data) < page_size:
break
offset += page_size
return all_pages
def get_pending_urls(client: Client, run_id: str) -> list:
run = get_run(client, run_id)
pending = run.get("pending_urls")
if isinstance(pending, str):
return json.loads(pending)
return pending or []
|