{
  "openapi": "3.0.3",
  "info": {
    "title": "Hydrobit API",
    "description": "Comprehensive API documentation for the Hydrobit platform.\n\nThis API enables management of forms, records, workers, projects, and related data within Hydrobit.\n\n## Authentication\n- **User endpoints:** Require a JWT in the `Authorization` header (Bearer token).\n\n## Features\n- Form management and record submission\n- Project and sector data retrieval\n- Worker management and operations\n- Production session and record management\n\n> **Note:** API access is available for Corporate accounts. For access or support, contact support@hydrobit.ag.\n",
    "version": "2.0.0",
    "contact": {
      "name": "Hydrobit Support",
      "url": "https://hydrobit.ag",
      "email": "support@hydrobit.ag"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://www.hydrobit.ag/terms-conditions"
    }
  },
  "servers": [
    {
      "url": "https://api.hydrobit.ag",
      "description": "Production server"
    },
    {
      "url": "https://iot.hydrobit.ag",
      "description": "IoT server"
    },
    {
      "url": "wss://iot.hydrobit.ag",
      "description": "MQTT over WebSocket endpoint"
    }
  ],
  "tags": [
    {
      "name": "Forms",
      "description": "Endpoints for form management and record submission"
    },
    {
      "name": "Mobile",
      "description": "Endpoints for mobile application (Expo) with custom domain authentication"
    },
    {
      "name": "Projects",
      "description": "Endpoints for project and sector data retrieval"
    },
    {
      "name": "Workers",
      "description": "Endpoints for worker management and operations"
    },
    {
      "name": "Production Sessions",
      "description": "Endpoints for managing production sessions (open, close, update)"
    },
    {
      "name": "Production Records",
      "description": "Endpoints for creating and managing production records"
    },
    {
      "name": "Phytosanitary",
      "description": "Endpoints for phytosanitary monitoring and analysis (pest/disease tracking)"
    },
    {
      "name": "Weather",
      "description": "Endpoints for weather and climate data retrieval"
    },
    {
      "name": "Plant",
      "description": "Endpoints for plant monitoring, growth, and health data"
    },
    {
      "name": "Irrigation",
      "description": "Endpoints for irrigation control, logs, and automation"
    },
    {
      "name": "IoT Endpoint",
      "description": "Endpoints for IoT devices, telemetry, and field data integration"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "JWT token for authentication"
      },
      "apiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Static or scoped API token for IoT data endpoints (weather, plant, irrigation)"
      },
      "iotToken": {
        "type": "apiKey",
        "in": "header",
        "name": "x-iot-token",
        "description": "Short-lived token for MQTT over WebSocket authentication"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "error"
          },
          "message": {
            "type": "string",
            "example": "Error message description"
          },
          "error": {
            "type": "string",
            "example": "Detailed error information"
          }
        }
      },
      "Form": {
        "type": "object",
        "properties": {
          "_id": {
            "type": "string",
            "description": "Form unique identifier",
            "example": "form_abc123"
          },
          "name": {
            "type": "string",
            "description": "Form name",
            "example": "Hydrobit Inspection"
          },
          "formKey": {
            "type": "string",
            "description": "Form key identifier",
            "example": "inspection_v1"
          },
          "type": {
            "type": "string",
            "description": "Form type",
            "example": "inspection"
          },
          "subtype": {
            "type": "string",
            "description": "Form subtype (e.g., monitoring, task)",
            "example": "monitoring"
          },
          "companyId": {
            "type": "string",
            "description": "Company identifier",
            "example": "comp_12345"
          },
          "status": {
            "type": "string",
            "description": "Form status (e.g., published)",
            "example": "published"
          },
          "elements": {
            "type": "array",
            "description": "Form field elements",
            "items": {
              "type": "object"
            }
          },
          "category": {
            "type": "string",
            "description": "Form category name",
            "example": "phytosanitary"
          },
          "categoryId": {
            "type": "string",
            "description": "Category identifier",
            "example": "cat_001"
          },
          "taskId": {
            "type": "string",
            "nullable": true,
            "description": "Associated task identifier",
            "example": null
          },
          "isTemporal": {
            "type": "boolean",
            "description": "Whether the form is temporary",
            "example": false
          }
        }
      },
      "Record": {
        "type": "object",
        "required": [
          "_id",
          "auth0Id",
          "type"
        ],
        "properties": {
          "_id": {
            "type": "string",
            "description": "Form ID (not the record ID)",
            "example": "form_abc123"
          },
          "auth0Id": {
            "type": "string",
            "description": "User identifier",
            "example": "user_123456789"
          },
          "type": {
            "type": "string",
            "description": "Record type",
            "example": "inspection"
          },
          "latitude": {
            "type": "number",
            "format": "double",
            "description": "GPS latitude",
            "example": 19.4326
          },
          "longitude": {
            "type": "number",
            "format": "double",
            "description": "GPS longitude",
            "example": -99.1332
          },
          "form_id": {
            "type": "string",
            "description": "Form identifier",
            "example": "form_abc123"
          },
          "form_values": {
            "type": "array",
            "description": "Array of form field values",
            "items": {
              "type": "object"
            }
          },
          "inicio": {
            "type": "string",
            "format": "date-time",
            "description": "Record start time",
            "example": "2025-10-09T10:00:00Z"
          },
          "segundos": {
            "type": "number",
            "description": "Time spent on record (in seconds)",
            "example": 120
          }
        }
      },
      "RecordResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "success"
          },
          "verification": {
            "type": "object",
            "properties": {
              "project": {
                "type": "boolean",
                "description": "Whether the location is verified within a project",
                "example": true
              },
              "sector": {
                "type": "boolean",
                "description": "Whether the location is verified within a sector",
                "example": true
              }
            }
          }
        }
      },
      "ProjectWithSectors": {
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string",
            "description": "Project unique identifier",
            "example": "proj_123"
          },
          "projectName": {
            "type": "string",
            "description": "Project name",
            "example": "Rancho San Pedro"
          },
          "sectors": {
            "type": "array",
            "description": "List of sectors in the project",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string",
                  "description": "Sector name",
                  "example": "Lote A-1"
                },
                "sectorId": {
                  "type": "string",
                  "description": "Sector unique identifier",
                  "example": "sector_001"
                }
              }
            }
          }
        }
      },
      "TimeRangeQuery": {
        "type": "object",
        "required": [
          "projectId",
          "from",
          "to",
          "timezone"
        ],
        "properties": {
          "projectId": {
            "type": "string",
            "description": "Project identifier",
            "example": "proj_123"
          },
          "from": {
            "type": "string",
            "format": "date-time",
            "description": "Start datetime in local timezone (ISO 8601)",
            "example": "2025-10-01T00:00:00-06:00"
          },
          "to": {
            "type": "string",
            "format": "date-time",
            "description": "End datetime in local timezone (ISO 8601)",
            "example": "2025-10-09T23:59:59-06:00"
          },
          "timezone": {
            "type": "string",
            "description": "IANA timezone for interpretation of local range",
            "example": "America/Mexico_City"
          }
        }
      },
      "Worker": {
        "type": "object",
        "properties": {
          "workerId": {
            "type": "string",
            "description": "Worker unique identifier",
            "example": "6507f1e3c9d8e2a4b1f9c3d5"
          },
          "worker_id": {
            "type": "string",
            "description": "Worker business ID (INITIALS + MMDD of hire date)",
            "example": "JS0315"
          },
          "first_name": {
            "type": "string",
            "description": "Worker first name",
            "example": "John"
          },
          "last_name": {
            "type": "string",
            "description": "Worker last name",
            "example": "Smith"
          },
          "phone": {
            "type": "string",
            "description": "Worker phone number",
            "example": "+1234567890"
          },
          "email": {
            "type": "string",
            "description": "Worker email address",
            "example": "john.smith@example.com"
          },
          "position": {
            "type": "string",
            "description": "Worker position",
            "example": "field_worker"
          },
          "employment_type": {
            "type": "string",
            "description": "Employment type",
            "example": "full_time"
          },
          "hire_date": {
            "type": "string",
            "format": "date",
            "description": "Hire date in YYYY-MM-DD format",
            "example": "2025-03-15"
          },
          "termination_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Termination date in YYYY-MM-DD format (null if still employed)",
            "example": null
          },
          "status": {
            "type": "string",
            "description": "Worker status",
            "example": "active"
          },
          "hourly_rate": {
            "type": "number",
            "description": "Hourly rate (if applicable)",
            "example": 18.5
          },
          "emergency_contact_name": {
            "type": "string",
            "description": "Emergency contact name",
            "example": "Jane Smith"
          },
          "emergency_contact_phone": {
            "type": "string",
            "description": "Emergency contact phone number",
            "example": "+1234567891"
          },
          "skills": {
            "type": "array",
            "description": "Worker skills",
            "items": {
              "type": "string"
            },
            "example": [
              "irrigation",
              "pruning"
            ]
          },
          "notes": {
            "type": "string",
            "description": "Additional notes about the worker",
            "example": "Experienced in avocado cultivation"
          },
          "photo": {
            "type": "string",
            "nullable": true,
            "description": "URL of worker photo",
            "example": "https://storage.example.com/photos/worker-photo.jpg"
          }
        }
      },
      "WorkerResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "success"
          },
          "data": {
            "type": "object",
            "properties": {
              "workerId": {
                "type": "string",
                "description": "Worker unique identifier",
                "example": "6507f1e3c9d8e2a4b1f9c3d5"
              },
              "worker_id": {
                "type": "string",
                "description": "Business worker ID",
                "example": "JS0315"
              },
              "photoUrl": {
                "type": "string",
                "nullable": true,
                "description": "URL of the uploaded photo (if photo was provided)",
                "example": "https://storage.example.com/photos/worker-photo.jpg"
              }
            }
          }
        }
      },
      "Bonus": {
        "type": "object",
        "required": [
          "type",
          "value"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "flat",
              "percent"
            ],
            "description": "Bonus type (flat amount or percentage)",
            "example": "percent"
          },
          "value": {
            "type": "number",
            "minimum": 0,
            "description": "Bonus value (0-100 for percent, any positive for flat)",
            "example": 10
          },
          "note": {
            "type": "string",
            "description": "Optional note about the bonus",
            "example": "High quality bonus"
          }
        }
      },
      "ProductionSession": {
        "type": "object",
        "properties": {
          "sessionId": {
            "type": "string",
            "description": "Session unique identifier",
            "example": "6507f1e3c9d8e2a4b1f9c3d5"
          },
          "companyId": {
            "type": "string",
            "description": "Company identifier",
            "example": "comp_12345"
          },
          "projectId": {
            "type": "string",
            "description": "Project identifier",
            "example": "proj_123"
          },
          "auth0Id": {
            "type": "string",
            "description": "User identifier who opened the session",
            "example": "user_123456789"
          },
          "sectorId": {
            "type": "string",
            "description": "Sector identifier",
            "example": "sector_001"
          },
          "sector_name": {
            "type": "string",
            "description": "Sector name",
            "example": "Lote A-1"
          },
          "timezone": {
            "type": "string",
            "description": "Project timezone",
            "example": "America/Mexico_City"
          },
          "day": {
            "type": "string",
            "format": "date-time",
            "description": "Session day (normalized to start of day in project timezone)",
            "example": "2025-10-19T00:00:00.000Z"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "closed"
            ],
            "description": "Session status",
            "example": "open"
          },
          "openedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when the session was opened (ISO 8601 UTC)",
            "example": "2025-10-19T08:00:00.000Z"
          },
          "closedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the session was closed (null if still open)",
            "example": null
          },
          "maxDurationHours": {
            "type": "integer",
            "minimum": 1,
            "maximum": 24,
            "description": "Maximum duration in hours",
            "example": 12
          },
          "samplingUnit": {
            "type": "string",
            "description": "Unit of measurement (e.g., box, kg, ton)",
            "example": "box"
          },
          "pricePerUnit": {
            "type": "number",
            "minimum": 0,
            "description": "Price per unit",
            "example": 5.5
          },
          "bonus": {
            "$ref": "#/components/schemas/Bonus"
          },
          "totals": {
            "type": "object",
            "properties": {
              "totalUnits": {
                "type": "number",
                "description": "Total units recorded in this session",
                "example": 150
              }
            }
          },
          "notes": {
            "type": "string",
            "maxLength": 500,
            "description": "Optional notes about the session",
            "example": "Good weather conditions"
          }
        }
      },
      "ProductionSessionResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "success"
          },
          "data": {
            "$ref": "#/components/schemas/ProductionSession"
          }
        }
      },
      "ProductionRecord": {
        "type": "object",
        "required": [
          "sessionId",
          "workerId",
          "worker_name",
          "recordedAtUtc",
          "clientEventId"
        ],
        "properties": {
          "sessionId": {
            "type": "string",
            "description": "Session identifier",
            "example": "6507f1e3c9d8e2a4b1f9c3d5"
          },
          "workerId": {
            "type": "string",
            "description": "Worker identifier",
            "example": "JS0315"
          },
          "worker_name": {
            "type": "string",
            "description": "Worker full name",
            "example": "John Smith"
          },
          "units": {
            "type": "number",
            "minimum": 0,
            "description": "Number of units to record (defaults to 1)",
            "example": 5
          },
          "recordedAtUtc": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when the record was created (ISO 8601 UTC)",
            "example": "2025-10-19T14:30:00.000Z"
          },
          "idempotencyKey": {
            "type": "string",
            "description": "Idempotency key for deduplication",
            "example": "mobile-app-key-timestamp-123456"
          },
          "clientEventId": {
            "type": "string",
            "description": "Unique client-side event identifier for idempotency",
            "example": "evt_1234567890abcdef"
          }
        }
      },
      "ProductionRecordResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "success"
          },
          "data": {
            "type": "object",
            "properties": {
              "payloadPreview": {
                "type": "object",
                "properties": {
                  "recordId": {
                    "type": "string",
                    "description": "Generated record identifier",
                    "example": "rec_1234567890abcdef"
                  },
                  "sessionId": {
                    "type": "string",
                    "example": "6507f1e3c9d8e2a4b1f9c3d5"
                  },
                  "workerId": {
                    "type": "string",
                    "example": "JS0315"
                  },
                  "units": {
                    "type": "number",
                    "example": 5
                  }
                }
              },
              "idempotent": {
                "type": "boolean",
                "description": "Whether this was an idempotent replay",
                "example": false
              }
            }
          }
        }
      },
      "WeatherPoint": {
        "type": "object",
        "properties": {
          "local_time": {
            "type": "string",
            "format": "date-time",
            "example": "2025-10-09T10:00:00-06:00"
          },
          "te": {
            "type": "number",
            "description": "Temperature (°C)",
            "example": 26.4
          },
          "hr": {
            "type": "number",
            "description": "Relative humidity (%)",
            "example": 60
          },
          "wind": {
            "type": "number",
            "description": "Wind speed (m/s)",
            "example": 3.2
          },
          "vpd": {
            "type": "number",
            "description": "Vapor Pressure Deficit (kPa)",
            "example": 1.2
          }
        }
      },
      "WeatherSeriesResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "success"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WeatherPoint"
            }
          }
        }
      },
      "PlantPoint": {
        "type": "object",
        "properties": {
          "local_time": {
            "type": "string",
            "format": "date-time",
            "example": "2025-10-09T10:00:00-06:00"
          },
          "vigor_index": {
            "type": "number",
            "description": "Vegetation vigor index (0-1)",
            "example": 0.78
          },
          "incidence": {
            "type": "number",
            "description": "Pest/disease incidence (%)",
            "example": 12.5
          },
          "severity": {
            "type": "number",
            "description": "Severity scale (0-1)",
            "example": 0.32
          }
        }
      },
      "PlantSeriesResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "success"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlantPoint"
            }
          }
        }
      },
      "IrrigationEvent": {
        "type": "object",
        "properties": {
          "start_local": {
            "type": "string",
            "format": "date-time",
            "example": "2025-10-09T07:15:00-06:00"
          },
          "end_local": {
            "type": "string",
            "format": "date-time",
            "example": "2025-10-09T08:00:00-06:00"
          },
          "duration_min": {
            "type": "number",
            "example": 45
          },
          "volume_l": {
            "type": "number",
            "example": 1200
          },
          "sectorId": {
            "type": "string",
            "example": "sector_001"
          }
        }
      },
      "IrrigationSeriesResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "success"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IrrigationEvent"
            }
          }
        }
      },
      "PhytosanitaryPestDisease": {
        "type": "object",
        "properties": {
          "pest_disease_name": {
            "type": "string",
            "description": "Name of the pest or disease",
            "example": "Aphids"
          },
          "incidence": {
            "type": "number",
            "description": "Percentage of affected plants (0-100)",
            "example": 15.5
          },
          "severity": {
            "type": "number",
            "description": "Severity level (0-100)",
            "example": 25
          }
        }
      },
      "PhytosanitarySector": {
        "type": "object",
        "properties": {
          "sector_name": {
            "type": "string",
            "description": "Sector name",
            "example": "Lote A-1"
          },
          "incidence": {
            "type": "number",
            "description": "Overall incidence for the sector (0-100)",
            "example": 12.3
          },
          "severity": {
            "type": "number",
            "description": "Overall severity for the sector (0-100)",
            "example": 18.5
          },
          "pests_diseases": {
            "type": "array",
            "description": "List of pests and diseases detected in this sector",
            "items": {
              "$ref": "#/components/schemas/PhytosanitaryPestDisease"
            }
          }
        }
      },
      "PhytosanitaryProject": {
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string",
            "nullable": true,
            "description": "Project identifier",
            "example": "proj_123"
          },
          "projectName": {
            "type": "string",
            "nullable": true,
            "description": "Project name",
            "example": "Rancho San Pedro"
          },
          "sectors": {
            "type": "array",
            "description": "List of sectors with phytosanitary data",
            "items": {
              "$ref": "#/components/schemas/PhytosanitarySector"
            }
          }
        }
      },
      "PhytosanitarySummaryResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "success"
          },
          "scope": {
            "type": "string",
            "enum": [
              "company",
              "project",
              "sector"
            ],
            "description": "Scope of the query (company, project, or sector)",
            "example": "project"
          },
          "range": {
            "type": "object",
            "properties": {
              "startTime": {
                "type": "string",
                "description": "Start date in YYYY-MM-DD format",
                "example": "2025-10-01"
              },
              "endTime": {
                "type": "string",
                "description": "End date in YYYY-MM-DD format",
                "example": "2025-10-09"
              }
            }
          },
          "projectTimezone": {
            "type": "string",
            "description": "Timezone used for the project",
            "example": "America/Mexico_City"
          },
          "filters": {
            "type": "object",
            "properties": {
              "companyId": {
                "type": "string",
                "nullable": true,
                "example": "comp_12345"
              },
              "projectId": {
                "type": "string",
                "nullable": true,
                "example": "proj_123"
              },
              "sectorId": {
                "type": "string",
                "nullable": true,
                "example": "sector_001"
              }
            }
          },
          "totalRecords": {
            "type": "integer",
            "description": "Total number of phytosanitary form records",
            "example": 42
          },
          "totalProjects": {
            "type": "integer",
            "description": "Total number of projects (only for company scope)",
            "example": 3
          },
          "totalSectors": {
            "type": "integer",
            "description": "Total number of sectors (for project/sector scope)",
            "example": 5
          },
          "projects": {
            "type": "array",
            "description": "Projects with nested sectors (only for company scope)",
            "items": {
              "$ref": "#/components/schemas/PhytosanitaryProject"
            }
          },
          "sectors": {
            "type": "array",
            "description": "Sectors with phytosanitary data (for project/sector scope)",
            "items": {
              "$ref": "#/components/schemas/PhytosanitarySector"
            }
          }
        }
      },
      "MqttConnectInfo": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "example": "wss://iot.hydrobit.ag/mqtt"
          },
          "deviceId": {
            "type": "string",
            "example": "bitRTU-01"
          },
          "topic": {
            "type": "string",
            "description": "MQTT topic to publish/subscribe",
            "example": "connect/comp_123/proj_123/bitRTU-01/#"
          },
          "protocol": {
            "type": "string",
            "example": "MQTT v3.1.1 over WebSocket"
          }
        }
      }
    }
  },
  "paths": {
    "/api/control/forms/getForms": {
      "get": {
        "tags": [
          "Forms"
        ],
        "summary": "Get forms for a user",
        "description": "Retrieves all forms accessible to a user based on their company context.\n\nRequires JWT token authentication in the Authorization header.\n\n- If `subtype=tasks`, returns all task forms for the user\n- Otherwise, returns monitoring forms based on user access permissions\n",
        "operationId": "getForms",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "auth0Id",
            "in": "query",
            "required": true,
            "description": "User identifier",
            "schema": {
              "type": "string"
            },
            "example": "user_123456789"
          },
          {
            "name": "companyId",
            "in": "query",
            "required": true,
            "description": "Company identifier",
            "schema": {
              "type": "string"
            },
            "example": "comp_12345"
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Form type filter",
            "schema": {
              "type": "string"
            },
            "example": "inspection"
          },
          {
            "name": "subtype",
            "in": "query",
            "required": false,
            "description": "Form subtype (e.g., 'tasks' for task forms)",
            "schema": {
              "type": "string"
            },
            "example": "tasks"
          }
        ],
        "responses": {
          "200": {
            "description": "Forms retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "success"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Form"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request - missing required parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - invalid or expired token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/control/mobile/forms/getForms": {
      "get": {
        "tags": [
          "Mobile"
        ],
        "summary": "Get forms for mobile app user",
        "description": "Retrieves all forms accessible to a mobile app user based on their company context.\n\n**Mobile Authentication**: Uses custom domain authentication (auth.hydrobit.ag) for Expo mobile app.\n\nRequires JWT token from mobile authentication in the Authorization header.\n\n- If `subtype=tasks`, returns all task forms for the user\n- Otherwise, returns monitoring forms based on user access permissions\n",
        "operationId": "getMobileForms",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "auth0Id",
            "in": "query",
            "required": true,
            "description": "User identifier",
            "schema": {
              "type": "string"
            },
            "example": "user_123456789"
          },
          {
            "name": "companyId",
            "in": "query",
            "required": true,
            "description": "Company identifier",
            "schema": {
              "type": "string"
            },
            "example": "comp_12345"
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Form type filter",
            "schema": {
              "type": "string"
            },
            "example": "inspection"
          },
          {
            "name": "subtype",
            "in": "query",
            "required": false,
            "description": "Form subtype (e.g., 'tasks' for task forms)",
            "schema": {
              "type": "string"
            },
            "example": "tasks"
          }
        ],
        "responses": {
          "200": {
            "description": "Forms retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "success"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Form"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request - missing required parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - invalid or expired token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/control/forms/record": {
      "post": {
        "tags": [
          "Forms"
        ],
        "summary": "Submit a form record",
        "description": "Submits a new form record with field values and location data.\n\nThis endpoint:\n- Validates the record data\n- Processes form field values\n- Determines location (project/sector) using GPS or forced location\n- Saves data to persistent storage\n- Uploads media files (photos, audio, signatures) to cloud storage\n- Updates task status if applicable\n",
        "operationId": "submitRecord",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "record"
                ],
                "properties": {
                  "record": {
                    "$ref": "#/components/schemas/Record"
                  }
                }
              },
              "examples": {
                "basicRecord": {
                  "summary": "Basic record submission",
                  "value": {
                    "record": {
                      "_id": "form_abc123",
                      "auth0Id": "user_123456789",
                      "type": "inspection",
                      "latitude": 19.4326,
                      "longitude": -99.1332,
                      "form_id": "form_abc123",
                      "form_values": [
                        {
                          "field_temp": "25"
                        },
                        {
                          "field_notes": "All looking good"
                        }
                      ],
                      "inicio": "2025-10-09T10:00:00Z",
                      "segundos": 120
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Record created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request - invalid record data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - invalid or expired token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/control/projects": {
      "get": {
        "tags": [
          "Projects"
        ],
        "summary": "Get projects with sectors",
        "description": "Retrieves all projects for the authenticated user's company with nested sector information.\n\nRequires JWT token authentication in the Authorization header.\n\nThis endpoint:\n- Automatically resolves the user's company context from their JWT token\n- Returns all projects associated with the company\n- For each project, includes nested sectors with only name and sectorId fields\n- Only returns projectId and projectName for each project\n",
        "operationId": "getProjects",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Projects retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "success"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ProjectWithSectors"
                      }
                    }
                  }
                },
                "examples": {
                  "successResponse": {
                    "summary": "Successful response with projects and sectors",
                    "value": {
                      "status": "success",
                      "data": [
                        {
                          "projectId": "proj_123",
                          "projectName": "Rancho San Pedro",
                          "sectors": [
                            {
                              "name": "Lote A-1",
                              "sectorId": "sector_001"
                            },
                            {
                              "name": "Lote A-2",
                              "sectorId": "sector_002"
                            }
                          ]
                        },
                        {
                          "projectId": "proj_456",
                          "projectName": "Finca Los Pinos",
                          "sectors": [
                            {
                              "name": "Bloque Norte",
                              "sectorId": "sector_003"
                            }
                          ]
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request - user does not have associated companyId",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "User does not have an associated companyId"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - invalid or expired token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "Token has expired or is invalid"
                }
              }
            }
          },
          "404": {
            "description": "User not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "User not found"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "Error fetching projects"
                }
              }
            }
          }
        }
      }
    },
    "/api/control/workers": {
      "post": {
        "tags": [
          "Workers"
        ],
        "summary": "Create a new worker",
        "description": "Creates a new worker record with automatic ID generation and optional photo upload.\n\nKey features:\n- Worker ID is auto-generated as INITIALS + MMDD (from hire date)\n- Requires JWT token authentication in the Authorization header\n- Company context is inferred from the authenticated user\n- Validates position, employment_type, and status against template options\n- Ensures worker_id uniqueness per company (idempotent on duplicate)\n- Supports photo upload via base64 data URL (JPEG, PNG, WebP up to 12MB)\n- Photos are uploaded to cloud storage and URL is returned in response\n",
        "operationId": "createWorker",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "auth0Id",
                  "first_name",
                  "last_name",
                  "hire_date",
                  "position",
                  "employment_type"
                ],
                "properties": {
                  "auth0Id": {
                    "type": "string",
                    "description": "User identifier (internal use, derived from JWT token)",
                    "example": "user_123456789"
                  },
                  "first_name": {
                    "type": "string",
                    "description": "Worker first name",
                    "example": "John"
                  },
                  "last_name": {
                    "type": "string",
                    "description": "Worker last name",
                    "example": "Smith"
                  },
                  "phone": {
                    "type": "string",
                    "description": "Worker phone number",
                    "example": "+1234567890"
                  },
                  "email": {
                    "type": "string",
                    "description": "Worker email address",
                    "example": "john.smith@example.com"
                  },
                  "position": {
                    "type": "string",
                    "description": "Worker position (must match template options)",
                    "example": "field_worker"
                  },
                  "employment_type": {
                    "type": "string",
                    "description": "Employment type (must match template options)",
                    "example": "full_time"
                  },
                  "hire_date": {
                    "type": "string",
                    "format": "date",
                    "description": "Hire date in YYYY-MM-DD format (used to generate worker_id)",
                    "example": "2025-03-15"
                  },
                  "termination_date": {
                    "type": "string",
                    "format": "date",
                    "nullable": true,
                    "description": "Termination date in YYYY-MM-DD format (optional)",
                    "example": null
                  },
                  "status": {
                    "type": "string",
                    "description": "Worker status (defaults to 'active')",
                    "example": "active"
                  },
                  "hourly_rate": {
                    "type": "number",
                    "description": "Hourly rate (must be >= 0)",
                    "example": 18.5
                  },
                  "emergency_contact_name": {
                    "type": "string",
                    "description": "Emergency contact name",
                    "example": "Jane Smith"
                  },
                  "emergency_contact_phone": {
                    "type": "string",
                    "description": "Emergency contact phone number",
                    "example": "+1234567891"
                  },
                  "skills": {
                    "type": "array",
                    "description": "Array of worker skills (filtered by template options)",
                    "items": {
                      "type": "string"
                    },
                    "example": [
                      "irrigation",
                      "pruning"
                    ]
                  },
                  "notes": {
                    "type": "string",
                    "description": "Additional notes about the worker",
                    "example": "Experienced in avocado cultivation"
                  },
                  "photo": {
                    "type": "string",
                    "description": "Worker photo in base64 data URL format (optional).\nSupported formats: JPEG, PNG, WebP.\nMaximum size: 12MB.\nFormat: data:image/jpeg;base64,/9j/4AAQ... or data:image/png;base64,iVBORw0KG...\n",
                    "example": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..."
                  }
                }
              },
              "examples": {
                "basicWorker": {
                  "summary": "Basic worker creation",
                  "value": {
                    "auth0Id": "user_123456789",
                    "first_name": "John",
                    "last_name": "Smith",
                    "hire_date": "2025-03-15",
                    "position": "field_worker",
                    "employment_type": "full_time"
                  }
                },
                "fullWorker": {
                  "summary": "Complete worker with all fields",
                  "value": {
                    "auth0Id": "user_123456789",
                    "first_name": "John",
                    "last_name": "Smith",
                    "phone": "+1234567890",
                    "email": "john.smith@example.com",
                    "position": "field_worker",
                    "employment_type": "full_time",
                    "hire_date": "2025-03-15",
                    "status": "active",
                    "hourly_rate": 18.5,
                    "emergency_contact_name": "Jane Smith",
                    "emergency_contact_phone": "+1234567891",
                    "skills": [
                      "irrigation",
                      "pruning"
                    ],
                    "notes": "Experienced in avocado cultivation"
                  }
                },
                "workerWithPhoto": {
                  "summary": "Worker with photo",
                  "value": {
                    "auth0Id": "user_123456789",
                    "first_name": "John",
                    "last_name": "Smith",
                    "hire_date": "2025-03-15",
                    "position": "field_worker",
                    "employment_type": "full_time",
                    "photo": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Worker already exists (idempotent response)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "exists"
                    },
                    "message": {
                      "type": "string",
                      "example": "worker already exists"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "workerId": {
                          "type": "string",
                          "example": "6507f1e3c9d8e2a4b1f9c3d5"
                        },
                        "worker_id": {
                          "type": "string",
                          "example": "JS0315"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "201": {
            "description": "Worker created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkerResponse"
                },
                "examples": {
                  "withoutPhoto": {
                    "summary": "Worker created without photo",
                    "value": {
                      "status": "success",
                      "data": {
                        "workerId": "6507f1e3c9d8e2a4b1f9c3d5",
                        "worker_id": "JS0315",
                        "photoUrl": null
                      }
                    }
                  },
                  "withPhoto": {
                    "summary": "Worker created with photo",
                    "value": {
                      "status": "success",
                      "data": {
                        "workerId": "6507f1e3c9d8e2a4b1f9c3d5",
                        "worker_id": "JS0315",
                        "photoUrl": "https://storage.example.com/photos/worker-photo.jpg"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request - validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "missingAuth0Id": {
                    "summary": "Missing user identifier",
                    "value": {
                      "status": "error",
                      "message": "auth0Id is required at top-level body"
                    }
                  },
                  "missingRequiredFields": {
                    "summary": "Missing required fields",
                    "value": {
                      "status": "error",
                      "message": "first_name, last_name, hire_date, position, employment_type are required"
                    }
                  },
                  "invalidHireDate": {
                    "summary": "Invalid hire date format",
                    "value": {
                      "status": "error",
                      "message": "Invalid hire_date format (expected YYYY-MM-DD)"
                    }
                  },
                  "invalidPosition": {
                    "summary": "Invalid position value",
                    "value": {
                      "status": "error",
                      "message": "position must be one of: field_worker, supervisor, technician"
                    }
                  },
                  "invalidHourlyRate": {
                    "summary": "Invalid hourly rate",
                    "value": {
                      "status": "error",
                      "message": "hourly_rate must be a number >= 0"
                    }
                  },
                  "invalidPhotoFormat": {
                    "summary": "Invalid photo format",
                    "value": {
                      "status": "error",
                      "message": "invalid data URL format (expect data:image/jpeg|png|webp;base64,...)"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - user not found or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "User not found"
                }
              }
            }
          },
          "404": {
            "description": "Workers database not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "Workers database not found"
                }
              }
            }
          },
          "413": {
            "description": "Photo too large",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "photo too large (max 12MB)"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "Error creating worker",
                  "error": "Detailed error message"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Workers"
        ],
        "summary": "Get list of workers",
        "description": "Retrieves a paginated list of workers for the authenticated user's company.\n\nFeatures:\n- Requires JWT token authentication in the Authorization header\n- Company context is inferred from the authenticated user\n- Supports search by name or worker_id using the 'q' parameter\n- Filter by status, position, or employment_type\n- Pagination with customizable page size (default 25, max 100)\n- Results sorted by creation date (newest first)\n",
        "operationId": "listWorkers",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "auth0Id",
            "in": "query",
            "required": true,
            "description": "User identifier (internal use, can be derived from JWT token)",
            "schema": {
              "type": "string"
            },
            "example": "user_123456789"
          },
          {
            "name": "companyId",
            "in": "query",
            "required": false,
            "description": "Company identifier (must match user's company, otherwise forbidden)",
            "schema": {
              "type": "string"
            },
            "example": "comp_12345"
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Search query (searches in first_name, last_name, and worker_id)",
            "schema": {
              "type": "string"
            },
            "example": "John"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by worker status",
            "schema": {
              "type": "string"
            },
            "example": "active"
          },
          {
            "name": "position",
            "in": "query",
            "required": false,
            "description": "Filter by worker position",
            "schema": {
              "type": "string"
            },
            "example": "field_worker"
          },
          {
            "name": "employment_type",
            "in": "query",
            "required": false,
            "description": "Filter by employment type",
            "schema": {
              "type": "string"
            },
            "example": "full_time"
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number (default 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "example": 1
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Number of items per page (default 25, max 100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "example": 25
          }
        ],
        "responses": {
          "200": {
            "description": "Workers retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "success"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "total": {
                          "type": "integer",
                          "description": "Total number of workers matching the query",
                          "example": 42
                        },
                        "page": {
                          "type": "integer",
                          "description": "Current page number",
                          "example": 1
                        },
                        "pageSize": {
                          "type": "integer",
                          "description": "Number of items per page",
                          "example": 25
                        },
                        "items": {
                          "type": "array",
                          "items": {
                            "allOf": [
                              {
                                "$ref": "#/components/schemas/Worker"
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "_id": {
                                    "type": "string",
                                    "description": "unique identifier",
                                    "example": "6507f1e3c9d8e2a4b1f9c3d5"
                                  },
                                  "name": {
                                    "type": "string",
                                    "description": "Full name (first + last)",
                                    "example": "John Smith"
                                  },
                                  "companyId": {
                                    "type": "string",
                                    "example": "comp_12345"
                                  },
                                  "companyName": {
                                    "type": "string",
                                    "example": "Hydrobit Client SA"
                                  },
                                  "createdAt": {
                                    "type": "string",
                                    "format": "date-time",
                                    "example": "2025-03-15T10:30:00.000Z"
                                  },
                                  "updatedAt": {
                                    "type": "string",
                                    "format": "date-time",
                                    "example": "2025-03-15T10:30:00.000Z"
                                  }
                                }
                              }
                            ]
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "successResponse": {
                    "summary": "Successful response with workers",
                    "value": {
                      "status": "success",
                      "data": {
                        "total": 42,
                        "page": 1,
                        "pageSize": 25,
                        "items": [
                          {
                            "_id": "6507f1e3c9d8e2a4b1f9c3d5",
                            "worker_id": "JS0315",
                            "first_name": "John",
                            "last_name": "Smith",
                            "name": "John Smith",
                            "phone": "+1234567890",
                            "email": "john.smith@example.com",
                            "position": "field_worker",
                            "employment_type": "full_time",
                            "hire_date": "2025-03-15",
                            "termination_date": null,
                            "status": "active",
                            "hourly_rate": 18.5,
                            "emergency_contact_name": "Jane Smith",
                            "emergency_contact_phone": "+1234567891",
                            "skills": [
                              "irrigation",
                              "pruning"
                            ],
                            "notes": "Experienced in avocado cultivation",
                            "photo": "https://storage.example.com/photos/worker-photo.jpg",
                            "companyId": "comp_12345",
                            "companyName": "Hydrobit Client SA",
                            "createdAt": "2025-03-15T10:30:00.000Z",
                            "updatedAt": "2025-03-15T10:30:00.000Z"
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request - missing user identifier or user has no company context",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "missingAuth0Id": {
                    "summary": "Missing user identifier parameter",
                    "value": {
                      "status": "error",
                      "message": "auth0Id is required as query param"
                    }
                  },
                  "noCompanyContext": {
                    "summary": "User has no company context",
                    "value": {
                      "status": "error",
                      "message": "User has no company context"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - user not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "User not found"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - companyId does not match user's company",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "Forbidden: companyId does not match user context"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "Error fetching workers",
                  "error": "Detailed error message"
                }
              }
            }
          }
        }
      }
    },
    "/api/control/workers/{worker}": {
      "get": {
        "tags": [
          "Workers"
        ],
        "summary": "Get a single worker",
        "description": "Retrieves detailed information about a specific worker by unique identifier or worker_id.\n\nFeatures:\n- Requires JWT token authentication in the Authorization header\n- Company context is inferred from the authenticated user\n- Can fetch by unique identifier or by worker_id (e.g., \"JS0315\")\n- Returns full worker details including all fields\n",
        "operationId": "getWorker",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "worker",
            "in": "path",
            "required": true,
            "description": "Worker identifier (unique id or worker_id like \"JS0315\")",
            "schema": {
              "type": "string"
            },
            "examples": {
              "byUniqueId": {
                "summary": "By unique identifier",
                "value": "6507f1e3c9d8e2a4b1f9c3d5"
              },
              "byWorkerId": {
                "summary": "By business worker id",
                "value": "JS0315"
              }
            }
          },
          {
            "name": "auth0Id",
            "in": "query",
            "required": true,
            "description": "User identifier (internal use, can be derived from JWT token)",
            "schema": {
              "type": "string"
            },
            "example": "user_123456789"
          }
        ],
        "responses": {
          "200": {
            "description": "Worker retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "success"
                    },
                    "data": {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Worker"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "unique identifier",
                              "example": "6507f1e3c9d8e2a4b1f9c3d5"
                            },
                            "name": {
                              "type": "string",
                              "description": "Full name (first + last)",
                              "example": "John Smith"
                            },
                            "companyId": {
                              "type": "string",
                              "example": "comp_12345"
                            },
                            "companyName": {
                              "type": "string",
                              "example": "Hydrobit Client SA"
                            },
                            "createdAt": {
                              "type": "string",
                              "format": "date-time",
                              "example": "2025-03-15T10:30:00.000Z"
                            },
                            "updatedAt": {
                              "type": "string",
                              "format": "date-time",
                              "example": "2025-03-15T10:30:00.000Z"
                            }
                          }
                        }
                      ]
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "_id": "6507f1e3c9d8e2a4b1f9c3d5",
                    "worker_id": "JS0315",
                    "first_name": "John",
                    "last_name": "Smith",
                    "name": "John Smith",
                    "phone": "+1234567890",
                    "email": "john.smith@example.com",
                    "position": "field_worker",
                    "employment_type": "full_time",
                    "hire_date": "2025-03-15",
                    "termination_date": null,
                    "status": "active",
                    "hourly_rate": 18.5,
                    "emergency_contact_name": "Jane Smith",
                    "emergency_contact_phone": "+1234567891",
                    "skills": [
                      "irrigation",
                      "pruning"
                    ],
                    "notes": "Experienced in avocado cultivation",
                    "photo": "https://storage.example.com/photos/worker-photo.jpg",
                    "companyId": "comp_12345",
                    "companyName": "Hydrobit Client SA",
                    "createdAt": "2025-03-15T10:30:00.000Z",
                    "updatedAt": "2025-03-15T10:30:00.000Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request - missing user identifier or user has no company context",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "missingAuth0Id": {
                    "summary": "Missing user identifier parameter",
                    "value": {
                      "status": "error",
                      "message": "auth0Id is required as query param"
                    }
                  },
                  "noCompanyContext": {
                    "summary": "User has no company context",
                    "value": {
                      "status": "error",
                      "message": "User has no company context"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - user not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "User not found"
                }
              }
            }
          },
          "404": {
            "description": "Worker not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "Worker not found"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "Error fetching worker",
                  "error": "Detailed error message"
                }
              }
            }
          }
        }
      }
    },
    "/api/control/phytosanitary/summary": {
      "get": {
        "tags": [
          "Phytosanitary"
        ],
        "summary": "Get phytosanitary monitoring summary",
        "description": "Retrieves aggregated phytosanitary data (pest and disease incidence/severity) for a specified time range.\n\nRequires API token authentication with `read:phytosanitary` scope via the `x-api-key` header.\n\nKey features:\n- Aggregates data from phytosanitary form records\n- Supports filtering by company, project, or sector\n- Returns incidence and severity metrics per sector\n- Maximum range: 180 days\n- Dates must be in YYYY-MM-DD format (local time, no timezone suffix)\n- Timezone is automatically resolved from the project settings\n",
        "operationId": "getPhytosanitarySummary",
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "companyId",
            "in": "query",
            "required": false,
            "description": "Company identifier (at least one of companyId, projectId, or sectorId is required)",
            "schema": {
              "type": "string"
            },
            "example": "comp_12345"
          },
          {
            "name": "projectId",
            "in": "query",
            "required": false,
            "description": "Project identifier (at least one of companyId, projectId, or sectorId is required)",
            "schema": {
              "type": "string"
            },
            "example": "proj_123"
          },
          {
            "name": "sectorId",
            "in": "query",
            "required": false,
            "description": "Sector identifier (at least one of companyId, projectId, or sectorId is required)",
            "schema": {
              "type": "string"
            },
            "example": "sector_001"
          },
          {
            "name": "startTime",
            "in": "query",
            "required": true,
            "description": "Start date in YYYY-MM-DD format (local time, no timezone suffix)",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            },
            "example": "2025-10-01"
          },
          {
            "name": "endTime",
            "in": "query",
            "required": true,
            "description": "End date in YYYY-MM-DD format (local time, no timezone suffix)",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            },
            "example": "2025-10-09"
          }
        ],
        "responses": {
          "200": {
            "description": "Phytosanitary summary retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhytosanitarySummaryResponse"
                },
                "examples": {
                  "sectorScope": {
                    "summary": "Summary for a single sector",
                    "value": {
                      "status": "success",
                      "scope": "sector",
                      "range": {
                        "startTime": "2025-10-01",
                        "endTime": "2025-10-09"
                      },
                      "projectTimezone": "America/Mexico_City",
                      "filters": {
                        "companyId": null,
                        "projectId": null,
                        "sectorId": "sector_001"
                      },
                      "totalRecords": 12,
                      "totalSectors": 1,
                      "sectors": [
                        {
                          "sector_name": "Lote A-1",
                          "incidence": 12.5,
                          "severity": 18.3,
                          "pests_diseases": [
                            {
                              "pest_disease_name": "Aphids",
                              "incidence": 15.5,
                              "severity": 25
                            },
                            {
                              "pest_disease_name": "Powdery mildew",
                              "incidence": 8.2,
                              "severity": 12.5
                            }
                          ]
                        }
                      ]
                    }
                  },
                  "projectScope": {
                    "summary": "Summary for a project with multiple sectors",
                    "value": {
                      "status": "success",
                      "scope": "project",
                      "range": {
                        "startTime": "2025-10-01",
                        "endTime": "2025-10-09"
                      },
                      "projectTimezone": "America/Mexico_City",
                      "filters": {
                        "companyId": null,
                        "projectId": "proj_123",
                        "sectorId": null
                      },
                      "totalRecords": 42,
                      "totalSectors": 3,
                      "sectors": [
                        {
                          "sector_name": "Lote A-1",
                          "incidence": 12.5,
                          "severity": 18.3,
                          "pests_diseases": [
                            {
                              "pest_disease_name": "Aphids",
                              "incidence": 15.5,
                              "severity": 25
                            }
                          ]
                        },
                        {
                          "sector_name": "Lote A-2",
                          "incidence": 8,
                          "severity": 10.5,
                          "pests_diseases": [
                            {
                              "pest_disease_name": "Spider mites",
                              "incidence": 10,
                              "severity": 15
                            }
                          ]
                        }
                      ]
                    }
                  },
                  "companyScope": {
                    "summary": "Summary for a company with nested projects",
                    "value": {
                      "status": "success",
                      "scope": "company",
                      "range": {
                        "startTime": "2025-10-01",
                        "endTime": "2025-10-09"
                      },
                      "projectTimezone": "America/Monterrey",
                      "filters": {
                        "companyId": "comp_12345",
                        "projectId": null,
                        "sectorId": null
                      },
                      "totalRecords": 150,
                      "totalProjects": 2,
                      "projects": [
                        {
                          "projectId": "proj_123",
                          "projectName": "Rancho San Pedro",
                          "sectors": [
                            {
                              "sector_name": "Lote A-1",
                              "incidence": 12.5,
                              "severity": 18.3,
                              "pests_diseases": [
                                {
                                  "pest_disease_name": "Aphids",
                                  "incidence": 15.5,
                                  "severity": 25
                                }
                              ]
                            }
                          ]
                        },
                        {
                          "projectId": "proj_456",
                          "projectName": "Finca Los Pinos",
                          "sectors": [
                            {
                              "sector_name": "Bloque Norte",
                              "incidence": 5.2,
                              "severity": 8,
                              "pests_diseases": [
                                {
                                  "pest_disease_name": "Whiteflies",
                                  "incidence": 7,
                                  "severity": 10
                                }
                              ]
                            }
                          ]
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request - missing or invalid parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "missingDates": {
                    "summary": "Missing required date parameters",
                    "value": {
                      "error": "Faltan parámetros: startTime, endTime."
                    }
                  },
                  "missingScope": {
                    "summary": "Missing scope identifier",
                    "value": {
                      "error": "Debes proporcionar al menos uno de: companyId, projectId o sectorId."
                    }
                  },
                  "invalidDateFormat": {
                    "summary": "Invalid date format",
                    "value": {
                      "error": "startTime y endTime deben ser YYYY-MM-DD (sin Z)."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - invalid or missing API token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Invalid API token"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - insufficient scopes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Insufficient scopes. Required: read:phytosanitary"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable entity - invalid date range",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalidRange": {
                    "summary": "End date before start date",
                    "value": {
                      "error": "endTime no puede ser menor que startTime."
                    }
                  },
                  "rangeTooLarge": {
                    "summary": "Date range exceeds maximum",
                    "value": {
                      "error": "Rango máximo 180 días."
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Internal server error"
                }
              }
            }
          }
        }
      }
    },
    "/api/control/phytosanitary/company-summary": {
      "get": {
        "tags": [
          "Phytosanitary"
        ],
        "summary": "Get phytosanitary summary for entire company",
        "description": "Retrieves aggregated phytosanitary data (pest and disease incidence/severity) for all projects and sectors belonging to the authenticated company within a specified time range.\n\nRequires API token authentication with `read:phytosanitary` scope via the `x-api-key` header.\n\nKey features:\n- Automatically uses companyId from the authenticated API token\n- Aggregates data from all projects and sectors belonging to the company\n- Returns incidence and severity metrics grouped by project and sector\n- Maximum range: 180 days\n- Dates must be in YYYY-MM-DD format (local time, no timezone suffix)\n- Timezone is automatically resolved from the company's projects\n- No need to specify companyId, projectId, or sectorId manually\n",
        "operationId": "getPhytosanitaryCompanySummary",
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "startTime",
            "in": "query",
            "required": true,
            "description": "Start date in YYYY-MM-DD format (local time, no timezone suffix)",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            },
            "example": "2025-10-01"
          },
          {
            "name": "endTime",
            "in": "query",
            "required": true,
            "description": "End date in YYYY-MM-DD format (local time, no timezone suffix)",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            },
            "example": "2025-10-09"
          }
        ],
        "responses": {
          "200": {
            "description": "Company phytosanitary summary retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ],
                      "example": "success"
                    },
                    "scope": {
                      "type": "string",
                      "enum": [
                        "company"
                      ],
                      "example": "company"
                    },
                    "range": {
                      "type": "object",
                      "properties": {
                        "startTime": {
                          "type": "string",
                          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                          "example": "2025-10-01"
                        },
                        "endTime": {
                          "type": "string",
                          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                          "example": "2025-10-09"
                        }
                      }
                    },
                    "companyTimezone": {
                      "type": "string",
                      "description": "Timezone resolved from company's projects",
                      "example": "America/Monterrey"
                    },
                    "companyId": {
                      "type": "string",
                      "description": "Company identifier from authenticated token",
                      "example": "comp_12345"
                    },
                    "totalRecords": {
                      "type": "integer",
                      "description": "Total number of phytosanitary records found",
                      "example": 150
                    },
                    "totalProjects": {
                      "type": "integer",
                      "description": "Total number of projects with data",
                      "example": 2
                    },
                    "projects": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "projectId": {
                            "type": "string",
                            "example": "proj_123"
                          },
                          "projectName": {
                            "type": "string",
                            "example": "Rancho San Pedro"
                          },
                          "sectors": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "sector_name": {
                                  "type": "string",
                                  "example": "Lote A-1"
                                },
                                "incidence": {
                                  "type": "number",
                                  "format": "float",
                                  "example": 12.5
                                },
                                "severity": {
                                  "type": "number",
                                  "format": "float",
                                  "example": 18.3
                                },
                                "pests_diseases": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "pest_disease_name": {
                                        "type": "string",
                                        "example": "Aphids"
                                      },
                                      "incidence": {
                                        "type": "number",
                                        "format": "float",
                                        "example": 15.5
                                      },
                                      "severity": {
                                        "type": "number",
                                        "format": "float",
                                        "example": 25
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "scope": "company",
                  "range": {
                    "startTime": "2025-10-01",
                    "endTime": "2025-10-09"
                  },
                  "companyTimezone": "America/Monterrey",
                  "companyId": "comp_12345",
                  "totalRecords": 150,
                  "totalProjects": 2,
                  "projects": [
                    {
                      "projectId": "proj_123",
                      "projectName": "Rancho San Pedro",
                      "sectors": [
                        {
                          "sector_name": "Lote A-1",
                          "incidence": 12.5,
                          "severity": 18.3,
                          "pests_diseases": [
                            {
                              "pest_disease_name": "Aphids",
                              "incidence": 15.5,
                              "severity": 25
                            }
                          ]
                        },
                        {
                          "sector_name": "Lote A-2",
                          "incidence": 8,
                          "severity": 10.5,
                          "pests_diseases": [
                            {
                              "pest_disease_name": "Spider mites",
                              "incidence": 10,
                              "severity": 15
                            }
                          ]
                        }
                      ]
                    },
                    {
                      "projectId": "proj_456",
                      "projectName": "Finca Los Pinos",
                      "sectors": [
                        {
                          "sector_name": "Bloque Norte",
                          "incidence": 5.2,
                          "severity": 8,
                          "pests_diseases": [
                            {
                              "pest_disease_name": "Whiteflies",
                              "incidence": 7,
                              "severity": 10
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad request - missing or invalid parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "missingDates": {
                    "summary": "Missing required date parameters",
                    "value": {
                      "error": "Faltan parámetros: startTime, endTime."
                    }
                  },
                  "invalidDateFormat": {
                    "summary": "Invalid date format",
                    "value": {
                      "error": "startTime y endTime deben ser YYYY-MM-DD (sin Z)."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - invalid or missing API token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalidToken": {
                    "summary": "Invalid or missing API token",
                    "value": {
                      "error": "Invalid API token"
                    }
                  },
                  "missingCompanyInfo": {
                    "summary": "Missing company information in token",
                    "value": {
                      "error": "Missing company information in authentication token."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - insufficient scopes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Insufficient scopes. Required: read:phytosanitary"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable entity - invalid date range",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalidRange": {
                    "summary": "End date before start date",
                    "value": {
                      "error": "endTime no puede ser menor que startTime."
                    }
                  },
                  "rangeTooLarge": {
                    "summary": "Date range exceeds maximum",
                    "value": {
                      "error": "Rango máximo 180 días."
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Internal server error"
                }
              }
            }
          }
        }
      }
    },
    "/api/control/phytosanitary/company-records": {
      "get": {
        "tags": [
          "Phytosanitary"
        ],
        "summary": "Get all phytosanitary records for the company",
        "description": "Retrieves all individual phytosanitary monitoring records for the authenticated company within a specified time range.\n\nUnlike `/company-summary` which returns aggregated incidence/severity metrics, this endpoint returns the raw records with full detail: dates, user information, location, and each pest/disease response.\n\nRequires API token authentication with `read:phytosanitary` scope via the `x-api-key` header.\n\nKey features:\n- Automatically uses companyId from the authenticated API token\n- Returns individual records (not aggregated)\n- Each record includes: dates, user id/name, project, sector, crop, coordinates\n- Each record includes its pest/disease responses with value and severity\n- Maximum range: 180 days\n- Dates must be in YYYY-MM-DD format (local time, no timezone suffix)\n",
        "operationId": "getPhytosanitaryCompanyRecords",
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "startTime",
            "in": "query",
            "required": true,
            "description": "Start date in YYYY-MM-DD format (local time, no timezone suffix)",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            },
            "example": "2025-10-01"
          },
          {
            "name": "endTime",
            "in": "query",
            "required": true,
            "description": "End date in YYYY-MM-DD format (local time, no timezone suffix)",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            },
            "example": "2025-10-09"
          }
        ],
        "responses": {
          "200": {
            "description": "Company phytosanitary records retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ],
                      "example": "success"
                    },
                    "range": {
                      "type": "object",
                      "properties": {
                        "startTime": {
                          "type": "string",
                          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                          "example": "2025-10-01"
                        },
                        "endTime": {
                          "type": "string",
                          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                          "example": "2025-10-09"
                        }
                      }
                    },
                    "companyTimezone": {
                      "type": "string",
                      "description": "Timezone resolved from company's projects",
                      "example": "America/Monterrey"
                    },
                    "companyId": {
                      "type": "string",
                      "description": "Company identifier from authenticated token",
                      "example": "comp_12345"
                    },
                    "totalRecords": {
                      "type": "integer",
                      "description": "Total number of phytosanitary records found",
                      "example": 3
                    },
                    "records": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "record_id": {
                            "type": "string",
                            "description": "Unique identifier of the record",
                            "example": "rec_abc123"
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time",
                            "description": "Timestamp when the record was created (UTC)",
                            "example": "2025-10-05T14:30:00.000Z"
                          },
                          "record_time": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true,
                            "description": "Timestamp of the actual field observation (UTC)",
                            "example": "2025-10-05T14:25:00.000Z"
                          },
                          "user_id": {
                            "type": "string",
                            "description": "Unique identifier of the user who created the record",
                            "example": "user_789"
                          },
                          "user_name": {
                            "type": "string",
                            "description": "Full name of the user who created the record",
                            "example": "Juan Pérez"
                          },
                          "projectId": {
                            "type": "string",
                            "nullable": true,
                            "description": "Project identifier",
                            "example": "proj_123"
                          },
                          "project_name": {
                            "type": "string",
                            "nullable": true,
                            "description": "Project name",
                            "example": "Rancho San Pedro"
                          },
                          "sectorId": {
                            "type": "string",
                            "nullable": true,
                            "description": "Sector identifier",
                            "example": "sec_456"
                          },
                          "sector_name": {
                            "type": "string",
                            "nullable": true,
                            "description": "Sector name",
                            "example": "Lote A-1"
                          },
                          "crop": {
                            "type": "string",
                            "nullable": true,
                            "description": "Crop type",
                            "example": "Tomato"
                          },
                          "variety": {
                            "type": "string",
                            "nullable": true,
                            "description": "Crop variety",
                            "example": "Saladette"
                          },
                          "latitude": {
                            "type": "number",
                            "format": "float",
                            "nullable": true,
                            "description": "GPS latitude of the observation",
                            "example": 25.6866
                          },
                          "longitude": {
                            "type": "number",
                            "format": "float",
                            "nullable": true,
                            "description": "GPS longitude of the observation",
                            "example": -100.3161
                          },
                          "responses": {
                            "type": "array",
                            "description": "Pest and disease observations for this record",
                            "items": {
                              "type": "object",
                              "properties": {
                                "response_id": {
                                  "type": "string",
                                  "description": "Unique identifier of the response",
                                  "example": "resp_001"
                                },
                                "variable_name": {
                                  "type": "string",
                                  "description": "Internal variable name",
                                  "example": "aphids_count"
                                },
                                "variable_type": {
                                  "type": "string",
                                  "enum": [
                                    "pests",
                                    "diseases"
                                  ],
                                  "description": "Type of variable (pest or disease)",
                                  "example": "pests"
                                },
                                "name": {
                                  "type": "string",
                                  "description": "Display name of the pest or disease",
                                  "example": "Aphids"
                                },
                                "value_number": {
                                  "type": "number",
                                  "nullable": true,
                                  "description": "Observed count or value",
                                  "example": 5
                                },
                                "severity": {
                                  "type": "number",
                                  "nullable": true,
                                  "description": "Severity level of the observation",
                                  "example": 2.5
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "range": {
                    "startTime": "2025-10-01",
                    "endTime": "2025-10-09"
                  },
                  "companyTimezone": "America/Monterrey",
                  "companyId": "comp_12345",
                  "totalRecords": 3,
                  "records": [
                    {
                      "record_id": "rec_abc123",
                      "created_at": "2025-10-05T14:30:00.000Z",
                      "record_time": "2025-10-05T14:25:00.000Z",
                      "user_id": "user_789",
                      "user_name": "Juan Pérez",
                      "projectId": "proj_123",
                      "project_name": "Rancho San Pedro",
                      "sectorId": "sec_456",
                      "sector_name": "Lote A-1",
                      "crop": "Tomato",
                      "variety": "Saladette",
                      "latitude": 25.6866,
                      "longitude": -100.3161,
                      "responses": [
                        {
                          "response_id": "resp_001",
                          "variable_name": "aphids_count",
                          "variable_type": "pests",
                          "name": "Aphids",
                          "value_number": 5,
                          "severity": 2.5
                        },
                        {
                          "response_id": "resp_002",
                          "variable_name": "powdery_mildew",
                          "variable_type": "diseases",
                          "name": "Powdery Mildew",
                          "value_number": 3,
                          "severity": 1.8
                        }
                      ]
                    },
                    {
                      "record_id": "rec_def456",
                      "created_at": "2025-10-06T09:15:00.000Z",
                      "record_time": "2025-10-06T09:10:00.000Z",
                      "user_id": "user_321",
                      "user_name": "María López",
                      "projectId": "proj_123",
                      "project_name": "Rancho San Pedro",
                      "sectorId": "sec_789",
                      "sector_name": "Lote A-2",
                      "crop": "Tomato",
                      "variety": "Saladette",
                      "latitude": 25.687,
                      "longitude": -100.3165,
                      "responses": [
                        {
                          "response_id": "resp_003",
                          "variable_name": "spider_mites",
                          "variable_type": "pests",
                          "name": "Spider Mites",
                          "value_number": 8,
                          "severity": 3
                        }
                      ]
                    },
                    {
                      "record_id": "rec_ghi789",
                      "created_at": "2025-10-07T11:45:00.000Z",
                      "record_time": "2025-10-07T11:40:00.000Z",
                      "user_id": "user_789",
                      "user_name": "Juan Pérez",
                      "projectId": "proj_456",
                      "project_name": "Finca Los Pinos",
                      "sectorId": "sec_012",
                      "sector_name": "Bloque Norte",
                      "crop": "Pepper",
                      "variety": "Jalapeño",
                      "latitude": 25.71,
                      "longitude": -100.32,
                      "responses": [
                        {
                          "response_id": "resp_004",
                          "variable_name": "whiteflies_count",
                          "variable_type": "pests",
                          "name": "Whiteflies",
                          "value_number": 12,
                          "severity": 4
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad request - missing or invalid parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "missingDates": {
                    "summary": "Missing required date parameters",
                    "value": {
                      "error": "Faltan parámetros: startTime, endTime."
                    }
                  },
                  "invalidDateFormat": {
                    "summary": "Invalid date format",
                    "value": {
                      "error": "startTime y endTime deben ser YYYY-MM-DD (sin Z)."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - invalid or missing API token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalidToken": {
                    "summary": "Invalid or missing API token",
                    "value": {
                      "error": "Invalid API token"
                    }
                  },
                  "missingCompanyInfo": {
                    "summary": "Missing company information in token",
                    "value": {
                      "error": "Missing company information in authentication token."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - insufficient scopes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Insufficient scopes. Required: read:phytosanitary"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable entity - invalid date range",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalidRange": {
                    "summary": "End date before start date",
                    "value": {
                      "error": "endTime no puede ser menor que startTime."
                    }
                  },
                  "rangeTooLarge": {
                    "summary": "Date range exceeds maximum",
                    "value": {
                      "error": "Rango máximo 180 días."
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Internal server error"
                }
              }
            }
          }
        }
      }
    },
    "/api/control/production/sessions": {
      "post": {
        "tags": [
          "Production Sessions"
        ],
        "summary": "Create a new production session",
        "description": "Opens a new production session for a specific project, sector, and day.\n\nRequires JWT token authentication in the Authorization header.\n\nKey features:\n- Automatically resolves company context from authenticated user\n- Resolves project timezone for day normalization\n- Ensures uniqueness: only one open session per (company, project, day, sector)\n- Supports custom pricing, bonuses, and duration settings\n- Defaults are inherited from project configuration if not provided\n",
        "operationId": "createProductionSession",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "auth0Id",
                  "projectId",
                  "openedAt",
                  "sectorId",
                  "sector_name"
                ],
                "properties": {
                  "auth0Id": {
                    "type": "string",
                    "description": "User identifier (internal use, derived from JWT token)",
                    "example": "user_123456789"
                  },
                  "projectId": {
                    "type": "string",
                    "description": "Project identifier",
                    "example": "proj_123"
                  },
                  "openedAt": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Session opening timestamp in ISO 8601 UTC format (will be normalized to project timezone for day calculation)",
                    "example": "2025-10-19T08:00:00.000Z"
                  },
                  "sectorId": {
                    "type": "string",
                    "description": "Sector identifier",
                    "example": "sector_001"
                  },
                  "sector_name": {
                    "type": "string",
                    "description": "Sector name",
                    "example": "Lote A-1"
                  },
                  "samplingUnit": {
                    "type": "string",
                    "description": "Unit of measurement (defaults to project setting)",
                    "example": "box"
                  },
                  "pricePerUnit": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Price per unit (defaults to project setting)",
                    "example": 5.5
                  },
                  "bonus": {
                    "$ref": "#/components/schemas/Bonus"
                  },
                  "maxDurationHours": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 24,
                    "description": "Maximum session duration in hours (defaults to 12)",
                    "example": 12
                  },
                  "notes": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "Optional notes",
                    "example": "Good weather today"
                  }
                }
              },
              "examples": {
                "basicSession": {
                  "summary": "Basic session",
                  "value": {
                    "auth0Id": "user_123456789",
                    "projectId": "proj_123",
                    "openedAt": "2025-10-19T08:00:00.000Z",
                    "sectorId": "sector_001",
                    "sector_name": "Lote A-1"
                  }
                },
                "fullSession": {
                  "summary": "Session with custom settings",
                  "value": {
                    "auth0Id": "user_123456789",
                    "projectId": "proj_123",
                    "openedAt": "2025-10-19T08:00:00.000Z",
                    "sectorId": "sector_001",
                    "sector_name": "Lote A-1",
                    "samplingUnit": "box",
                    "pricePerUnit": 5.5,
                    "bonus": {
                      "type": "percent",
                      "value": 10,
                      "note": "High quality bonus"
                    },
                    "maxDurationHours": 12,
                    "notes": "Good weather conditions"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Session created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductionSessionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request - missing required fields or invalid data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "missingFields": {
                    "summary": "Missing required fields",
                    "value": {
                      "status": "error",
                      "message": "Missing required fields: projectId, openedAt, sectorId, sector_name"
                    }
                  },
                  "invalidDay": {
                    "summary": "Invalid opening timestamp",
                    "value": {
                      "status": "error",
                      "message": "Invalid 'openedAt' or project timezone"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - invalid or expired token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflict - session already open for this scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "Session already open for that scope"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/control/production/sessions/{sessionId}": {
      "get": {
        "tags": [
          "Production Sessions"
        ],
        "summary": "Get a production session",
        "description": "Retrieves detailed information about a specific production session.\n\nRequires JWT token authentication in the Authorization header.\n\nOnly the session owner (user who opened it) can view the session.\n",
        "operationId": "getProductionSession",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "Session identifier (unique identifier)",
            "schema": {
              "type": "string"
            },
            "example": "6507f1e3c9d8e2a4b1f9c3d5"
          }
        ],
        "responses": {
          "200": {
            "description": "Session retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductionSessionResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - invalid or expired token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - only session owner can view",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "Forbidden: only session owner (auth0Id) can view"
                }
              }
            }
          },
          "404": {
            "description": "Session not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Production Sessions"
        ],
        "summary": "Update session metadata",
        "description": "Updates metadata of an open production session.\n\nRequires JWT token authentication in the Authorization header.\n\nOnly the session owner can update. Session must be open.\n\nUpdatable fields: samplingUnit, pricePerUnit, bonus, notes\n",
        "operationId": "updateProductionSession",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "Session identifier (unique identifier)",
            "schema": {
              "type": "string"
            },
            "example": "6507f1e3c9d8e2a4b1f9c3d5"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "auth0Id"
                ],
                "properties": {
                  "auth0Id": {
                    "type": "string",
                    "description": "User identifier (internal use, derived from JWT token)",
                    "example": "user_123456789"
                  },
                  "samplingUnit": {
                    "type": "string",
                    "example": "kg"
                  },
                  "pricePerUnit": {
                    "type": "number",
                    "minimum": 0,
                    "example": 6
                  },
                  "bonus": {
                    "$ref": "#/components/schemas/Bonus"
                  },
                  "notes": {
                    "type": "string",
                    "maxLength": 500,
                    "example": "Updated notes"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Session updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "success"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "updated": {
                          "type": "boolean",
                          "example": true
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request - missing auth0Id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - invalid or expired token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - only opener can edit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Session not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflict - session is closed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "Session is closed"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/control/production/sessions/{sessionId}/close": {
      "post": {
        "tags": [
          "Production Sessions"
        ],
        "summary": "Close a production session",
        "description": "Closes an open production session.\n\nRequires JWT token authentication in the Authorization header.\n\nOnly the session owner can close it. Session must be open.\n",
        "operationId": "closeProductionSession",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "Session identifier (unique identifier)",
            "schema": {
              "type": "string"
            },
            "example": "6507f1e3c9d8e2a4b1f9c3d5"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "auth0Id"
                ],
                "properties": {
                  "auth0Id": {
                    "type": "string",
                    "description": "User identifier (internal use, derived from JWT token)",
                    "example": "user_123456789"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Session closed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "success"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "sessionId": {
                          "type": "string",
                          "example": "6507f1e3c9d8e2a4b1f9c3d5"
                        },
                        "status": {
                          "type": "string",
                          "example": "closed"
                        },
                        "closedAt": {
                          "type": "string",
                          "format": "date-time",
                          "example": "2025-10-19T18:00:00.000Z"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request - missing auth0Id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - invalid or expired token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - only opener can close",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "Forbidden: only the opener (auth0Id) can close"
                }
              }
            }
          },
          "404": {
            "description": "Session not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflict - session already closed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "Session already closed"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/control/production/sessions/{sessionId}/extend": {
      "post": {
        "tags": [
          "Production Sessions"
        ],
        "summary": "Extend session duration",
        "description": "Extends the maximum duration of an open production session.\n\nRequires JWT token authentication in the Authorization header.\n\nOnly the session owner can extend it. Session must be open.\n",
        "operationId": "extendProductionSession",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "Session identifier (unique identifier)",
            "schema": {
              "type": "string"
            },
            "example": "6507f1e3c9d8e2a4b1f9c3d5"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "auth0Id",
                  "maxDurationHours"
                ],
                "properties": {
                  "auth0Id": {
                    "type": "string",
                    "description": "User identifier (internal use, derived from JWT token)",
                    "example": "user_123456789"
                  },
                  "maxDurationHours": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 24,
                    "description": "New maximum duration in hours",
                    "example": 18
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Session extended successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "success"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "maxDurationHours": {
                          "type": "integer",
                          "example": 18
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request - invalid maxDurationHours",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "maxDurationHours must be a positive integer"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - invalid or expired token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - only opener can extend",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Session not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflict - session is closed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": "error",
                  "message": "Session is closed"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/control/production/records": {
      "post": {
        "tags": [
          "Production Records"
        ],
        "summary": "Create a production record",
        "description": "Creates a new production record to add units to an open session.\n\nRequires JWT token authentication in the Authorization header.\n\nKey features:\n- Only the session owner can create records\n- Session must be open\n- Supports idempotency via clientEventId and optional idempotencyKey\n- Optimized for high-performance processing\n",
        "operationId": "createProductionRecord",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/ProductionRecord"
                  },
                  {
                    "type": "object",
                    "required": [
                      "auth0Id"
                    ],
                    "properties": {
                      "auth0Id": {
                        "type": "string",
                        "description": "User identifier (internal use, derived from JWT token)",
                        "example": "user_123456789"
                      }
                    }
                  }
                ]
              },
              "examples": {
                "basicRecord": {
                  "summary": "Basic record with 1 unit",
                  "value": {
                    "auth0Id": "user_123456789",
                    "sessionId": "6507f1e3c9d8e2a4b1f9c3d5",
                    "workerId": "JS0315",
                    "worker_name": "John Smith",
                    "recordedAtUtc": "2025-10-19T14:30:00.000Z",
                    "clientEventId": "evt_1234567890abcdef"
                  }
                },
                "multipleUnits": {
                  "summary": "Record with multiple units",
                  "value": {
                    "auth0Id": "user_123456789",
                    "sessionId": "6507f1e3c9d8e2a4b1f9c3d5",
                    "workerId": "JS0315",
                    "worker_name": "John Smith",
                    "units": 5,
                    "recordedAtUtc": "2025-10-19T14:30:00.000Z",
                    "idempotencyKey": "mobile-app-key-12345",
                    "clientEventId": "evt_1234567890abcdef"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Idempotent replay - record already exists",
            "headers": {
              "X-Idempotent-Replay": {
                "schema": {
                  "type": "string"
                },
                "description": "Set to \"true\" when returning idempotent response"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProductionRecordResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "idempotent": {
                              "type": "boolean",
                              "example": true
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Record created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductionRecordResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request - missing required fields or invalid data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - invalid or expired token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - only session owner can create records",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Session not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflict - session is closed or idempotency conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/control/production/records/bulk": {
      "post": {
        "tags": [
          "Production Records"
        ],
        "summary": "Bulk create production records",
        "description": "Creates multiple production records in a single request (offline sync).\n\nRequires JWT token authentication in the Authorization header.\n\nEach record is processed independently with full validation and idempotency.\nReturns multi-status response (207) with individual results.\n",
        "operationId": "bulkCreateProductionRecords",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "auth0Id",
                  "records"
                ],
                "properties": {
                  "auth0Id": {
                    "type": "string",
                    "description": "User identifier (internal use, derived from JWT token)",
                    "example": "user_123456789"
                  },
                  "records": {
                    "type": "array",
                    "description": "Array of production records to create",
                    "items": {
                      "$ref": "#/components/schemas/ProductionRecord"
                    }
                  }
                }
              },
              "example": {
                "auth0Id": "user_123456789",
                "records": [
                  {
                    "sessionId": "6507f1e3c9d8e2a4b1f9c3d5",
                    "workerId": "JS0315",
                    "worker_name": "John Smith",
                    "units": 5,
                    "recordedAtUtc": "2025-10-19T14:30:00.000Z",
                    "clientEventId": "evt_1234567890abcdef"
                  },
                  {
                    "sessionId": "6507f1e3c9d8e2a4b1f9c3d5",
                    "workerId": "JS0315",
                    "worker_name": "John Smith",
                    "units": 3,
                    "recordedAtUtc": "2025-10-19T15:00:00.000Z",
                    "clientEventId": "evt_9876543210fedcba"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "207": {
            "description": "Multi-status - records processed with individual results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "success"
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "index": {
                            "type": "integer",
                            "description": "Index of the record in the request array",
                            "example": 0
                          },
                          "statusCode": {
                            "type": "integer",
                            "description": "HTTP status code for this record (201=created, 200=duplicate, 4xx/5xx=error)",
                            "example": 201
                          },
                          "payloadPreview": {
                            "type": "object",
                            "properties": {
                              "recordId": {
                                "type": "string",
                                "example": "rec_1234567890abcdef"
                              },
                              "sessionId": {
                                "type": "string",
                                "example": "6507f1e3c9d8e2a4b1f9c3d5"
                              },
                              "workerId": {
                                "type": "string",
                                "example": "JS0315"
                              },
                              "units": {
                                "type": "number",
                                "example": 5
                              }
                            }
                          },
                          "idempotent": {
                            "type": "boolean",
                            "description": "Present when statusCode=200 (duplicate)",
                            "example": false
                          },
                          "error": {
                            "type": "string",
                            "description": "Error message (only when statusCode indicates error)",
                            "example": "Missing sessionId or workerId"
                          }
                        }
                      }
                    },
                    "summary": {
                      "type": "object",
                      "properties": {
                        "ok": {
                          "type": "integer",
                          "description": "Number of successfully created records",
                          "example": 2
                        },
                        "duplicated": {
                          "type": "integer",
                          "description": "Number of idempotent duplicates",
                          "example": 0
                        },
                        "failed": {
                          "type": "integer",
                          "description": "Number of failed records",
                          "example": 0
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request - missing auth0Id or empty records array",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - invalid or expired token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/control/production/records/check-idempotency": {
      "head": {
        "tags": [
          "Production Records"
        ],
        "summary": "Check idempotency key",
        "description": "Checks if an idempotency key has been used before.\n\nRequires JWT token authentication in the Authorization header.\n\nReturns 200 if key exists, 404 if not.\n",
        "operationId": "checkIdempotencyKey",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "key",
            "in": "query",
            "required": true,
            "description": "Idempotency key to check",
            "schema": {
              "type": "string"
            },
            "example": "client:6507f1e3c9d8e2a4b1f9c3d5:JS0315:evt_1234567890abcdef"
          }
        ],
        "responses": {
          "200": {
            "description": "Idempotency key exists"
          },
          "401": {
            "description": "Unauthorized - invalid or expired token"
          },
          "404": {
            "description": "Idempotency key not found"
          },
          "500": {
            "description": "Internal server error"
          }
        }
      }
    },
    "/api/control/production/records/{recordId}": {
      "get": {
        "tags": [
          "Production Records"
        ],
        "summary": "Get a production record",
        "description": "Retrieves detailed information about a specific production record.\n\nRequires JWT token authentication in the Authorization header.\n",
        "operationId": "getProductionRecord",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "recordId",
            "in": "path",
            "required": true,
            "description": "Record identifier",
            "schema": {
              "type": "string"
            },
            "example": "rec_1234567890abcdef"
          }
        ],
        "responses": {
          "200": {
            "description": "Record retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "success"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "recordId": {
                          "type": "string",
                          "example": "rec_1234567890abcdef"
                        },
                        "sessionId": {
                          "type": "string",
                          "example": "6507f1e3c9d8e2a4b1f9c3d5"
                        },
                        "workerId": {
                          "type": "string",
                          "example": "JS0315"
                        },
                        "units": {
                          "type": "number",
                          "example": 5
                        },
                        "state": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "inserted"
                          ],
                          "description": "Record insertion state",
                          "example": "inserted"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - invalid or expired token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Record not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/control/production/records/{recordId}/void": {
      "post": {
        "tags": [
          "Production Records"
        ],
        "summary": "Void a production record",
        "description": "Voids (cancels) a production record by creating a counter-movement with negative units.\n\nRequires JWT token authentication in the Authorization header.\n\nOnly the session owner can void records. Session must be open.\nSupports idempotency - voiding the same record multiple times is safe.\n",
        "operationId": "voidProductionRecord",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "recordId",
            "in": "path",
            "required": true,
            "description": "Record identifier to void",
            "schema": {
              "type": "string"
            },
            "example": "rec_1234567890abcdef"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "auth0Id",
                  "reason"
                ],
                "properties": {
                  "auth0Id": {
                    "type": "string",
                    "description": "User identifier (internal use, derived from JWT token)",
                    "example": "user_123456789"
                  },
                  "reason": {
                    "type": "string",
                    "description": "Reason for voiding the record",
                    "example": "Duplicate entry"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Record voided successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "success"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "payloadPreview": {
                          "type": "object",
                          "properties": {
                            "recordId": {
                              "type": "string",
                              "description": "New void record identifier",
                              "example": "rec_void_9876543210"
                            },
                            "voidOf": {
                              "type": "string",
                              "description": "Original record identifier",
                              "example": "rec_1234567890abcdef"
                            },
                            "idempotent": {
                              "type": "boolean",
                              "description": "Present when this is an idempotent replay",
                              "example": false
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request - missing recordId or reason",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - invalid or expired token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - only session opener can void records",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Record or session not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflict - session is closed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/iot/weather": {
      "get": {
        "tags": [
          "Weather"
        ],
        "summary": "Get weather time series for local range",
        "description": "Returns weather and microclimate time series for a project within a local-time range (Leaf-style).\nAuth via API token in `x-api-key`.\n",
        "operationId": "getWeatherSeries",
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": true,
            "description": "Start datetime in **local timezone** (ISO 8601)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "description": "End datetime in **local timezone** (ISO 8601)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "timezone",
            "in": "query",
            "required": true,
            "description": "IANA timezone (e.g., America/Mexico_City)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Optional alternative to query params (for complex queries)",
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TimeRangeQuery"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Weather time series",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WeatherSeriesResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request (missing/invalid range or timezone)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized (invalid token)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/iot/plant": {
      "get": {
        "tags": [
          "Plant"
        ],
        "summary": "Get plant health and vigor series for local range",
        "description": "Returns plant KPIs (e.g., vigor, incidence, severity) aggregated for a project in a local-time range.\nAuth via API token in `x-api-key`.\n",
        "operationId": "getPlantSeries",
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "timezone",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Plant KPI series",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlantSeriesResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/iot/irrigation": {
      "get": {
        "tags": [
          "Irrigation"
        ],
        "summary": "Get irrigation events for local range",
        "description": "Returns irrigation events for a project within a local-time range.\nAuth via API token in `x-api-key`.\n",
        "operationId": "getIrrigationEvents",
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "timezone",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Irrigation events",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IrrigationSeriesResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/mqtt": {
      "get": {
        "tags": [
          "IoT Endpoint"
        ],
        "summary": "Establish mqtt connection over websocket",
        "description": "Upgrade to WebSocket at `wss://iot.hydrobit.ag/mqtt` and authenticate with `x-iot-token`.\nAfter upgrade, speak MQTT (v3.1.1). Use `deviceId` to scope topics.\n",
        "operationId": "mqttOverWebSocket",
        "servers": [
          {
            "url": "wss://iot.hydrobit.ag",
            "description": "MQTT over WebSocket endpoint"
          }
        ],
        "security": [
          {
            "iotToken": []
          }
        ],
        "parameters": [
          {
            "name": "deviceId",
            "in": "query",
            "required": true,
            "description": "Device identifier to scope topics",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "101": {
            "description": "Switching Protocols (WebSocket upgrade to MQTT)"
          },
          "200": {
            "description": "Handshake info for non-upgrade clients",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MqttConnectInfo"
                }
              }
            }
          },
          "400": {
            "description": "Bad request (missing deviceId)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized (invalid or expired x-iot-token)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  }
}