All Insights
EngineeringMarch 5, 2026

The 139-Table Problem: Designing a Database for Operational Complexity

By Raiden Stack

When someone hears that our operations platform has 139 database tables, the first reaction is usually concern. That sounds like a lot of complexity. And it is. But every single table exists because a real operational process demanded it. This is not accidental complexity. It is earned complexity, the kind that comes from modeling a business with 12+ locations, 200+ employees, and a regulatory environment that would make most developers reconsider their career choices.

The database design started with a principle: get the relationships right at the data layer, and everything built on top will be solid. Get them wrong, and you'll spend the next two years fighting your own schema. We spent three weeks on the data model before writing a single React component.

HR case management alone required 14 tables. Not because we over-engineered it, but because real HR work is complicated. A case has a type (investigation, coaching, disciplinary, accommodation, complaint). It involves one or more employees who may work at different locations. It has a timeline of events, each with notes and attached documents. It has an outcome with follow-up actions. Some cases escalate. Some trigger legal holds. Some involve external parties (attorneys, regulatory agencies). Each of these relationships needed to be modeled correctly from the start.

The learning management system added another 18 tables. Courses, modules, lessons, quizzes, enrollments, completions, certificates, assignments, role-based curricula, certification expiration tracking, and the AI content generation pipeline that feeds new material into the system. A single "employee completed a training course" event touches six tables. That's not bloat. That's an audit trail that can prove regulatory compliance during an inspection.

Row-level security (RLS) in Supabase was essential. Location managers need to see their own data. Regional managers need to see data for their locations. Corporate leadership needs to see everything. The same table, the same query, returns different data depending on who's asking. Implementing this correctly in PostgreSQL policies rather than application code means security can't be bypassed by a frontend bug.

The POS integration layer was the most interesting engineering challenge. Sales data from multiple locations needs to flow into the platform in near-real-time. Each transaction includes line items, payment methods, employee attribution, and timestamps. Aggregating this data across locations while maintaining the ability to drill down to individual transactions required careful schema design. The denormalization decisions we made for analytics queries would make a database purist uncomfortable, but they make the location comparison dashboards load in under two seconds.

One lesson that applies universally: model for the edge case, not the common case. The common HR case is simple: employee did something, manager documented it, case closed. The edge case is an investigation that spans three locations, involves a contractor (not a direct employee), requires a legal hold on all related documents, and needs to be reportable to an external regulatory body. If you design for the edge case from the start, the common case handles itself. If you design for the common case only, the edge case will break your system six months later.

The encrypted credential vault was a security imperative. Managing access credentials for POS systems, security cameras, alarm systems, and vendor portals across 12+ locations used to mean credentials stored in places they shouldn't be. The vault encrypts at rest, requires role-based access with MFA for sensitive entries, logs every access event, and supports credential rotation with notifications. It is exactly the kind of boring, essential infrastructure that prevents the kind of security incident that can shut a business down.

139 tables is a lot. But it's the right number for a platform that actually runs a business. Every table represents a process that used to be manual, fragmented, or invisible. Making those processes structured, queryable, and auditable is what separates a real platform from a dashboard with a database behind it.