Supabase is a hosted Postgres database with an admin dashboard and an instant API bolted on. Today you learn what that actually means — what Postgres is, what a table and a row are — by reading the real votes table Focaccia Vote has been writing to.
Last week you shipped Focaccia Vote and people actually voted — every tap landed as a row in a Postgres table you've never looked at directly. Right now that data is a black box you can only see through the app's own UI. After today you can open the database itself, count the rows, and answer questions the app doesn't have a screen for.
Postgres is a database engine — a program whose whole job is to store structured data and answer questions about it fast. Think of it as a folder of ruthlessly organized spreadsheets: each <strong>table</strong> is one sheet (votes, users, candidates), each <strong>column</strong> is a typed field (a timestamp, a piece of text, a number — and the type is enforced, you cannot put 'banana' in a date column), and each <strong>row</strong> is one record — one vote, one user, one event. That's 90% of the mental model.
Supabase is not a different database — it's Postgres that someone else runs for you, wrapped in three conveniences: a web dashboard so you can browse tables without writing code, an auto-generated API so your app can read/write rows over HTTPS with one JS call, and a bundled auth system. When Focaccia Vote 'saves a vote', it's really making an HTTPS call to Supabase's API, which inserts one row into the <code>votes</code> table. No server of your own anywhere — that's why it's the DB + Auth default in your stack doc.
The failure mode to respect: the API is reachable by anyone on the internet, and what stops a stranger from reading or spam-writing your table is <strong>Row Level Security (RLS)</strong> — per-table rules about who may do what. A table with RLS off and a public anon key is an open guestbook. You don't need to master RLS today; you need to know it exists and check whether your votes table has it on.
Three queries to run in the Supabase SQL Editor (dashboard → SQL Editor → New query) — each answers something the app's UI can't:
-- 1. How many votes total?
select count(*) from votes;
-- 2. The five most recent votes, newest first
select * from votes
order by created_at desc
limit 5;
-- 3. What columns does the table actually have?
select column_name, data_type
from information_schema.columns
where table_name = 'votes';
A database is just typed spreadsheets with rules — and you can always bypass the app and ask it directly: select count(*) is how you check the pulse of anything you've shipped.