Vibe Coded Today

Prompt snippets · 39 pages

Building blocks

The parts every real app needs: data, auth, uploads, jobs, money, time.

Draft a database schema

Get the tables right before there's data in them.

database-schema-draft.txt
My app does: <one sentence>
The things it stores: <list the nouns — users, orders, notes...>

Design the schema. For each table: columns, types, and which are
required. Then:
- Draw the relationships in words ("one user has many notes").
- Flag every column you added that I did not ask for, and why.
- Tell me the one decision here that is expensive to change later.

Use <Postgres / MySQL / SQLite>. No ORM code yet, just the tables.

Schema mistakes are the ones that get costly. Everything else you can rewrite on a wet Sunday; data you already collected in the wrong shape follows you around.

Scaffold an API endpoint

One endpoint, fully finished, including the unhappy paths.

api-endpoint-scaffold.txt
Build one endpoint: <METHOD> <path>

It should: <what it does>
Input: <fields and types>
Output on success: <shape>

Include, explicitly:
- Validation of every input, with what it returns when validation fails.
- The status code for each outcome, including not-found and not-allowed.
- What happens when the database call fails.

Match the style of this existing endpoint: <paste one>

Pasting an existing endpoint is worth more than any amount of description. Models copy patterns far more reliably than they follow instructions.

Validate the form properly

Both sides, or neither counts.

form-validation.txt
Here is my form: <paste the markup>

Add validation on both sides:
- In the browser, for fast feedback. Messages next to the field,
  announced to screen readers, not just red borders.
- On the server, treating every submitted value as hostile. This is
  the one that actually protects me.

For each field, tell me the rule you applied and what a user sees when
they break it. Do not use an alert() anywhere.

Browser validation is a courtesy to honest users. Server validation is the only kind that stops anyone. You need both and they are not the same code.

Add login without rolling your own

The one area where "just use the boring library" is not negotiable.

auth-without-tears.txt
I need users to log in. My stack: <stack>. Expected users: <a handful /
hundreds / thousands>.

First: recommend whether I should use a hosted auth provider or a
well-established library in my framework. Pick one and justify it in
three lines. Do not suggest I implement password hashing and session
handling myself.

Then give me the smallest working integration: sign up, log in, log
out, and "is this request authenticated?". Nothing else yet.

Password resets, session fixation, timing attacks, token rotation. Every one is a solved problem and every one is a way to leak your users' data if you improvise it.

Rate limits and retries

What to do when the thing you call says "slow down".

rate-limit-and-retry.txt
I'm calling <the API> from <where>. It has a rate limit of <limit, or
"I don't know">.

Add proper handling:
- Retry on failures that are worth retrying, and only those. Tell me
  which status codes you decided are retryable and why.
- Exponential backoff with jitter. Explain the jitter part.
- A hard ceiling on attempts, so a broken call can't loop forever.
- Respect a Retry-After header if one comes back.

Show me what the user sees while this is happening.

Retrying a 400 forever is how you turn one bad request into a rate-limit ban. Retry what might work next time; fail fast on what never will.

Decide what to cache

Before adding a cache, be able to say what goes stale.

caching-plan.txt
This is slow: <describe the operation and roughly how slow>

Before adding a cache, tell me honestly: is caching the right fix here,
or am I hiding a query I should just make faster?

If caching is right:
- What exactly gets cached, keyed by what.
- How long it lives, and what specifically invalidates it early.
- What a user sees if they get stale data — is that acceptable?

The hard part of caching was never the storing. It is knowing when what you stored stopped being true.

Move slow work off the request

Anything over a second probably shouldn't block a page load.

background-jobs.txt
This runs during a web request and takes <n> seconds: <describe>

Move it to the background. My stack is <stack> and I'd rather not run
extra infrastructure unless I have to.

- Recommend the simplest mechanism that fits (a queue, a cron, a
  worker) and say what it costs me to operate.
- Show me how the user finds out it finished.
- What happens if the job fails halfway? Can it safely be run twice?

"Can it safely run twice?" is the question that separates a background job from a background incident. Retries will happen whether you planned for them or not.

Accept file uploads safely

The feature most likely to be your first security incident.

file-upload-handling.txt
Users need to upload <what kind of file>, up to <size>.

Implement it with these checks spelled out:
- Size limit enforced on the server, not just the form.
- Type checked by actual content, not by the filename extension.
- Stored with a name I generate, never the name the user sent.
- Stored somewhere it cannot be executed or served as HTML.

Tell me what an attacker would try here and which check stops it.

An upload form is a stranger writing files onto your server. Every one of those rules exists because someone skipped it.

Add search that isn't useless

LIKE '%query%' is a prototype, not a feature.

search-that-works.txt
Users need to search <what>. Roughly <n> records, growing to <n>.

Start with the simplest thing that will be good enough at my size, and
tell me the point at which it stops being good enough.

Handle, at minimum: partial words, different capitalisation, extra
whitespace, and a query that matches nothing. Show me the empty state.

Do not reach for a search service unless my numbers actually need it.

Ask for the threshold. Knowing "this breaks past about 50,000 rows" turns a future emergency into a calendar entry.

Paginate a long list

The list that was fine with twelve rows and isn't with twelve thousand.

pagination.txt
This loads every record at once and it's getting slow: <paste>

Add pagination. First tell me which approach fits: page numbers, or a
cursor / "load more". Say which and why, given that my data
<changes constantly / rarely changes>.

Then implement it, including:
- The database query, limited properly — not fetched then sliced.
- The total count, or an honest reason for not showing one.
- What the last page looks like, and what page 999 of 10 does.

Fetching everything and slicing in code is the classic version of this bug. It looks like pagination and does none of the work pagination is for.

Handle dates and time zones

The bug that only appears for users in another country.

date-and-timezone.txt
Here is my date handling: <paste>

Audit it against the rules that matter:
- Store in UTC. Convert only when displaying to a person.
- Never build a date from string slicing.
- "Today" depends on who is asking — where does my code assume mine?
- Watch for daylight saving: a day is not always 24 hours, and some
  local times happen twice or not at all.

Point at each line that breaks a rule and show me the fix.

Test with a user in a different hemisphere and a date near the end of the month. That combination surfaces almost every timezone bug you have.

Handle money without losing pennies

Floating point and currency are old enemies.

money-and-rounding.txt
My app handles money here: <paste>

Check it properly:
- Am I using floats anywhere? Show me where and change it to integer
  minor units or a decimal type.
- Where does rounding happen, and does it happen exactly once?
- Is the currency stored alongside the amount, or assumed?
- Do totals recompute from the parts, or get stored and drift?

Show me a worked example where my current code loses or gains a penny.

Ask for the worked example. A concrete "£19.99 × 3 gives you this" is more persuasive, and more testable, than any explanation of binary fractions.

Send email that arrives

Deliverability is most of the problem.

email-sending.txt
My app needs to send: <transactional / notifications / both>.
Stack: <stack>. Volume: <roughly how many a day>.

- Recommend one sending service and say why, for my volume.
- Show me the integration, with sending done in the background so a
  slow provider can't hang a page load.
- Tell me exactly which DNS records I need (SPF, DKIM, DMARC) and what
  each one does.
- Both a plain-text and an HTML part. Handle the bounce case.

Then: how do I test this without emailing real people?

Mail sent straight from your own server without those DNS records mostly lands in spam. The records are the difference between "sent" and "delivered".

Receive a webhook safely

A public URL that strangers can POST to.

webhooks.txt
I need to receive webhooks from <provider> at <path>.

Implement the endpoint with all of this:
- Verify the signature before trusting a single byte. Show me how.
- Respond 200 fast, then do the work in the background — providers
  time out and retry.
- Make it idempotent: the same event delivered twice must not charge,
  email or create anything twice.
- Log every event received, including ones I reject.

What does the provider do if I return a 500? Design for that.

Providers retry. Yours will receive duplicates whether you handle them or not — the only choice is whether that's a feature or a support ticket.

Run something on a schedule

Scheduled jobs fail silently, which is the whole problem.

cron-and-schedules.txt
I need <this task> to run <how often>.

- Recommend the simplest scheduler for my setup: <stack / host>.
- Make it safe to run twice, and safe to skip a run.
- Stop two copies overlapping if one runs long.
- Tell me how I find out it FAILED, and how I find out it didn't run
  at all — those are different failures and I need both.

What time zone does the schedule use, and what happens at a DST change?

Nobody notices a nightly job that stopped running. Alerting on absence, not just on errors, is the part everyone skips.

Delete without losing it

The mis-click that isn't permanent.

soft-delete.txt
Add soft delete to <the record>: <paste the model and the delete code>

- A deleted_at timestamp rather than removing the row.
- Every existing query excludes deleted records. Show me every query
  that needs changing — missing one is the whole risk here.
- A way to restore, and a way to permanently purge after <n> days.
- Unique constraints still work: a deleted record must not block
  reusing its email or slug. Say how you handled that.

Then tell me what this costs — where deleted rows will accumulate and
slow things down, and what I do about it.

The unique-constraint problem catches everyone. Someone deletes an account, tries to sign up again with the same email, and is told it's taken.

Record who changed what

The first time someone asks, it either exists or it doesn't.

audit-trail.txt
Add an audit trail to <the records>: <paste the model and update code>

Record for every change: who, when, what changed — old and new values —
and where from (which endpoint or screen).

- Store it separately from the record itself, append-only.
- Never log passwords, tokens, or full payment details. Say what you
  excluded and how you'd handle a field that's sensitive but needs
  tracking.
- Make it queryable: everything one user did, and everything that
  happened to one record.
- Say how it grows and when I'd need to archive it.

Show me the screen that displays a record's history readably.

Capture the old value as well as the new. "Changed status" is much less useful than "changed status from pending to paid" when you're working out what went wrong.

Import a spreadsheet

Real files are messier than your test file.

csv-import.txt
Let users import <records> from a CSV. Expected columns: <list>.

Handle what real files actually contain:
- Different encodings, including UTF-8 with a BOM. Excel emits these.
- Columns in a different order, with different capitalisation, with
  trailing spaces in the headers.
- Quoted fields containing commas and newlines.
- Empty rows, and a trailing empty line.
- Dates in several formats, and numbers with thousands separators or
  a currency symbol.

Flow:
- Validate everything BEFORE writing anything, and show a preview
  with per-row errors.
- All-or-nothing, or skip-bad-rows? Recommend one and let me choose.
- A downloadable report of what was skipped and why.

Validate the whole file before writing a single row. A half-completed import that failed on row 400 is a much worse problem than a rejected file.

Let people take their data

A trust feature that costs an afternoon.

export-data.txt
Add data export for <the user's data>.

- A format that opens somewhere useful: CSV for tabular, JSON for
  nested. Say which fits mine.
- Everything they'd need to leave and reconstruct it elsewhere —
  including related records, not just the top-level table.
- Generate in the background for anything large, then email or notify
  a link. Don't hang a request.
- The download link expires and is only usable by that user.
- Exclude other users' data and my internal fields. List what you
  excluded and why.

Then: what would a user be annoyed to find missing from this export?

In many jurisdictions this is a legal right, not a feature. Building it once is cheaper than handling requests by hand.

Tell users something happened

In-app, email, or push — and the rules that stop it being spam.

notifications.txt
Users need to know when <events>. Stack: <stack>.

Design it:
- Which channel for which event, and why. Don't email things that
  only matter while someone is looking at the page.
- Per-user preferences, per event type, honoured everywhere.
- Batching: five events in a minute should not be five emails.
- A record of what was sent, so I can answer "did they get it?"
- Sent in the background. A slow email provider must never hang a
  request or fail the action that triggered it.

Then: what's the unsubscribe path, and is it legally sufficient for
each channel?

Default to fewer notifications than you think. The cost of one too many is someone muting you forever; the cost of one too few is they check the page.

Keep customers' data apart

The bug where one account sees another's records.

multi-tenancy.txt
My app serves multiple <organisations / teams>. Here's my schema and
some queries: <paste>

Review the isolation:
- Does every query filter by tenant, without exception? List any that
  don't — that's a data leak.
- Where is the tenant ID coming from? If it's from the request body or
  a URL parameter the user controls, that's the vulnerability.
- What happens if a user is a member of two tenants?
- Are IDs sequential and guessable across tenants?

Then recommend how to make this structurally safe rather than
relying on remembering — a scoped query layer, a database policy, or
whatever fits my stack.

"Remember to add the tenant filter" is not a strategy. It works until the one query somebody writes in a hurry, and that's the incident.

Put work on a queue

The pattern behind every "we'll email you when it's ready".

queue-job.txt
This takes <n> seconds during a request and should be in the
background: <paste>

Stack: <stack>. I'd rather not run extra infrastructure unless needed.

- Recommend the simplest queue that fits, and say what it costs to
  operate.
- Enqueue returns immediately with an ID the user can poll or be
  notified against.
- The job is safe to run twice. Say how you made it so.
- Retries with backoff, a maximum attempt count, and a dead letter
  destination for jobs that never succeed.
- I must be able to see: pending, running, failed, and why.

Show me what the user sees at each stage, including failure.

A queue with no visibility into failures is a place jobs go to disappear. The failed-jobs view is not optional.

Make an operation safe to repeat

Networks retry. Users double-click. Both must be harmless.

idempotency.txt
This operation must not happen twice: <describe — a charge, an email,
a record creation>

Here's the current code: <paste>

Make it idempotent:
- The caller supplies a key, or I derive one from the request. Say
  which fits and why.
- Store the key with the result. A repeat returns the original result
  rather than doing the work again.
- Handle two identical requests arriving at the same moment, not just
  one after the other.
- Say how long keys are kept and what happens after that.

Then tell me what happens today if the user double-clicks, and if the
network retries.

Two simultaneous requests is the case that catches people. Checking then inserting is not enough — you need the database to enforce it.

Who is allowed to do what

Get this wrong and it's a data breach, not a bug.

permissions.txt
My app has these kinds of user: <list them>
And these actions: <list them>

Design the permission model:
- A table of who can do what. Be explicit about every combination.
- Where the check happens — it must be server-side, on every route,
  including ones that only read.
- How a check is written so it's hard to forget. Suggest something
  structural rather than "remember to add it".

Then audit my existing routes: <paste them>. List every route that
checks authentication but not authorisation — that a logged-in user
could use to reach someone else's data.

Authentication is "who are you". Authorisation is "are you allowed". Nearly every real breach in a small app is the second one missing.

Password reset, done safely

A well-known flow with a well-known set of mistakes.

password-reset.txt
Implement password reset. Stack: <stack>.

Requirements, all of them:
- The token is random, long, and stored hashed — a database leak must
  not let someone reset every account.
- Single use, and expires in <30-60> minutes.
- The "check your email" response is identical whether or not the
  address exists. Don't leak which addresses are registered.
- Resetting invalidates existing sessions.
- Rate limited per address and per IP.
- The email says who requested it and what to do if it wasn't them.

Tell me what an attacker tries against this and which rule stops it.

The identical-response rule is the one most often skipped. A reset form that says "no account found" is a tool for discovering who has an account.

Sessions that behave

Log out should actually log out.

sessions.txt
Review my session handling: <paste>

Check:
- Cookies marked HttpOnly, Secure and SameSite. Say which SameSite
  value and why.
- The session ID regenerated on login — otherwise session fixation
  works.
- Logout invalidates server-side, not just deleting the cookie.
- An absolute maximum lifetime as well as an idle timeout.
- Sessions invalidated on password change.
- What happens across multiple devices — should logging out of one
  affect the others?

Tell me what's currently missing and what each gap allows.

Deleting the cookie is not logging out. If the session is still valid server-side, anyone who captured it still has access.

Change the schema without losing data

The change you can't casually undo.

migration.txt
I need to change my schema: <describe — new column, renamed column,
split table, changed type>

Current schema: <paste>. Rows: roughly <n>. Downtime acceptable:
<yes / no>.

Write the migration:
- Forward steps, in order, each one safe to run on live data.
- Whether this needs to be done in phases so old and new code can both
  run during the deploy. If so, spell out the phases.
- The rollback, and be honest if there isn't one.
- What happens to existing rows — defaults, backfill, null handling.
- How long it will lock the table, roughly, at my size.

Then: what do I check afterwards to confirm nothing was lost?

Ask about locking. A migration that takes a table offline for four minutes is fine at 3am and an incident at lunchtime.

Realistic test data

Clean fixtures hide the bugs real data finds.

seed-data.txt
Write a seed script for my schema: <paste>

I want data that finds bugs, not data that looks tidy:
- Names with apostrophes, accents, and non-Latin scripts.
- Very long values, and empty optional fields.
- Records at the boundaries — the first, the newest, one from years ago.
- A user with no related records at all, so I hit the empty state.
- A user with hundreds, so I hit pagination.
- Amounts that round awkwardly.

Make it repeatable: running it twice shouldn't duplicate everything,
and it must be obviously safe to never run in production.

A seed script that only produces neat data means you'll first meet apostrophes in a bug report from someone called O'Brien.

Change an API without breaking callers

Once someone depends on it, the shape is a promise.

api-versioning.txt
I need to change this endpoint: <paste current shape and the change>
It's used by: <my own frontend only / other people>.

Tell me first: is this actually breaking? Adding an optional field
usually isn't; removing one or changing a type is.

If it's breaking:
- How do I ship it without breaking existing callers — a new version,
  a new field alongside the old, or a transition period?
- How long do I keep the old behaviour, and how do I find out who's
  still using it?
- What do I tell callers, and when?

If it isn't breaking, say so and let me just ship it.

Log usage of the old shape before removing it. "Nobody uses that any more" is a belief until you have the number.

Add two-factor authentication

Worth it the moment your app holds anything people care about.

two-factor.txt
Add optional two-factor authentication. Stack: <stack>.

- Use TOTP (an authenticator app) rather than SMS. Say why in one
  line so I can explain it to users.
- Enrolment: show a QR code and the secret as text, then require a
  correct code before it's switched on. Never enable it on the
  strength of the QR being displayed.
- Recovery codes, generated once, shown once, stored hashed.
- Allow a small time window either side for clock drift. Say how much.
- Reject reuse of a code within its window, so a captured code is
  useless.
- Rate limit verification attempts.

Then: what's my process when someone loses both their phone and their
recovery codes?

Answer the lost-everything question before you launch this. Without a process, two-factor turns a support request into a permanently locked account.

Limit what a user can consume

Free tiers, quotas, and not funding a stranger's project.

usage-limits.txt
This feature costs me money per use: <describe> and I need limits.

- Where the counter lives, and how it handles two simultaneous
  requests without letting both through.
- The reset boundary — rolling window or calendar month? Say which
  and why.
- What the user sees as they approach and hit the limit. The message
  must say when it resets.
- An overall cap across all users, independent of per-user limits, so
  one bug can't run up the bill.
- How I raise a specific user's limit without a deploy.

Then tell me what happens today if someone scripts this endpoint.

Per-user limits don't protect you from a thousand new accounts. You need a global cap as well, and it should fail closed.

A contact form that works on my host

It sends, it arrives, and it doesn't become a spam relay.

contact-form.txt
Add a contact form to my site. Stack: <stack>. Host: <host>.

- Name, email and message. Validated in the browser for speed and on the
  server because that's the one that counts.
- Sending: through this host's mail, or a sending service? Pick the one
  that will actually arrive, and say why.
- Spam protection without a captcha: a hidden honeypot field and a time
  check.
- A clear success message on the same page, and a real error if sending
  fails, never a fake "thanks".
- The visitor's address goes in Reply-To, never in From, or the message
  will be treated as forged.

Show me every file that changes.

Putting the visitor's address in From makes the email look forged and it gets filtered. Send from your own domain and reply to theirs.

Add user accounts to my stack

Sign up, log in, log out, and nothing clever.

accounts.txt
I'm building <one sentence> with <stack> on <host>, and it now needs user
accounts.

First, recommend how: this stack's built-in or standard auth library, or
a hosted auth service. Pick one for my situation and justify it in three
lines. Don't hand-roll password handling.

Then the smallest working version: sign up, log in, log out, password
reset, and a single check for "is this person logged in". Include the
session and cookie settings that matter on this host, especially over
HTTPS.

Whatever you choose, check every page that shows data belongs to the person asking. Logged in is not the same as allowed.

Allow bigger uploads on my host

Files over a certain size fail and nobody says why.

upload-limits.txt
My <stack> app on <host> needs to accept uploads up to <size>. Bigger
files fail, sometimes silently.

Tell me every limit in the way, in order:
- The language runtime's upload and request size limits.
- The web server's limit.
- Any proxy or platform limit in front of it.
- Timeouts that cut off slow uploads.

For each: can I change it on this host, and exactly how? If the total
can't reach <size>, show me how to upload straight to object storage
instead, so the file never passes through my server.

Several limits apply at once and the smallest one wins. Raising one of them and not the others produces an error that looks exactly the same.

Set up the database on my host

Create it, connect to it, and keep the password out of the code.

db-setup.txt
My app is built with <stack> and hosted on <host>. It needs a
<database type> database.

Walk me through it on this host:
- Creating the database and a user with only the permissions the app
  needs. Not an admin account.
- Where the connection details go, outside the web root.
- Connecting from my code, with a clear error if it fails.
- Creating the tables from a script I keep in the repo, so I can rebuild
  them anywhere.
- How to take a backup and restore it, and how to test that.

Show me the connection code and the table script.

Give the app its own database user with limited rights. If the app is ever compromised, that's the difference between leaking a table and losing the lot.

Build my first API endpoint

One endpoint, finished properly, as the template for the rest.

first-api.txt
My project is <one sentence>, built with <stack> and hosted on <host>.
I need an endpoint: <METHOD> <path> that <does what>.

Build it with:
- Routing done this stack's normal way.
- Every input validated, with clear 400-style responses.
- The right status code for each outcome.
- One consistent error format I can copy to every future endpoint.
- Anything this host needs for the route to be reachable, such as
  rewrite rules.

Then show me how to call it with curl so I can test it on the live host.

Get the error format right on the first endpoint. Everything after it copies the first one, mistakes included.

Background jobs on a host without workers

When you can't run a queue, a table and a scheduled job will do.

jobs-without-workers.txt
My <stack> app on <host> needs to do slow work after a request finishes:
<describe it>. This host can't run a long-lived worker process.

Design the simplest thing that works here:
- A jobs table in my existing database.
- A scheduled job that picks up pending work every minute or so.
- Locking, so two runs never take the same job.
- Retries with a limit, and somewhere to see jobs that keep failing.
- How the user finds out their job is done.

Only use what this host supports. Show me the table, the scheduled
script and how a page queues a job.

A table and a scheduled job is a real queue. It handles far more than a small project needs, and there's no extra service to keep alive.

Resize images on my host

Thumbnails and web-sized copies, with the tools the host has.

image-processing.txt
My <stack> app on <host> accepts image uploads and needs thumbnails and
web-sized versions.

- Which image libraries this host has available, and how to check.
- Resizing on upload vs when first requested. Pick one for my setup.
- Fixing phone photos that come out sideways.
- Stripping location data and other metadata by default.
- Output format and quality settings that keep files small.
- Staying inside this host's memory limit. Big photos can exhaust it.

Show me the code and where the resized files are stored.

A 12-megapixel photo needs far more memory to resize than its file size suggests. Test with the biggest image your users could send, not a sample.

Add search to my site

Good enough search without a search service.

site-search.txt
My site is <one sentence>, built with <stack> on <host>. It has about
<n> items, and people need to search them.

Build the simplest search that's good enough at this size:
- Using what my database and host already provide. Say what that is.
- Matching partial words, ignoring case, and handling no results kindly.
- Results ranked so the obvious match comes first.
- The point at which this stops being good enough, in items or queries.

Don't reach for a separate search service unless my numbers need one.

Most databases a host provides already have decent full-text search built in. Try that before paying for anything.