Under the hood

For the person who will ask how it actually works

You do not need this page to use Sales OS. It is here because somewhere between you and a signature there is an IT lead, a security reviewer or a curious CTO who will want it — so here is the whole shape of the thing: a browser tier that renders, a server tier that decides, a database that enforces, and the outside systems it keeps honest.

100
Migrations
68
Tables
161
RLS policies
45
DB functions
20
AI features
10
Scheduled jobs
The system

What connects to what

Each boundary below is a real one — a different protocol, a different trust level, and a different failure mode.

01

Browser

React 19 · server-rendered shell, client-driven app

TanStack Router

File-based routes

TanStack Query

Cache & invalidation

Tailwind v4 · shadcn/ui

Radix primitives

Tiptap · Recharts

Editing & charts

typed server functions
02

Application server

Nitro runtime · TanStack Start

Server functions

One module per domain

Zod validation

Every boundary typed

Domain services

Pipeline, deals, meetings

Job runner

10 scheduled handlers

Integration clients

Graph · Odoo · OpenRouter

Export engine

docx · ExcelJS

SQL · HTTPS · OAuth 2.0
03

Supabase

Postgres

Postgres

68 tables · 161 RLS policies

Auth

Sessions & identity

Storage

Attachments & figures

03

Intelligence

OpenRouter

Model gateway

Single provider surface

Structured output

JSON-schema responses

Web-grounded models

For research briefs

03

Systems of record

Customer-owned

Microsoft Graph

Mail · Calendar · To Do

Odoo CRM

Leads · opportunities

Encrypted keys

AES-256-GCM at rest

Principles

Four decisions that shape everything else

Architecture is mostly the consequences of a handful of early choices. These are ours.

Typed from the button to the table

A click calls a server function whose arguments are parsed by Zod and whose return type flows back to the component. Database types are generated from the schema, so a column rename breaks the build rather than production.

The database decides who sees what

Authorization is expressed as row-level security policies next to the data, not as conditionals in the UI. A query issued from anywhere returns only the rows that caller is entitled to.

Sync belongs in the background

Nothing important waits for a page view. Scheduled handlers pull mail, calendar and CRM state, and every run is recorded with its duration, outcome and error.

Models are configuration, not architecture

Every AI call names a feature key; the model behind that key is chosen in Settings and routed through one provider. Swapping models is a dropdown, never a refactor.

End to end

One email, traced through the whole system

A single inbound reply touches every tier in the diagram above. Here is the actual path it takes.

01

A reply lands in Outlook

The inbox sync job pulls the thread through Microsoft Graph using a delta cursor, so only what changed comes across.

02

It is matched to a deal

Sender domain, contacts and existing links are scored against open opportunities. A confident match links the thread; an ambiguous one is left for a human.

03

The record moves

A deal event is written, activity is appended, and pipeline signals recompute — stage age, momentum, and whether the deal has gone quiet.

04

Work is proposed

The task generator turns commitments in the thread and meeting into tasks, and pushes them to Microsoft To Do so they surface where the rep already works.

05

An agent drafts

The drafter assembles the thread, client memory, meeting notes and prior documents into context, then streams a reply from the model assigned to that feature.

06

Documents compose

Estimation feeds the proposal; the approved SOW feeds the narrative. All three render from your templates against one set of numbers.

07

It leaves as a file

Export writes real DOCX and XLSX — styled documents with tables and figures, not HTML printed to a page.

The stack

Chosen deliberately, and kept small

Six groups, no duplicates, nothing in the tree that is not actually load-bearing.

Interface

  • React 19Concurrent rendering
  • TanStack RouterFile-based, type-safe routes
  • TanStack QueryServer-state cache
  • Tailwind CSS v4OKLCH token system
  • shadcn/ui + RadixAccessible primitives
  • Framer MotionInteraction & transition

Runtime

  • TanStack StartServer functions as typed RPC
  • NitroPortable server output
  • Vite 8Build & dev server
  • TypeScriptStrict, end to end
  • ZodRuntime schema validation
  • ESLint + PrettierEnforced in CI

Data

  • Supabase Postgres68 tables, 100 migrations
  • Row-level security161 policies
  • Postgres functions45 server-side routines
  • Supabase AuthSession & identity
  • Supabase StorageAttachments and figures
  • Generated typesSchema-derived, not hand-written

Intelligence

  • OpenRouterOne gateway, many models
  • 20 feature keysModel chosen per feature
  • Structured outputJSON-schema responses
  • StreamingToken-level UI updates
  • Usage ledgerTokens and cost per call
  • LlamaParseDocument ingestion

Integrations

  • Microsoft GraphMail, calendar, To Do
  • OAuth 2.0Per-user delegated access
  • Odoo CRMTwo-way lead and deal sync
  • AES-256-GCMConnection keys sealed at rest
  • Delta cursorsIncremental, resumable sync
  • Job registry10 scheduled handlers

Documents

  • TiptapRich text with tables and figures
  • docxNative Word output
  • ExcelJSNative workbook output
  • Turndown + markedMarkdown round-tripping
  • Template engineEstimation, proposal, SOW
  • RechartsPipeline and target charts