Back to Docs
Recipe

Sales Pipeline View

Build a real-time dashboard that visualizes your entire sales pipeline — from lead to closed-won — using Meridian's relational views and computed rollups.

Overview

This recipe wires together three Meridian primitives — adealstable, apipeline_stageslookup, and apipeline_viewsaved query — to produce a kanban-style board with per-stage totals, weighted forecasts, and aging indicators.

Step 1 — Define the schema

CREATE TABLE deals (
  id UUID PRIMARY KEY,
  title TEXT NOT NULL,
  value_cents BIGINT,
  stage_id UUID,
  owner_id UUID,
  created_at TIMESTAMPTZ
);

CREATE TABLE pipeline_stages (
  id UUID PRIMARY KEY,
  name TEXT,
  sort_order INT
);

Step 2 — Create the pipeline view

CREATE VIEW pipeline_view AS
SELECT
  ps.name AS stage,
  COUNT(d.id) AS deal_count,
  COALESCE(SUM(d.value_cents), 0) AS total_value,
  AVG(EXTRACT(DAY FROM NOW() - d.created_at))::INT AS avg_age_days
FROM pipeline_stages ps
LEFT JOIN deals d ON d.stage_id = ps.id
GROUP BY ps.name, ps.sort_order
ORDER BY ps.sort_order;

Step 3 — Query from your frontend

Call the Meridian REST endpoint with your project key. The response shape matches the view columns exactly — no ORM mapping required.

GET /v1/query/pipeline_view
Authorization: Bearer mk_live_...

// Response
[
  { "stage": "Qualified", "deal_count": 12, "total_value": 840000, "avg_age_days": 7 },
  { "stage": "Proposal",  "deal_count": 5,  "total_value": 310000, "avg_age_days": 14 },
  { "stage": "Closed Won","deal_count": 3,  "total_value": 195000, "avg_age_days": 22 }
]

Step 4 — Render the board

Map each stage to a column. Useavg_age_daysto flag stale deals with an amber or red indicator. Re-fetch every 60 seconds or on webhook events for near-real-time updates.

Pro tip:Combine this view with Meridian's row-level security to scope pipelines per team or region without writing additional WHERE clauses.