mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-05 05:05:08 +02:00
fix: pre-landing review fixes — JSONB field order, version filter, RLS verification
- Dashboard JSON parsing: use per-object grep instead of field-order-dependent regex (JSONB doesn't preserve key order) - Version distribution: filter to skill_run events only (was counting all types) - verify-rls.sh: only 401/403 count as PASS (not empty 200 or 5xx); add Authorization header to test as anon role properly - Remove dead empty loop in community-pulse
This commit is contained in:
@@ -59,10 +59,11 @@ echo "────────────────────────"
|
||||
# Parse top_skills array from JSON
|
||||
SKILLS="$(echo "$DATA" | grep -o '"top_skills":\[[^]]*\]' || echo "")"
|
||||
if [ -n "$SKILLS" ] && [ "$SKILLS" != '"top_skills":[]' ]; then
|
||||
echo "$SKILLS" | grep -o '"skill":"[^"]*","count":[0-9]*' | while read -r ENTRY; do
|
||||
SKILL="$(echo "$ENTRY" | grep -o '"skill":"[^"]*"' | awk -F'"' '{print $4}')"
|
||||
COUNT="$(echo "$ENTRY" | grep -o '"count":[0-9]*' | grep -o '[0-9]*')"
|
||||
printf " /%-20s %s runs\n" "$SKILL" "$COUNT"
|
||||
# Parse each object — handle any key order (JSONB doesn't preserve order)
|
||||
echo "$SKILLS" | grep -o '{[^}]*}' | while read -r OBJ; do
|
||||
SKILL="$(echo "$OBJ" | grep -o '"skill":"[^"]*"' | awk -F'"' '{print $4}')"
|
||||
COUNT="$(echo "$OBJ" | grep -o '"count":[0-9]*' | grep -o '[0-9]*')"
|
||||
[ -n "$SKILL" ] && [ -n "$COUNT" ] && printf " /%-20s %s runs\n" "$SKILL" "$COUNT"
|
||||
done
|
||||
else
|
||||
echo " No data yet"
|
||||
@@ -75,10 +76,10 @@ echo "──────────────────"
|
||||
|
||||
CRASHES="$(echo "$DATA" | grep -o '"crashes":\[[^]]*\]' || echo "")"
|
||||
if [ -n "$CRASHES" ] && [ "$CRASHES" != '"crashes":[]' ]; then
|
||||
echo "$CRASHES" | grep -o '"error_class":"[^"]*"[^}]*"total_occurrences":[0-9]*' | head -5 | while read -r ENTRY; do
|
||||
ERR="$(echo "$ENTRY" | grep -o '"error_class":"[^"]*"' | awk -F'"' '{print $4}')"
|
||||
C="$(echo "$ENTRY" | grep -o '"total_occurrences":[0-9]*' | grep -o '[0-9]*')"
|
||||
printf " %-30s %s occurrences\n" "$ERR" "${C:-?}"
|
||||
echo "$CRASHES" | grep -o '{[^}]*}' | head -5 | while read -r OBJ; do
|
||||
ERR="$(echo "$OBJ" | grep -o '"error_class":"[^"]*"' | awk -F'"' '{print $4}')"
|
||||
C="$(echo "$OBJ" | grep -o '"total_occurrences":[0-9]*' | grep -o '[0-9]*')"
|
||||
[ -n "$ERR" ] && printf " %-30s %s occurrences\n" "$ERR" "${C:-?}"
|
||||
done
|
||||
else
|
||||
echo " No crashes reported"
|
||||
@@ -91,10 +92,10 @@ echo "────────────────────────
|
||||
|
||||
VERSIONS="$(echo "$DATA" | grep -o '"versions":\[[^]]*\]' || echo "")"
|
||||
if [ -n "$VERSIONS" ] && [ "$VERSIONS" != '"versions":[]' ]; then
|
||||
echo "$VERSIONS" | grep -o '"version":"[^"]*","count":[0-9]*' | head -5 | while read -r ENTRY; do
|
||||
VER="$(echo "$ENTRY" | grep -o '"version":"[^"]*"' | awk -F'"' '{print $4}')"
|
||||
COUNT="$(echo "$ENTRY" | grep -o '"count":[0-9]*' | grep -o '[0-9]*')"
|
||||
printf " v%-15s %s events\n" "$VER" "$COUNT"
|
||||
echo "$VERSIONS" | grep -o '{[^}]*}' | head -5 | while read -r OBJ; do
|
||||
VER="$(echo "$OBJ" | grep -o '"version":"[^"]*"' | awk -F'"' '{print $4}')"
|
||||
COUNT="$(echo "$OBJ" | grep -o '"count":[0-9]*' | grep -o '[0-9]*')"
|
||||
[ -n "$VER" ] && [ -n "$COUNT" ] && printf " v%-15s %s events\n" "$VER" "$COUNT"
|
||||
done
|
||||
else
|
||||
echo " No data yet"
|
||||
|
||||
@@ -85,12 +85,10 @@ Deno.serve(async () => {
|
||||
|
||||
// Version distribution (last 7 days)
|
||||
const versionCounts: Record<string, number> = {};
|
||||
for (const row of skillRows ?? []) {
|
||||
// skillRows doesn't have version — query separately
|
||||
}
|
||||
const { data: versionRows } = await supabase
|
||||
.from("telemetry_events")
|
||||
.select("gstack_version")
|
||||
.eq("event_type", "skill_run")
|
||||
.gte("event_timestamp", weekAgo)
|
||||
.limit(1000);
|
||||
|
||||
|
||||
+21
-14
@@ -23,6 +23,7 @@ check() {
|
||||
|
||||
local args=(-sf -o /dev/null -w '%{http_code}' --max-time 10
|
||||
-H "apikey: ${KEY}"
|
||||
-H "Authorization: Bearer ${KEY}"
|
||||
-H "Content-Type: application/json")
|
||||
|
||||
if [ "$method" = "GET" ]; then
|
||||
@@ -33,24 +34,29 @@ check() {
|
||||
HTTP="$(curl "${args[@]}" -X PATCH "${URL}/rest/v1/${path}" -d "$data" 2>/dev/null || echo "000")"
|
||||
fi
|
||||
|
||||
# Success = anything that is NOT a 200/201 with data
|
||||
# 403, 401, or empty 200 (=[]) all count as "denied"
|
||||
# Only 401/403 prove RLS denial. 200 (even empty) means access is granted.
|
||||
# 5xx means something errored but access wasn't denied by policy.
|
||||
case "$HTTP" in
|
||||
401|403)
|
||||
echo " PASS $desc (HTTP $HTTP, denied by RLS)"
|
||||
PASS=$(( PASS + 1 ))
|
||||
;;
|
||||
200)
|
||||
# For GETs, check if response is empty array
|
||||
BODY="$(curl -sf --max-time 10 "${URL}/rest/v1/${path}" -H "apikey: ${KEY}" -H "Content-Type: application/json" 2>/dev/null || echo "")"
|
||||
if [ "$BODY" = "[]" ] || [ -z "$BODY" ]; then
|
||||
echo " PASS $desc (HTTP $HTTP, empty)"
|
||||
PASS=$(( PASS + 1 ))
|
||||
# 200 means the request was accepted — check if data was returned
|
||||
if [ "$method" = "GET" ]; then
|
||||
BODY="$(curl -sf --max-time 10 "${URL}/rest/v1/${path}" -H "apikey: ${KEY}" -H "Authorization: Bearer ${KEY}" -H "Content-Type: application/json" 2>/dev/null || echo "")"
|
||||
if [ "$BODY" = "[]" ] || [ -z "$BODY" ]; then
|
||||
echo " WARN $desc (HTTP $HTTP, empty — may be RLS or empty table, verify manually)"
|
||||
FAIL=$(( FAIL + 1 ))
|
||||
else
|
||||
echo " FAIL $desc (HTTP $HTTP, got data)"
|
||||
FAIL=$(( FAIL + 1 ))
|
||||
fi
|
||||
else
|
||||
echo " FAIL $desc (HTTP $HTTP, got data)"
|
||||
echo " FAIL $desc (HTTP $HTTP, write accepted)"
|
||||
FAIL=$(( FAIL + 1 ))
|
||||
fi
|
||||
;;
|
||||
401|403|404|406)
|
||||
echo " PASS $desc (HTTP $HTTP, denied)"
|
||||
PASS=$(( PASS + 1 ))
|
||||
;;
|
||||
201)
|
||||
echo " FAIL $desc (HTTP $HTTP, write succeeded!)"
|
||||
FAIL=$(( FAIL + 1 ))
|
||||
@@ -60,8 +66,9 @@ check() {
|
||||
FAIL=$(( FAIL + 1 ))
|
||||
;;
|
||||
*)
|
||||
echo " PASS $desc (HTTP $HTTP)"
|
||||
PASS=$(( PASS + 1 ))
|
||||
# 404, 406, 500, etc. — access not definitively denied by RLS
|
||||
echo " WARN $desc (HTTP $HTTP — not a clean RLS denial)"
|
||||
FAIL=$(( FAIL + 1 ))
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user