diff --git a/packages/ai-contracts/src/gemini.ts b/packages/ai-contracts/src/gemini.ts index a62ca2d..c1843fe 100644 --- a/packages/ai-contracts/src/gemini.ts +++ b/packages/ai-contracts/src/gemini.ts @@ -76,10 +76,10 @@ function requestOnce(input: string | URL | Request, init: RequestInit | undefine return; } - let body = ""; - res.setEncoding("utf8"); - res.on("data", (chunk) => { body += chunk; }); + const chunks: Buffer[] = []; + res.on("data", (chunk: Buffer) => { chunks.push(chunk); }); res.on("end", () => { + const body = Buffer.concat(chunks); resolve( new Response(body, { status, diff --git a/scripts/e2e-scan.sh b/scripts/e2e-scan.sh new file mode 100755 index 0000000..0a63077 --- /dev/null +++ b/scripts/e2e-scan.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash +set -euo pipefail + +API="https://api.cibello.app" +FIXTURE="apps/worker/src/eval/fixtures/fridge-1.jpg" +EMAIL="e2e-$(date +%s)@example.com" +PASS="E2ETest123!" + +echo "[e2e] register $EMAIL" +REG=$(curl -fsS -X POST "$API/v1/auth/register" -H 'content-type: application/json' \ + -d "{\"email\":\"$EMAIL\",\"password\":\"$PASS\",\"displayName\":\"E2E\",\"locale\":\"sv-SE\"}") +TOKEN=$(echo "$REG" | node -e "let d='';process.stdin.on('data',c=>d+=c).on('end',()=>console.log(JSON.parse(d).accessToken))") +echo "[e2e] token OK" + +echo "[e2e] create household" +HH=$(curl -fsS -X POST "$API/v1/households" -H "Authorization: Bearer $TOKEN" -H 'content-type: application/json' \ + -d '{"name":"E2E-hushåll"}') +HHID=$(echo "$HH" | node -e "let d='';process.stdin.on('data',c=>d+=c).on('end',()=>console.log(JSON.parse(d).id))") +echo "[e2e] household $HHID" + +echo "[e2e] grant image_training consent" +curl -fsS -X PUT "$API/v1/me/consents" -H "Authorization: Bearer $TOKEN" -H 'content-type: application/json' \ + -d '{"kind":"image_training","granted":true}' >/dev/null +echo "[e2e] consent OK" + +echo "[e2e] create scan" +SCAN=$(curl -fsS -X POST "$API/v1/scans" -H "Authorization: Bearer $TOKEN" -H 'content-type: application/json' \ + -d '{"scanType":"fridge","imageCount":1,"contentType":"image/jpeg"}') +SCANID=$(echo "$SCAN" | node -e "let d='';process.stdin.on('data',c=>d+=c).on('end',()=>console.log(JSON.parse(d).scan.id))") +UPLOAD=$(echo "$SCAN" | node -e "let d='';process.stdin.on('data',c=>d+=c).on('end',()=>console.log(JSON.stringify(JSON.parse(d).uploads[0])))") +URL=$(echo "$UPLOAD" | node -e "let d='';process.stdin.on('data',c=>d+=c).on('end',()=>console.log(JSON.parse(d).uploadUrl))") +KEY=$(echo "$UPLOAD" | node -e "let d='';process.stdin.on('data',c=>d+=c).on('end',()=>console.log(JSON.parse(d).key))") +echo "[e2e] scan $SCANID, upload key $KEY" + +echo "[e2e] PUT image" +curl -fsS -X PUT "$URL" -H 'content-type: image/jpeg' --data-binary "@$FIXTURE" >/dev/null +echo "[e2e] image uploaded" + +echo "[e2e] start scan" +curl -fsS -X POST "$API/v1/scans/$SCANID/start" -H "Authorization: Bearer $TOKEN" >/dev/null +echo "[e2e] scan started" + +echo "[e2e] poll status" +for i in $(seq 1 30); do + STATUS=$(curl -fsS "$API/v1/scans/$SCANID" -H "Authorization: Bearer $TOKEN" | node -e "let d='';process.stdin.on('data',c=>d+=c).on('end',()=>console.log(JSON.parse(d).status))") + echo "[e2e] status: $STATUS" + if [ "$STATUS" = "awaiting_confirmation" ] || [ "$STATUS" = "completed" ]; then + echo "$SCANID" > /tmp/e2e-scan-id.txt + echo "$KEY" > /tmp/e2e-s3-key.txt + echo "$EMAIL" > /tmp/e2e-email.txt + exit 0 + fi + if [ "$STATUS" = "failed" ]; then + echo "[e2e] scan failed" + exit 1 + fi + sleep 2 +done +echo "[e2e] timeout" +exit 1