The saved filters table
crm_saved_filters stores named, reusable filter snapshots per user and org over the company, person and signal list views. Each row is a serialized query — a schema-less JSONB snapshot of a list view's filter state that re-runs live every time it is applied. This page traces it top-down: where it is served from, how a saved view is born and applied, then its full schema, relationships and rules.
System design
interactive Start from the top. The filter bar never touches storage directly — it talks to the saved_filters subdomain, the only thing that reads or writes crm_saved_filters. A saved view is a snapshot of the current filter state, not a result set. Click a node to trace what it connects to.
Data flow — birth of a saved view
interactiveHow a saved filter is captured and applied, as a closed loop. A user builds a view, the frontend snapshots its filter state, a row is written under RLS, the saved-views dropdown lists and applies it live — and maintenance closes back to the start. Click a stage to follow it.
Schema
interactiveThe row is small: a definition envelope plus one schema-less JSONB snapshot. Pick a group; colour marks each column's kind, and clicking a column expands its category and any table it references. Everything is org-scoped; the criteria column carries the whole filter state.
Who owns the saved view, which surface it targets, and how widely it is shared.
- primary key
Primary key.
- enum
Which list view the filter targets: company · person · signal.
- enum
private (creator only) · org (whole organization can read).
- text
Display name in the saved-views dropdown.
- text
Optional longer note about the view.
- timestamp
Audit timestamps.
Relationships
interactiveA saved filter is a lightweight envelope — it points at its creator and its tenant, and it contrasts with the heavier list tables. Hover or click a table to trace its link and see its key columns.
crm_saved_filters belongs to a creator and an org; contrast it with crm_lists, which materializes members.
RLS, scope & schema
modelThe database is storage only — no business logic. What it does enforce: visibility gating, tenant isolation, per-surface scope, and the schema-less criteria contract that lets the saved shape evolve.
SELECT = superadmin OR same-org AND (own row OR visibility = org). INSERT / UPDATE / DELETE = creator only. So an org-shared filter is readable by every member but editable only by its author.
The jsonb snapshot evolves with the list view. When a new filter dimension ships on a list, the saved shape just carries it — no migration on crm_saved_filters.
member_type (company / person / signal) scopes the filter to one list view. A saved companies view never appears in the people dropdown.
organization_id sits on every row. Combined with RLS, a saved view can only ever be read inside the org that owns it.
A saved filter is a serialized query, not a result set. It re-evaluates against live data every time it is applied, so a shared org view always reflects the current CRM. crm_saved_filters holds no rules of its own — tables, indexes, RLS and the schema-less criteria snapshot only.