Transport API (11 endpoints): - POST /api/transport/seed-acquisition - Record seed acquisition events - POST /api/transport/planting - Record planting events - POST /api/transport/growing - Record growing transport events - POST /api/transport/harvest - Record harvest events - POST /api/transport/distribution - Record distribution events - POST /api/transport/seed-saving - Record seed saving events - POST /api/transport/seed-sharing - Record seed sharing events - GET /api/transport/journey/[plantId] - Get plant journey - GET /api/transport/footprint/[userId] - Get environmental impact - GET /api/transport/verify/[blockHash] - Verify block integrity - GET /api/transport/qr/[id] - Generate QR code data Demand API (6 endpoints): - POST/GET /api/demand/preferences - Consumer preferences - POST /api/demand/signal - Generate demand signal - GET /api/demand/recommendations - Get planting recommendations - GET /api/demand/forecast - Get demand forecast - POST /api/demand/supply - Register supply commitment - POST /api/demand/match - Create market match Vertical Farm API (9 endpoints): - POST /api/vertical-farm/register - Register new farm - GET /api/vertical-farm/[farmId] - Get farm details - GET/POST /api/vertical-farm/[farmId]/zones - Manage zones - GET /api/vertical-farm/[farmId]/analytics - Get farm analytics - POST /api/vertical-farm/batch/start - Start crop batch - GET /api/vertical-farm/batch/[batchId] - Get batch details - PUT /api/vertical-farm/batch/[batchId]/environment - Record environment - POST /api/vertical-farm/batch/[batchId]/harvest - Complete harvest - GET /api/vertical-farm/recipes - List growing recipes
126 lines
3.5 KiB
TypeScript
126 lines
3.5 KiB
TypeScript
/**
|
|
* API Route: Manage zones
|
|
* GET - List zones for a farm
|
|
* POST - Add a new zone
|
|
*/
|
|
|
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
|
import { getVerticalFarmController } from '../../../../lib/vertical-farming/controller';
|
|
import { GrowingZone, ZoneEnvironmentTargets, ZoneEnvironmentReadings } from '../../../../lib/vertical-farming/types';
|
|
|
|
export default async function handler(
|
|
req: NextApiRequest,
|
|
res: NextApiResponse
|
|
) {
|
|
const { farmId } = req.query;
|
|
|
|
if (!farmId || typeof farmId !== 'string') {
|
|
return res.status(400).json({
|
|
success: false,
|
|
error: 'Farm ID is required'
|
|
});
|
|
}
|
|
|
|
const controller = getVerticalFarmController();
|
|
const farm = controller.getFarm(farmId);
|
|
|
|
if (!farm) {
|
|
return res.status(404).json({
|
|
success: false,
|
|
error: `Farm not found: ${farmId}`
|
|
});
|
|
}
|
|
|
|
if (req.method === 'GET') {
|
|
try {
|
|
res.status(200).json({
|
|
success: true,
|
|
data: {
|
|
farmId,
|
|
totalZones: farm.zones.length,
|
|
zones: farm.zones
|
|
}
|
|
});
|
|
} catch (error: any) {
|
|
console.error('Error fetching zones:', error);
|
|
res.status(500).json({ success: false, error: error.message || 'Internal server error' });
|
|
}
|
|
} else if (req.method === 'POST') {
|
|
try {
|
|
const {
|
|
name,
|
|
level,
|
|
areaSqm,
|
|
lengthM,
|
|
widthM,
|
|
growingMethod,
|
|
plantPositions
|
|
} = req.body;
|
|
|
|
// Validate required fields
|
|
if (!name || level === undefined || !areaSqm || !growingMethod || !plantPositions) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
error: 'Missing required fields: name, level, areaSqm, growingMethod, plantPositions'
|
|
});
|
|
}
|
|
|
|
const defaultTargets: ZoneEnvironmentTargets = {
|
|
temperatureC: { min: 18, max: 26, target: 22 },
|
|
humidityPercent: { min: 50, max: 80, target: 65 },
|
|
co2Ppm: { min: 400, max: 1500, target: 1000 },
|
|
lightPpfd: { min: 100, max: 500, target: 300 },
|
|
lightHours: 16,
|
|
nutrientEc: { min: 1.0, max: 2.0, target: 1.5 },
|
|
nutrientPh: { min: 5.5, max: 6.5, target: 6.0 },
|
|
waterTempC: { min: 18, max: 24, target: 20 }
|
|
};
|
|
|
|
const defaultReadings: ZoneEnvironmentReadings = {
|
|
timestamp: new Date().toISOString(),
|
|
temperatureC: 22,
|
|
humidityPercent: 65,
|
|
co2Ppm: 800,
|
|
vpd: 1.0,
|
|
ppfd: 300,
|
|
dli: 17,
|
|
waterTempC: 20,
|
|
ec: 1.5,
|
|
ph: 6.0,
|
|
dissolvedOxygenPpm: 8,
|
|
airflowMs: 0.5,
|
|
alerts: []
|
|
};
|
|
|
|
const zone: GrowingZone = {
|
|
id: `zone-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
name,
|
|
level,
|
|
areaSqm,
|
|
lengthM: lengthM || Math.sqrt(areaSqm),
|
|
widthM: widthM || Math.sqrt(areaSqm),
|
|
growingMethod,
|
|
plantPositions,
|
|
currentCrop: '',
|
|
plantIds: [],
|
|
plantingDate: '',
|
|
expectedHarvestDate: '',
|
|
environmentTargets: defaultTargets,
|
|
currentEnvironment: defaultReadings,
|
|
status: 'empty'
|
|
};
|
|
|
|
farm.zones.push(zone);
|
|
|
|
res.status(201).json({
|
|
success: true,
|
|
data: zone
|
|
});
|
|
} catch (error: any) {
|
|
console.error('Error adding zone:', error);
|
|
res.status(500).json({ success: false, error: error.message || 'Internal server error' });
|
|
}
|
|
} else {
|
|
return res.status(405).json({ success: false, error: 'Method not allowed' });
|
|
}
|
|
}
|