dhaga.blog

dhaga. blog · Engineering

Engineering

Deep dives on the hardest problems behind Dhaga — a 21k-node graph in the browser, AI unit economics, tenant isolation on serverless Postgres.

Shipping Pages: the deadlock we almost deployed

Two weeks, many parallel AI agents, one merge. Which layer of verification caught which bug, the boot deadlock our own tests could not see, and what we changed.

engineeringpostgresrow-level-securitytesting

DPDP consent on a signup form: what the law asks, what we built

What India's DPDP Act asks of a signup checkbox, how GDPR and LGPD compare, and how we built a separate, recorded consent box, including what it cannot prove.

engineeringprivacydpdpgdpr

The nudge we could already send twice

Delivering every minute didn't add a double-send; it made an old one routine. Why the queue is materialised, and why the claim must happen in the database.

engineeringpostgresconcurrencyserverless

The CI that waited on itself

Twenty-nine minutes of CI cut to about ten by splitting the job and sharding the suite — but the changes that mattered most stopped a green tick lying.

engineeringcigithub-actionsvitest

Your login page is a signup form

A captcha on the signup form guards one door of five: in most auth libraries, magic links, email OTP, One Tap and OAuth all create accounts by default.

engineeringsecurityauthenticationbetter-auth

Don't build sharing with row-level security

Widening row-level security with an OR so colleagues can share records exposes every column and costs your hottest index. Publish a projection instead.

engineeringpostgresrlssecurity

One token cannot be both

On a light ground, a colour's fill and text contrast multiply to a constant — ours is 16.78 — so no one value clears 4.5:1 at both. Hence accent pairs.

engineeringdesign-systemsaccessibilitycss

The matcher that meant something else

Duplicate detection merged strangers via a tag suggester that groups by surname on purpose. Why types couldn't catch it, nor a smarter helper fix it.

engineeringcorrectnessapi-designwar-story

The model that could not read a card

Card scans came back confident, well-formed and wrong. The same 408px image read perfectly on a stronger model — the fix was the model, not more pixels.

engineeringaillmvision

The summariser didn't fabricate. It overclaimed.

We summarised 847 commits with LLMs and audited every line. No invented features — but true-when-written claims, and a 'shipped' path no user could reach.

engineeringaillmdocumentation

One message, two notes

One message, one place — a rule that lived only in the prompt, checked by no code. Why a Zod refinement was the wrong lever, and why we repair bad plans.

engineeringaillmzod

The LLM didn't truncate. It edited.

A capture came back four fifths shorter, silently. Not a token limit, not summarisation — the model filtered to fit the schema. A schema is a filter too.

engineeringaillmstructured-outputs

The fan-out that killed the search

Six sources under one Promise.all, a pool of three: HTTP 500 with one user. Why Promise.all multiplies concurrency when every read takes a connection.

engineeringpostgresperformancemulti-tenant

How we build Dhaga with Claude Code

A checked-in rulebook, hooks that gate every edit, and memory that survives sessions — how we make an AI agent a reliable Dhaga contributor.

engineeringaiclaude-codedeveloper-workflow

Isolating tenants on serverless Postgres

Row-level security is easy to get catastrophically wrong. How a connection pooler nearly leaked tenant data, and the transaction-scoped fix that stops it.

engineeringpostgressecuritymulti-tenancy

The bill is the model, not the servers

In an AI product, inference is the P&L. How we found Dhaga's real cost driver, and the guardrails that stop one heavy user costing $7,200 a month.

engineeringaicostllm

The feature flag that didn't fire

Our documented escape hatch for a native dependency didn't stop a crash on deploy. Why `import` runs first, and a flag can't gate a static import.

engineeringdebuggingdeploymentjavascript

A schema that heals itself on cold start

No migration tool and a 15-second sign-in. How one content hash turned a full schema replay on every serverless cold start into a self-healing no-op.

engineeringpostgresmigrationsself-hosting

Rendering a 21,000-node graph in the browser

63,000 edges at 60fps on integrated graphics — no graph database, no server render farm. How Dhaga renders a whole knowledge graph client-side.

engineeringperformancedata-visualizationgraph