Blog
Notes on what I ship, most days.
- Plan for a database host that refuses your triggersCheap managed MySQL often blocks triggers and fine-grained grants. Find out before deploy day, make the migration record what it got, and keep a check that works without them.
- Add related reading by reusing the ranking you already trustA "you might also like" block is a second selection problem. Reuse the main ranking, exclude what is already shown, widen the fetch window, and tag the links so you can measure them.
- Retire a duplicate page with a 301, not a deleteWhen two pages cover the same thing, pick the keeper with data, unpublish the other, and permanently redirect every one of its URLs to the matching keeper URL.
- Use one cron trigger and route by the scheduled timeWhen a scheduler lets you register several cron triggers, some can silently never fire. One trigger plus a small routing function in code is easier to trust, test, and debug.
- Preview a CSV import before you commit itBulk imports go wrong one row at a time. Validate every row up front, show a preview with per-row errors, and check each row again when the person confirms.
- Deactivating a user should end their sessionsFlipping an account to inactive does nothing to the browser that is already signed in. Check status on every request, delete stored sessions, and treat a password reset the same way.
- Tie every acknowledgment to the exact version someone readAn "I have read this policy" checkbox is only useful if you can prove which words were on the screen. Version the document, hash it, store the hash on the acknowledgment, and never edit in place.
- Send people back where they were after login, safelyShared deep links break when login always lands on the dashboard. Carry the return path through sign-in, but accept only same-origin paths so it never becomes an open redirect.
- Skip boilerplate sources and leftover source wordsA rewrite pipeline is only as good as what you feed it. Drop paywall and disclaimer text before the model runs, and flag leftover source-language words in code after.
- Make one-time redemptions safe to retryA one-time code that fails halfway is worse than a slow one. Claim it with a short lock, key retries with a client submission id, and return the original result instead of creating a second booking.
- Run local-time jobs on a UTC-only cronMost schedulers only speak UTC, and daylight saving time moves your users twice a year. Fire at both possible UTC times, decide in code, and make the job safe to run twice.
- Treat Postgres RLS as the security boundaryA filter in your app code is a suggestion an attacker will not send. Put ownership in Postgres with Row Level Security, prove it with an API call that skips the UI, and treat middleware as UX.
- Check LLM output in code, then retry exactly onceA limit written into a prompt is a wish, not a rule. Measure the output in code, feed the problems back for one rewrite, and decide up front what a failure that survives means.
- Rebuilding this siteWhy coltonpomeroy.com moved off WordPress to a static Astro site, and what I want it to be from here.
- Switching hosts without breaking my emailMoving coltonpomeroy.com to a new static host was the easy part. Pointing the domain without dropping my email, and surviving a short SSL gap, took more care.