Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/GaelCeballos/Smart_Enviro_Backend/llms.txt

Use this file to discover all available pages before exploring further.

Smart Enviro Backend persists all of its state across six MySQL tables. Users own devices — a single user_id foreign key ties each device to its owner, and that key is set to NULL when the user is deleted rather than cascading the delete, so orphaned devices remain available for re-adoption. Devices in turn own three dependent record types: key-value configuration pairs (device_properties), time-series telemetry readings (sensor_data), and an append-only activity journal (device_logs). Sensor readings are further categorised through a shared sensor_types lookup table that defines the name, machine-readable metric key, and unit of measure for each observable quantity.

Table Reference

users

The standard Laravel 11 users table extended with a current_token column to enforce single-session semantics. The password and remember_token columns are hidden from serialisation by the #[Hidden] model attribute; current_token is similarly hidden.
ColumnTypeConstraintsNotes
idbigint unsignedPK, auto-increment
namevarchar(255)NOT NULLUser’s display name
emailvarchar(255)NOT NULL, UNIQUELogin identifier
email_verified_attimestampNullableSet when email is verified
passwordvarchar(255)NOT NULLBcrypt hash; hidden from API output
current_tokenvarchar(255)NullableActive Sanctum plain-text token
remember_tokenvarchar(100)NullableLaravel remember-me token
created_attimestampNullable
updated_attimestampNullable
current_token is the cornerstone of single-session enforcement. When it is non-null, any new login attempt for the same account returns 409 Conflict. See Authentication for the full flow.

devices

Represents a physical ESP32 unit. Devices can exist without an owner (user_id is nullable) — this is the “available” state, visible through GET /api/devices/available. Soft deletes are enabled via the SoftDeletes trait, so deleted rows remain in the table with deleted_at set.
ColumnTypeConstraintsNotes
idbigint unsignedPK, auto-increment
user_idbigint unsignedNullable, FK → users.id, nullOnDeleteSet to NULL when owner is deleted
mac_addressvarchar(17)NOT NULL, UNIQUEHardware MAC address
device_tokenvarchar(64)NOT NULL, UNIQUESecret used by the ESP32 for auth
namevarchar(255)NOT NULL, DEFAULT 'Dispositivo Smart Enviro'Human-readable label
typevarchar(50)NOT NULLe.g. bomba, sensor_multi
is_activetinyint(1)NOT NULL, DEFAULT 1Whether the device is enabled
is_onlinetinyint(1)NOT NULL, DEFAULT 0Updated on each sync call
current_stateenum('ON','OFF','STANDBY')NOT NULL, DEFAULT 'STANDBY'Last commanded state
last_seen_attimestampNullableSet on every successful sync
deleted_attimestampNullableSoft-delete timestamp
created_attimestampNullable
updated_attimestampNullable
Because user_id uses nullOnDelete rather than cascadeOnDelete, deregistering a user account does not wipe the physical hardware’s record. The device reverts to “available” status and can be claimed by a new user.

device_properties

A flexible key-value store for per-device configuration. Each row pairs a property_key string (e.g. humidity_threshold, auto_water, has_pump) with a property_value string. The composite unique constraint on (device_id, property_key) ensures a device cannot have duplicate keys — an upsert pattern is used when updating.
ColumnTypeConstraintsNotes
idbigint unsignedPK, auto-increment
device_idbigint unsignedNOT NULL, FK → devices.id, cascadeOnDeleteDeleted with the device
property_keyvarchar(100)NOT NULLe.g. humidity_threshold, auto_water
property_valuevarchar(255)NOT NULLString-serialised value
created_attimestampNullable
updated_attimestampNullable
Unique constraint: (device_id, property_key)
All property values are stored as strings. Numeric thresholds, booleans, and other typed values must be cast on read by the consuming client or the device firmware.

sensor_types

A seed/lookup table that defines the catalogue of measurable quantities the system recognises. The metric_key is the machine-readable identifier that ESP32 firmware and API clients use when referencing a measurement type.
ColumnTypeConstraintsNotes
idbigint unsignedPK, auto-increment
namevarchar(255)NOT NULL, UNIQUEHuman-readable name, e.g. Temperatura ambiente
metric_keyvarchar(50)NOT NULL, UNIQUEMachine key, e.g. temp_amb, humedad_suelo
unitvarchar(20)NOT NULLDisplay unit, e.g. °C, %
created_attimestampNullable
updated_attimestampNullable

sensor_data

The primary time-series telemetry table. It deliberately omits created_at and updated_at (Laravel’s $timestamps = false) to reduce write overhead — recorded_at serves as the sole temporal column and defaults to the current timestamp at insert time.
ColumnTypeConstraintsNotes
idbigint unsignedPK, auto-increment
device_idbigint unsignedNOT NULL, FK → devices.id, cascadeOnDeleteCascade-deleted with the device
sensor_type_idbigint unsignedNOT NULL, FK → sensor_types.id, restrictOnDeleteCannot delete a sensor type while readings reference it
reading_valuedecimal(10, 4)NOT NULLFour decimal places of precision
recorded_attimestampNOT NULL, DEFAULT CURRENT_TIMESTAMPTime of measurement
Composite indexes:
IndexColumnsPurpose
sensor_data_device_id_recorded_at_index(device_id, recorded_at)Time-range queries per device
sensor_data_sensor_type_id_recorded_at_index(sensor_type_id, recorded_at)Time-range queries per metric type
The restrictOnDelete constraint on sensor_type_id prevents accidental deletion of a sensor type that still has associated readings. Prune all related sensor_data rows before removing a sensor_types record.

device_logs

An append-only audit and event log. The UPDATED_AT constant is set to null in the DeviceLog model, so Laravel never attempts to write an updated_at column. Only created_at is tracked, and it defaults to the current timestamp.
ColumnTypeConstraintsNotes
idbigint unsignedPK, auto-increment
device_idbigint unsignedNOT NULL, FK → devices.id, cascadeOnDeleteDeleted with the device
log_typevarchar(255)NOT NULL, DEFAULT 'INFO'One of: EVENT, ERROR, INFO, COMMAND
messagetextNOT NULLHuman-readable log message
payloadjsonNullableArbitrary structured context; cast to array by the model
created_attimestampNOT NULL, DEFAULT CURRENT_TIMESTAMPAppend time
The payload JSON column is automatically decoded to a PHP array when accessed via the DeviceLog Eloquent model, thanks to the 'payload' => 'array' cast. Store any structured diagnostic data (sensor snapshots, command parameters, error codes) here rather than serialising into message.

Relationships Diagram

The following Eloquent relationships are defined across the model layer:
  • User hasMany Device — a user can own many devices.
  • Device belongsTo User — each device has at most one owner (nullable).
  • Device hasMany DeviceProperty — a device can have many key-value properties.
  • DeviceProperty belongsTo Device.
  • Device hasMany SensorData — a device generates many sensor readings over time.
  • SensorData belongsTo Device.
  • Device hasMany DeviceLog — a device accumulates many log entries.
  • DeviceLog belongsTo Device.
  • SensorType hasMany SensorData — one measurement type (e.g. temp_amb) categorises many individual readings.
  • SensorData belongsTo SensorType.
Here is a concise summary of all relationships:
User
 └── hasMany ──► Device
                  ├── hasMany ──► DeviceProperty
                  ├── hasMany ──► SensorData ──► belongsTo ──► SensorType
                  └── hasMany ──► DeviceLog

Build docs developers (and LLMs) love