feat(server): implement ship REST endpoints with Zod validation
Adds GET/POST/PATCH/DELETE /api/ships with constraint validation (current <= max), enum checks for maneuver_class, and cascade delete for weapons. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
49
server/src/validation/ship-schema.ts
Normal file
49
server/src/validation/ship-schema.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
const maneuverClasses = ['A', 'B', 'C', 'D', 'E', 'F', 'S'] as const;
|
||||
|
||||
export const createShipSchema = z.object({
|
||||
name: z.string().min(1).max(100).default('Unnamed Ship'),
|
||||
hull_current: z.number().int().min(0).default(0),
|
||||
hull_max: z.number().int().min(0).default(0),
|
||||
armor_current: z.number().int().min(0).default(0),
|
||||
armor_max: z.number().int().min(0).default(0),
|
||||
ac: z.number().int().min(0).default(10),
|
||||
con_save: z.number().int().nullable().default(null),
|
||||
speed: z.number().int().min(0).nullable().default(null),
|
||||
maneuver_class: z.enum(maneuverClasses).nullable().default(null),
|
||||
size_category: z.string().max(50).nullable().default(null),
|
||||
notes: z.string().nullable().default(null),
|
||||
});
|
||||
|
||||
export const updateShipSchema = z
|
||||
.object({
|
||||
name: z.string().min(1).max(100),
|
||||
hull_current: z.number().int().min(0),
|
||||
hull_max: z.number().int().min(0),
|
||||
armor_current: z.number().int().min(0),
|
||||
armor_max: z.number().int().min(0),
|
||||
ac: z.number().int().min(0),
|
||||
con_save: z.number().int().nullable(),
|
||||
speed: z.number().int().min(0).nullable(),
|
||||
maneuver_class: z.enum(maneuverClasses).nullable(),
|
||||
size_category: z.string().max(50).nullable(),
|
||||
notes: z.string().nullable(),
|
||||
})
|
||||
.partial()
|
||||
.refine(
|
||||
(data) => {
|
||||
// Ensure current <= max when both are provided
|
||||
if (data.hull_current !== undefined && data.hull_max !== undefined) {
|
||||
return data.hull_current <= data.hull_max;
|
||||
}
|
||||
if (data.armor_current !== undefined && data.armor_max !== undefined) {
|
||||
return data.armor_current <= data.armor_max;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
{ message: 'Current values must not exceed max values' },
|
||||
);
|
||||
|
||||
export type CreateShipInput = z.infer<typeof createShipSchema>;
|
||||
export type UpdateShipInput = z.infer<typeof updateShipSchema>;
|
||||
Reference in New Issue
Block a user