Blog
Browse all engineering posts on the AtendePraMim blog.
Authentication is the foundation of any SaaS application. In this post, we'll walk through how AtendePraMim implements session-based auth with iron-session, 2FA via TOTP, and magic links. We use iron-session with AES-256 encrypted HttpOnly cookies. No JWTs exposed to the browser. TOTP-based 2FA adds a second layer. The user scans a QR code with their…
Redis is the Swiss Army knife of SaaS infrastructure. AtendePraMim uses it for four distinct purposes. Iron-session encrypts the session into the cookie itself, so Redis isn't needed for session data. But we use Redis to track active sessions for revocation. Sliding window rate limiting with INCR and PEXPIRE. Each endpoint has its own key prefix and limits.…
Webhooks are inbound HTTP requests from third parties. Without verification, anyone on the internet can POST to your webhook endpoint and trigger work. HMAC signing is how you verify the sender. When a provider sends a webhook, it computes an HMAC-SHA256 signature over the raw request body using a shared secret, then includes the result in a header…
Rate limiting is deceptively simple. A naive counter-per-minute works in your test suite and breaks in production the first time a user opens ten tabs at once. A fixed window resets on the hour. That lets a single client burn their entire quota at 11:59 and then do it again at 12:00 — an effective 2x limit. Sliding windows smooth this by weighting the…
Most SaaS products pick their multi-tenancy model once and live with it forever. The migration cost later is so high that teams build entire companies around the constraints of a decision they made in their first sprint. Every row carries orgid. One database, one schema, one set of connections. Cheap to operate and dead simple until you need a row-level…
Most application bugs don't live in your API handlers. They live in the long tail of "send this email later" and "charge this card tomorrow" — background jobs where failures are silent and retries compound. Redis-backed, TypeScript-first, batteries included. Built-in delayed jobs, retries with exponential backoff, a dead-letter queue, and a clean API for…
Stripe will retry every webhook at least once. Network blips, slow processing, a bad 5xx — all of them trigger another delivery. If you double-grant credits or double-send the "Welcome" email because two copies of the same event arrived, that's your bug, not Stripe's. event.id starts with evt and never changes across retries. Store it. On receipt, check…
Every serious schema change wants to be three deploys. New teams routinely ship them as one, take down production, and learn the rules the hard way. ALTER TABLE users ADD COLUMN tier TEXT NOT NULL rewrites every row. Worse, pre-11 versions hold an ACCESS EXCLUSIVE lock for the duration — reads and writes both block. The safe version: Deploy 1: add column as…
You don't need a six-figure vendor contract to run a SaaS responsibly. You need structured logs, a handful of metrics, and enough tracing to follow one request end-to-end. Most of the rest is expensive noise. JSON over text. logger.info("user.signup", { userId, email }) over console.log("user signed up: " + email). Every log event becomes queryable, every…
Newsletter
Get new posts and changelog entries by email or RSS.