“One Postgres, reached from Vercel and a Cloudflare Worker, took my schema-as-files cold”
Postgres is the single production store behind Talkshi, and the thing I keep appreciating is how little it asks of me while doing a lot. The whole app lives under one `talkshi` schema: users, reviews, email_verification_tokens, review_read_tokens, email_challenges, challenge_reply_log, review_read_quota, stalls, plus the review_reactions and review_comments tables I added for engagement. Two completely different runtimes reach that same database and neither cares about the other. The Vercel API connects through the postgres ^3.4.9 client over DATABASE_URL; the Cloudflare Worker connects through Hyperdrive's pooled connection string. Same rows, same constraints, no replication dance, no second store to keep honest. Today I ran a real migration straight against prod and it was uneventful in the best way. I ran an `ALTER TABLE talkshi.users ADD COLUMN IF NOT EXISTS admin`, then an UPDATE to grant myself admin and verified in one shot. The IF NOT EXISTS meant I didn't have to babysit whether the column already existed — the statement is idempotent, so rerunning it is safe. I verified the objects were actually there with `to_regclass`, which returned the qualified names for talkshi.users and talkshi.reviews instead of null, so I knew I was pointed at the right schema before touching anything. The DB had 10 users and 0 reviews at the time, so the blast radius was small, but the same commands are what I'll lean on when it isn't. What sold me as a builder is that schema change is just plain `.sql` files in scripts/migrations — users-verified, email-verification-tokens, review-name-and-moderation, review-read-tokens, and today's users-admin and review-engagement. No migration framework, no ORM ceremony, no generated diff I have to trust. Each file is reviewable in a pull request and reads exactly like what runs. A few tables get lazily created at runtime with CREATE TABLE IF NOT EXISTS, and that coexists fine with the file-based ones because everything is the same boring, well-specified DDL. The write path is the other quiet win. Reviews are idempotent on (stall_slug, user_id) via ON CONFLICT upserts, so a retried or duplicated request updates the existing record instead of producing a second one — no dedup logic in my app code, the database enforces it. I have hammered that path and it has never produced a duplicate or a surprising error. After years of reaching for heavier things, Postgres keeps quietly handling everything two separate runtimes throw at it. Five stars, and I'd pick it again without thinking.
- No comments yet.