Market signal
Market signal
Last updated 5/3/2026
Market Signal
This document stores the source context for the Market Signal metric in ZoomProp.
Definition
| Field | Value |
|---|---|
| KPI-ID | KPI-001 |
| Source | /api/analytics/markets → src/app/api/analytics/markets/route.ts; /api/analytics/appreciation-distribution → src/app/api/analytics/appreciation-distribution/route.ts; /api/ai/property-analysis → src/app/api/ai/property-analysis/route.ts |
| Owner | Analytics & AI Platform team (zoomprop/zp-alpha) |
| Frequency | Computed on each request to /api/analytics/markets; alert triggers evaluated continuously via /api/alerts/trigger → src/app/api/alerts/trigger/route.ts |
What It Measures
Market Signal quantifies the aggregate investment attractiveness of a real-estate market region as perceived by ZoomProp users and derived from platform-side data signals. It combines four sub-signals:
-
Cap-rate spread — derived from the
CapRateCalculationSchemadefined insrc/lib/schemas/cap-rate.ts(fields:constMonthlyRent,constVacancydefault 5 %,constOperExpensesdefault 30 %,constResEstimatedefault 5 %,constClosingCostsdefault 2 %,listPrice). A widening spread between computed cap rate and a market baseline indicates improving yield conditions. -
Appreciation distribution — sourced from
/api/analytics/appreciation-distribution(src/app/api/analytics/appreciation-distribution/route.ts). Tracks the share of properties in a region showing positive year-over-year price movement. A rising share is a bullish market signal. -
AI-derived intent score — produced by
/api/ai/intent(src/app/api/ai/intent/route.ts) and the LangGraph orchestration layer (@langchain/langgraph ^0.3.5,@langchain/openai ^0.5.16). The intent model classifies inbound user queries against market topics; rising intent volume for a region elevates its signal score. -
Alert trigger velocity — the rate at which user-configured alert filters (managed through
/api/alert-filters→src/app/api/alert-filters/route.tsand/api/alerts/configure→src/app/api/alerts/configure/route.ts) fire for a given region within a rolling 24-hour window. High velocity indicates heightened user attention on a market.
The composite score is normalised to a 0–100 scale and surfaced through /api/analytics/markets. It is displayed in the src/app/(dashboard)/alerts/_components/alert-center-dashboard.tsx UI component and indexed in Elasticsearch (@elastic/elasticsearch ^8.18.2) for sub-second regional queries. Geographic context is rendered via Mapbox (@mapbox/mapbox-gl-draw ^1.5.0, NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN) and Google Maps (@googlemaps/js-api-loader ^1.16.10).
Thresholds
| Level | Value | Action |
|---|---|---|
| Healthy | Score ≥ 65 / 100 | No action required. Cap-rate spread is positive, appreciation share > 50 %, AI intent volume is growing, and alert trigger velocity is within normal range. Continue standard monitoring via /api/ai/performance-monitoring. |
| Warning | Score 40–64 / 100 | Notify the Analytics team via Knock (@knocklabs/node ^1.11.1). Trigger /api/alerts/trigger with severity warning. Review appreciation-distribution endpoint for regional outliers. AI personas (/api/ai/personas) may surface targeted market summaries to affected users. |
| Critical | Score < 40 / 100 | Fire a critical alert through /api/alerts/trigger and surface a banner in src/app/(dashboard)/alerts/_components/alert-center-dashboard.tsx. Escalate to the investment-analysis pipeline (/api/ai/analysis → src/app/api/ai/analysis/route.ts). Pause automated outreach cron jobs (archive/legacy-api-backup/cron/process-investment-followups/route.ts lineage) until score recovers. Initiate incident review against .github/workflows/alert-testing.yml. |
Related IDs
- BR-001 — Business requirement: surface real-time market attractiveness scores to investors during property discovery (see
src/app/(auth)/onboarding/_components/steps/investment-interests-step.tsxandgeographic-focus-step.tsx). - BR-002 — Business requirement: alert investors when a tracked market crosses a sentiment threshold (see
/api/alerts/preferences→src/app/api/alerts/preferences/route.ts). - MON-001 — Observability: OpenTelemetry tracing (
@opentelemetry/api ^1.9.0,@opentelemetry/sdk-trace-base ^2.0.1) instrumenting all calls to/api/analytics/marketsand/api/ai/intent. - MON-002 — CI health gate:
.github/workflows/test-coverage.ymlenforces coverage acrosstests/api/markets/route.test.tsandtests/api/alerts/trigger.test.tsto prevent regressions in signal computation logic. - UJ-001 — User journey: Investor completes geographic-focus onboarding step (
src/app/(auth)/onboarding/_components/steps/geographic-focus-step.tsx), Market Signal scores are pre-fetched for selected regions and injected into the dashboard. - UJ-002 — User journey: Investor configures a threshold alert via
src/app/(dashboard)/alerts/_components/alert-config-form.tsx; the platform fires a Knock notification when the Market Signal for a watched region crosses into Warning or Critical. - API-001 —
/api/analytics/markets(src/app/api/analytics/markets/route.ts) — primary data source. - API-002 —
/api/analytics/appreciation-distribution(src/app/api/analytics/appreciation-distribution/route.ts) — appreciation sub-signal. - API-003 —
/api/ai/intent(src/app/api/ai/intent/route.ts) — intent-score sub-signal. - API-004 —
/api/alerts/trigger(src/app/api/alerts/trigger/route.ts) — threshold enforcement. - DBT-001 —
CapRateCalculationSchema(src/lib/schemas/cap-rate.ts) — canonical schema for cap-rate sub-signal inputs validated withzod.