Skip to Content
FeaturesMonitoring

Monitoring

The Monitor pillar tracks engagement, data quality, and revenue per tenant — and exposes one-sentence “what to do next” briefs to operators and agents.

The observations engine

CollectionPurpose
observationsAppend-only facts emitted by monitoring tasks (data quality, evals, GSC, Stripe, internal search). Tenant-scoped. Upsert via (tenant, dedupeKey).

Every monitoring task emits structured observations rather than ad-hoc metrics. Cards on the /operate dashboard read those observations via getBrief() — no separate analytics service for MVP.

The /operate dashboard

Lives in src/domains/monitor/components/. Surfaces:

  • Data quality — records total, display readiness, schema conformance, field fill rate
  • Evals — completeness vs. target, revenue vs. target
  • GSC (Search Console pull) — top queries, top pages, low-CTR pages, page-2 opportunities
  • Stripe — revenue + subscription metrics into the same observations engine

Card components: MetricCard, StatusCard, TopNCard, StackedBarCard. Sidebar + tenant switcher are baked in for portfolio operators running multiple tenants.

CLI access

The same brief is exposed via the CLI for agent use:

shipmore monitor brief --tenant ramen.example.com

Returns the most recent observations as JSON, plus the headline one-sentence “what to do next” recommendation.

Domain layout

src/domains/monitor/ ├── services/ # observations, brief, checks, evaluate ├── lib/ │ ├── chart-adapters.ts # observation row → Recharts data │ ├── dedupe-key.ts # stable hash for upsert │ ├── operator-context.ts # /operate auth + tenant resolution │ └── tasks/ # check-data, evaluate (Payload job handlers) ├── components/ # MetricCard, StatusCard, TopNCard, StackedBarCard, │ # AppSidebar, TenantSwitcher └── schemas.ts # OBSERVATION_SOURCES, BriefOutput, metric registries

Adding an observation source

  1. Add a new task handler in src/domains/monitor/lib/tasks/. Tasks run via Payload jobs.
  2. Each task produces zero or more observations and writes them via the observations service (which handles upsert + dedupe).
  3. Update OBSERVATION_SOURCES in src/domains/monitor/schemas.ts.
  4. Wire a card on /operate that reads the new source via getBrief().

Why one-sentence briefs

Charts don’t drive action; sentences do. The brief layer collapses each card into a single recommendation pointing at a decision (e.g. “3 records have missing image — operate decay risk on the directory homepage.”). Same brief is consumed by the /operate UI and the monitor brief CLI, so an agent operating overnight has the same view as a human at the dashboard.

Future sources

GSC and Stripe pulls are first-class. Internal search log capture, outbound click tracking, and Meta CAPI conversion events are on the roadmap and will write into the same observations engine — no schema migration needed.