feat(c4): lançamento de pedido — catálogo, alçada por linha, POST /orders
- Prisma: Product + RepDiscountLimit + productCategory em OrderItem + migration - Seed: 28 produtos (5 categorias) + alçadas user-001 (default 10%, bebidas 8%, perecíveis 5%) - @sar/api-interface: ProductSummarySchema, ProductDetailSchema, ProductSyncRequestSchema, CreateOrderSchema - API: CatalogModule (GET /catalog, GET /catalog/:id, POST /catalog/sync) - API: POST /orders — valida alçada por linha/produto (OQ-2), idempotency-key (FR-4.3), desnorm cliente - Web: NewOrderPage (3 steps: catálogo → desconto/obs → confirmação) - Web: botão Novo Pedido na ClientDetailPage (desabilitado se financialStatus=blocked) - Web: rota /pedidos/novo com search param clientId Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -91,3 +91,24 @@ export const OrderListResponseSchema = z.object({
|
||||
limit: z.number().int().positive(),
|
||||
});
|
||||
export type OrderListResponse = z.infer<typeof OrderListResponseSchema>;
|
||||
|
||||
// ─── Create Order (POST /orders) ──────────────────────────────────────────────
|
||||
|
||||
export const CreateOrderItemSchema = z.object({
|
||||
productCode: z.string().min(1),
|
||||
productName: z.string().min(1),
|
||||
productCategory: z.string().default('geral'),
|
||||
quantity: z.number().positive(),
|
||||
unitPrice: z.number().positive(),
|
||||
discountPct: z.number().min(0).max(100).default(0),
|
||||
});
|
||||
export type CreateOrderItem = z.infer<typeof CreateOrderItemSchema>;
|
||||
|
||||
export const CreateOrderSchema = z.object({
|
||||
clientId: z.string().uuid(),
|
||||
discountPct: z.number().min(0).max(100).default(0), // desconto global do pedido
|
||||
notes: z.string().optional(),
|
||||
idempotencyKey: z.string().optional(),
|
||||
items: z.array(CreateOrderItemSchema).min(1),
|
||||
});
|
||||
export type CreateOrder = z.infer<typeof CreateOrderSchema>;
|
||||
|
||||
Reference in New Issue
Block a user