Initial Claude Run

This commit is contained in:
Jake Kasper
2025-08-21 07:06:36 -05:00
parent 5ead64afcd
commit 2a46f7261e
53 changed files with 7633 additions and 2 deletions

View File

@@ -0,0 +1,164 @@
const Joi = require('joi');
// User validation schemas
const registerSchema = Joi.object({
email: Joi.string().email().required(),
password: Joi.string().min(8).pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/).required()
.messages({
'string.pattern.base': 'Password must contain at least one lowercase letter, one uppercase letter, one number, and one special character'
}),
firstName: Joi.string().max(100).required(),
lastName: Joi.string().max(100).required()
});
const loginSchema = Joi.object({
email: Joi.string().email().required(),
password: Joi.string().required()
});
const updateUserSchema = Joi.object({
firstName: Joi.string().max(100),
lastName: Joi.string().max(100),
email: Joi.string().email()
});
const changePasswordSchema = Joi.object({
currentPassword: Joi.string().required(),
newPassword: Joi.string().min(8).pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/).required()
.messages({
'string.pattern.base': 'Password must contain at least one lowercase letter, one uppercase letter, one number, and one special character'
})
});
// Property validation schemas
const propertySchema = Joi.object({
name: Joi.string().max(255).required(),
address: Joi.string().max(500),
latitude: Joi.number().min(-90).max(90),
longitude: Joi.number().min(-180).max(180),
totalArea: Joi.number().positive()
});
const lawnSectionSchema = Joi.object({
name: Joi.string().max(255).required(),
area: Joi.number().positive().required(),
polygonData: Joi.object(),
grassType: Joi.string().max(100),
soilType: Joi.string().max(100)
});
// Equipment validation schemas
const equipmentSchema = Joi.object({
equipmentTypeId: Joi.number().integer().positive().required(),
customName: Joi.string().max(255),
tankSize: Joi.number().positive(),
pumpGpm: Joi.number().positive(),
nozzleGpm: Joi.number().positive(),
nozzleCount: Joi.number().integer().positive(),
spreaderWidth: Joi.number().positive()
});
// Product validation schemas
const productSchema = Joi.object({
name: Joi.string().max(255).required(),
brand: Joi.string().max(100),
categoryId: Joi.number().integer().positive().required(),
productType: Joi.string().valid('granular', 'liquid').required(),
activeIngredients: Joi.string(),
description: Joi.string()
});
const productRateSchema = Joi.object({
applicationType: Joi.string().max(100).required(),
rateAmount: Joi.number().positive().required(),
rateUnit: Joi.string().max(50).required(),
notes: Joi.string()
});
const userProductSchema = Joi.object({
productId: Joi.number().integer().positive(),
customName: Joi.string().max(255),
customRateAmount: Joi.number().positive(),
customRateUnit: Joi.string().max(50),
notes: Joi.string()
});
// Application validation schemas
const applicationPlanSchema = Joi.object({
lawnSectionId: Joi.number().integer().positive().required(),
equipmentId: Joi.number().integer().positive().required(),
plannedDate: Joi.date().required(),
notes: Joi.string(),
products: Joi.array().items(Joi.object({
productId: Joi.number().integer().positive(),
userProductId: Joi.number().integer().positive(),
rateAmount: Joi.number().positive().required(),
rateUnit: Joi.string().max(50).required()
})).min(1).required()
});
const applicationLogSchema = Joi.object({
planId: Joi.number().integer().positive(),
lawnSectionId: Joi.number().integer().positive().required(),
equipmentId: Joi.number().integer().positive().required(),
weatherConditions: Joi.object(),
gpsTrack: Joi.object(),
averageSpeed: Joi.number().positive(),
areaCovered: Joi.number().positive(),
notes: Joi.string(),
products: Joi.array().items(Joi.object({
productId: Joi.number().integer().positive(),
userProductId: Joi.number().integer().positive(),
rateAmount: Joi.number().positive().required(),
rateUnit: Joi.string().max(50).required(),
actualProductAmount: Joi.number().positive(),
actualWaterAmount: Joi.number().positive(),
actualSpeedMph: Joi.number().positive()
})).min(1).required()
});
// Validation middleware
const validateRequest = (schema) => {
return (req, res, next) => {
const { error } = schema.validate(req.body, { abortEarly: false });
if (error) {
return next(error);
}
next();
};
};
const validateParams = (schema) => {
return (req, res, next) => {
const { error } = schema.validate(req.params, { abortEarly: false });
if (error) {
return next(error);
}
next();
};
};
const idParamSchema = Joi.object({
id: Joi.number().integer().positive().required()
});
module.exports = {
// Schemas
registerSchema,
loginSchema,
updateUserSchema,
changePasswordSchema,
propertySchema,
lawnSectionSchema,
equipmentSchema,
productSchema,
productRateSchema,
userProductSchema,
applicationPlanSchema,
applicationLogSchema,
idParamSchema,
// Middleware
validateRequest,
validateParams
};