Skip to main content
Ownership Validation: You can only update terrains that belong to your authenticated user account. Attempting to update another user’s terrain will return a 404 error.

Authentication Required

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

Path Parameters

  • id (integer, required): The terrain ID to update

Request Body

All fields are optional. Only the fields you provide will be updated (using COALESCE in the SQL query).

Updatable Fields

  • name (string): Name of the terrain
  • altitude_meters (number): Altitude in meters
  • slope_percentage (number): Slope percentage
  • soil_type (string): Type of soil
  • temperature_celsius (number): Temperature in Celsius
  • status (string): Status of the terrain

Response Codes

  • 200: Terrain updated successfully
  • 400: Invalid terrain ID
  • 401: Unauthorized (missing or invalid JWT token)
  • 404: Terrain not found or does not belong to the authenticated user
  • 500: Internal server error

Partial Updates

You can update only specific fields without providing all terrain data:
{
  "name": "Parcela Norte Actualizada",
  "slope_percentage": 12
}
Fields not provided will retain their current values.

Example Request

curl -X PUT https://api.maqagr.com/api/terrains/1 \
  -H "Authorization: Bearer your_jwt_token" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Parcela Norte Actualizada",
    "slope_percentage": 12,
    "temperature_celsius": 20
  }'

Example Response

{
  "success": true,
  "message": "Terreno actualizado exitosamente",
  "data": {
    "terrain_id": 1,
    "user_id": 5,
    "name": "Parcela Norte Actualizada",
    "altitude_meters": 2500,
    "slope_percentage": 12,
    "soil_type": "clay",
    "temperature_celsius": 20,
    "status": "active"
  }
}

Error Response Example

{
  "success": false,
  "message": "Terreno no encontrado"
}

Ownership Verification

Before updating, the endpoint verifies that the terrain belongs to the authenticated user:
const existing = await Terrain.findByIdAndUser(id, userId);

if (!existing) {
  return res.status(404).json({
    success: false,
    message: "Terreno no encontrado",
  });
}

Implementation Details

From terrainController.js:150-205:
export const updateTerrain = asyncHandler(async (req, res) => {
  const id = parseInt(req.params.id, 10);
  const userId = req.user.user_id;

  if (Number.isNaN(id) || id <= 0) {
    return res.status(400).json({
      success: false,
      message: "ID de terreno inválido",
    });
  }

  // Verificar propiedad del terreno
  const existing = await Terrain.findByIdAndUser(id, userId);

  if (!existing) {
    return res.status(404).json({
      success: false,
      message: "Terreno no encontrado",
    });
  }

  const {
    name,
    altitude_meters,
    slope_percentage,
    soil_type,
    temperature_celsius,
    status,
  } = req.body || {};

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

  const updated = await Terrain.update(id, updateData);

  return res.json({
    success: true,
    message: "Terreno actualizado exitosamente",
    data: updated,
  });
});
From Terrain.js:73-105 (using COALESCE for partial updates):
static async update(id, terrainData) {
  const {
    name,
    altitude_meters,
    slope_percentage,
    soil_type,
    temperature_celsius,
    status,
  } = terrainData;

  const query = `
    UPDATE terrain 
    SET name = COALESCE($1, name),
        altitude_meters = COALESCE($2, altitude_meters),
        slope_percentage = COALESCE($3, slope_percentage),
        soil_type = COALESCE($4, soil_type),
        temperature_celsius = COALESCE($5, temperature_celsius),
        status = COALESCE($6, status)
    WHERE terrain_id = $7
    RETURNING *
  `;
  const values = [
    name,
    altitude_meters,
    slope_percentage,
    soil_type,
    temperature_celsius,
    status,
    id,
  ];
  const result = await pool.query(query, values);
  return result.rows[0];
}

Cache Invalidation

Updating a terrain invalidates both the terrains and recommendations caches, as terrain changes may affect recommendation results.

Build docs developers (and LLMs) love