Risemi
Filters2
Integrations

Auth — DONE. Supabase magic link; /app and /history require a session; /login and / are public.
Database — DONE. users(id, email, plan, trial_ends_at), courses(id, title), progress(id, user_id, course_id, lesson_no, completed_at). RLS: users read/write only rows where user_id = auth.uid().
Payments — NEEDS KEY. Stripe Checkout, $49/month, 5-day trial. Webhook /api/stripe/webhook verifies the signature with STRIPE_WEBHOOK_SECRET before any write. checkout.session.completed → users.plan = "pro"; invoice.payment_failed → plan = "past_due"; customer.subscription.deleted → plan = "free".
Email — NEEDS KEY. Resend: welcome on sign-up ("You're in — here's day 1"); trial-ending 2 days before trial_ends_at ("Your trial ends Thursday").

Source of truth for "paid": users.plan, written only by the webhook. The client never sets it.

Secrets expected in the environment panel: SUPABASE_URL, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY (server only), STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, RESEND_API_KEY.

Test before going live:
1. Sign up with a fresh email → magic link arrives → /app loads → one row in users with plan = "free".
2. Stripe test card 4242… → return to /app → plan = "pro" within 5 seconds → welcome email received.
3. Fire a test `customer.subscription.deleted` from the Stripe dashboard → plan = "free".
PromptCodePro
  • Claude Code
  • Codex
  • Copilot
  • +1
Coding

Wire Auth, Database, Payments and Email

One prompt that wires the real stack — secrets in the vault and a manual test for each integration.

0 copies
$3.99
Walkthrough
Lines 1–8 pull `items` from the cache with no validation. Lines 10–18 loop and sum `item.price * item.qty`. Lines 20–22 return the total as a float.

Assumptions
1. The cache always returns a list → None raises AttributeError at line 10.
2. Every item has `price` and `qty` → legacy rows without `qty` raise KeyError mid-loop; partial sums are lost.
3. `price` is numeric → a string price silently concatenates on some paths. Dangerous.
4. The list is not mutated during iteration → a concurrent cache refresh mutates it; totals come back inconsistent with no error. Dangerous.
5. An empty list means a zero total → returns 0 silently; callers cannot tell "no items" from "free". Dangerous.

Verdict on your concerns: concurrency — unsafe; error handling — none; empty list — silent zero.

Tests
- items = None → a clear 500 with a logged cause
- one item missing qty → validation error naming the item id
- 10k items during a cache refresh → a consistent snapshot or a retry

Confirm the diagnosis and I will propose a patch.
PromptCodePro
  • ChatGPT
  • Claude
  • Claude Code
  • +2
Coding

Code Walkthrough: Assumptions and Breakpoints

Line-by-line read of a function, every assumption it makes, what breaks when each fails — before any fix.

0 copies
$3.99
Built. Here is what exists now:

- /today — the screen learners live on: today's lesson card, a 7-day streak strip, and a trial banner counting down from 5 days with one coral "Keep my streak" button that routes to /upgrade.
- /login — magic-link sign-in by email, no password.
- /settings — sign-out only.

Data model (created before UI, as asked):
users(id, email, created_at, trial_ends_at, plan)
lessons(id, day_number, title, duration_min)
completions(id, user_id, lesson_id, completed_at)
Streak is computed from completions, not stored.

Assumptions: one lesson per day; streak resets after a missed day; trial length fixed at 5 days.
Left out on purpose: analytics, onboarding tour, dark mode, admin.
One question before the next screen: should a learner on day 6 with no plan still see today's lesson, or only the upgrade page?
PromptCodeFree
  • Claude Code
  • Codex
  • Copilot
  • +1
Coding

The First Build Prompt

Who, the one job, the data, the feel — and an app that looks like yours on the first generation.

0 copies
Free
Node list
1. Stripe Trigger — fires on checkout.session.completed — reads nothing upstream.
2. Notion — Create database page in "Customers" — Email ← $json.customer_details.email; Plan ← $json.metadata.plan; Amount ← $json.amount_total / 100; Date ← $json.created.
3. Slack — Post to #revenue — "New paid signup: {email} on {plan} ({amount} USD)" built from the same fields.

Workflow JSON: attached below, importable; credentials referenced as "Stripe account", "Notion workspace", "Slack bot" — create those three in Credentials before activating.

Error path: Error Trigger workflow "Alerts" → Slack #ops with the failing workflow name, the item's customer email, and the error message.

Test plan: in the Stripe Trigger node, click "Listen for test event", then send a test checkout.session.completed from the Stripe dashboard → Notion shows one row with the four fields → Slack shows one message → execution list shows green.

Smallest v1: this is already the smallest version (3 nodes). Add the welcome email as node 4 next week, after you have watched this run for a few days.
PromptCodeFree
  • ChatGPT
  • Claude
  • n8n
Ops

n8n Workflow From a Plain-English Spec

Five spec lines in; a node list, importable JSON, an error path and a test plan out.

0 copies
Free
Done — one change.

Files changed:
- src/pages/Pricing.tsx — added a Monthly / Yearly segmented toggle above the plan cards; yearly shows the discounted price and a "save 20%" tag
- src/lib/pricing.ts — added `yearlyPrice(monthly)`; no other exports touched

Outside the pricing page: nothing. Layout, colour tokens, routes and the dashboard are untouched. I did not reformat Pricing.tsx beyond the inserted block.

Acceptance: toggle defaults to Monthly; switching shows $190/yr under the Pro plan instead of $19/mo, and the tag appears. Verified in preview.

Revert: delete the toggle block in Pricing.tsx (lines 41–58) and the `yearlyPrice` helper.
PromptCodePro
  • Claude Code
  • Codex
  • Copilot
  • +2
Coding

Scoped Edit: Change One Thing, Keep the Rest

A targeted change request with an acceptance check and a keep-list, so the AI stops rebuilding what worked.

0 copies
$3.99
Restating: submitting the sign-up form throws `column "email" does not exist`, and you expected to be redirected to /dashboard. It worked before the profile table was added.

Ranked causes
1. The sign-up handler now inserts into `profiles`, which has no `email` column — the form was pointed at the new table, not `users`. Check: open the insert in `signup.ts`; if the table is `profiles`, confirmed.
2. A migration added `profiles` without `email` while the ORM model still declares it. Check: compare `schema.sql` to the model.
3. Two databases (local vs. hosted) with different schemas. Check: run the migration list against the hosted DB.

Checking #1: `signup.ts` line 22 inserts `{ email, name }` into `profiles`. Confirmed.

Fix (smallest): insert `email` into `users` as before, and only `{ user_id, name }` into `profiles`.
- await db.from("profiles").insert({ email, name })
+ const { data: u } = await db.from("users").insert({ email }).select("id").single()
+ await db.from("profiles").insert({ user_id: u.id, name })

Verify: sign up with a fresh address; you should land on /dashboard and see one row in each table.
Regression risk: any other code that assumed profiles.email — I found none.
PromptCodeFree
  • ChatGPT
  • Claude Code
  • Codex
  • +3
Coding

Diagnose Before You Fix

A bug report the AI can act on: what you did, what happened, what you expected — with a confirm-first rule.

0 copies
Free