Skip to content

Guest quotas, AI budget before every AI call, blocked features (2/3) - #15

Merged
DHYEY166 merged 4 commits into
mainfrom
feature/guest-limits
Oct 2, 2026
Merged

DHYEY166 merged 4 commits into
mainfrom
feature/guest-limits

Conversation

@DHYEY166

@DHYEY166 DHYEY166 commented Oct 2, 2026 •

Copy link
Copy Markdown
Owner

Stack: 2 of 3. This PR's base is feature/guest-identity (#14). Merge #14 first, then retarget this PR to main. #16 (guest demo) is stacked on this one.

What

  • Guest quotas, counted in Postgres (src/lib/guest-quota.ts, src/lib/billing.ts):
    • A "guest" quota plan: 10,000 rows all-time. Runs refused for size do not count.
    • 5,000 rows per run, checked in suggest-transforms before templates or AI.
    • Uploads: 3 per guest and 10 per IP hash per 24 h, enforced by one capped INSERT. The same insert also refuses an expired session.
    • 5 pipelines per guest.
  • checkAiBudget(teamId, calls) (src/lib/bedrock-meter.ts) runs before every Bedrock call:
    • suggest-transforms on every pass. This replaces the old pass-1-only spend check.
    • The auto-validate committee, which reserves its 3 calls together and falls back to manual review when over budget.
    • chat-builder and generate-data.
    • Users keep the monthly hard cap. Guests get 10 calls/h, $0.25 per guest, and $5 per UTC day across all guests (team_id LIKE 'guest\_%', with a new bedrock_usage(created_at) index in 003).
    • meterBedrockCall is now awaited, so the next check sees the call.
  • Blocked for guests: chat-builder/generate-data, auto-clean, export-training, alerts, account deletion, templates (API and /templates page) and /api/admin. The middleware answers 403 for API requests and redirects pages; each route also calls forbidGuest.
  • Chat-builder metering for signed-in users. This was cheap: a cap check up front and streamText onFinish metering. generate-data is capped and metered the same way.

Look hardest at

  • The two capped INSERT ... SELECT statements.
  • checkAiBudget's single query.
  • The middleware ordering. A Clerk or test user with a stale guest cookie is never blocked.

Verified (locally)

  • tsc, lint (0 errors), vitest: 221 passed.
  • Integration: 23 passed. New guest-limits.test.ts covers:
    • 3-upload cap and 10-per-IP cap across 4 guests.
    • Expired session.
    • 5-pipeline cap.
    • 5,001-row run failed with no AI call.
    • 10k rows per guest.
    • 11th AI call/h refused.
    • $0.25 per guest and $5 across all guests per day refused.
    • Auto-validate falling back to manual review at 8 calls/h.
  • e2e: 11 passed. New test: a guest is redirected from /templates, gets 403 on 6 blocked APIs, and gets 429 on the 4th upload.

Caveat

Usage is recorded after a call, so concurrent requests can overshoot a cap by the cost of the calls in flight. This is documented in the README.

Guests get a "guest" quota plan: 10,000 rows all-time (runs refused for size
do not count), 5,000 rows per run checked in suggest-transforms before
templates or AI, 3 uploads per guest and 10 per IP hash per 24 h via one
capped INSERT that also refuses an expired session, and 5 pipelines.

checkAiBudget(teamId, calls) replaces the pass-1-only spend check and runs
before every Bedrock call: suggest-transforms on every pass and the 3-call
auto-validate committee (which falls back to manual review when over
budget). Users keep the monthly hard cap; guests get 10 calls/h, $0.25 each
and $5/UTC day for all guests together, counted from bedrock_usage (new
created_at index in 003). meterBedrockCall is now awaited so the next check
sees the call. Rejected: Upstash counters (they fail open).
Guests cannot use chat-builder/generate-data, auto-clean, training export,
Slack alerts, account deletion, templates or /api/admin: the middleware
answers 403 for the API (redirects /templates to the dashboard) and each
route also refuses guest ids, so a matcher mistake cannot expose them. A
signed-in user with a stale guest cookie is unaffected.

chat-builder and generate-data were neither metered nor capped. They now
check the monthly AI cap first and record usage (streamText onFinish).
@vercel

vercel Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
clean-stack Building Building Preview Oct 2, 2026 5:23pm UTC
cleanstack Building Building Preview, v0 Oct 2, 2026 5:23pm UTC

@DHYEY166
DHYEY166 merged commit 3b524f5 into main Oct 2, 2026
9 checks passed
@DHYEY166
DHYEY166 deleted the feature/guest-limits branch October 2, 2026 17:30

This branch was successfully deployed

2 active deployments
Preview – cleanstack — 7be83fe0 Deployed Oct 2, 2026 by vercel[bot]
Preview – clean-stack — 7be83fe0 Deployed Oct 2, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant