feat(products): catálogos de Tipo/Grupo/Subgrupo/Marca/Unidade com submenu e dropdowns
Menu Produtos ganha submenu (AppShell agora suporta itens aninhados) para cadastrar Tipos/Grupos/Marcas/Unidades; Subgrupo é gerenciado a partir da tela do Grupo (sempre pertence a um). O cadastro de item passa a usar dropdowns desses catálogos em vez de texto livre — exatamente o que o comentário original da migration de products já previa como trabalho futuro. Backend: 5 tabelas de catálogo simples (mesmo padrão dos catálogos fiscais), products ganha as FKs correspondentes com backfill, e endpoints CRUD (sem exclusão física, active=false é o "apagar"). Corrige também um buraco de integridade real encontrado na integração: PATCH /v1/products/:id usava COALESCE para os campos de catálogo opcionais, então não dava para distinguir "não mexer" de "limpar" — trocar o Grupo de um produto sem tocar no Subgrupo deixava o vínculo antigo órfão e inconsistente, sem nenhuma validação pegando isso. Agora a atualização valida o estado efetivo resultante (bloqueia com 400 em vez de corromper o vínculo) e productSubgroupId: null limpa de verdade. Suíte: 95/95 verdes (92→95). pnpm turbo run typecheck build: 28/28. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,10 @@ import { CompaniesListPage } from "./routes/companies/CompaniesListPage.js";
|
||||
import { CompanyFormPage } from "./routes/companies/CompanyFormPage.js";
|
||||
import { ProductsListPage } from "./routes/products/ProductsListPage.js";
|
||||
import { ProductFormPage } from "./routes/products/ProductFormPage.js";
|
||||
import { ProductTypesListPage } from "./routes/products/catalogs/ProductTypesListPage.js";
|
||||
import { ProductGroupsListPage } from "./routes/products/catalogs/ProductGroupsListPage.js";
|
||||
import { BrandsListPage } from "./routes/products/catalogs/BrandsListPage.js";
|
||||
import { UnitsListPage } from "./routes/products/catalogs/UnitsListPage.js";
|
||||
import { ResellersListPage } from "./routes/resellers/ResellersListPage.js";
|
||||
import { ResellerFormPage } from "./routes/resellers/ResellerFormPage.js";
|
||||
import { LeadsListPage } from "./routes/crm/LeadsListPage.js";
|
||||
@@ -82,6 +86,10 @@ export function App() {
|
||||
<Route path="/products" element={<ProductsListPage />} />
|
||||
<Route path="/products/new" element={<ProductFormPage />} />
|
||||
<Route path="/products/:id/edit" element={<ProductFormPage />} />
|
||||
<Route path="/products/types" element={<ProductTypesListPage />} />
|
||||
<Route path="/products/groups" element={<ProductGroupsListPage />} />
|
||||
<Route path="/products/brands" element={<BrandsListPage />} />
|
||||
<Route path="/products/units" element={<UnitsListPage />} />
|
||||
|
||||
<Route path="/resellers" element={<ResellersListPage />} />
|
||||
<Route path="/resellers/new" element={<ResellerFormPage />} />
|
||||
|
||||
Reference in New Issue
Block a user