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
| Collection | Purpose |
|---|---|
observations | Append-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.comReturns 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 registriesAdding an observation source
- Add a new task handler in
src/domains/monitor/lib/tasks/. Tasks run via Payload jobs. - Each task produces zero or more observations and writes them via the
observationsservice (which handles upsert + dedupe). - Update
OBSERVATION_SOURCESinsrc/domains/monitor/schemas.ts. - Wire a card on
/operatethat reads the new source viagetBrief().
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.