Productive— faster every day
For your professionTeachersStudentsManagersMarketingDevelopersFreelancersParents

Prompt library · AI · 14 prompts

Prompts from the guide

An internal CRM with Supabase: a detailed guide from data to deployment

14 prompts from this guide. Fill in whatever sits in [square brackets] — your own context, the document text or the name of your tool. That context is exactly what separates a generic answer from a usable one.

Read the full guide →

What you already have, you just don’t know it

I'm preparing data for our company's internal CRM [a small coffee
roastery, 6 people, roughly 80 wholesale customers]. I'm uploading
exports: contacts from my phone (CSV), contacts from email, a table
from transcribed business cards, three spreadsheets of orders for
[2024-2026], and an invoice export.

Do an inventory, don't change anything yet:
1. For each file, list which columns it contains, how many records it
   has, and what a typical row looks like
2. Estimate overlaps: how many companies and people show up in more
   than one source
3. List format inconsistencies: phone numbers, tax IDs, company names,
   dates
4. Flag anything that's completely missing from the sources and that
   I'll have to fill in by hand
The output is a summary table of the sources and a list of problems
ranked by severity. I'll wait for approval before we start cleaning.

Cleanup: deduplication and normalization

Clean up the uploaded contacts and companies data using these rules:
1. Convert phone numbers to international format [+420 and nine
   digits, no spaces]; whatever can't be converted, flag in a
   problem column
2. Tax ID: must have 8 digits and a valid check digit — flag invalid
   ones, don't guess at them
3. Standardize company names: remove differences like "s.r.o." vs
   "s. r. o.", casing, typos — but keep the original name in an
   original_name column
4. Find likely duplicates (same tax ID, similar name + same city, same
   email) and list them as PAIRS with a confidence level — don't
   merge anything yourself, I approve merges one at a time
5. Check emails for obvious domain typos; only suggest fixes
Return the cleaned table and, separately, the list of proposed merges.

Cleanup: deduplication and normalization

From the approved, cleaned data, produce import CSV files that match
the CRM schema exactly: companies.csv, contacts.csv, orders.csv,
notes.csv [I'll paste in the schema from the next phase]. Rules:
- every order row must reference an existing company; where the link
  is missing, put the row in orders_unmatched.csv, don't guess
- for contacts, fill in the source column (marta-phone,
  business-cards-trade-show-2026, invoicing-export...) so we always
  know where a record came from
- leave empty values empty, no "not provided" and no made-up data
At the end, print checksums: the row count for each file and how many
records got lost along the way, and why.

RLS policies for three roles, sentence by sentence

Generate SQL migrations for the CRM: the companies, contacts, orders,
interactions, notes, and profiles tables per the schema we designed.
Turn on RLS for every table and write policies per this matrix:
- select: everyone signed in
- insert and update: the sales and admin roles
- delete: admin only
- profiles: signed-in users only read, nobody writes through the API
Add a comment to every policy stating exactly what it allows and for
whom. Then explain each migration to me as if I don't read SQL every
day — what happens if I run it, and what would happen if I didn't.
I approve each migration separately; don't run anything without
approval.

The anon key, the service role key, and what the JWT carries

In a test project, create three test accounts: test-admin, test-sales,
and test-viewer, with the matching roles in profiles. Then, for each
account, try every operation against every CRM table: select, insert,
update, delete — plus one operation with no sign-in, using only the
anon key. Return a results matrix: operation x table as rows, role as
columns, allowed/denied in each cell. Flag every cell where the
result differs from the intended permission matrix, and explain why.
Test against the test project with made-up data, not against live
data.

Sync: from the CRM to Brevo, and only unsubscribes flow back

Write a script that syncs contacts from our Supabase CRM to Brevo
through its API:
1. From contacts, select only records where newsletter_consent = true
   and unsubscribed_at is empty — don't send anyone else to Brevo
2. Add them to a list based on the company's category [wholesale /
   end customer] and fill in the NAME, CITY, and CATEGORY attributes
3. Contacts that are in Brevo but no longer meet the condition should
   be removed from the lists (don't remove them from the Brevo account,
   just from the lists)
4. Read the Brevo API key from an environment variable; it must never
   appear in the code
5. The script needs a dry-run mode: print what it would do, without
   writing anything
Also write a short guide on how to run the script, and what each line
of output means. We'll do the first run together in dry-run mode.

Sync: from the CRM to Brevo, and only unsubscribes flow back

Set up the return flow of unsubscribes from Brevo to the CRM:
1. Create a server-side endpoint in the project that receives Brevo's
   webhook for unsubscribes and undeliverable addresses (hard bounces)
2. The endpoint looks up the contact by email and sets unsubscribed_at
   to the event's timestamp; if it can't find the contact, log the
   event, don't discard it
3. Write to the database using the service role key — the endpoint
   runs on the server; explain to me why the anon key isn't enough
   here
4. Secure the endpoint by verifying the request genuinely came from
   Brevo
Show me the code and walk me through it block by block before we
deploy it.

The right to erasure: a process, not a button

Design a "right to erasure" process for our CRM and Brevo:
1. Using email or name, find every place the person appears: contacts,
   notes, interactions, Brevo lists and contacts
2. List what you propose to delete, what to anonymize (the company's
   orders stay — they're business records, just without a link to the
   person), and what we're legally required to keep — state the reason
   for each
3. Don't delete anything; the output is a proposal log that I'll
   approve, and only then generate the actual SQL and the steps in
   Brevo
4. At the end, add a record that the request was handled, with a date
   — we archive that outside the CRM
Deletion is irreversible, so I approve each step individually.

Phase 4: what it will cost — an honest reckoning

Help me put together a cost analysis for a self-built CRM. Our
numbers: [6] users, [about 80] companies and [500] contacts in the
database, a newsletter [1x a month to 80 addresses, growing toward
2,000 end customers], database size today [under 1 GB]. Look up the
CURRENT price lists and free-tier terms for Supabase, Vercel, and
Brevo (cite dated sources) and answer:
1. How long the free tiers will last us, and which limit we'll hit
   first
2. Exactly what we get with the first paid tier of each service
3. Compare the annual cost of this stack with [the off-the-shelf CRM
   we're considering] at our user count
4. Which limits may have changed since your training data — mark what
   you actually verified in sources and what you didn't
No marketing language, just numbers and sources.

Setting up the project and migrations

We're setting up a Supabase project for the internal CRM. Go step by
step, and wait for approval before each one:
1. Create the project in the EU region [Frankfurt] — the database
   will hold customer personal data, and we want EU jurisdiction
2. Apply the approved migrations in order: the table schema, profiles
   with roles, RLS policies, the newsletter columns — in that order,
   and after each migration print the state (which tables exist,
   where RLS is turned on)
3. Save the migrations as files in git, so the schema has a history
4. At the end, run a check: list every table without RLS turned on
   and every table without policies — both numbers must be zero
Print me the anon key and project URL, but never print the service
role key anywhere — we'll set it directly as an environment variable.

The app: an internal table UI, no design

Build a simple internal app on top of our Supabase CRM (Next.js):
1. Sign-in through Supabase Auth (both email + password and magic
   link); with no sign-in, nothing shows at all, not even the company
   list
2. Companies page: a table with search by name and a filter by
   category; clicking a row goes to the company detail page
3. Company detail: contacts, orders sorted newest first, notes, and
   interactions, with a form for adding a new note
4. Show forms according to the role from profiles: read-only for
   viewers — but add a code comment noting that the actual enforcement
   is done by RLS
5. No design system, a readable table and forms are enough; make the
   mobile view usable, since the salesperson will be out in the field
Go page by page, and show me each one before starting the next.

Deployment: locked down from minute one

Deploy the CRM to Vercel using this security checklist:
1. The service role key and other secrets only as server-side
   environment variables; check that no secret variable has the
   prefix that sends it to the browser
2. Verify that no page or API endpoint is reachable without signing
   in — walk through every route and list what it's protected by
3. Turn on preview deployment protection, so no one who isn't signed
   in can see work-in-progress versions
4. Try opening the app in an incognito window and list what's
   visible — the correct answer is only the sign-in page
Return a checklist with the result of every point, not just "done".

Data import: checksums, for the third and last time

Import the cleaned data from phase 1 (companies.csv, contacts.csv,
orders.csv, notes.csv) into the production database:
1. Dry-run first: print how many rows would be inserted into each
   table, how many would be rejected, and why (missing links,
   duplicate tax IDs)
2. After my approval, run the import through a server-side script
   using the service role key, and print the final counts
3. Compare the counts against the source CSVs: explain every
   discrepancy specifically, no "a few rows didn't fit"
4. Finally, spot-check by printing 10 companies with their contacts
   and latest orders — I'll check them against the original records
   by hand
The import must never run twice: propose a safeguard against a
duplicate run and explain it to me.

The first views: make the CRM pay off in week one

Create the dormant_customers and top_customers views in the CRM per
the design, and add an Overview page to the app that displays them.
For dormant customers, add a link to each company's detail page and a
"log a contact note" button. Explain to me how the views respect RLS
(security_invoker), and verify it with a test using the viewer role.
Make the 42-day threshold configurable in one place, not copy-pasted
throughout the code.

All prompts