Cultivos
Los cultivos (crops) representan lotes de plantas en proceso de crecimiento. Esta API permite gestionar el ciclo completo de cultivo, desde la siembra hasta la cosecha, incluyendo cambios de etapa, registro de actividades y seguimiento de progreso.
La API de Cultivos es actualmente una implementacion mocked. Todas las operaciones funcionan correctamente pero no persisten datos en un backend real.
El modelo de Cultivo
El modelo de cultivo contiene informacion completa sobre el lote de plantas, su estado actual, historial y configuracion.
Propiedades
- Name
id- Type
- string
- Description
Identificador unico del cultivo.
- Name
name- Type
- string
- Description
Nombre descriptivo del cultivo.
- Name
strain- Type
- object
- Description
Cepa asociada al cultivo.
- Name
id- Type
- string
- Description
ID de la cepa.
- Name
name- Type
- string
- Description
Nombre de la cepa.
- Name
stage- Type
- PlantStage
- Description
Etapa actual del cultivo.
- Name
plantedAt- Type
- timestamp
- Description
Fecha de siembra/inicio.
- Name
expectedHarvestDate- Type
- timestamp
- Description
Fecha estimada de cosecha.
- Name
expectedYield- Type
- number
- Description
Rendimiento esperado en gramos.
- Name
plants- Type
- array
- Description
IDs de plantas individuales.
- Name
spaces- Type
- Space[]
- Description
Espacios donde se encuentra el cultivo.
- Name
lights- Type
- Light[]
- Description
Luces asignadas al cultivo.
- Name
pot- Type
- Pot
- Description
Configuracion de maceta.
- Name
milliliters- Type
- number
- Description
Capacidad en ml.
- Name
substrate- Type
- array
- Description
Sustratos y porcentajes.
- Name
timeline- Type
- PlantInteractionLog[]
- Description
Historial de actividades del cultivo.
- Name
stages- Type
- array
- Description
Historial de etapas con fechas.
- Name
seed- Type
- object
- Description
Semilla origen del cultivo.
- Name
createdAt- Type
- timestamp
- Description
Fecha de creacion del registro.
- Name
updatedAt- Type
- timestamp
- Description
Ultima actualizacion.
Ejemplo de cultivo
{
"id": "crop-001",
"name": "Blue Dream Indoor Batch A",
"strain": {
"id": "strain_blue_dream",
"name": "Blue Dream"
},
"stage": "FLOWERING",
"plantedAt": "2024-06-15T00:00:00Z",
"expectedHarvestDate": "2024-09-15T00:00:00Z",
"expectedYield": 500,
"plants": ["plant-001", "plant-002", "plant-003"],
"spaces": [
{
"id": "space-001",
"name": "Sala de Floracion A"
}
],
"lights": [
{
"id": "light-001",
"name": "LED 600W",
"type": "LED"
}
],
"pot": {
"milliliters": 20000,
"substrate": [
{ "type": "COCO", "percentage": 70 },
{ "type": "PERLITE", "percentage": 30 }
]
},
"timeline": [...],
"stages": [
{ "stage": "SEED", "start": "2024-06-15", "end": "2024-06-20" },
{ "stage": "GERMINATION", "start": "2024-06-20", "end": "2024-06-25" },
{ "stage": "SEEDLING", "start": "2024-06-25", "end": "2024-07-10" },
{ "stage": "VEGETATIVE", "start": "2024-07-10", "end": "2024-08-01" },
{ "stage": "FLOWERING", "start": "2024-08-01", "end": "" }
],
"createdAt": "2024-06-15T10:00:00Z",
"updatedAt": "2024-10-01T14:30:00Z"
}
Etapas del Cultivo (PlantStage)
El cultivo pasa por diferentes etapas durante su ciclo de vida.
Enum PlantStage
| Etapa | Descripcion | Duracion Tipica |
|---|---|---|
CLONE | Esqueje o clon | 1-2 semanas |
SEED | Semilla seca | 1-3 dias |
GERMINATION | Germinacion | 3-7 dias |
SEEDLING | Plantula | 2-3 semanas |
VEGETATIVE | Vegetativo | 4-8 semanas |
PREFLOWERING | Pre-floracion | 1-2 semanas |
FLOWERING | Floracion | 8-12 semanas |
HARVEST | Cosecha | 1 dia |
DRYING | Secado | 7-14 dias |
CURING | Curado | 2-8 semanas |
STOCKED | En stock | - |
Diagrama de Flujo de Etapas
Tipos de Interaccion (PlantInteraction)
Las actividades que se pueden registrar en el timeline del cultivo.
| Tipo | Descripcion | Datos Asociados |
|---|---|---|
PLANTING | Siembra inicial | - |
WATERING | Riego | pH, EC, cantidad |
FERTILIZATION | Fertilizacion | nutrientes, dosis |
TRANSPLANT | Trasplante | maceta origen/destino |
PRUNING | Poda | tecnica utilizada |
TRAINING | Entrenamiento | tecnica (LST, HST, etc.) |
LIGHT_SCHEDULE | Cambio de luz | horario on/off |
HEALTH | Estado de salud | observaciones |
OBSERVATION | Observacion general | notas |
HARVESTING | Cosecha | peso humedo |
Listar cultivos
Este endpoint permite obtener una lista filtrada de cultivos.
Parametros de Consulta
- Name
stage- Type
- PlantStage
- Description
Filtrar por etapa actual.
- Name
strain- Type
- string
- Description
Filtrar por ID de cepa.
- Name
spaceId- Type
- string
- Description
Filtrar por espacio.
- Name
search- Type
- string
- Description
Busqueda por nombre.
Request
curl -G https://api.cannahub.tech/api/crops \
-H "Authorization: Bearer {token}" \
-d stage=FLOWERING \
-d search=blue
Response
{
"crops": [
{
"id": "crop-001",
"name": "Blue Dream Indoor Batch A",
"strain": { "id": "strain_blue_dream", "name": "Blue Dream" },
"stage": "FLOWERING",
"plantedAt": "2024-06-15T00:00:00Z"
}
],
"count": 1,
"filters": {
"stage": "FLOWERING",
"search": "blue"
}
}
Crear cultivo
Este endpoint permite crear un nuevo cultivo.
Campos Requeridos
- Name
name- Type
- string
- Description
Nombre del cultivo.
- Name
strain- Type
- string
- Description
ID de la cepa.
- Name
stage- Type
- PlantStage
- Description
Etapa inicial.
Campos Opcionales
- Name
plantedAt- Type
- timestamp
- Description
Fecha de siembra.
- Name
expectedYield- Type
- number
- Description
Rendimiento esperado.
- Name
expectedHarvestDate- Type
- timestamp
- Description
Fecha estimada de cosecha.
- Name
pot- Type
- Pot
- Description
Configuracion de maceta.
- Name
plants- Type
- array
- Description
IDs de plantas.
- Name
seed- Type
- string
- Description
ID de semilla origen.
Request
curl -X POST https://api.cannahub.tech/api/crops \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"name": "OG Kush Lote 2024-B",
"strain": "strain_og_kush",
"strainName": "OG Kush",
"stage": "SEED",
"expectedYield": 400,
"pot": {
"milliliters": 15000,
"substrate": [
{ "type": "SOIL", "percentage": 100 }
]
}
}'
Response (201)
{
"crop": {
"id": "crop-1698765432100",
"name": "OG Kush Lote 2024-B",
"strain": {
"id": "strain_og_kush",
"name": "OG Kush"
},
"stage": "SEED",
"plantedAt": "2024-10-31T10:00:00Z",
"expectedYield": 400,
"createdAt": "2024-10-31T10:00:00Z"
}
}
Obtener cultivo
Este endpoint retorna los detalles de un cultivo especifico.
Request
curl https://api.cannahub.tech/api/crops/crop-001 \
-H "Authorization: Bearer {token}"
Response
{
"crop": {
"id": "crop-001",
"name": "Blue Dream Indoor Batch A",
"strain": { "id": "strain_blue_dream", "name": "Blue Dream" },
"stage": "FLOWERING",
"timeline": [...],
"stages": [...]
}
}
Actualizar cultivo
Este endpoint permite actualizar los datos de un cultivo.
Para cambiar la etapa del cultivo, usa el endpoint /api/crops/:id/stage que valida las transiciones permitidas.
Request
curl -X PATCH https://api.cannahub.tech/api/crops/crop-001 \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"expectedYield": 550,
"expectedHarvestDate": "2024-09-20T00:00:00Z"
}'
Response
{
"crop": {
"id": "crop-001",
"expectedYield": 550,
"expectedHarvestDate": "2024-09-20T00:00:00Z",
"updatedAt": "2024-10-31T10:00:00Z"
}
}
Eliminar cultivo
Este endpoint elimina un cultivo del sistema.
La eliminacion es permanente. Considera archivar cultivos en lugar de eliminarlos.
Request
curl -X DELETE https://api.cannahub.tech/api/crops/crop-001 \
-H "Authorization: Bearer {token}"
Response
{
"success": true
}
BFF: Cultivo Completo
Esta ruta BFF retorna el cultivo con todos sus datos relacionados en una sola llamada.
Datos Incluidos
- Cultivo completo con espacios expandidos
- Cepa con informacion completa
- Cosechas relacionadas
- Estadisticas calculadas
Response
- Name
crop- Type
- Crop
- Description
Cultivo completo con espacios expandidos.
- Name
strain- Type
- Strain
- Description
Informacion completa de la cepa.
- Name
harvests- Type
- array
- Description
Cosechas relacionadas.
- Name
stats- Type
- object
- Description
Estadisticas calculadas.
- Name
daysInCurrentStage- Type
- number
- Description
Dias en la etapa actual.
- Name
totalDaysFromSeed- Type
- number
- Description
Dias totales desde siembra.
- Name
totalTimelineEntries- Type
- number
- Description
Total de entradas en timeline.
- Name
wateringCount- Type
- number
- Description
Cantidad de riegos.
- Name
fertilizationCount- Type
- number
- Description
Cantidad de fertilizaciones.
- Name
totalHarvests- Type
- number
- Description
Cosechas totales.
- Name
totalDryWeight- Type
- number
- Description
Peso seco total cosechado.
Request
curl https://api.cannahub.tech/api/crops/crop-001/complete \
-H "Authorization: Bearer {token}"
Response
{
"crop": {
"id": "crop-001",
"name": "Blue Dream Indoor Batch A",
"stage": "FLOWERING",
"spaces": [
{
"id": "space-001",
"name": "Sala de Floracion A",
"squareMeters": 20,
"status": "ACTIVE"
}
]
},
"strain": {
"id": "strain_blue_dream",
"name": "Blue Dream",
"type": "hybrid",
"cannabinoids": { "thc": 21, "cbd": 0.1 }
},
"harvests": [
{
"id": "harvest-001",
"name": "Blue Dream Lote #1",
"status": "STOCKED",
"dryWeight": 280
}
],
"stats": {
"daysInCurrentStage": 45,
"totalDaysFromSeed": 120,
"totalTimelineEntries": 87,
"wateringCount": 45,
"fertilizationCount": 30,
"totalHarvests": 1,
"totalDryWeight": 280
}
}
BFF: Cambiar Etapa
Esta ruta BFF permite cambiar la etapa del cultivo con validacion de transiciones.
Transiciones Validas
Solo se permiten transiciones logicas entre etapas. Por ejemplo:
VEGETATIVEpuede ir aPREFLOWERINGoFLOWERINGFLOWERINGsolo puede ir aHARVESTSTOCKEDes un estado terminal
Request
- Name
newStage- Type
- PlantStage
- Description
Nueva etapa del cultivo.
- Name
notes- Type
- string
- Description
Notas sobre el cambio.
- Name
author- Type
- object
- Description
Usuario que realiza el cambio.
Request
curl -X POST https://api.cannahub.tech/api/crops/crop-001/stage \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"newStage": "HARVEST",
"notes": "Tricomas ambar al 30%, listo para cosecha"
}'
Response
{
"crop": {
"id": "crop-001",
"stage": "HARVEST",
"stages": [
{ "stage": "FLOWERING", "start": "2024-08-01", "end": "2024-10-15" },
{ "stage": "HARVEST", "start": "2024-10-15", "end": "" }
]
},
"transition": {
"from": "FLOWERING",
"to": "HARVEST",
"timestamp": "2024-10-15T10:00:00Z"
}
}
Error - Transicion Invalida
{
"error": "Invalid stage transition from FLOWERING to VEGETATIVE. Valid transitions: HARVEST",
"currentStage": "FLOWERING",
"validTransitions": ["HARVEST"]
}
BFF: Agregar Actividad
Esta ruta permite agregar una entrada al timeline del cultivo.
Request
- Name
type- Type
- PlantInteraction
- Description
Tipo de interaccion.
- Name
notes- Type
- string
- Description
Notas o comentarios.
- Name
data- Type
- object
- Description
Datos especificos segun el tipo.
- Name
evidences- Type
- array
- Description
URLs de fotos/videos.
- Name
author- Type
- object
- Description
Usuario que registra la actividad.
- Name
date- Type
- timestamp
- Description
Fecha de la actividad (default: ahora).
Datos por Tipo
WATERING:
{ "amount": 2000, "unit": "ml", "pH": 6.2, "EC": 1.4 }
FERTILIZATION:
[
{ "name": "Bio Grow", "nutrients": ["NITROGEN"], "amount": 4, "unit": "ml" }
]
Request
curl -X POST https://api.cannahub.tech/api/crops/crop-001/timeline \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"type": "WATERING",
"data": {
"amount": 2000,
"unit": "ml",
"pH": 6.2,
"EC": 1.4
},
"notes": "Riego matutino con nutrientes"
}'
Response (201)
{
"entry": {
"type": "WATERING",
"date": "2024-10-31T10:00:00Z",
"data": {
"amount": 2000,
"unit": "ml",
"pH": 6.2,
"EC": 1.4
},
"notes": "Riego matutino con nutrientes"
},
"crop": {
"id": "crop-001",
"timeline": [...]
}
}
React Query Hooks
Cannahub provee hooks de React Query para gestionar cultivos.
Query Keys
export const cropKeys = {
all: ['crops'] as const,
lists: () => [...cropKeys.all, 'list'] as const,
list: (filters?: CropFilters) => [...cropKeys.lists(), filters] as const,
details: () => [...cropKeys.all, 'detail'] as const,
detail: (id: string) => [...cropKeys.details(), id] as const,
complete: (id: string) => [...cropKeys.detail(id), 'complete'] as const,
timeline: (id: string) => [...cropKeys.detail(id), 'timeline'] as const,
}
Queries
import { useCropsQuery, useCropQuery, useCropCompleteQuery } from '@/features/Club/Crops/hooks'
// Listar cultivos con filtros
const { data } = useCropsQuery({ stage: 'FLOWERING' })
// Obtener cultivo individual
const { data: crop } = useCropQuery('crop-001')
// Obtener cultivo completo con BFF
const { data: complete } = useCropCompleteQuery('crop-001')
Mutations
import {
useCreateCropMutation,
useUpdateCropMutation,
useDeleteCropMutation,
useChangeCropStageMutation,
useAddTimelineEntryMutation
} from '@/features/Club/Crops/hooks'
// Crear cultivo
const { mutate: createCrop } = useCreateCropMutation()
createCrop({ name: 'Nuevo Cultivo', strain: 'strain_001', stage: 'SEED' })
// Cambiar etapa
const { mutate: changeStage } = useChangeCropStageMutation()
changeStage({ cropId: 'crop-001', newStage: 'FLOWERING' })
// Agregar actividad
const { mutate: addEntry } = useAddTimelineEntryMutation()
addEntry({ cropId: 'crop-001', type: 'WATERING', data: { amount: 2000 } })