Data Models
All models live in apps/backend/src/models/. Every model uses Mongoose with { timestamps: true } which automatically adds created_at and updated_at fields.
User — users collection
File: models/userModel.js
| Field | Type | Required | Notes |
|---|---|---|---|
email | String | ✅ | Unique, indexed |
password | String | ✅ | bcrypt hash (pre-save hook) |
full_name | String | ✅ | |
phone | String | ||
organization | String | ||
address | String | ||
language | String | ||
has_preferences_setup | Boolean | Default: false | |
preferences | Object | Default: {} | |
type | String | Enum: ['user', 'admin'], default 'user' | |
features | Object | Default: {} | |
email_verified | Boolean | Default: false | |
email_verified_date | Date |
Indexes: { email: 1 } (unique)
Device — devices collection
File: models/deviceModel.js
| Field | Type | Required | Notes |
|---|---|---|---|
name | String | ||
code | String | ✅ | Unique device identifier, indexed |
settings | Object | Default: {} | |
recent_sensor_data | Object | Latest sensor reading (cached) | |
recent_network_data | Object | Latest network reading (cached) | |
last_communicated_at | Date | Indexed | |
unit_id | ObjectId | Ref: Unit | |
user_id | ObjectId | Ref: User |
Indexes: { code: 1 } (unique), { code: "text" }
Unit — units collection
File: models/unitModel.js
| Field | Type | Required | Notes |
|---|---|---|---|
name | String | ✅ | Zone display name |
status | String | ||
min_temperature | Number | Lower threshold for temperature | |
max_temperature | Number | Upper threshold for temperature | |
min_humidity | Number | Lower threshold for humidity | |
max_humidity | Number | Upper threshold for humidity | |
min_volt | Number | Lower threshold for voltage | |
max_volt | Number | Upper threshold for voltage | |
device_id | ObjectId | Ref: Device, indexed | |
recent_sensor_data | Object | Default: {} | |
recent_network_data | Object | Default: {} | |
live_alerts | [Object] | Default: [] — computed on every reading | |
last_communicated_at | Date | Indexed | |
user_id | ObjectId | Ref: User, indexed | |
email_recipient_ids | [ObjectId] | Ref: Recipient array | |
sms_recipient_ids | [ObjectId] | Ref: Recipient array | |
email_alert | Boolean | Default: false | |
sms_alert | Boolean | Default: false |
SensorData — sensor_data collection
File: models/deviceSensorDataModel.js
| Field | Type | Required | Notes |
|---|---|---|---|
device_id | ObjectId | ✅ | Ref: Device |
date | Date | ✅ | Reading timestamp |
temperature | Number | ||
humidity | Number | ||
volt | Number | ||
seq_no | Number | Sequence number from device |
Indexes: { device_id: 1, date: -1 }
DiagnosticData — diagnostic_data collection
File: models/deviceDiagnosticDataModel.js
| Field | Type | Required | Notes |
|---|---|---|---|
device_id | ObjectId | ✅ | Ref: Device |
date | Date | ✅ | |
os_ver | String | OS version of device firmware | |
sw_ver | String | Software version | |
hw_ver | String | Hardware version | |
dev_log | String | Device log output |
Indexes: { device_id: 1, date: -1 }
NetworkData — network_data collection
File: models/deviceNetworkDataModel.js
| Field | Type | Required | Notes |
|---|---|---|---|
device_id | ObjectId | ✅ | Indexed |
date | Date | ✅ | |
operator | Number | Mobile network operator | |
mnc | Number | Mobile Network Code | |
sinr | Number | Signal-to-noise ratio | |
mcc | Number | Mobile Country Code | |
lac | Number | ||
rssi | Number | Received signal strength | |
channel | Number | ||
rsrp | Number | ||
rsrq | Number | ||
ci | Number | Cell ID | |
tech | String | Radio technology (4G etc) | |
band | String | Frequency band |
RawSensorData — raw_sensor_data collection
File: models/rawDeviceSensorDataModel.js
| Field | Type | Required | Notes |
|---|---|---|---|
device_id | ObjectId | ✅ | Ref: Device |
date | Date | ✅ |
Indexes: { device_id: 1, date: -1 }
Recipient — recipients collection
File: models/recipientModel.js
| Field | Type | Required | Notes |
|---|---|---|---|
name | String | ✅ | |
phone | String | ||
email | String | ||
user_id | ObjectId | ✅ | Ref: User |
status | String | Enum: ['active', 'deleted'], default 'active' | |
is_default | Boolean | Default: false — created on signup |
Default Recipient
Every user gets a default recipient created automatically during signup (using the same _id as the user). This recipient has is_default: true and pre-populates new units' notification lists.
UserToken — user_tokens collection
File: models/userTokenModel.js
| Field | Type | Required | Notes |
|---|---|---|---|
userId | ObjectId | ✅ | Ref: User |
token | String | ✅ | |
createdAt | Date | Default: now; TTL: 7 days |
The TTL index on createdAt auto-purges expired tokens. This is the server-side session store for JWT revocation.
Verification — verifications collection
File: models/verificationModel.js
| Field | Type | Required | Notes |
|---|---|---|---|
user_identification | String | ✅ | Email address |
verification_type | String | ✅ | Enum: ['signup', 'reset_password'] |
token | String | ✅ | 32-byte hex random token |
Indexes:
- Compound:
{ user_identification, verification_type }— ensures one active token per type per email - TTL on
user_identification: expires after 1800 seconds (30 minutes)
UnitAndDeviceLog — unit_and_device_logs collection
File: models/unitAndDeviceLogModel.js
Audit trail for device↔unit assignments.
| Field | Type | Required |
|---|---|---|
unit_id | ObjectId | ✅ |
device_id | ObjectId | ✅ |
user_id | ObjectId | ✅ |
added_date | Date | ✅ |
removed_date | Date | |
added_by | ObjectId | ✅ |
removed_by | ObjectId |
UserAndDeviceLog — user_and_device_logs collection
File: models/userAndDeviceLogsModel.js
Audit trail for device↔user assignments.
| Field | Type | Required |
|---|---|---|
user_id | ObjectId | ✅ |
device_id | ObjectId | ✅ |
added_date | Date | ✅ |
removed_date | Date | |
added_by | ObjectId | ✅ |
removed_by | ObjectId |
NotificationReceiver — notification_receivers collection
File: models/notificationReceiver.js
| Field | Type | Required |
|---|---|---|
unit_id | ObjectId | ✅ |
email_recipient_ids | [ObjectId] | |
sms_recipient_ids | [ObjectId] | |
email_alert | Boolean | |
sms_alert | Boolean |
