hosman20 puts Mike behind a paywall

The fork now ships with a full Stripe subscription stack, a 14-day trial on signup, and a paywall that intercepts every AI call.

infrastructureworkflow

hosman20 has wired Mike up as a paid product. New signups automatically get a 14-day trial; once that expires - or the user blows past their token allowance - the backend refuses the next AI request with a structured reason code, and the browser quietly redirects them to a public pricing page with Starter, Professional, and Enterprise tiers. A countdown banner inside the app reminds trial users where they stand, and a billing settings tab links out to Stripe's customer portal for self-serve upgrades and cancellations.

The plumbing is the interesting part: token usage is tallied after each chat stream finishes rather than before it starts, so metering never slows the response down. The Enterprise tier is still a sales-email placeholder, but everything beneath it is in place and covered by tests.

So what Worth a look for any legal-tech team thinking about how to put a usage-based AI product behind a subscription without throttling the user experience.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

2 commits from hosman20/mike-2.0, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
ba00445b feat(billing): add Stripe subscriptions and paywall middleware z 2026-05-13 ↗ GitHub
commit body
Batch 5 - gate AI chat endpoints behind an active subscription
(or active 14-day trial) and record token usage against the
subscription's monthly limit.

Database:
- backend/migrations/001_add_subscriptions.sql: idempotent
  (CREATE IF NOT EXISTS), RLS-enabled, auto-provisions a trial
  row on every new auth.users insert via trigger.
- backend/schema.sql: mirror of the migration appended.

Backend:
- backend/src/lib/stripe.ts: Stripe SDK wiring.
- backend/src/lib/billing/usage.ts: recordTokenUsage() fire-and-
  forget bookkeeping after stream completion (never blocks the
  hot path, never throws).
- backend/src/routes/billing.ts: checkout/portal/webhook endpoints.
  Handles checkout.session.completed and
  customer.subscription.{created,updated,deleted}.
- backend/src/middleware/requireActiveSubscription.ts: paywall.
- backend/src/index.ts: mount raw-body parser ahead of express.json
  for the Stripe webhook signature check; gate POST /chat,
  /projects/:id/chat, /tabular-review/:id/chat, and
  /tabular-review/:id/generate with requireAuth + paywall.
- backend/.env.example: STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET,
  and STRIPE_PRICE_{STARTER,PROFESSIONAL,ENTERPRISE}.
- backend/package.json: stripe@^22.1.1 + vitest test runner.
- routes/{chat,projectChat,tabular}.ts: void recordTokenUsage(...)
  after each successful stream.

Frontend:
- frontend/src/lib/billing.ts: tier metadata + helpers.
- frontend/src/app/lib/mikeApi.ts: HTTP 402 interceptor redirects
  the browser to /pricing?reason=... on paywall rejection.

Tests:
- 6 middleware tests + 4 webhook tests (10 new tests total).

Agent ID: aa83ddc67d4dfac03 (general-purpose).
d3956d04 feat(billing-ui): pricing page, billing settings, and trial banner z 2026-05-13 ↗ GitHub
commit body
Batch 6 - surface the new subscription state in the product:
public pricing page, in-app billing settings tab, and a top-of-
main trial countdown banner.

- frontend/src/app/pricing/page.tsx: public /pricing route, lands
  logged-out users redirected from a 402. Enterprise CTA stubs out
  to mailto:sales@mike.ai (placeholder).
- frontend/src/app/(pages)/account/billing/page.tsx: in-app billing
  settings - current plan, trial status, token usage, manage button
  (Stripe customer portal).
- frontend/src/components/chrome/trial-banner.tsx: countdown banner
  for trialing users, mounted at top of <main> in (pages)/layout.tsx.
- frontend/src/app/(pages)/account/layout.tsx: re-add the "Billing"
  tab (replaces the "Models & API Keys" tab removed in batch 4).
- frontend/src/app/lib/mikeApi.ts: SubscriptionTier/Status/Info
  types + subscription field on UserProfile.
- frontend/src/contexts/UserProfileContext.tsx: thread subscription
  through the profile context.
- backend/src/routes/user.ts: return the subscription block on the
  /user/profile response.
- 5 new tests (3 pricing + 2 billing).

Agent ID: ad65cb0ceb7e70da6 (general-purpose).

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-409.md from inside the repo you want the changes in.

⬇ Download capture-thread-409.md