What you'll accomplish
Understand solarOS's core nouns before reading any other guide. Every other page assumes you know these two chains.
Prerequisites
None.
The property chain: Customer → Property → System → MonitoringDevice
A Customer owns one or more Properties (service addresses). Each
Property can have one or more Systems (a solar PV array, a battery, etc.;
systemType is a free-text field like "Solar PV" or "Battery Storage"). Each System can have one or more MonitoringDevices, which
are what actually reports data (inverter, gateway, or similar), synced
through Texture.
Customer
└─ Property (a service address)
└─ System (a physical solar/battery install at that property)
└─ MonitoringDevice (the thing reporting telemetry via Texture)
"Site" is not a data model concept. One staff nav label (Monitoring →
Fleet → Sites, at /monitoring/sites) uses the word "Sites," but it
points at Property records, not a separate model. If you're reading the
schema or calling the Org API, ignore "Site" as a noun and think
"Property."
A Property's monitoringStatus (whether it's actively monitored) is a
separate value from a MonitoringDevice's connectionStatus (whether that
specific device is currently connected):
PropertyMonitoringStatus
| Value |
|---|
| UNMONITORED |
| ACTIVE |
| SUSPENDED |
DeviceConnectionStatus
| Value |
|---|
| PENDING |
| CONNECTED |
| DISCONNECTED |
| ERROR |
| INACTIVE |
| SUSPENDED |
Device health shown to customers (green/amber/red) isn't a stored field:
it's computed on the fly from active alerts and device connection status.
See determineHealthStatus in src/lib/monitoring/system-health.ts: red if
any high/critical alert is open or every device is down; amber if any
low/medium alert is open or some devices are down; green otherwise.
The sales-to-project chain: Lead → Opportunity → Quote → Contract → Project
A Lead is raw interest before you know if it's a real deal. Converting a Lead creates (or links) a Customer, Property, and Opportunity. An Opportunity moves through a pipeline and, once you're proposing pricing, gets one or more Quotes. Accepting a Quote can produce a Contract for signature, and once work is ready to schedule it becomes a Project (which holds the actual work: tasks, work orders, etc.).
Lead → Opportunity → Quote → Contract → Project
Each stage has its own status enum, generated here from the same source the Org API and app code use, so this table can't drift from what's actually enforced:
LeadStatus
| Value |
|---|
| NEW |
| CONTACTED |
| QUALIFIED |
| UNQUALIFIED |
| CONVERTED |
OpportunityStage
| Value |
|---|
| NEW |
| PROPOSAL |
| NEGOTIATION |
| CLOSED_WON |
| CLOSED_LOST |
QuoteStatus
| Value |
|---|
| DRAFT |
| PENDING_APPROVAL |
| SENT |
| VIEWED |
| ACCEPTED |
| REJECTED |
| EXPIRED |
| CANCELLED |
ContractStatus
| Value |
|---|
| DRAFT |
| PENDING_SIGNATURE |
| PARTIALLY_SIGNED |
| COMPLETED |
| VOIDED |
| EXPIRED |
ProjectStatus
| Value |
|---|
| DRAFT |
| ACTIVE |
| ON_HOLD |
| COMPLETED |
| CANCELLED |
| CLOSED |
Work Orders vs. Cases
Both records mean "someone doing work at a property," and they're easy to conflate:
- A Work Order is scheduled field work: it carries scope and a required Report Type, and is delivered through one or more Service Appointments (the calendar bookings: time, assigned crew, dispatch state, arrival window). Work Orders come from a Project (via a Project Template's Work Order item, direct creation, or a Quote that takes scope from itself), or directly from a Case.
- A Case is the organization's tracked record of a customer's service
issue (hardware defect, workmanship, monitoring, billing), the only
customer-facing service record, worked by its Business Owner through
queue semantics (Case Responsibility). A Case doesn't perform field work
itself: its "Start resolving work" action creates (or links) a Project
and Work Order to actually do the work, and the Case keeps a direct link
to that Project (
Case.projectId).
In short: a Work Order is what gets scheduled and completed on-site; a Case is the support/issue record that can spawn one.
Verify it worked
You can explain, without looking anything up, why "Site" isn't a real solarOS object, the difference between a Work Order and a Case, and you can name the five stages a Lead passes through on its way to becoming a Project.
Common problems
Two different "subscription" concepts get conflated. solarOS has two separate billing systems that share vocabulary:
- Subscription: a homeowner's maintenance/monitoring plan, tied to a
Property(SubscriptionStatusbelow). - PlatformSubscription: the contractor organization's own solarOS
billing (one per organization,
PlatformSubscriptionStatusbelow).
They're unrelated records with unrelated statuses. If a support conversation mentions "the subscription," confirm which one before you go looking.
SubscriptionStatus (homeowner maintenance/monitoring plan)
| Value |
|---|
| PENDING |
| ACTIVE |
| PAST_DUE |
| CANCELED |
| PAUSED |
PlatformSubscriptionStatus (the contractor org's own solarOS billing)
| Value |
|---|
| TRIALING |
| ACTIVE |
| PAST_DUE |
| UNPAID |
| CANCELLED |
| PAUSED |