Skip to main content
User Association: The user_id is automatically assigned from your JWT token. You cannot create terrains for other users.

Authentication Required

This endpoint requires a valid JWT token in the Authorization header:
Authorization: Bearer <your_token>

Request Body

Required Fields

  • name (string): Name of the terrain
  • altitude_meters (number): Altitude in meters
  • slope_percentage (number): Slope percentage
  • soil_type (string): Type of soil (e.g., “clay”, “loam”, “sandy”)

Optional Fields

  • temperature_celsius (number): Temperature in Celsius
  • status (string): Status of the terrain (defaults to “active”)

Response Codes

  • 201: Terrain created successfully
  • 400: Validation errors (missing required fields or invalid data)
  • 401: Unauthorized (missing or invalid JWT token)
  • 500: Internal server error

Automatic User Assignment

The user_id field is automatically populated from the authenticated user’s JWT token:
const userId = req.user.user_id;
const payload = {
  user_id: userId,
  // ... other fields
};
Users cannot specify a different user_id in the request body.

Example Request

curl -X POST https://api.maqagr.com/api/terrains \
  -H "Authorization: Bearer your_jwt_token" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Parcela Norte",
    "altitude_meters": 2500,
    "slope_percentage": 15,
    "soil_type": "clay",
    "temperature_celsius": 18
  }'

Example Response

{
  "success": true,
  "message": "Terreno creado exitosamente",
  "data": {
    "terrain_id": 1,
    "user_id": 5,
    "name": "Parcela Norte",
    "altitude_meters": 2500,
    "slope_percentage": 15,
    "soil_type": "clay",
    "temperature_celsius": 18,
    "status": "active"
  }
}

Validation Error Response

{
  "success": false,
  "errors": [
    "name es requerido",
    "altitude_meters es requerido",
    "soil_type es requerido"
  ]
}

Implementation Details

From terrainController.js:91-144:
export const createTerrain = asyncHandler(async (req, res) => {
  const userId = req.user.user_id;
  const {
    name,
    altitude_meters,
    slope_percentage,
    soil_type,
    temperature_celsius,
    status,
  } = req.body || {};

  // Validaciones básicas
  const errors = [];
  if (!name || typeof name !== "string" || !name.trim()) {
    errors.push("name es requerido");
  }
  if (altitude_meters === undefined || altitude_meters === null) {
    errors.push("altitude_meters es requerido");
  }
  if (slope_percentage === undefined || slope_percentage === null) {
    errors.push("slope_percentage es requerido");
  }
  if (!soil_type || typeof soil_type !== "string" || !soil_type.trim()) {
    errors.push("soil_type es requerido");
  }

  if (errors.length > 0) {
    return res.status(400).json({
      success: false,
      errors,
    });
  }

  const payload = {
    user_id: userId,
    name,
    altitude_meters: Number(altitude_meters),
    slope_percentage: Number(slope_percentage),
    soil_type,
    temperature_celsius:
      temperature_celsius !== undefined && temperature_celsius !== null
        ? Number(temperature_celsius)
        : null,
    status,
  };

  const newTerrain = await Terrain.create(payload);

  return res.status(201).json({
    success: true,
    message: "Terreno creado exitosamente",
    data: newTerrain,
  });
});

Cache Invalidation

Creating a terrain invalidates the terrains cache to ensure list endpoints return fresh data.

Build docs developers (and LLMs) love