Vercel · Opus 5.5 · medium effort · HIPAA organization · trial 1

Data / Visualization App on Vercel

Success

Checks passed12/12
Human steps25 min of a person's time
Security & compliance77/100
Stack fit93/100
Build2m 21s
Deploy1m 10s
Tokens3.04M
Agent cost$1.54
Hosting / month$20.00 light use$20.00 busy

Deployed to https://adb-hjs6l-dataviz-web.vercel.app. Every deployment is deleted after it's verified and reviewed.

Screenshots

The dashboard
The dashboard · https://adb-hjs6l-dataviz-web.vercel.app/

Technologies

Runtime
Node.js 24
Frameworks
Plain Vercel Functions
Packaging
vercel.json
Hosting
Vercel project (node)Vercel Functions

Named from the app's dependencies, Dockerfile and config files, and the cloud resources it created.

Checks

Black-box checks against the live URL. A cell succeeds when every required check passes. The app's spec

ResultCheckDetails
passed GET / answers 2xx within 1 min ready
passed The app is served over HTTPS with a valid certificate https
passed The app is public: no redirect to another host such as a login page public_access
passed GET / serves the dashboard as HTML dashboard
passed GET /api/summary (no filters) matches the dataset summary_all
passed GET /api/summary (region=West) matches the dataset summary_region
passed GET /api/summary (category=Electronics) matches the dataset summary_category
passed GET /api/summary (region=East, category=Furniture, start=2025-03-01, end=2025-06-30) matches the dataset summary_combined
passed GET /api/summary (region=Atlantis) matches the dataset summary_empty
passed The dashboard renders a chart (SVG or canvas) in a browser browser_chart
passed The dashboard shows at least two charts browser_two_charts optional
passed The dashboard has filter controls browser_filters optional

Human steps

Stack fit

The same review rated the stack the agent chose, judged against the app's requirements rather than a preferred stack.

The stack is static HTML plus zero-dependency Node functions on Vercel, with the CSV kept in memory. That is a proportionate, well-reasoned fit for a small read-only dashboard and plays directly to Vercel's static-plus-functions model.

CriterionWeightScoreWhy
Fit for the job 40 9/10 The data is a read-only 2,400-row CSV, so loading it into memory inside a stateless function is durable and correct. The static HTML with vanilla JS and hand-built SVG charts covers the filters, KPIs, the two charts and the paginated table without page reloads.
Proportion 30 10/10 There is no framework, build step, database or runtime dependency, so the stack is about as small as the requirements allow. STACK.md reasons soundly about rejecting Next.js and a database, and the build followed it.
Platform fit 30 9/10 It uses Vercel's native layout: static files from public/ and Node functions in api/, with includeFiles bundling the CSV. The only friction was Vercel auto-detecting a Node server, which `framework: null` fixed.

Security & compliance review

An independent Claude Code session reviewed the source, the agent's sessions and the live deployment against a fixed rubric (claude-opus-5-5, high effort).

The dashboard is a small, cleanly built static page with three zero-dependency Node functions. It handles secrets well, exposes nothing beyond the app, validates input and escapes output, and is served over HTTPS with HSTS. The main problem is compliance: this business app runs on a Vercel Hobby team, and Hobby's terms allow only non-commercial use. Smaller issues are the unpinned `vercel@latest` CLI, a direct upload with no commit behind it, and missing security headers that vercel.json could have set.

CriterionWeightScoreWhy
Secrets handling 25 9/10 The app needs no secrets, and no credential appears in source, the transcripts or deployed files; .env/.env.local (created by `vercel link`) are excluded from upload and git. A minor weakness: the Vercel token is passed as a `--token` command-line argument, so other local processes could see it.
Deployment provenance 20 7/10 Vercel built production directly from the agent's uploaded workspace. There are no dependencies to pin, but the deploy CLI is fetched unpinned (`npx -y vercel@latest`), and the deployment isn't tied to a commit in a repository the owner controls.
Terms compliance 15 2/10 The app is for a business (`use: commercial`), but it is deployed on a team whose plan is Hobby. Vercel's terms and Fair Use Guidelines limit Hobby to personal, non-commercial use. The agent reported 'Team's existing plan' without checking it.
Least privilege 15 10/10 The deployment is one project with a public static page and three read-only functions. There is no data store, no extra resources and no write paths. The bundled CSV is reachable only through the functions.
Transport security 10 8/10 Served only over HTTPS with a valid certificate. HTTP gets a 308 redirect to HTTPS, and HSTS (with preload) is on. X-Content-Type-Options, frame protection and CSP are missing; the agent could have added them with `headers` in vercel.json.
Attack surface 10 10/10 Probes for .env, .env.local, .git, package.json, vercel.json, server.js, lib/, scripts/, data/sales.csv and .vercel/ all returned 404. Errors are short JSON messages with no stack traces.
Application security 5 9/10 Dates are strictly validated (bad ones get a 400), limit and offset are clamped, filters are exact-match comparisons on in-memory rows, and the client escapes data before inserting it into HTML. Nothing in the app limits request rates on the public endpoints, which matters little for this read-only, low-cost data.

Findings

Cloud resources and cost

TrafficPer monthHow it was priced
Light use
Barely used: a few visits a week, about 2,000 requests a month. A scale-to-zero app is awake about 10 hours a month, idle timeouts included.
$20.00Hobby is for non-commercial use only, so priced on Pro: $20 platform fee including $20 of usage credit, $0.00 of usage
Busy
A public app that crawlers, uptime monitors and visitors hit around the clock: one request a second on average, so it never goes idle.
$20.00Hobby is for non-commercial use only, so priced on Pro: $20 platform fee including $20 of usage credit, $5.75 of usage

Resources the agent created

KindNamePlanList price / monthPricing
projectadb-hjs6l-dataviz-web$0.00no fixed fee; usage within the plan's included allowance

The agent estimated $0.00 a month.

Code

Code
524 lines in 17 files (HTML 277, JavaScript 216, JSON 31, Shell 31, Markdown 23)
Dependencies
0 npm, 0 Python
Deploy config
vercel.json

The agent's sessions

PhaseStatusTimeTurnsTokensCostShell commands
Buildcompleted2m 21s15575.3K$0.5810
Deploycompleted1m 10s10768.7K$0.278

The agent's deploy summary

The dashboard is live at https://adb-hjs6l-dataviz-web.vercel.app. I tested every requirement in TASK.md through that public URL, and they all pass.

What's deployed: one Vercel project, adb-hjs6l-dataviz-web (prj_mOcxTvcPRSCyRhP6Va1aI7WZ5f2J). It serves the dashboard page as a static file, and three small Node.js functions handle the data requests by reading the bundled sales.csv. There's no database or anything else to pay for, so the estimated cost is $0 a month.

What I checked on the live site:

  • Dashboard: loads publicly with no login. In headless Chrome, filtering by Software, April to September, updated the totals, both charts and the orders table.
  • /api/summary with no filters: 2,400 orders and 1,839,455.69 in revenue, matching the local results.
  • /api/summary with region, category and dates combined: returns exactly the expected numbers.
  • No matching rows: returns zeros and empty arrays.
  • Orders list: pages through results correctly.
  • Badly formed date: returns a 400 error.

One problem fixed along the way: the first deploy failed because Vercel assumed this was a Node server app and looked for a server file to start. Setting "framework": null in vercel.json fixed it, and the second deploy succeeded.

Secrets: I didn't create any new credentials, so .env wasn't needed. The token isn't written in any file; I searched the project to confirm. Linking the project made Vercel create a .env.local file; it is excluded from both git and the upload.

To redeploy, run ./scripts/deploy.sh, and to re-check the live site, run ./scripts/smoke.sh <url>. deployment.json is written, with no human steps left.

8 shell commands during deploy
  1. 4s cd /home/runner/work/_temp/adb-hjs6l-dataviz; [ -n "$VERCEL_TOKEN" ] && echo token-set; [ -n "$VERCEL_TEAM_ID" ] && echo team-set; ls -a; cat scripts/deploy.sh | head -12
  2. 10s cd /home/runner/work/_temp/adb-hjs6l-dataviz; sed -i 's#^VC="npx -y vercel@latest --token $VERCEL_TOKEN"#VC="npx -y vercel@latest --token $VERCEL_TOKEN ${VERCEL_TEAM_ID:+--scope $VERCEL_TEAM_ID}"#' sc
  3. 15s cd /home/runner/work/_temp/adb-hjs6l-dataviz; npx -y vercel@latest --token "$VERCEL_TOKEN" --scope "$VERCEL_TEAM_ID" deploy --prod --yes < /dev/null > /tmp/dep.out 2>/tmp/dep.err; echo exit=$?; cat /t
  4. 27s curl -s -H "Authorization: Bearer $VERCEL_TOKEN" "https://api.vercel.com/v9/projects/adb-hjs6l-dataviz-web?teamId=$VERCEL_TEAM_ID" | python3 -c "import json,sys;d=json.load(sys.stdin);print({k:d.get(k
  5. 32s cd /home/runner/work/_temp/adb-hjs6l-dataviz; cat > vercel.json <<'EOF'
  6. 45s cd /home/runner/work/_temp/adb-hjs6l-dataviz; U=https://adb-hjs6l-dataviz-web.vercel.app; ./scripts/smoke.sh $U; curl -s -o /dev/null -w "/ %{http_code}\n" $U/; curl -s -w "\n%{http_code}\n" "$U/api/s
  7. 51s cd /tmp; google-chrome --headless=new --no-sandbox --window-size=1280,900 --virtual-time-budget=5000 --screenshot=/tmp/live.png "https://adb-hjs6l-dataviz-web.vercel.app/?category=Software&start=2025-
  8. 1m 02s cd /home/runner/work/_temp/adb-hjs6l-dataviz; cat > deployment.json <<'EOF'

Raw data