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
94 lines
3.2 KiB
TypeScript
94 lines
3.2 KiB
TypeScript
/**
|
|
* API Route: Consumer preferences
|
|
* POST - Register/update consumer preferences
|
|
* GET - Get consumer preferences
|
|
*/
|
|
|
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
|
import { getDemandForecaster } from '../../../lib/demand/forecaster';
|
|
import { ConsumerPreference } from '../../../lib/demand/types';
|
|
|
|
export default async function handler(
|
|
req: NextApiRequest,
|
|
res: NextApiResponse
|
|
) {
|
|
const forecaster = getDemandForecaster();
|
|
|
|
if (req.method === 'POST') {
|
|
try {
|
|
const preference = req.body as ConsumerPreference;
|
|
|
|
// Validate required fields
|
|
if (!preference.consumerId || !preference.location || !preference.preferredItems) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
error: 'Missing required fields: consumerId, location, preferredItems'
|
|
});
|
|
}
|
|
|
|
// Add timestamps
|
|
const now = new Date().toISOString();
|
|
preference.createdAt = preference.createdAt || now;
|
|
preference.updatedAt = now;
|
|
|
|
// Set defaults
|
|
preference.householdSize = preference.householdSize || 1;
|
|
preference.dietaryType = preference.dietaryType || ['omnivore'];
|
|
preference.allergies = preference.allergies || [];
|
|
preference.dislikes = preference.dislikes || [];
|
|
preference.preferredCategories = preference.preferredCategories || [];
|
|
preference.certificationPreferences = preference.certificationPreferences || [];
|
|
preference.freshnessImportance = preference.freshnessImportance || 3;
|
|
preference.priceImportance = preference.priceImportance || 3;
|
|
preference.sustainabilityImportance = preference.sustainabilityImportance || 3;
|
|
preference.deliveryPreferences = preference.deliveryPreferences || {
|
|
method: ['home_delivery'],
|
|
frequency: 'weekly',
|
|
preferredDays: ['saturday']
|
|
};
|
|
|
|
forecaster.registerPreference(preference);
|
|
|
|
res.status(201).json({
|
|
success: true,
|
|
data: preference
|
|
});
|
|
} catch (error: any) {
|
|
console.error('Error registering preference:', error);
|
|
res.status(500).json({ success: false, error: error.message || 'Internal server error' });
|
|
}
|
|
} else if (req.method === 'GET') {
|
|
try {
|
|
const { consumerId } = req.query;
|
|
|
|
if (!consumerId || typeof consumerId !== 'string') {
|
|
return res.status(400).json({
|
|
success: false,
|
|
error: 'Consumer ID is required'
|
|
});
|
|
}
|
|
|
|
// Access internal state for lookup
|
|
const state = forecaster.toJSON() as any;
|
|
const preferences = state.preferences as [string, ConsumerPreference][];
|
|
const preference = preferences.find(([id]) => id === consumerId);
|
|
|
|
if (!preference) {
|
|
return res.status(404).json({
|
|
success: false,
|
|
error: `Preference not found for consumer: ${consumerId}`
|
|
});
|
|
}
|
|
|
|
res.status(200).json({
|
|
success: true,
|
|
data: preference[1]
|
|
});
|
|
} catch (error: any) {
|
|
console.error('Error fetching preference:', 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' });
|
|
}
|
|
}
|