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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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".
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.