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