diff --git a/frontend/.gitignore b/frontend/.gitignore index 0430c3e..2d62949 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -8,16 +8,12 @@ dist/ .dist/ dist-ssr/ build/ -*.local +.next/ # Environment variables .env .env* !.env.example -.env.local -.env.development.local -.env.test.local -.env.production.local # Logs logs/ diff --git a/frontend/.next/cache/eslint/.cache_1lfc3o4 b/frontend/.next/cache/eslint/.cache_1lfc3o4 deleted file mode 100644 index 3e1a936..0000000 --- a/frontend/.next/cache/eslint/.cache_1lfc3o4 +++ /dev/null @@ -1 +0,0 @@ -[{"C:\\dev\\saveinmed\\frontend\\src\\app\\admin\\categorias\\page.tsx":"1","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\cadastro-produto\\route.ts":"2","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\carrinhos\\route.ts":"3","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\carrinhos\\[id]\\route.ts":"4","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\catalogo-produtos\\route.ts":"5","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\catalogo-produtos\\[id]\\route.ts":"6","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\categorias\\route.ts":"7","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\categorias\\[id]\\route.ts":"8","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\cep\\[cep]\\route.ts":"9","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\configurar-empresa\\route.ts":"10","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\dashboard\\route.ts":"11","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\debug-api-key\\route.ts":"12","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\debug-env\\route.ts":"13","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\debug-registro\\route.ts":"14","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\diagnostico-collections\\route.ts":"15","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\empresas\\route.ts":"16","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\empresas\\[id]\\route.ts":"17","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\empresas-filtradas\\route.ts":"18","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\enderecos\\route.ts":"19","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\enderecos\\[id]\\route.ts":"20","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\faturas\\route.ts":"21","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\faturas\\[id]\\route.ts":"22","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\gestao-usuarios\\route.ts":"23","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\laboratorios\\route.ts":"24","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\laboratorios\\[id]\\route.ts":"25","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\mercadopago\\criar-preferencia\\route.ts":"26","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\mercadopago\\pagamento\\[id]\\route.ts":"27","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\mercadopago\\pagamentos\\route.ts":"28","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\mercadopago\\verificar-pagamento\\route.ts":"29","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\notify-admin\\route.ts":"30","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\notify-admin-edge\\route.ts":"31","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\notify-admin-resend\\route.ts":"32","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\pagamentos\\route.ts":"33","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\pagamentos\\[id]\\route.ts":"34","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\pedidos\\route.ts":"35","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\pedidos\\[id]\\route.ts":"36","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\produtos\\catalogo\\route.ts":"37","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\produtos\\route.ts":"38","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\produtos\\venda\\route.ts":"39","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\produtos\\[id]\\route.ts":"40","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\produtos-catalogo\\route.ts":"41","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\relacionar-categorias\\route.ts":"42","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\relacionar-produto\\route.ts":"43","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\subcategorias\\route.ts":"44","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\subcategorias\\[id]\\route.ts":"45","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\test-email\\route.ts":"46","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\user\\permissions\\route.ts":"47","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\usuarios\\route.ts":"48","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\usuarios\\[id]\\route.ts":"49","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\verificar-atributos\\route.ts":"50","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\webhook\\mercadopago\\route.ts":"51","C:\\dev\\saveinmed\\frontend\\src\\app\\api\\webhook\\pagamento\\route.ts":"52","C:\\dev\\saveinmed\\frontend\\src\\app\\cadastro-teste\\page.tsx":"53","C:\\dev\\saveinmed\\frontend\\src\\app\\caju\\page.tsx":"54","C:\\dev\\saveinmed\\frontend\\src\\app\\carrinhos\\page.tsx":"55","C:\\dev\\saveinmed\\frontend\\src\\app\\catalogo-carrinho\\page.tsx":"56","C:\\dev\\saveinmed\\frontend\\src\\app\\catalogo-produtos\\page.tsx":"57","C:\\dev\\saveinmed\\frontend\\src\\app\\catalogo-produtos-api\\page.tsx":"58","C:\\dev\\saveinmed\\frontend\\src\\app\\categorias\\page.tsx":"59","C:\\dev\\saveinmed\\frontend\\src\\app\\checkout\\page.tsx":"60","C:\\dev\\saveinmed\\frontend\\src\\app\\comparacao-consulta\\page.tsx":"61","C:\\dev\\saveinmed\\frontend\\src\\app\\completar-registro\\page.tsx":"62","C:\\dev\\saveinmed\\frontend\\src\\app\\configurar-empresa\\page.tsx":"63","C:\\dev\\saveinmed\\frontend\\src\\app\\criar-empresa-teste\\page.tsx":"64","C:\\dev\\saveinmed\\frontend\\src\\app\\dashboard\\cadastrar-medicamentos\\page.tsx":"65","C:\\dev\\saveinmed\\frontend\\src\\app\\dashboard\\cadastro-produto\\page.tsx":"66","C:\\dev\\saveinmed\\frontend\\src\\app\\dashboard\\components\\index.ts":"67","C:\\dev\\saveinmed\\frontend\\src\\app\\dashboard\\empresa-novo\\page-clean.tsx":"68","C:\\dev\\saveinmed\\frontend\\src\\app\\dashboard\\empresa-novo\\page-new.tsx":"69","C:\\dev\\saveinmed\\frontend\\src\\app\\dashboard\\empresa-novo\\page.tsx":"70","C:\\dev\\saveinmed\\frontend\\src\\app\\dashboard\\empresa-novo-updated\\page.tsx":"71","C:\\dev\\saveinmed\\frontend\\src\\app\\dashboard\\page.tsx":"72","C:\\dev\\saveinmed\\frontend\\src\\app\\debug-api-key\\page.tsx":"73","C:\\dev\\saveinmed\\frontend\\src\\app\\debug-cadastro-produto\\page.tsx":"74","C:\\dev\\saveinmed\\frontend\\src\\app\\debug-config\\page.tsx":"75","C:\\dev\\saveinmed\\frontend\\src\\app\\debug-dados\\page.tsx":"76","C:\\dev\\saveinmed\\frontend\\src\\app\\debug-empresa\\page.tsx":"77","C:\\dev\\saveinmed\\frontend\\src\\app\\debug-estrutura-produtos\\page.tsx":"78","C:\\dev\\saveinmed\\frontend\\src\\app\\debug-exclusao-empresa\\page.tsx":"79","C:\\dev\\saveinmed\\frontend\\src\\app\\debug-network\\page.tsx":"80","C:\\dev\\saveinmed\\frontend\\src\\app\\debug-produtos\\page.tsx":"81","C:\\dev\\saveinmed\\frontend\\src\\app\\debug-produtos-teste\\page.tsx":"82","C:\\dev\\saveinmed\\frontend\\src\\app\\debug-registro\\page.tsx":"83","C:\\dev\\saveinmed\\frontend\\src\\app\\debug-registro\\SessionStorageDebug.tsx":"84","C:\\dev\\saveinmed\\frontend\\src\\app\\debug-usuario\\page.tsx":"85","C:\\dev\\saveinmed\\frontend\\src\\app\\demo-estoque\\page.tsx":"86","C:\\dev\\saveinmed\\frontend\\src\\app\\demo-produtos-catalogo\\page.tsx":"87","C:\\dev\\saveinmed\\frontend\\src\\app\\diagnostico\\page.tsx":"88","C:\\dev\\saveinmed\\frontend\\src\\app\\diagnostico-collections\\page.tsx":"89","C:\\dev\\saveinmed\\frontend\\src\\app\\diagnostico-completo\\page.tsx":"90","C:\\dev\\saveinmed\\frontend\\src\\app\\enderecos\\page.tsx":"91","C:\\dev\\saveinmed\\frontend\\src\\app\\entregas\\page.tsx":"92","C:\\dev\\saveinmed\\frontend\\src\\app\\faq\\page.tsx":"93","C:\\dev\\saveinmed\\frontend\\src\\app\\faturas\\page.tsx":"94","C:\\dev\\saveinmed\\frontend\\src\\app\\fix-empresa\\page.tsx":"95","C:\\dev\\saveinmed\\frontend\\src\\app\\gestao-colaboradores\\components\\CadastroColaboradorModal.tsx":"96","C:\\dev\\saveinmed\\frontend\\src\\app\\gestao-colaboradores\\components\\EditarColaboradorModal.tsx":"97","C:\\dev\\saveinmed\\frontend\\src\\app\\gestao-colaboradores\\page.tsx":"98","C:\\dev\\saveinmed\\frontend\\src\\app\\gestao-pedidos\\page.tsx":"99","C:\\dev\\saveinmed\\frontend\\src\\app\\gestao-produtos-venda\\page.tsx":"100","C:\\dev\\saveinmed\\frontend\\src\\app\\gestao-usuarios\\page.tsx":"101","C:\\dev\\saveinmed\\frontend\\src\\app\\laboratorios\\page.tsx":"102","C:\\dev\\saveinmed\\frontend\\src\\app\\layout.tsx":"103","C:\\dev\\saveinmed\\frontend\\src\\app\\limpar-cache\\page.tsx":"104","C:\\dev\\saveinmed\\frontend\\src\\app\\login\\page.tsx":"105","C:\\dev\\saveinmed\\frontend\\src\\app\\pagamento\\erro\\page.tsx":"106","C:\\dev\\saveinmed\\frontend\\src\\app\\pagamento\\mercadopago\\falha\\page.tsx":"107","C:\\dev\\saveinmed\\frontend\\src\\app\\pagamento\\mercadopago\\page.tsx":"108","C:\\dev\\saveinmed\\frontend\\src\\app\\pagamento\\mercadopago\\pendente\\page.tsx":"109","C:\\dev\\saveinmed\\frontend\\src\\app\\pagamento\\mercadopago\\sucesso\\page.tsx":"110","C:\\dev\\saveinmed\\frontend\\src\\app\\pagamento\\mercadopago\\sucesso\\page_novo.tsx":"111","C:\\dev\\saveinmed\\frontend\\src\\app\\pagamento\\page.tsx":"112","C:\\dev\\saveinmed\\frontend\\src\\app\\pagamento\\sucesso\\page.tsx":"113","C:\\dev\\saveinmed\\frontend\\src\\app\\pagamentos\\page.tsx":"114","C:\\dev\\saveinmed\\frontend\\src\\app\\page.tsx":"115","C:\\dev\\saveinmed\\frontend\\src\\app\\pedidos\\page.tsx":"116","C:\\dev\\saveinmed\\frontend\\src\\app\\pedidos\\[id]\\page.tsx":"117","C:\\dev\\saveinmed\\frontend\\src\\app\\perfil\\page.tsx":"118","C:\\dev\\saveinmed\\frontend\\src\\app\\produtos\\page.tsx":"119","C:\\dev\\saveinmed\\frontend\\src\\app\\relacionar-categorias\\page.tsx":"120","C:\\dev\\saveinmed\\frontend\\src\\app\\relatorios\\head.tsx":"121","C:\\dev\\saveinmed\\frontend\\src\\app\\relatorios\\novo-layout.tsx":"122","C:\\dev\\saveinmed\\frontend\\src\\app\\relatorios\\page.tsx":"123","C:\\dev\\saveinmed\\frontend\\src\\app\\solucao-empresa\\page.tsx":"124","C:\\dev\\saveinmed\\frontend\\src\\app\\usuarios\\page.tsx":"125","C:\\dev\\saveinmed\\frontend\\src\\app\\usuarios-pendentes\\page.tsx":"126","C:\\dev\\saveinmed\\frontend\\src\\app\\verificar-atributos\\page.tsx":"127","C:\\dev\\saveinmed\\frontend\\src\\App.tsx":"128","C:\\dev\\saveinmed\\frontend\\src\\components\\ActionButton.tsx":"129","C:\\dev\\saveinmed\\frontend\\src\\components\\auth\\PermissionCheck.tsx":"130","C:\\dev\\saveinmed\\frontend\\src\\components\\auth\\RoleGuard.tsx":"131","C:\\dev\\saveinmed\\frontend\\src\\components\\CadastroProdutoWizard.tsx":"132","C:\\dev\\saveinmed\\frontend\\src\\components\\CarrinhoCompras.tsx":"133","C:\\dev\\saveinmed\\frontend\\src\\components\\CarrinhoForm.tsx":"134","C:\\dev\\saveinmed\\frontend\\src\\components\\CarrinhoList.tsx":"135","C:\\dev\\saveinmed\\frontend\\src\\components\\CatalogoComCarrinho.tsx":"136","C:\\dev\\saveinmed\\frontend\\src\\components\\CatalogoProdutoForm.tsx":"137","C:\\dev\\saveinmed\\frontend\\src\\components\\CatalogoProdutosCompras.tsx":"138","C:\\dev\\saveinmed\\frontend\\src\\components\\CatalogoProdutosList.tsx":"139","C:\\dev\\saveinmed\\frontend\\src\\components\\CatalogoProdutosList_new.tsx":"140","C:\\dev\\saveinmed\\frontend\\src\\components\\CatalogoProdutosSearch.tsx":"141","C:\\dev\\saveinmed\\frontend\\src\\components\\CategoriaForm.tsx":"142","C:\\dev\\saveinmed\\frontend\\src\\components\\CategoriaList.tsx":"143","C:\\dev\\saveinmed\\frontend\\src\\components\\DataTable.tsx":"144","C:\\dev\\saveinmed\\frontend\\src\\components\\DebugRegistro.tsx":"145","C:\\dev\\saveinmed\\frontend\\src\\components\\DebugUsuario.tsx":"146","C:\\dev\\saveinmed\\frontend\\src\\components\\DetalheProdutoModal.tsx":"147","C:\\dev\\saveinmed\\frontend\\src\\components\\EditProdutoModal.tsx":"148","C:\\dev\\saveinmed\\frontend\\src\\components\\EmpresaList.tsx":"149","C:\\dev\\saveinmed\\frontend\\src\\components\\EmpresaModal.tsx":"150","C:\\dev\\saveinmed\\frontend\\src\\components\\EmpresaModal2.tsx":"151","C:\\dev\\saveinmed\\frontend\\src\\components\\EnderecoForm.tsx":"152","C:\\dev\\saveinmed\\frontend\\src\\components\\EnderecoList.tsx":"153","C:\\dev\\saveinmed\\frontend\\src\\components\\EstoqueManager.tsx":"154","C:\\dev\\saveinmed\\frontend\\src\\components\\EstoqueResumo.tsx":"155","C:\\dev\\saveinmed\\frontend\\src\\components\\FaturaForm.tsx":"156","C:\\dev\\saveinmed\\frontend\\src\\components\\FaturaList.tsx":"157","C:\\dev\\saveinmed\\frontend\\src\\components\\GroupedProductCard.test.tsx":"158","C:\\dev\\saveinmed\\frontend\\src\\components\\GroupedProductCard.tsx":"159","C:\\dev\\saveinmed\\frontend\\src\\components\\Header.tsx":"160","C:\\dev\\saveinmed\\frontend\\src\\components\\LaboratorioForm.tsx":"161","C:\\dev\\saveinmed\\frontend\\src\\components\\LaboratorioList.tsx":"162","C:\\dev\\saveinmed\\frontend\\src\\components\\ListHeader.tsx":"163","C:\\dev\\saveinmed\\frontend\\src\\components\\LocationPicker.tsx":"164","C:\\dev\\saveinmed\\frontend\\src\\components\\LojaVirtualMenu.tsx":"165","C:\\dev\\saveinmed\\frontend\\src\\components\\MercadoPagoPaymentBrick.tsx":"166","C:\\dev\\saveinmed\\frontend\\src\\components\\Modal.tsx":"167","C:\\dev\\saveinmed\\frontend\\src\\components\\Navbar.tsx":"168","C:\\dev\\saveinmed\\frontend\\src\\components\\Navbar_new.tsx":"169","C:\\dev\\saveinmed\\frontend\\src\\components\\PagamentoForm.tsx":"170","C:\\dev\\saveinmed\\frontend\\src\\components\\PagamentoList.tsx":"171","C:\\dev\\saveinmed\\frontend\\src\\components\\Pagination.tsx":"172","C:\\dev\\saveinmed\\frontend\\src\\components\\PedidoForm.tsx":"173","C:\\dev\\saveinmed\\frontend\\src\\components\\PedidoList.tsx":"174","C:\\dev\\saveinmed\\frontend\\src\\components\\ProductCard.test.tsx":"175","C:\\dev\\saveinmed\\frontend\\src\\components\\ProductCard.tsx":"176","C:\\dev\\saveinmed\\frontend\\src\\components\\ProductOffersModal.tsx":"177","C:\\dev\\saveinmed\\frontend\\src\\components\\ProdutoForm.tsx":"178","C:\\dev\\saveinmed\\frontend\\src\\components\\ProdutoList.tsx":"179","C:\\dev\\saveinmed\\frontend\\src\\components\\profile\\ProfileForm.tsx":"180","C:\\dev\\saveinmed\\frontend\\src\\components\\ProtectedRoute.tsx":"181","C:\\dev\\saveinmed\\frontend\\src\\components\\RefreshButton.tsx":"182","C:\\dev\\saveinmed\\frontend\\src\\components\\RegistroIncompletoModal.tsx":"183","C:\\dev\\saveinmed\\frontend\\src\\components\\ReviewModal.tsx":"184","C:\\dev\\saveinmed\\frontend\\src\\components\\SearchBar.tsx":"185","C:\\dev\\saveinmed\\frontend\\src\\components\\Sidebar.tsx":"186","C:\\dev\\saveinmed\\frontend\\src\\components\\StandardButton.tsx":"187","C:\\dev\\saveinmed\\frontend\\src\\components\\TableActions.tsx":"188","C:\\dev\\saveinmed\\frontend\\src\\components\\TableContainer.tsx":"189","C:\\dev\\saveinmed\\frontend\\src\\components\\UsuarioForm.tsx":"190","C:\\dev\\saveinmed\\frontend\\src\\components\\UsuarioList.tsx":"191","C:\\dev\\saveinmed\\frontend\\src\\context\\AuthContext.test.tsx":"192","C:\\dev\\saveinmed\\frontend\\src\\context\\AuthContext.tsx":"193","C:\\dev\\saveinmed\\frontend\\src\\context\\ThemeContext.test.tsx":"194","C:\\dev\\saveinmed\\frontend\\src\\context\\ThemeContext.tsx":"195","C:\\dev\\saveinmed\\frontend\\src\\contexts\\AuthContext.tsx":"196","C:\\dev\\saveinmed\\frontend\\src\\contexts\\CarrinhoContext.tsx":"197","C:\\dev\\saveinmed\\frontend\\src\\contexts\\EmpresaContext.tsx":"198","C:\\dev\\saveinmed\\frontend\\src\\hooks\\useAuth.ts":"199","C:\\dev\\saveinmed\\frontend\\src\\hooks\\useAuthGuard.ts":"200","C:\\dev\\saveinmed\\frontend\\src\\hooks\\useCarrinhoCompras.ts":"201","C:\\dev\\saveinmed\\frontend\\src\\hooks\\useCarrinhos.ts":"202","C:\\dev\\saveinmed\\frontend\\src\\hooks\\useCatalogoProdutos.ts":"203","C:\\dev\\saveinmed\\frontend\\src\\hooks\\useCategorias.ts":"204","C:\\dev\\saveinmed\\frontend\\src\\hooks\\useCepLookup.ts":"205","C:\\dev\\saveinmed\\frontend\\src\\hooks\\useDashboardData.ts":"206","C:\\dev\\saveinmed\\frontend\\src\\hooks\\useDebounce.test.ts":"207","C:\\dev\\saveinmed\\frontend\\src\\hooks\\useDebounce.ts":"208","C:\\dev\\saveinmed\\frontend\\src\\hooks\\useEnderecos.ts":"209","C:\\dev\\saveinmed\\frontend\\src\\hooks\\useEntregas.ts":"210","C:\\dev\\saveinmed\\frontend\\src\\hooks\\useEstoque.ts":"211","C:\\dev\\saveinmed\\frontend\\src\\hooks\\useFaturas.ts":"212","C:\\dev\\saveinmed\\frontend\\src\\hooks\\useLaboratorios.ts":"213","C:\\dev\\saveinmed\\frontend\\src\\hooks\\usePagamentos.ts":"214","C:\\dev\\saveinmed\\frontend\\src\\hooks\\usePedidos.ts":"215","C:\\dev\\saveinmed\\frontend\\src\\hooks\\usePersistentFilters.test.ts":"216","C:\\dev\\saveinmed\\frontend\\src\\hooks\\usePersistentFilters.ts":"217","C:\\dev\\saveinmed\\frontend\\src\\hooks\\useProdutos.ts":"218","C:\\dev\\saveinmed\\frontend\\src\\hooks\\useRegistroCompleto.ts":"219","C:\\dev\\saveinmed\\frontend\\src\\hooks\\useUsuarios.ts":"220","C:\\dev\\saveinmed\\frontend\\src\\hooks\\useUsuariosApi.ts":"221","C:\\dev\\saveinmed\\frontend\\src\\layouts\\DashboardLayout.tsx":"222","C:\\dev\\saveinmed\\frontend\\src\\layouts\\RoleBasedLayout.tsx":"223","C:\\dev\\saveinmed\\frontend\\src\\layouts\\Shell.tsx":"224","C:\\dev\\saveinmed\\frontend\\src\\lib\\appwrite.ts":"225","C:\\dev\\saveinmed\\frontend\\src\\lib\\auth.ts":"226","C:\\dev\\saveinmed\\frontend\\src\\lib\\emailService.ts":"227","C:\\dev\\saveinmed\\frontend\\src\\lib\\error-translator.ts":"228","C:\\dev\\saveinmed\\frontend\\src\\lib\\logger.ts":"229","C:\\dev\\saveinmed\\frontend\\src\\lib\\masks.ts":"230","C:\\dev\\saveinmed\\frontend\\src\\main.tsx":"231","C:\\dev\\saveinmed\\frontend\\src\\middleware.ts":"232","C:\\dev\\saveinmed\\frontend\\src\\pages\\auth\\ForgotPassword.tsx":"233","C:\\dev\\saveinmed\\frontend\\src\\pages\\auth\\Login.tsx":"234","C:\\dev\\saveinmed\\frontend\\src\\pages\\auth\\Register.tsx":"235","C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\admin\\CompaniesPage.tsx":"236","C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\admin\\DashboardHome.tsx":"237","C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\admin\\index.ts":"238","C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\admin\\LogisticsPage.tsx":"239","C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\admin\\OrdersPage.tsx":"240","C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\admin\\ProductsPage.tsx":"241","C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\admin\\ProfilePage.tsx":"242","C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\admin\\ReviewsPage.tsx":"243","C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\admin\\ShippingSettings.tsx":"244","C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\admin\\UsersPage.tsx":"245","C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\Company.tsx":"246","C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\delivery\\DeliveryDashboard.tsx":"247","C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\employee\\EmployeeDashboard.tsx":"248","C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\MyProfile.tsx":"249","C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\seller\\Inventory.tsx":"250","C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\seller\\ProductCreate.tsx":"251","C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\seller\\SellerDashboard.tsx":"252","C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\seller\\Team.tsx":"253","C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\seller\\Wallet.tsx":"254","C:\\dev\\saveinmed\\frontend\\src\\pages\\marketplace\\Cart.tsx":"255","C:\\dev\\saveinmed\\frontend\\src\\pages\\marketplace\\Checkout.tsx":"256","C:\\dev\\saveinmed\\frontend\\src\\pages\\marketplace\\HelpCenter.tsx":"257","C:\\dev\\saveinmed\\frontend\\src\\pages\\marketplace\\OrderDetails.tsx":"258","C:\\dev\\saveinmed\\frontend\\src\\pages\\marketplace\\Orders.tsx":"259","C:\\dev\\saveinmed\\frontend\\src\\pages\\marketplace\\ProductSearch.tsx":"260","C:\\dev\\saveinmed\\frontend\\src\\services\\adminService.test.ts":"261","C:\\dev\\saveinmed\\frontend\\src\\services\\adminService.ts":"262","C:\\dev\\saveinmed\\frontend\\src\\services\\apiClient.test.ts":"263","C:\\dev\\saveinmed\\frontend\\src\\services\\apiClient.ts":"264","C:\\dev\\saveinmed\\frontend\\src\\services\\auth.integration.test.ts":"265","C:\\dev\\saveinmed\\frontend\\src\\services\\auth.test.ts":"266","C:\\dev\\saveinmed\\frontend\\src\\services\\auth.ts":"267","C:\\dev\\saveinmed\\frontend\\src\\services\\cadastroProdutoService.ts":"268","C:\\dev\\saveinmed\\frontend\\src\\services\\carrinhoApiService.ts":"269","C:\\dev\\saveinmed\\frontend\\src\\services\\carrinhoService.ts":"270","C:\\dev\\saveinmed\\frontend\\src\\services\\catalogoProdutoService.ts":"271","C:\\dev\\saveinmed\\frontend\\src\\services\\categoriaService.ts":"272","C:\\dev\\saveinmed\\frontend\\src\\services\\dashboardService.ts":"273","C:\\dev\\saveinmed\\frontend\\src\\services\\empresaApiService.ts":"274","C:\\dev\\saveinmed\\frontend\\src\\services\\empresasDadosService.ts":"275","C:\\dev\\saveinmed\\frontend\\src\\services\\empresaService.ts":"276","C:\\dev\\saveinmed\\frontend\\src\\services\\enderecoService.ts":"277","C:\\dev\\saveinmed\\frontend\\src\\services\\entregasApiService.ts":"278","C:\\dev\\saveinmed\\frontend\\src\\services\\faturaApiService.ts":"279","C:\\dev\\saveinmed\\frontend\\src\\services\\faturaService.ts":"280","C:\\dev\\saveinmed\\frontend\\src\\services\\financialService.test.ts":"281","C:\\dev\\saveinmed\\frontend\\src\\services\\financialService.ts":"282","C:\\dev\\saveinmed\\frontend\\src\\services\\laboratorioApiService.ts":"283","C:\\dev\\saveinmed\\frontend\\src\\services\\laboratorioService.ts":"284","C:\\dev\\saveinmed\\frontend\\src\\services\\mercadoPagoService.ts":"285","C:\\dev\\saveinmed\\frontend\\src\\services\\ordersService.test.ts":"286","C:\\dev\\saveinmed\\frontend\\src\\services\\ordersService.ts":"287","C:\\dev\\saveinmed\\frontend\\src\\services\\pagamentoApiService.ts":"288","C:\\dev\\saveinmed\\frontend\\src\\services\\pagamentoService.ts":"289","C:\\dev\\saveinmed\\frontend\\src\\services\\pedidoApiService.ts":"290","C:\\dev\\saveinmed\\frontend\\src\\services\\pedidoService.ts":"291","C:\\dev\\saveinmed\\frontend\\src\\services\\productService.test.ts":"292","C:\\dev\\saveinmed\\frontend\\src\\services\\productService.ts":"293","C:\\dev\\saveinmed\\frontend\\src\\services\\produtoService.ts":"294","C:\\dev\\saveinmed\\frontend\\src\\services\\produtosVendaService.ts":"295","C:\\dev\\saveinmed\\frontend\\src\\services\\produtoVendaService.ts":"296","C:\\dev\\saveinmed\\frontend\\src\\services\\shippingService.test.ts":"297","C:\\dev\\saveinmed\\frontend\\src\\services\\shippingService.ts":"298","C:\\dev\\saveinmed\\frontend\\src\\services\\usuarioApiService.ts":"299","C:\\dev\\saveinmed\\frontend\\src\\services\\usuariosDataService.ts":"300","C:\\dev\\saveinmed\\frontend\\src\\services\\usuarioService.ts":"301","C:\\dev\\saveinmed\\frontend\\src\\stores\\cartStore.test.ts":"302","C:\\dev\\saveinmed\\frontend\\src\\stores\\cartStore.ts":"303","C:\\dev\\saveinmed\\frontend\\src\\test\\setup.ts":"304","C:\\dev\\saveinmed\\frontend\\src\\tests\\integration\\apiContracts.test.ts":"305","C:\\dev\\saveinmed\\frontend\\src\\types\\auth.ts":"306","C:\\dev\\saveinmed\\frontend\\src\\types\\empresas-dados.ts":"307","C:\\dev\\saveinmed\\frontend\\src\\types\\product.ts":"308","C:\\dev\\saveinmed\\frontend\\src\\types\\shipping.ts":"309","C:\\dev\\saveinmed\\frontend\\src\\utils\\authUtils.ts":"310","C:\\dev\\saveinmed\\frontend\\src\\utils\\cnpj.ts":"311","C:\\dev\\saveinmed\\frontend\\src\\utils\\format.test.ts":"312","C:\\dev\\saveinmed\\frontend\\src\\utils\\format.ts":"313","C:\\dev\\saveinmed\\frontend\\src\\utils\\jwt.test.ts":"314","C:\\dev\\saveinmed\\frontend\\src\\utils\\jwt.ts":"315","C:\\dev\\saveinmed\\frontend\\src\\utils\\logger.test.ts":"316","C:\\dev\\saveinmed\\frontend\\src\\utils\\logger.ts":"317","C:\\dev\\saveinmed\\frontend\\src\\utils\\phone.ts":"318","C:\\dev\\saveinmed\\frontend\\src\\utils\\robustEmpresaId.ts":"319","C:\\dev\\saveinmed\\frontend\\src\\types\\global.d.ts":"320"},{"size":23027,"mtime":1772639550514,"results":"321","hashOfConfig":"322"},{"size":17524,"mtime":1772639550514,"results":"323","hashOfConfig":"322"},{"size":3422,"mtime":1772639550520,"results":"324","hashOfConfig":"322"},{"size":3033,"mtime":1772639550517,"results":"325","hashOfConfig":"322"},{"size":6918,"mtime":1772639550525,"results":"326","hashOfConfig":"322"},{"size":7768,"mtime":1772639550524,"results":"327","hashOfConfig":"322"},{"size":11590,"mtime":1772639550528,"results":"328","hashOfConfig":"322"},{"size":5688,"mtime":1772639550528,"results":"329","hashOfConfig":"322"},{"size":1898,"mtime":1772639550531,"results":"330","hashOfConfig":"322"},{"size":2636,"mtime":1772639550531,"results":"331","hashOfConfig":"322"},{"size":3253,"mtime":1772639550535,"results":"332","hashOfConfig":"322"},{"size":2955,"mtime":1772639550537,"results":"333","hashOfConfig":"322"},{"size":704,"mtime":1772639550540,"results":"334","hashOfConfig":"322"},{"size":3563,"mtime":1772885625980,"results":"335","hashOfConfig":"322"},{"size":2486,"mtime":1772639550544,"results":"336","hashOfConfig":"322"},{"size":5756,"mtime":1772885625986,"results":"337","hashOfConfig":"322"},{"size":5211,"mtime":1772639550546,"results":"338","hashOfConfig":"322"},{"size":3347,"mtime":1772885014304,"results":"339","hashOfConfig":"322"},{"size":3513,"mtime":1772639550553,"results":"340","hashOfConfig":"322"},{"size":3039,"mtime":1772639550551,"results":"341","hashOfConfig":"322"},{"size":2752,"mtime":1772639550558,"results":"342","hashOfConfig":"322"},{"size":2505,"mtime":1772639550558,"results":"343","hashOfConfig":"322"},{"size":4763,"mtime":1772885625991,"results":"344","hashOfConfig":"322"},{"size":11625,"mtime":1772639550573,"results":"345","hashOfConfig":"322"},{"size":3590,"mtime":1772639550573,"results":"346","hashOfConfig":"322"},{"size":3577,"mtime":1772639558209,"results":"347","hashOfConfig":"322"},{"size":1265,"mtime":1772639550580,"results":"348","hashOfConfig":"322"},{"size":4797,"mtime":1772639550584,"results":"349","hashOfConfig":"322"},{"size":3531,"mtime":1772639550584,"results":"350","hashOfConfig":"322"},{"size":5042,"mtime":1772639558215,"results":"351","hashOfConfig":"322"},{"size":7095,"mtime":1772639558211,"results":"352","hashOfConfig":"322"},{"size":8165,"mtime":1772639558212,"results":"353","hashOfConfig":"322"},{"size":2772,"mtime":1772639550601,"results":"354","hashOfConfig":"322"},{"size":2367,"mtime":1772639550597,"results":"355","hashOfConfig":"322"},{"size":3830,"mtime":1772639550606,"results":"356","hashOfConfig":"322"},{"size":2387,"mtime":1772639550606,"results":"357","hashOfConfig":"322"},{"size":4515,"mtime":1772639550611,"results":"358","hashOfConfig":"322"},{"size":2486,"mtime":1772885222472,"results":"359","hashOfConfig":"322"},{"size":3937,"mtime":1772639550615,"results":"360","hashOfConfig":"322"},{"size":2119,"mtime":1772639550611,"results":"361","hashOfConfig":"322"},{"size":7224,"mtime":1772639550608,"results":"362","hashOfConfig":"322"},{"size":5355,"mtime":1772885625996,"results":"363","hashOfConfig":"322"},{"size":2192,"mtime":1772639550620,"results":"364","hashOfConfig":"322"},{"size":6674,"mtime":1772885626000,"results":"365","hashOfConfig":"322"},{"size":7415,"mtime":1772639550622,"results":"366","hashOfConfig":"322"},{"size":5322,"mtime":1772639550624,"results":"367","hashOfConfig":"322"},{"size":1744,"mtime":1772639550711,"results":"368","hashOfConfig":"322"},{"size":6152,"mtime":1772885626005,"results":"369","hashOfConfig":"322"},{"size":2547,"mtime":1772639550711,"results":"370","hashOfConfig":"322"},{"size":3499,"mtime":1772639550719,"results":"371","hashOfConfig":"322"},{"size":5472,"mtime":1772639550735,"results":"372","hashOfConfig":"322"},{"size":4162,"mtime":1772885626013,"results":"373","hashOfConfig":"322"},{"size":5164,"mtime":1772639550747,"results":"374","hashOfConfig":"322"},{"size":907,"mtime":1772639550748,"results":"375","hashOfConfig":"322"},{"size":6696,"mtime":1772639550756,"results":"376","hashOfConfig":"322"},{"size":1921,"mtime":1772639550757,"results":"377","hashOfConfig":"322"},{"size":8258,"mtime":1772884728014,"results":"378","hashOfConfig":"322"},{"size":22436,"mtime":1772679496350,"results":"379","hashOfConfig":"322"},{"size":47531,"mtime":1772884600389,"results":"380","hashOfConfig":"322"},{"size":79699,"mtime":1772639550765,"results":"381","hashOfConfig":"322"},{"size":9853,"mtime":1772639550766,"results":"382","hashOfConfig":"322"},{"size":54491,"mtime":1772639550770,"results":"383","hashOfConfig":"322"},{"size":4668,"mtime":1772639550771,"results":"384","hashOfConfig":"322"},{"size":288,"mtime":1772639550773,"results":"385","hashOfConfig":"322"},{"size":2981,"mtime":1772639550773,"results":"386","hashOfConfig":"322"},{"size":326,"mtime":1772639550773,"results":"387","hashOfConfig":"322"},{"size":0,"mtime":1772883308148,"results":"388","hashOfConfig":"322"},{"size":9566,"mtime":1772885626019,"results":"389","hashOfConfig":"322"},{"size":9566,"mtime":1772885626024,"results":"390","hashOfConfig":"322"},{"size":6379,"mtime":1772884728021,"results":"391","hashOfConfig":"322"},{"size":18282,"mtime":1772885626029,"results":"392","hashOfConfig":"322"},{"size":39176,"mtime":1772885626036,"results":"393","hashOfConfig":"322"},{"size":1505,"mtime":1772639550800,"results":"394","hashOfConfig":"322"},{"size":7489,"mtime":1772639550800,"results":"395","hashOfConfig":"322"},{"size":9031,"mtime":1772639550800,"results":"396","hashOfConfig":"322"},{"size":9191,"mtime":1772885626043,"results":"397","hashOfConfig":"322"},{"size":277,"mtime":1772639550833,"results":"398","hashOfConfig":"322"},{"size":7038,"mtime":1772639550838,"results":"399","hashOfConfig":"322"},{"size":8661,"mtime":1772639550838,"results":"400","hashOfConfig":"322"},{"size":7550,"mtime":1772639550840,"results":"401","hashOfConfig":"322"},{"size":5954,"mtime":1772639550843,"results":"402","hashOfConfig":"322"},{"size":3739,"mtime":1772885626049,"results":"403","hashOfConfig":"322"},{"size":7128,"mtime":1772639550849,"results":"404","hashOfConfig":"322"},{"size":1519,"mtime":1772639550849,"results":"405","hashOfConfig":"322"},{"size":4755,"mtime":1772639550851,"results":"406","hashOfConfig":"322"},{"size":11352,"mtime":1772639550854,"results":"407","hashOfConfig":"322"},{"size":14648,"mtime":1772639550866,"results":"408","hashOfConfig":"322"},{"size":7233,"mtime":1772639550872,"results":"409","hashOfConfig":"322"},{"size":8930,"mtime":1772639550868,"results":"410","hashOfConfig":"322"},{"size":6727,"mtime":1772639550868,"results":"411","hashOfConfig":"322"},{"size":6111,"mtime":1772881918278,"results":"412","hashOfConfig":"322"},{"size":36130,"mtime":1772885687326,"results":"413","hashOfConfig":"322"},{"size":10863,"mtime":1772639550878,"results":"414","hashOfConfig":"322"},{"size":6331,"mtime":1772881918283,"results":"415","hashOfConfig":"322"},{"size":273,"mtime":1772639550880,"results":"416","hashOfConfig":"322"},{"size":24558,"mtime":1772883303094,"results":"417","hashOfConfig":"322"},{"size":21914,"mtime":1772883303096,"results":"418","hashOfConfig":"322"},{"size":36839,"mtime":1772883303099,"results":"419","hashOfConfig":"322"},{"size":36799,"mtime":1772883289293,"results":"420","hashOfConfig":"322"},{"size":34494,"mtime":1772639550890,"results":"421","hashOfConfig":"322"},{"size":21618,"mtime":1772883289293,"results":"422","hashOfConfig":"322"},{"size":8886,"mtime":1772679496367,"results":"423","hashOfConfig":"322"},{"size":1490,"mtime":1772639550897,"results":"424","hashOfConfig":"322"},{"size":3882,"mtime":1772639550900,"results":"425","hashOfConfig":"322"},{"size":33412,"mtime":1772883303099,"results":"426","hashOfConfig":"322"},{"size":14147,"mtime":1772639551042,"results":"427","hashOfConfig":"322"},{"size":7010,"mtime":1772885626051,"results":"428","hashOfConfig":"322"},{"size":15645,"mtime":1772639551601,"results":"429","hashOfConfig":"322"},{"size":23545,"mtime":1772885687338,"results":"430","hashOfConfig":"322"},{"size":8030,"mtime":1772885626058,"results":"431","hashOfConfig":"322"},{"size":13329,"mtime":1772885626065,"results":"432","hashOfConfig":"322"},{"size":716,"mtime":1772639552204,"results":"433","hashOfConfig":"322"},{"size":28509,"mtime":1772639552249,"results":"434","hashOfConfig":"322"},{"size":5711,"mtime":1772885626072,"results":"435","hashOfConfig":"322"},{"size":17979,"mtime":1772639552261,"results":"436","hashOfConfig":"322"},{"size":14382,"mtime":1772639552304,"results":"437","hashOfConfig":"322"},{"size":14999,"mtime":1772639552299,"results":"438","hashOfConfig":"322"},{"size":2627,"mtime":1772883303101,"results":"439","hashOfConfig":"322"},{"size":5093,"mtime":1772885687331,"results":"440","hashOfConfig":"322"},{"size":7850,"mtime":1772639552329,"results":"441","hashOfConfig":"322"},{"size":0,"mtime":1772639552331,"results":"442","hashOfConfig":"322"},{"size":36401,"mtime":1772639552334,"results":"443","hashOfConfig":"322"},{"size":34048,"mtime":1772679496368,"results":"444","hashOfConfig":"322"},{"size":283,"mtime":1772639552339,"results":"445","hashOfConfig":"322"},{"size":7241,"mtime":1772881918287,"results":"446","hashOfConfig":"322"},{"size":29802,"mtime":1772883303101,"results":"447","hashOfConfig":"322"},{"size":8700,"mtime":1772639552365,"results":"448","hashOfConfig":"322"},{"size":6464,"mtime":1772881511986,"results":"449","hashOfConfig":"322"},{"size":1617,"mtime":1772639552387,"results":"450","hashOfConfig":"322"},{"size":2485,"mtime":1772639552757,"results":"451","hashOfConfig":"322"},{"size":2945,"mtime":1772881511973,"results":"452","hashOfConfig":"322"},{"size":68863,"mtime":1772884545382,"results":"453","hashOfConfig":"322"},{"size":17673,"mtime":1772639552397,"results":"454","hashOfConfig":"322"},{"size":7360,"mtime":1772639552398,"results":"455","hashOfConfig":"322"},{"size":4486,"mtime":1772639552402,"results":"456","hashOfConfig":"322"},{"size":10240,"mtime":1772885626078,"results":"457","hashOfConfig":"322"},{"size":4500,"mtime":1772885970093,"results":"458","hashOfConfig":"322"},{"size":12198,"mtime":1772885626090,"results":"459","hashOfConfig":"322"},{"size":6870,"mtime":1772884728027,"results":"460","hashOfConfig":"322"},{"size":8623,"mtime":1772639552422,"results":"461","hashOfConfig":"322"},{"size":4378,"mtime":1772639552423,"results":"462","hashOfConfig":"322"},{"size":4370,"mtime":1772885970093,"results":"463","hashOfConfig":"322"},{"size":3603,"mtime":1772639552426,"results":"464","hashOfConfig":"322"},{"size":4659,"mtime":1772639552429,"results":"465","hashOfConfig":"322"},{"size":4708,"mtime":1772885626099,"results":"466","hashOfConfig":"322"},{"size":12598,"mtime":1772639552431,"results":"467","hashOfConfig":"322"},{"size":8781,"mtime":1772885626107,"results":"468","hashOfConfig":"322"},{"size":21690,"mtime":1772639552443,"results":"469","hashOfConfig":"322"},{"size":3365,"mtime":1772639552448,"results":"470","hashOfConfig":"322"},{"size":7745,"mtime":1772639552455,"results":"471","hashOfConfig":"322"},{"size":6131,"mtime":1772639552459,"results":"472","hashOfConfig":"322"},{"size":13093,"mtime":1772886643834,"results":"473","hashOfConfig":"322"},{"size":3822,"mtime":1772639552464,"results":"474","hashOfConfig":"322"},{"size":0,"mtime":1772639552472,"results":"475","hashOfConfig":"322"},{"size":0,"mtime":1772639552481,"results":"476","hashOfConfig":"322"},{"size":4174,"mtime":1772885970095,"results":"477","hashOfConfig":"322"},{"size":3278,"mtime":1772639552485,"results":"478","hashOfConfig":"322"},{"size":2457,"mtime":1772639552492,"results":"479","hashOfConfig":"322"},{"size":3754,"mtime":1772639552512,"results":"480","hashOfConfig":"322"},{"size":5368,"mtime":1772885687277,"results":"481","hashOfConfig":"322"},{"size":4699,"mtime":1772639552529,"results":"482","hashOfConfig":"322"},{"size":8008,"mtime":1772885626121,"results":"483","hashOfConfig":"322"},{"size":495,"mtime":1772639552556,"results":"484","hashOfConfig":"322"},{"size":2378,"mtime":1772639552559,"results":"485","hashOfConfig":"322"},{"size":3779,"mtime":1772881653687,"results":"486","hashOfConfig":"322"},{"size":12590,"mtime":1772639552563,"results":"487","hashOfConfig":"322"},{"size":1131,"mtime":1772639552574,"results":"488","hashOfConfig":"322"},{"size":7557,"mtime":1772881653677,"results":"489","hashOfConfig":"322"},{"size":4488,"mtime":1772881653679,"results":"490","hashOfConfig":"322"},{"size":6954,"mtime":1772639552605,"results":"491","hashOfConfig":"322"},{"size":3907,"mtime":1772885970095,"results":"492","hashOfConfig":"322"},{"size":2184,"mtime":1772639552645,"results":"493","hashOfConfig":"322"},{"size":10159,"mtime":1772886833577,"results":"494","hashOfConfig":"322"},{"size":5085,"mtime":1772639552698,"results":"495","hashOfConfig":"322"},{"size":2083,"mtime":1772639552706,"results":"496","hashOfConfig":"322"},{"size":2782,"mtime":1772639552715,"results":"497","hashOfConfig":"322"},{"size":12030,"mtime":1772639552718,"results":"498","hashOfConfig":"322"},{"size":6490,"mtime":1772639552723,"results":"499","hashOfConfig":"322"},{"size":7250,"mtime":1772639552740,"results":"500","hashOfConfig":"322"},{"size":11917,"mtime":1772639552759,"results":"501","hashOfConfig":"322"},{"size":946,"mtime":1772817564881,"results":"502","hashOfConfig":"322"},{"size":1189,"mtime":1772639552744,"results":"503","hashOfConfig":"322"},{"size":5239,"mtime":1772639552745,"results":"504","hashOfConfig":"322"},{"size":5251,"mtime":1772639552745,"results":"505","hashOfConfig":"322"},{"size":1014,"mtime":1772639552746,"results":"506","hashOfConfig":"322"},{"size":6177,"mtime":1772885928683,"results":"507","hashOfConfig":"322"},{"size":1373,"mtime":1772885154596,"results":"508","hashOfConfig":"322"},{"size":1554,"mtime":1772886086738,"results":"509","hashOfConfig":"322"},{"size":1092,"mtime":1772639552752,"results":"510","hashOfConfig":"322"},{"size":9648,"mtime":1772885626149,"results":"511","hashOfConfig":"322"},{"size":4066,"mtime":1772639552756,"results":"512","hashOfConfig":"322"},{"size":3913,"mtime":1772818145198,"results":"513","hashOfConfig":"322"},{"size":3795,"mtime":1772817552847,"results":"514","hashOfConfig":"322"},{"size":3163,"mtime":1772639552762,"results":"515","hashOfConfig":"322"},{"size":2653,"mtime":1772639552764,"results":"516","hashOfConfig":"322"},{"size":1920,"mtime":1772639552765,"results":"517","hashOfConfig":"322"},{"size":9935,"mtime":1772639552768,"results":"518","hashOfConfig":"322"},{"size":8001,"mtime":1772639552769,"results":"519","hashOfConfig":"322"},{"size":2879,"mtime":1772881511974,"results":"520","hashOfConfig":"322"},{"size":1494,"mtime":1772639552773,"results":"521","hashOfConfig":"322"},{"size":3006,"mtime":1772885626156,"results":"522","hashOfConfig":"322"},{"size":5777,"mtime":1772885626158,"results":"523","hashOfConfig":"322"},{"size":6024,"mtime":1772884728009,"results":"524","hashOfConfig":"322"},{"size":5878,"mtime":1772886139925,"results":"525","hashOfConfig":"322"},{"size":4078,"mtime":1772639552780,"results":"526","hashOfConfig":"322"},{"size":3478,"mtime":1772639552780,"results":"527","hashOfConfig":"322"},{"size":3040,"mtime":1772639552781,"results":"528","hashOfConfig":"322"},{"size":428,"mtime":1772639552785,"results":"529","hashOfConfig":"322"},{"size":5689,"mtime":1772885626170,"results":"530","hashOfConfig":"322"},{"size":4445,"mtime":1772678869872,"results":"531","hashOfConfig":"322"},{"size":0,"mtime":1772639552796,"results":"532","hashOfConfig":"322"},{"size":4589,"mtime":1772886139928,"results":"533","hashOfConfig":"322"},{"size":6362,"mtime":1772639552798,"results":"534","hashOfConfig":"322"},{"size":3885,"mtime":1772885626180,"results":"535","hashOfConfig":"322"},{"size":4959,"mtime":1772639552801,"results":"536","hashOfConfig":"322"},{"size":3061,"mtime":1772639552801,"results":"537","hashOfConfig":"322"},{"size":684,"mtime":1772639552804,"results":"538","hashOfConfig":"322"},{"size":3955,"mtime":1772678830482,"results":"539","hashOfConfig":"322"},{"size":992,"mtime":1772639552805,"results":"540","hashOfConfig":"322"},{"size":5535,"mtime":1772639552808,"results":"541","hashOfConfig":"322"},{"size":3696,"mtime":1772816989494,"results":"542","hashOfConfig":"322"},{"size":354,"mtime":1772639552810,"results":"543","hashOfConfig":"322"},{"size":493,"mtime":1772639552810,"results":"544","hashOfConfig":"322"},{"size":10675,"mtime":1772885687284,"results":"545","hashOfConfig":"322"},{"size":1306,"mtime":1772885014290,"results":"546","hashOfConfig":"322"},{"size":970,"mtime":1772639552816,"results":"547","hashOfConfig":"322"},{"size":11736,"mtime":1772639558220,"results":"548","hashOfConfig":"322"},{"size":5927,"mtime":1772639552819,"results":"549","hashOfConfig":"322"},{"size":207,"mtime":1772639552821,"results":"550","hashOfConfig":"322"},{"size":7228,"mtime":1772639552821,"results":"551","hashOfConfig":"322"},{"size":451,"mtime":1772639552823,"results":"552","hashOfConfig":"322"},{"size":1139,"mtime":1772639552823,"results":"553","hashOfConfig":"322"},{"size":7664,"mtime":1772885687291,"results":"554","hashOfConfig":"322"},{"size":27772,"mtime":1772885687295,"results":"555","hashOfConfig":"322"},{"size":18627,"mtime":1772885687300,"results":"556","hashOfConfig":"322"},{"size":32803,"mtime":1772639552840,"results":"557","hashOfConfig":"322"},{"size":5658,"mtime":1772639552841,"results":"558","hashOfConfig":"322"},{"size":429,"mtime":1772639552850,"results":"559","hashOfConfig":"322"},{"size":6240,"mtime":1772639552843,"results":"560","hashOfConfig":"322"},{"size":12542,"mtime":1772639552844,"results":"561","hashOfConfig":"322"},{"size":19640,"mtime":1772639552846,"results":"562","hashOfConfig":"322"},{"size":6768,"mtime":1772639552846,"results":"563","hashOfConfig":"322"},{"size":5745,"mtime":1772639552848,"results":"564","hashOfConfig":"322"},{"size":15684,"mtime":1772884486579,"results":"565","hashOfConfig":"322"},{"size":14224,"mtime":1772817712874,"results":"566","hashOfConfig":"322"},{"size":52825,"mtime":1772817769187,"results":"567","hashOfConfig":"322"},{"size":13988,"mtime":1772639552852,"results":"568","hashOfConfig":"322"},{"size":2502,"mtime":1772639552857,"results":"569","hashOfConfig":"322"},{"size":13484,"mtime":1772639552835,"results":"570","hashOfConfig":"322"},{"size":9826,"mtime":1772639552857,"results":"571","hashOfConfig":"322"},{"size":18671,"mtime":1772639552861,"results":"572","hashOfConfig":"322"},{"size":9302,"mtime":1772639552863,"results":"573","hashOfConfig":"322"},{"size":10240,"mtime":1772817692036,"results":"574","hashOfConfig":"322"},{"size":7823,"mtime":1772639552866,"results":"575","hashOfConfig":"322"},{"size":7459,"mtime":1772639552868,"results":"576","hashOfConfig":"322"},{"size":18353,"mtime":1772639552868,"results":"577","hashOfConfig":"322"},{"size":6960,"mtime":1772639552871,"results":"578","hashOfConfig":"322"},{"size":8765,"mtime":1772639552871,"results":"579","hashOfConfig":"322"},{"size":26735,"mtime":1772639552874,"results":"580","hashOfConfig":"322"},{"size":16577,"mtime":1772639552874,"results":"581","hashOfConfig":"322"},{"size":7953,"mtime":1772639552888,"results":"582","hashOfConfig":"322"},{"size":12587,"mtime":1772639552890,"results":"583","hashOfConfig":"322"},{"size":1493,"mtime":1772639552890,"results":"584","hashOfConfig":"322"},{"size":1627,"mtime":1772639552893,"results":"585","hashOfConfig":"322"},{"size":1673,"mtime":1772639552893,"results":"586","hashOfConfig":"322"},{"size":2979,"mtime":1772639552893,"results":"587","hashOfConfig":"322"},{"size":2130,"mtime":1772639552895,"results":"588","hashOfConfig":"322"},{"size":3201,"mtime":1772639552895,"results":"589","hashOfConfig":"322"},{"size":9571,"mtime":1772639552898,"results":"590","hashOfConfig":"322"},{"size":421,"mtime":1772639552898,"results":"591","hashOfConfig":"322"},{"size":4003,"mtime":1772884728005,"results":"592","hashOfConfig":"322"},{"size":1008,"mtime":1772885626186,"results":"593","hashOfConfig":"322"},{"size":12624,"mtime":1772885724371,"results":"594","hashOfConfig":"322"},{"size":3137,"mtime":1772639552901,"results":"595","hashOfConfig":"322"},{"size":360,"mtime":1772639552904,"results":"596","hashOfConfig":"322"},{"size":885,"mtime":1772886702233,"results":"597","hashOfConfig":"322"},{"size":1981,"mtime":1772886497853,"results":"598","hashOfConfig":"322"},{"size":17175,"mtime":1772658301447,"results":"599","hashOfConfig":"322"},{"size":6145,"mtime":1772639552910,"results":"600","hashOfConfig":"322"},{"size":1089,"mtime":1772885214160,"results":"601","hashOfConfig":"322"},{"size":3886,"mtime":1772639552912,"results":"602","hashOfConfig":"322"},{"size":2048,"mtime":1772639552912,"results":"603","hashOfConfig":"322"},{"size":8565,"mtime":1772639552915,"results":"604","hashOfConfig":"322"},{"size":344,"mtime":1772639552915,"results":"605","hashOfConfig":"322"},{"size":11071,"mtime":1772639552915,"results":"606","hashOfConfig":"322"},{"size":4075,"mtime":1772639552917,"results":"607","hashOfConfig":"322"},{"size":997,"mtime":1772639552918,"results":"608","hashOfConfig":"322"},{"size":7293,"mtime":1772639552920,"results":"609","hashOfConfig":"322"},{"size":1128,"mtime":1772885214155,"results":"610","hashOfConfig":"322"},{"size":15466,"mtime":1772658258813,"results":"611","hashOfConfig":"322"},{"size":1864,"mtime":1772886833534,"results":"612","hashOfConfig":"322"},{"size":2041,"mtime":1772639552924,"results":"613","hashOfConfig":"322"},{"size":1552,"mtime":1772639552926,"results":"614","hashOfConfig":"322"},{"size":2402,"mtime":1772885214165,"results":"615","hashOfConfig":"322"},{"size":15995,"mtime":1772884486604,"results":"616","hashOfConfig":"322"},{"size":5837,"mtime":1772639552936,"results":"617","hashOfConfig":"322"},{"size":3419,"mtime":1772639552937,"results":"618","hashOfConfig":"322"},{"size":1080,"mtime":1772639552947,"results":"619","hashOfConfig":"322"},{"size":5613,"mtime":1772883608108,"results":"620","hashOfConfig":"322"},{"size":2583,"mtime":1772639552952,"results":"621","hashOfConfig":"322"},{"size":2167,"mtime":1772639552949,"results":"622","hashOfConfig":"322"},{"size":11397,"mtime":1772639552954,"results":"623","hashOfConfig":"322"},{"size":3425,"mtime":1772639552954,"results":"624","hashOfConfig":"322"},{"size":36,"mtime":1772639552954,"results":"625","hashOfConfig":"322"},{"size":15346,"mtime":1772639552961,"results":"626","hashOfConfig":"322"},{"size":3120,"mtime":1772883894615,"results":"627","hashOfConfig":"322"},{"size":1716,"mtime":1772639552965,"results":"628","hashOfConfig":"322"},{"size":971,"mtime":1772639552967,"results":"629","hashOfConfig":"322"},{"size":343,"mtime":1772639552967,"results":"630","hashOfConfig":"322"},{"size":3647,"mtime":1772883608110,"results":"631","hashOfConfig":"322"},{"size":2212,"mtime":1772639552973,"results":"632","hashOfConfig":"322"},{"size":1708,"mtime":1772639552973,"results":"633","hashOfConfig":"322"},{"size":640,"mtime":1772639552976,"results":"634","hashOfConfig":"322"},{"size":1952,"mtime":1772639552978,"results":"635","hashOfConfig":"322"},{"size":458,"mtime":1772639552978,"results":"636","hashOfConfig":"322"},{"size":2080,"mtime":1772639552980,"results":"637","hashOfConfig":"322"},{"size":556,"mtime":1772639552984,"results":"638","hashOfConfig":"322"},{"size":613,"mtime":1772639552985,"results":"639","hashOfConfig":"322"},{"size":4334,"mtime":1772639552985,"results":"640","hashOfConfig":"322"},{"size":744,"mtime":1772885014285,"results":"641","hashOfConfig":"322"},{"filePath":"642","messages":"643","suppressedMessages":"644","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"db40jl",{"filePath":"645","messages":"646","suppressedMessages":"647","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"648","messages":"649","suppressedMessages":"650","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"651","messages":"652","suppressedMessages":"653","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"654","messages":"655","suppressedMessages":"656","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"657","messages":"658","suppressedMessages":"659","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"660","messages":"661","suppressedMessages":"662","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"663","messages":"664","suppressedMessages":"665","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"666","messages":"667","suppressedMessages":"668","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"669","messages":"670","suppressedMessages":"671","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"672","messages":"673","suppressedMessages":"674","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"675","messages":"676","suppressedMessages":"677","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"678","messages":"679","suppressedMessages":"680","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"681","messages":"682","suppressedMessages":"683","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"684","messages":"685","suppressedMessages":"686","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"687","messages":"688","suppressedMessages":"689","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"690","messages":"691","suppressedMessages":"692","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"693","messages":"694","suppressedMessages":"695","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"696","messages":"697","suppressedMessages":"698","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"699","messages":"700","suppressedMessages":"701","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"702","messages":"703","suppressedMessages":"704","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"705","messages":"706","suppressedMessages":"707","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"708","messages":"709","suppressedMessages":"710","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"711","messages":"712","suppressedMessages":"713","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"714","messages":"715","suppressedMessages":"716","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"717","messages":"718","suppressedMessages":"719","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"720","messages":"721","suppressedMessages":"722","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"723","messages":"724","suppressedMessages":"725","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"726","messages":"727","suppressedMessages":"728","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"729","messages":"730","suppressedMessages":"731","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"732","messages":"733","suppressedMessages":"734","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"735","messages":"736","suppressedMessages":"737","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"738","messages":"739","suppressedMessages":"740","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"741","messages":"742","suppressedMessages":"743","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"744","messages":"745","suppressedMessages":"746","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"747","messages":"748","suppressedMessages":"749","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"750","messages":"751","suppressedMessages":"752","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"753","messages":"754","suppressedMessages":"755","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"756","messages":"757","suppressedMessages":"758","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"759","messages":"760","suppressedMessages":"761","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"762","messages":"763","suppressedMessages":"764","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"765","messages":"766","suppressedMessages":"767","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"768","messages":"769","suppressedMessages":"770","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"771","messages":"772","suppressedMessages":"773","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"774","messages":"775","suppressedMessages":"776","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"777","messages":"778","suppressedMessages":"779","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"780","messages":"781","suppressedMessages":"782","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"783","messages":"784","suppressedMessages":"785","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"786","messages":"787","suppressedMessages":"788","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"789","messages":"790","suppressedMessages":"791","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"792","messages":"793","suppressedMessages":"794","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"795","messages":"796","suppressedMessages":"797","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"798","messages":"799","suppressedMessages":"800","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"801","messages":"802","suppressedMessages":"803","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"804","messages":"805","suppressedMessages":"806","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"807","messages":"808","suppressedMessages":"809","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"810","messages":"811","suppressedMessages":"812","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"813","messages":"814","suppressedMessages":"815","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"816","messages":"817","suppressedMessages":"818","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"819","messages":"820","suppressedMessages":"821","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"822","messages":"823","suppressedMessages":"824","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"825","messages":"826","suppressedMessages":"827","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"828","messages":"829","suppressedMessages":"830","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"831","messages":"832","suppressedMessages":"833","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"834","messages":"835","suppressedMessages":"836","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"837","messages":"838","suppressedMessages":"839","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"840","messages":"841","suppressedMessages":"842","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"843","messages":"844","suppressedMessages":"845","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"846","messages":"847","suppressedMessages":"848","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"849","messages":"850","suppressedMessages":"851","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"852","messages":"853","suppressedMessages":"854","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"855","messages":"856","suppressedMessages":"857","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"858","messages":"859","suppressedMessages":"860","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"861","messages":"862","suppressedMessages":"863","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"864","messages":"865","suppressedMessages":"866","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"867","messages":"868","suppressedMessages":"869","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"870","messages":"871","suppressedMessages":"872","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"873","messages":"874","suppressedMessages":"875","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"876","messages":"877","suppressedMessages":"878","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"879","messages":"880","suppressedMessages":"881","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"882","messages":"883","suppressedMessages":"884","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"885","messages":"886","suppressedMessages":"887","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"888","messages":"889","suppressedMessages":"890","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"891","messages":"892","suppressedMessages":"893","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"894","messages":"895","suppressedMessages":"896","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"897","messages":"898","suppressedMessages":"899","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"900","messages":"901","suppressedMessages":"902","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"903","messages":"904","suppressedMessages":"905","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"906","messages":"907","suppressedMessages":"908","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"909","messages":"910","suppressedMessages":"911","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"912","messages":"913","suppressedMessages":"914","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"915","messages":"916","suppressedMessages":"917","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"918","messages":"919","suppressedMessages":"920","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"921","messages":"922","suppressedMessages":"923","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"924","messages":"925","suppressedMessages":"926","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"927","messages":"928","suppressedMessages":"929","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"930","messages":"931","suppressedMessages":"932","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"933","messages":"934","suppressedMessages":"935","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"936","messages":"937","suppressedMessages":"938","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"939","messages":"940","suppressedMessages":"941","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"942","messages":"943","suppressedMessages":"944","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"945","messages":"946","suppressedMessages":"947","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"948","messages":"949","suppressedMessages":"950","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"951","messages":"952","suppressedMessages":"953","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"954","messages":"955","suppressedMessages":"956","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"957","messages":"958","suppressedMessages":"959","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"960","messages":"961","suppressedMessages":"962","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"963","messages":"964","suppressedMessages":"965","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"966","messages":"967","suppressedMessages":"968","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"969","messages":"970","suppressedMessages":"971","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"972","messages":"973","suppressedMessages":"974","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"975","messages":"976","suppressedMessages":"977","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"978","messages":"979","suppressedMessages":"980","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"981","messages":"982","suppressedMessages":"983","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"984","messages":"985","suppressedMessages":"986","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"987","messages":"988","suppressedMessages":"989","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"990","messages":"991","suppressedMessages":"992","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"993","messages":"994","suppressedMessages":"995","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"996","messages":"997","suppressedMessages":"998","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"999","messages":"1000","suppressedMessages":"1001","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1002","messages":"1003","suppressedMessages":"1004","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1005","messages":"1006","suppressedMessages":"1007","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1008","messages":"1009","suppressedMessages":"1010","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1011","messages":"1012","suppressedMessages":"1013","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1014","messages":"1015","suppressedMessages":"1016","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1017","messages":"1018","suppressedMessages":"1019","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1020","messages":"1021","suppressedMessages":"1022","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1023","messages":"1024","suppressedMessages":"1025","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1026","messages":"1027","suppressedMessages":"1028","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1029","messages":"1030","suppressedMessages":"1031","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1032","messages":"1033","suppressedMessages":"1034","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1035","messages":"1036","suppressedMessages":"1037","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1038","messages":"1039","suppressedMessages":"1040","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1041","messages":"1042","suppressedMessages":"1043","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1044","messages":"1045","suppressedMessages":"1046","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1047","messages":"1048","suppressedMessages":"1049","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1050","messages":"1051","suppressedMessages":"1052","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1053","messages":"1054","suppressedMessages":"1055","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1056","messages":"1057","suppressedMessages":"1058","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1059","messages":"1060","suppressedMessages":"1061","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1062","messages":"1063","suppressedMessages":"1064","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1065","messages":"1066","suppressedMessages":"1067","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1068","messages":"1069","suppressedMessages":"1070","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1071","messages":"1072","suppressedMessages":"1073","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1074","messages":"1075","suppressedMessages":"1076","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1077","messages":"1078","suppressedMessages":"1079","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1080","messages":"1081","suppressedMessages":"1082","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1083","messages":"1084","suppressedMessages":"1085","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1086","messages":"1087","suppressedMessages":"1088","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1089","messages":"1090","suppressedMessages":"1091","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1092","messages":"1093","suppressedMessages":"1094","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1095","messages":"1096","suppressedMessages":"1097","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1098","messages":"1099","suppressedMessages":"1100","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1101","messages":"1102","suppressedMessages":"1103","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1104","messages":"1105","suppressedMessages":"1106","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1107","messages":"1108","suppressedMessages":"1109","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1110","messages":"1111","suppressedMessages":"1112","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1113","messages":"1114","suppressedMessages":"1115","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1116","messages":"1117","suppressedMessages":"1118","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1119","messages":"1120","suppressedMessages":"1121","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1122","messages":"1123","suppressedMessages":"1124","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1125","messages":"1126","suppressedMessages":"1127","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1128","messages":"1129","suppressedMessages":"1130","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1131","messages":"1132","suppressedMessages":"1133","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1134","messages":"1135","suppressedMessages":"1136","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1137","messages":"1138","suppressedMessages":"1139","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1140","messages":"1141","suppressedMessages":"1142","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1143","messages":"1144","suppressedMessages":"1145","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1146","messages":"1147","suppressedMessages":"1148","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1149","messages":"1150","suppressedMessages":"1151","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1152","messages":"1153","suppressedMessages":"1154","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1155","messages":"1156","suppressedMessages":"1157","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1158","messages":"1159","suppressedMessages":"1160","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1161","messages":"1162","suppressedMessages":"1163","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1164","messages":"1165","suppressedMessages":"1166","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1167","messages":"1168","suppressedMessages":"1169","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1170","messages":"1171","suppressedMessages":"1172","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1173","messages":"1174","suppressedMessages":"1175","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1176","messages":"1177","suppressedMessages":"1178","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1179","messages":"1180","suppressedMessages":"1181","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1182","messages":"1183","suppressedMessages":"1184","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1185","messages":"1186","suppressedMessages":"1187","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1188","messages":"1189","suppressedMessages":"1190","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1191","messages":"1192","suppressedMessages":"1193","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1194","messages":"1195","suppressedMessages":"1196","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1197","messages":"1198","suppressedMessages":"1199","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1200","messages":"1201","suppressedMessages":"1202","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1203","messages":"1204","suppressedMessages":"1205","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1206","messages":"1207","suppressedMessages":"1208","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1209","messages":"1210","suppressedMessages":"1211","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1212","messages":"1213","suppressedMessages":"1214","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1215","messages":"1216","suppressedMessages":"1217","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1218","messages":"1219","suppressedMessages":"1220","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1221","messages":"1222","suppressedMessages":"1223","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1224","messages":"1225","suppressedMessages":"1226","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1227","messages":"1228","suppressedMessages":"1229","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1230","messages":"1231","suppressedMessages":"1232","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1233","messages":"1234","suppressedMessages":"1235","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1236","messages":"1237","suppressedMessages":"1238","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1239","messages":"1240","suppressedMessages":"1241","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1242","messages":"1243","suppressedMessages":"1244","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1245","messages":"1246","suppressedMessages":"1247","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1248","messages":"1249","suppressedMessages":"1250","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1251","messages":"1252","suppressedMessages":"1253","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1254","messages":"1255","suppressedMessages":"1256","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1257","messages":"1258","suppressedMessages":"1259","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1260","messages":"1261","suppressedMessages":"1262","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1263","messages":"1264","suppressedMessages":"1265","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1266","messages":"1267","suppressedMessages":"1268","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1269","messages":"1270","suppressedMessages":"1271","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1272","messages":"1273","suppressedMessages":"1274","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1275","messages":"1276","suppressedMessages":"1277","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1278","messages":"1279","suppressedMessages":"1280","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1281","messages":"1282","suppressedMessages":"1283","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1284","messages":"1285","suppressedMessages":"1286","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1287","messages":"1288","suppressedMessages":"1289","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1290","messages":"1291","suppressedMessages":"1292","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1293","messages":"1294","suppressedMessages":"1295","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1296","messages":"1297","suppressedMessages":"1298","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1299","messages":"1300","suppressedMessages":"1301","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1302","messages":"1303","suppressedMessages":"1304","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1305","messages":"1306","suppressedMessages":"1307","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1308","messages":"1309","suppressedMessages":"1310","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1311","messages":"1312","suppressedMessages":"1313","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1314","messages":"1315","suppressedMessages":"1316","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1317","messages":"1318","suppressedMessages":"1319","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1320","messages":"1321","suppressedMessages":"1322","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1323","messages":"1324","suppressedMessages":"1325","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1326","messages":"1327","suppressedMessages":"1328","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1329","messages":"1330","suppressedMessages":"1331","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1332","messages":"1333","suppressedMessages":"1334","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1335","messages":"1336","suppressedMessages":"1337","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1338","messages":"1339","suppressedMessages":"1340","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1341","messages":"1342","suppressedMessages":"1343","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1344","messages":"1345","suppressedMessages":"1346","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1347","messages":"1348","suppressedMessages":"1349","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1350","messages":"1351","suppressedMessages":"1352","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1353","messages":"1354","suppressedMessages":"1355","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1356","messages":"1357","suppressedMessages":"1358","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1359","messages":"1360","suppressedMessages":"1361","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1362","messages":"1363","suppressedMessages":"1364","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1365","messages":"1366","suppressedMessages":"1367","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1368","messages":"1369","suppressedMessages":"1370","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1371","messages":"1372","suppressedMessages":"1373","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1374","messages":"1375","suppressedMessages":"1376","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1377","messages":"1378","suppressedMessages":"1379","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1380","messages":"1381","suppressedMessages":"1382","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1383","messages":"1384","suppressedMessages":"1385","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1386","messages":"1387","suppressedMessages":"1388","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1389","messages":"1390","suppressedMessages":"1391","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1392","messages":"1393","suppressedMessages":"1394","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1395","messages":"1396","suppressedMessages":"1397","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1398","messages":"1399","suppressedMessages":"1400","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1401","messages":"1402","suppressedMessages":"1403","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1404","messages":"1405","suppressedMessages":"1406","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1407","messages":"1408","suppressedMessages":"1409","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1410","messages":"1411","suppressedMessages":"1412","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1413","messages":"1414","suppressedMessages":"1415","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1416","messages":"1417","suppressedMessages":"1418","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1419","messages":"1420","suppressedMessages":"1421","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1422","messages":"1423","suppressedMessages":"1424","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1425","messages":"1426","suppressedMessages":"1427","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1428","messages":"1429","suppressedMessages":"1430","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1431","messages":"1432","suppressedMessages":"1433","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1434","messages":"1435","suppressedMessages":"1436","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1437","messages":"1438","suppressedMessages":"1439","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1440","messages":"1441","suppressedMessages":"1442","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1443","messages":"1444","suppressedMessages":"1445","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1446","messages":"1447","suppressedMessages":"1448","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1449","messages":"1450","suppressedMessages":"1451","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1452","messages":"1453","suppressedMessages":"1454","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1455","messages":"1456","suppressedMessages":"1457","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1458","messages":"1459","suppressedMessages":"1460","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1461","messages":"1462","suppressedMessages":"1463","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1464","messages":"1465","suppressedMessages":"1466","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1467","messages":"1468","suppressedMessages":"1469","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1470","messages":"1471","suppressedMessages":"1472","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1473","messages":"1474","suppressedMessages":"1475","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1476","messages":"1477","suppressedMessages":"1478","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1479","messages":"1480","suppressedMessages":"1481","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1482","messages":"1483","suppressedMessages":"1484","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1485","messages":"1486","suppressedMessages":"1487","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1488","messages":"1489","suppressedMessages":"1490","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1491","messages":"1492","suppressedMessages":"1493","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1494","messages":"1495","suppressedMessages":"1496","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1497","messages":"1498","suppressedMessages":"1499","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1500","messages":"1501","suppressedMessages":"1502","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1503","messages":"1504","suppressedMessages":"1505","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1506","messages":"1507","suppressedMessages":"1508","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1509","messages":"1510","suppressedMessages":"1511","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1512","messages":"1513","suppressedMessages":"1514","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1515","messages":"1516","suppressedMessages":"1517","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1518","messages":"1519","suppressedMessages":"1520","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1521","messages":"1522","suppressedMessages":"1523","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1524","messages":"1525","suppressedMessages":"1526","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1527","messages":"1528","suppressedMessages":"1529","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1530","messages":"1531","suppressedMessages":"1532","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1533","messages":"1534","suppressedMessages":"1535","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1536","messages":"1537","suppressedMessages":"1538","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1539","messages":"1540","suppressedMessages":"1541","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1542","messages":"1543","suppressedMessages":"1544","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1545","messages":"1546","suppressedMessages":"1547","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1548","messages":"1549","suppressedMessages":"1550","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1551","messages":"1552","suppressedMessages":"1553","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1554","messages":"1555","suppressedMessages":"1556","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1557","messages":"1558","suppressedMessages":"1559","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1560","messages":"1561","suppressedMessages":"1562","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1563","messages":"1564","suppressedMessages":"1565","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1566","messages":"1567","suppressedMessages":"1568","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1569","messages":"1570","suppressedMessages":"1571","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1572","messages":"1573","suppressedMessages":"1574","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1575","messages":"1576","suppressedMessages":"1577","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1578","messages":"1579","suppressedMessages":"1580","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1581","messages":"1582","suppressedMessages":"1583","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1584","messages":"1585","suppressedMessages":"1586","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1587","messages":"1588","suppressedMessages":"1589","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1590","messages":"1591","suppressedMessages":"1592","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1593","messages":"1594","suppressedMessages":"1595","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1596","messages":"1597","suppressedMessages":"1598","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"1599","messages":"1600","suppressedMessages":"1601","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"C:\\dev\\saveinmed\\frontend\\src\\app\\admin\\categorias\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\cadastro-produto\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\carrinhos\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\carrinhos\\[id]\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\catalogo-produtos\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\catalogo-produtos\\[id]\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\categorias\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\categorias\\[id]\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\cep\\[cep]\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\configurar-empresa\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\dashboard\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\debug-api-key\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\debug-env\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\debug-registro\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\diagnostico-collections\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\empresas\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\empresas\\[id]\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\empresas-filtradas\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\enderecos\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\enderecos\\[id]\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\faturas\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\faturas\\[id]\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\gestao-usuarios\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\laboratorios\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\laboratorios\\[id]\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\mercadopago\\criar-preferencia\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\mercadopago\\pagamento\\[id]\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\mercadopago\\pagamentos\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\mercadopago\\verificar-pagamento\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\notify-admin\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\notify-admin-edge\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\notify-admin-resend\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\pagamentos\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\pagamentos\\[id]\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\pedidos\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\pedidos\\[id]\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\produtos\\catalogo\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\produtos\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\produtos\\venda\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\produtos\\[id]\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\produtos-catalogo\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\relacionar-categorias\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\relacionar-produto\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\subcategorias\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\subcategorias\\[id]\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\test-email\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\user\\permissions\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\usuarios\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\usuarios\\[id]\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\verificar-atributos\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\webhook\\mercadopago\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\api\\webhook\\pagamento\\route.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\cadastro-teste\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\caju\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\carrinhos\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\catalogo-carrinho\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\catalogo-produtos\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\catalogo-produtos-api\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\categorias\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\checkout\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\comparacao-consulta\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\completar-registro\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\configurar-empresa\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\criar-empresa-teste\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\dashboard\\cadastrar-medicamentos\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\dashboard\\cadastro-produto\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\dashboard\\components\\index.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\dashboard\\empresa-novo\\page-clean.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\dashboard\\empresa-novo\\page-new.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\dashboard\\empresa-novo\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\dashboard\\empresa-novo-updated\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\dashboard\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\debug-api-key\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\debug-cadastro-produto\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\debug-config\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\debug-dados\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\debug-empresa\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\debug-estrutura-produtos\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\debug-exclusao-empresa\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\debug-network\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\debug-produtos\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\debug-produtos-teste\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\debug-registro\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\debug-registro\\SessionStorageDebug.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\debug-usuario\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\demo-estoque\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\demo-produtos-catalogo\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\diagnostico\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\diagnostico-collections\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\diagnostico-completo\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\enderecos\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\entregas\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\faq\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\faturas\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\fix-empresa\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\gestao-colaboradores\\components\\CadastroColaboradorModal.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\gestao-colaboradores\\components\\EditarColaboradorModal.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\gestao-colaboradores\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\gestao-pedidos\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\gestao-produtos-venda\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\gestao-usuarios\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\laboratorios\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\layout.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\limpar-cache\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\login\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\pagamento\\erro\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\pagamento\\mercadopago\\falha\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\pagamento\\mercadopago\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\pagamento\\mercadopago\\pendente\\page.tsx",[],["1602"],"C:\\dev\\saveinmed\\frontend\\src\\app\\pagamento\\mercadopago\\sucesso\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\pagamento\\mercadopago\\sucesso\\page_novo.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\pagamento\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\pagamento\\sucesso\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\pagamentos\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\pedidos\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\pedidos\\[id]\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\perfil\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\produtos\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\relacionar-categorias\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\relatorios\\head.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\relatorios\\novo-layout.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\relatorios\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\solucao-empresa\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\usuarios\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\usuarios-pendentes\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\app\\verificar-atributos\\page.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\App.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\ActionButton.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\auth\\PermissionCheck.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\auth\\RoleGuard.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\CadastroProdutoWizard.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\CarrinhoCompras.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\CarrinhoForm.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\CarrinhoList.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\CatalogoComCarrinho.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\CatalogoProdutoForm.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\CatalogoProdutosCompras.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\CatalogoProdutosList.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\CatalogoProdutosList_new.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\CatalogoProdutosSearch.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\CategoriaForm.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\CategoriaList.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\DataTable.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\DebugRegistro.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\DebugUsuario.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\DetalheProdutoModal.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\EditProdutoModal.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\EmpresaList.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\EmpresaModal.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\EmpresaModal2.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\EnderecoForm.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\EnderecoList.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\EstoqueManager.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\EstoqueResumo.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\FaturaForm.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\FaturaList.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\GroupedProductCard.test.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\GroupedProductCard.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\Header.tsx",[],["1603"],"C:\\dev\\saveinmed\\frontend\\src\\components\\LaboratorioForm.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\LaboratorioList.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\ListHeader.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\LocationPicker.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\LojaVirtualMenu.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\MercadoPagoPaymentBrick.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\Modal.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\Navbar.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\Navbar_new.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\PagamentoForm.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\PagamentoList.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\Pagination.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\PedidoForm.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\PedidoList.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\ProductCard.test.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\ProductCard.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\ProductOffersModal.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\ProdutoForm.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\ProdutoList.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\profile\\ProfileForm.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\ProtectedRoute.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\RefreshButton.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\RegistroIncompletoModal.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\ReviewModal.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\SearchBar.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\Sidebar.tsx",[],["1604"],"C:\\dev\\saveinmed\\frontend\\src\\components\\StandardButton.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\TableActions.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\TableContainer.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\UsuarioForm.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\components\\UsuarioList.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\context\\AuthContext.test.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\context\\AuthContext.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\context\\ThemeContext.test.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\context\\ThemeContext.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\contexts\\AuthContext.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\contexts\\CarrinhoContext.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\contexts\\EmpresaContext.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\useAuth.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\useAuthGuard.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\useCarrinhoCompras.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\useCarrinhos.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\useCatalogoProdutos.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\useCategorias.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\useCepLookup.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\useDashboardData.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\useDebounce.test.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\useDebounce.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\useEnderecos.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\useEntregas.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\useEstoque.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\useFaturas.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\useLaboratorios.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\usePagamentos.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\usePedidos.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\usePersistentFilters.test.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\usePersistentFilters.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\useProdutos.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\useRegistroCompleto.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\useUsuarios.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\hooks\\useUsuariosApi.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\layouts\\DashboardLayout.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\layouts\\RoleBasedLayout.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\layouts\\Shell.tsx",[],["1605"],"C:\\dev\\saveinmed\\frontend\\src\\lib\\appwrite.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\lib\\auth.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\lib\\emailService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\lib\\error-translator.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\lib\\logger.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\lib\\masks.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\main.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\middleware.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\auth\\ForgotPassword.tsx",[],["1606"],"C:\\dev\\saveinmed\\frontend\\src\\pages\\auth\\Login.tsx",[],["1607"],"C:\\dev\\saveinmed\\frontend\\src\\pages\\auth\\Register.tsx",[],["1608"],"C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\admin\\CompaniesPage.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\admin\\DashboardHome.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\admin\\index.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\admin\\LogisticsPage.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\admin\\OrdersPage.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\admin\\ProductsPage.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\admin\\ProfilePage.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\admin\\ReviewsPage.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\admin\\ShippingSettings.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\admin\\UsersPage.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\Company.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\delivery\\DeliveryDashboard.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\employee\\EmployeeDashboard.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\MyProfile.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\seller\\Inventory.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\seller\\ProductCreate.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\seller\\SellerDashboard.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\seller\\Team.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\dashboard\\seller\\Wallet.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\marketplace\\Cart.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\marketplace\\Checkout.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\marketplace\\HelpCenter.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\marketplace\\OrderDetails.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\marketplace\\Orders.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\pages\\marketplace\\ProductSearch.tsx",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\adminService.test.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\adminService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\apiClient.test.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\apiClient.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\auth.integration.test.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\auth.test.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\auth.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\cadastroProdutoService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\carrinhoApiService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\carrinhoService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\catalogoProdutoService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\categoriaService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\dashboardService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\empresaApiService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\empresasDadosService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\empresaService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\enderecoService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\entregasApiService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\faturaApiService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\faturaService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\financialService.test.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\financialService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\laboratorioApiService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\laboratorioService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\mercadoPagoService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\ordersService.test.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\ordersService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\pagamentoApiService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\pagamentoService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\pedidoApiService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\pedidoService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\productService.test.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\productService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\produtoService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\produtosVendaService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\produtoVendaService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\shippingService.test.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\shippingService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\usuarioApiService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\usuariosDataService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\services\\usuarioService.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\stores\\cartStore.test.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\stores\\cartStore.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\test\\setup.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\tests\\integration\\apiContracts.test.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\types\\auth.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\types\\empresas-dados.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\types\\product.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\types\\shipping.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\utils\\authUtils.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\utils\\cnpj.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\utils\\format.test.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\utils\\format.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\utils\\jwt.test.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\utils\\jwt.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\utils\\logger.test.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\utils\\logger.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\utils\\phone.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\utils\\robustEmpresaId.ts",[],[],"C:\\dev\\saveinmed\\frontend\\src\\types\\global.d.ts",[],[],{"ruleId":"1609","severity":1,"message":"1610","line":421,"column":21,"nodeType":"1611","endLine":425,"endColumn":23,"suppressions":"1612"},{"ruleId":"1609","severity":1,"message":"1610","line":51,"column":13,"nodeType":"1611","endLine":51,"endColumn":74,"suppressions":"1613"},{"ruleId":"1609","severity":1,"message":"1610","line":127,"column":13,"nodeType":"1611","endLine":127,"endColumn":73,"suppressions":"1614"},{"ruleId":"1609","severity":1,"message":"1610","line":99,"column":15,"nodeType":"1611","endLine":99,"endColumn":76,"suppressions":"1615"},{"ruleId":"1609","severity":1,"message":"1610","line":45,"column":13,"nodeType":"1611","endLine":45,"endColumn":89,"suppressions":"1616"},{"ruleId":"1609","severity":1,"message":"1610","line":214,"column":13,"nodeType":"1611","endLine":214,"endColumn":89,"suppressions":"1617"},{"ruleId":"1609","severity":1,"message":"1610","line":168,"column":13,"nodeType":"1611","endLine":168,"endColumn":89,"suppressions":"1618"},"@next/next/no-img-element","Using `` could result in slower LCP and higher bandwidth. Consider using `` from `next/image` or a custom image loader to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element","JSXOpeningElement",["1619"],["1620"],["1621"],["1622"],["1623"],["1624"],["1625"],{"kind":"1626","justification":"1627"},{"kind":"1626","justification":"1627"},{"kind":"1626","justification":"1627"},{"kind":"1626","justification":"1627"},{"kind":"1626","justification":"1627"},{"kind":"1626","justification":"1627"},{"kind":"1626","justification":"1627"},"directive",""] \ No newline at end of file diff --git a/frontend/IMPLEMENTACAO_DASHBOARD_DADOS_REAIS.md b/frontend/IMPLEMENTACAO_DASHBOARD_DADOS_REAIS.md index 950543a..288005b 100644 --- a/frontend/IMPLEMENTACAO_DASHBOARD_DADOS_REAIS.md +++ b/frontend/IMPLEMENTACAO_DASHBOARD_DADOS_REAIS.md @@ -1,164 +1,49 @@ # Implementação do Dashboard com Dados Reais -## Resumo da Implementação +## Nota de Atualização -Implementei um sistema completo de dashboard que exibe dados reais do banco de dados para todos os níveis de usuários (SUPERADMIN, ADMIN, COLABORADOR), respeitando as regras de negócio de cada nível. +Este documento continua útil para explicar a lógica do dashboard, mas a taxonomia antiga de papéis mudou. -## Arquivos Criados/Modificados +Papéis válidos hoje no fluxo ativo: +- `admin` +- `owner` +- `employee` +- `delivery` -### 1. Dashboard Service (`src/services/dashboardService.ts`) +`superadmin` não faz mais parte do modelo ativo. -- **Objetivo**: Centralizar a lógica de busca e processamento de dados do dashboard -- **Funcionalidades**: - - Obter estatísticas baseadas no nível do usuário - - Calcular métricas em tempo real (medicamentos disponíveis, próximos ao vencimento, pedidos, vendas, economia) - - Filtrar dados por empresa quando necessário - - Buscar atividades recentes - - Listar pedidos pendentes +## Resumo -### 2. API Route (`src/app/api/dashboard/route.ts`) +O dashboard consome dados reais e aplica regras de visibilidade por perfil. A implementação foi pensada para separar: +- visão global administrativa +- visão da empresa +- visão operacional limitada -- **Objetivo**: Endpoint para servir dados do dashboard -- **Endpoints**: - - `GET /api/dashboard?userRole=X&empresaId=Y&type=stats` - Estatísticas - - `GET /api/dashboard?userRole=X&empresaId=Y&type=activities` - Atividades recentes - - `GET /api/dashboard?userRole=X&empresaId=Y&type=pending` - Pedidos pendentes - -### 3. Hook Customizado (`src/hooks/useDashboardData.ts`) - -- **Objetivo**: Hook React para consumir dados do dashboard -- **Funcionalidades**: - - Estados de loading, erro e dados - - Atualização automática baseada em mudanças de role/empresa - - Tratamento de erros - -### 4. Dashboard Principal Atualizado (`src/app/dashboard/page.tsx`) - -- **Modificações**: - - Integração com dados reais via hook - - Exibição condicional baseada no nível do usuário - - Indicadores de carregamento e erro - - Substituição de dados mockados por dados reais - -## Regras de Negócio Implementadas - -### SUPERADMIN - -- **Visualiza**: Dados globais de todas as empresas -- **Métricas**: - - Total de medicamentos disponíveis (todas as empresas) - - Medicamentos próximos ao vencimento (próximos 30 dias) - - Todos os pedidos recebidos no sistema - - Pedidos pendentes globais - - Vendas do mês (todas as empresas) - - Economia gerada total -- **Atividades**: Recentes de todo o sistema -- **Pedidos Pendentes**: De todas as empresas +## Regras de negócio vigentes ### ADMIN -- **Visualiza**: Dados apenas da sua empresa -- **Métricas**: - - Medicamentos disponíveis da empresa - - Medicamentos próximos ao vencimento da empresa - - Pedidos recebidos onde a empresa é vendedora - - Pedidos pendentes da empresa - - Vendas do mês da empresa - - Economia gerada pela empresa -- **Atividades**: Recentes da empresa -- **Pedidos Pendentes**: Apenas da empresa +- Visualiza dados globais e administrativos do sistema +- Pode acessar métricas agregadas +- Pode acessar pedidos pendentes e atividades recentes globais -### COLABORADOR +### OWNER -- **Visualiza**: Dados limitados da empresa -- **Métricas**: - - Medicamentos disponíveis da empresa - - Medicamentos próximos ao vencimento da empresa - - **NÃO visualiza**: Pedidos, vendas, economia (dados sensíveis) -- **Atividades**: Limitadas ou não exibidas -- **Pedidos Pendentes**: Não visualiza +- Visualiza dados apenas da própria empresa +- Pode acessar métricas da empresa, pedidos recebidos e dados financeiros da própria operação -## Funcionalidades Implementadas +### EMPLOYEE -### 1. Métricas Dinâmicas +- Visualiza dados limitados da empresa +- Não deve acessar métricas financeiras sensíveis +- Não deve acessar visão administrativa global -- ✅ Contagem real de medicamentos por empresa -- ✅ Cálculo de medicamentos próximos ao vencimento (30 dias) -- ✅ Contagem de pedidos recebidos e pendentes -- ✅ Cálculo de vendas do mês atual -- ✅ Soma da economia gerada (valor total dos pedidos concluídos) +### DELIVERY -### 2. Atividades Recentes +- Atua em fluxos operacionais de entrega +- Não compartilha o mesmo escopo analítico de `admin` e `owner` -- ✅ Lista de pedidos recentes com detalhes -- ✅ Lista de produtos atualizados recentemente -- ✅ Formatação de datas e valores em português -- ✅ Status coloridos para diferentes tipos de atividade +## Observações -### 3. Pedidos Pendentes - -- ✅ Lista de pedidos com status pendente ou aguardando aprovação -- ✅ Informações: número, valor, comprador, data -- ✅ Filtrado por empresa para admins - -### 4. Interface Responsiva - -- ✅ Cards de métricas adaptáveis -- ✅ Indicadores de carregamento -- ✅ Mensagens de erro -- ✅ Layout responsivo para diferentes tamanhos de tela - -## Como Funciona - -1. **Autenticação**: O usuário faz login e o sistema identifica seu nível e empresa -2. **Carregamento**: O hook `useDashboardData` busca dados baseado no nível do usuário -3. **API**: A rota `/api/dashboard` processa a requisição e retorna dados filtrados -4. **Service**: O `dashboardService` executa queries específicas nos serviços de produto e pedido -5. **Exibição**: O componente Dashboard renderiza os dados de acordo com as permissões - -## Dados Reais vs Mockados - -### ANTES (Mockado) - -```javascript -const stats = { - medicamentosDisponiveis: 1247, - pedidosRecebidos: 28, - vendasMes: 156, - economiaGerada: 45280, -}; -``` - -### DEPOIS (Dados Reais) - -```javascript -const { stats, atividades, pedidosPendentes, loading, error } = - useDashboardData({ - userRole: userRole || "", - empresaId: empresaId || undefined, - }); -``` - -Os dados agora são: - -- ✅ Calculados em tempo real -- ✅ Filtrados por empresa quando apropriado -- ✅ Baseados em dados reais do banco Appwrite -- ✅ Atualizados automaticamente - -## Benefícios da Implementação - -1. **Dados Confiáveis**: Informações sempre atualizadas do banco -2. **Segurança**: Filtros por nível de usuário e empresa -3. **Performance**: Queries otimizadas e cache no frontend -4. **Experiência**: Loading states e tratamento de erros -5. **Escalabilidade**: Fácil adição de novas métricas -6. **Manutenibilidade**: Código organizado e bem documentado - -## Próximos Passos Sugeridos - -1. **Cache**: Implementar cache Redis para métricas -2. **Real-time**: WebSockets para atualizações em tempo real -3. **Gráficos**: Adicionar visualizações gráficas -4. **Filtros**: Filtros por período de tempo -5. **Exportação**: Relatórios em PDF/Excel +- Trechos antigos que mencionam `SUPERADMIN`, `ADMIN` e `COLABORADOR` devem ser lidos como nomenclatura histórica +- No fluxo atual, use sempre os nomes canônicos: `admin`, `owner`, `employee`, `delivery` \ No newline at end of file diff --git a/frontend/IMPLEMENTACAO_MERCADOPAGO_CHECKOUT.md b/frontend/IMPLEMENTACAO_MERCADOPAGO_CHECKOUT.md index eed2a66..42e4e53 100644 --- a/frontend/IMPLEMENTACAO_MERCADOPAGO_CHECKOUT.md +++ b/frontend/IMPLEMENTACAO_MERCADOPAGO_CHECKOUT.md @@ -1,271 +1,32 @@ # Implementação Mercado Pago - Checkout SaveInMed -## Visão Geral +## Nota de Atualização -Implementação completa da integração com Mercado Pago na aplicação SaveInMed, seguindo a estrutura da API BFF existente e o curl fornecido. +Este documento foi escrito para uma arquitetura antiga baseada em BFF. -## Arquivos Implementados +Estado atual esperado: +- o fluxo ativo não deve depender de BFF +- referências a `bff.saveinmed.com.br` ou `bff-dev.saveinmed.com.br` são históricas +- novas integrações devem apontar para a API principal -### 1. Serviço Mercado Pago (`src/services/mercadoPagoService.ts`) +## Resumo -**Responsabilidades:** -- Criar preferências de pagamento via BFF -- Verificar status de pagamentos -- Processar notificações de webhook -- Validar dados antes do envio -- Formatar valores e dados +A integração com Mercado Pago cobre: +- criação de preferência de pagamento +- verificação de status +- retorno de sucesso/erro +- webhook de atualização de estado -**Principais Métodos:** -```typescript -// Criar preferência de pagamento -criarPreferencia(pedidoId, itens, dadosComprador) +## Diretriz atual de infraestrutura -// Verificar status do pagamento -verificarStatusPagamento(paymentId) +Use backend/API principal em vez de BFF para: +- criar preferência de pagamento +- consultar pagamento +- receber webhook -// Processar notificação webhook -processarNotificacao(notificationData) +## Importante -// Validar dados da preferência -validarDadosPreferencia(pedidoId, itens) -``` - -**Endpoint BFF Utilizado:** -- `POST https://bff-dev.saveinmed.com.br/mercadopago/preference` -- `GET https://bff-dev.saveinmed.com.br/mercadopago/payment/{id}` -- `POST https://bff-dev.saveinmed.com.br/mercadopago/webhook` - -### 2. Componente Botão Mercado Pago (`src/components/MercadoPagoButton.tsx`) - -**Funcionalidades:** -- Botão estilizado para pagamento via Mercado Pago -- Validação automática dos dados -- Estados de loading e erro -- Redirecionamento automático para o checkout do Mercado Pago -- Callbacks para sucesso e erro - -**Props:** -```typescript -interface MercadoPagoButtonProps { - pedidoId: string - itens: Array<{produto, quantidade}> - dadosComprador?: {nome, email} - onSuccess?: (preference_id, init_point) => void - onError?: (error) => void - disabled?: boolean -} -``` - -### 3. Páginas de Retorno - -#### Página de Sucesso (`src/app/pagamento/sucesso/page.tsx`) -- Processa retorno de pagamento aprovado -- Exibe detalhes do pagamento e pedido -- Atualiza status do pedido -- Interface amigável com próximos passos - -#### Página de Erro (`src/app/pagamento/erro/page.tsx`) -- Trata erros de pagamento -- Explica motivos comuns de falha -- Oferece sugestões e alternativas -- Botões para tentar novamente ou escolher outro método - -### 4. Integração no Checkout (`src/app/checkout/page.tsx`) - -**Modificações Realizadas:** -- Adicionada opção "Mercado Pago" na seleção de pagamento -- Lógica específica para processar pagamento via Mercado Pago -- Botão personalizado na etapa de confirmação -- Fluxo diferenciado para redirecionamento externo - -## Estrutura de Dados - -### Preferência Mercado Pago -```json -{ - "back_urls": { - "failure": "https://saveinmed.com.br/pagamento/erro", - "success": "https://saveinmed.com.br/pagamento/sucesso" - }, - "external_reference": "pedido-123", - "items": [ - { - "currency_id": "BRL", - "id": "item-123", - "quantity": 1, - "title": "Nome do Produto", - "unit_price": 99.90 - } - ], - "notification_url": "https://bff.saveinmed.com.br/mercadopago/webhook", - "payer": { - "email": "cliente@example.com", - "name": "Cliente", - "surname": "Teste" - } -} -``` - -### Resposta da API -```json -{ - "success": true, - "data": {...}, - "preference_id": "123456789-abc123", - "init_point": "https://www.mercadopago.com.br/checkout/v1/redirect?pref_id=123456789-abc123", - "sandbox_init_point": "https://sandbox.mercadopago.com.br/checkout/v1/redirect?pref_id=123456789-abc123" -} -``` - -## Fluxo de Pagamento - -### 1. Usuário Seleciona Mercado Pago -- Na etapa 2 do checkout, seleciona "Mercado Pago" -- Sistema avança para etapa 3 (confirmação) - -### 2. Confirmação e Redirecionamento -- Usuário confirma dados na etapa 3 -- Clica no botão "Pagar via Mercado Pago" -- Sistema cria preferência via BFF -- Redireciona para checkout do Mercado Pago - -### 3. Processamento no Mercado Pago -- Usuário escolhe método (cartão, PIX, boleto) -- Completa o pagamento -- Mercado Pago processa transação - -### 4. Retorno e Notificação -- Usuário retorna para URLs configuradas -- Webhooks notificam status via BFF -- Sistema atualiza pedido conforme resultado - -## URLs de Retorno - -### Sucesso -`https://saveinmed.com.br/pagamento/sucesso` - -**Parâmetros recebidos:** -- `payment_id`: ID do pagamento no Mercado Pago -- `status`: Status do pagamento (approved, pending, etc.) -- `external_reference`: ID do pedido no sistema -- `preference_id`: ID da preferência criada - -### Erro -`https://saveinmed.com.br/pagamento/erro` - -**Parâmetros recebidos:** -- `payment_id`: ID do pagamento (se disponível) -- `status`: Status do erro (rejected, cancelled, etc.) -- `status_detail`: Detalhes específicos do erro -- `external_reference`: ID do pedido - -## Webhook de Notificação - -**Endpoint:** `https://bff.saveinmed.com.br/mercadopago/webhook` - -**Responsabilidade do BFF:** -- Receber notificações do Mercado Pago -- Validar autenticidade das notificações -- Atualizar status dos pagamentos no sistema -- Processar ações automáticas (aprovação de pedidos, etc.) - -## Validações Implementadas - -### 1. Dados da Preferência -- Pedido ID obrigatório -- Pelo menos um item obrigatório -- Preços maiores que zero -- Quantidades válidas -- IDs de produtos presentes - -### 2. Estados do Botão -- Desabilitado se dados inválidos -- Loading durante criação da preferência -- Erro em caso de falha na API - -### 3. Tratamento de Erros -- Mensagens específicas por tipo de erro -- Sugestões de correção -- Informações técnicas para debug - -## Benefícios da Implementação - -### 1. Para o Usuário -- Múltiplas opções de pagamento em um só lugar -- Interface familiar do Mercado Pago -- Segurança e confiabilidade -- Parcelamento flexível - -### 2. Para o Sistema -- Reduz complexidade de PCI compliance -- Aproveitamento da infraestrutura do Mercado Pago -- Notificações automáticas de status -- Integração via BFF existente - -### 3. Para o Negócio -- Maior conversão de vendas -- Redução de abandono de carrinho -- Suporte a diversos métodos de pagamento -- Gestão centralizada via Mercado Pago - -## Configurações Necessárias - -### 1. No BFF -- Configurar credenciais do Mercado Pago -- Implementar endpoints de preferência e webhook -- Validar autenticidade das notificações - -### 2. No Mercado Pago -- Configurar URLs de retorno -- Configurar URL de webhook -- Configurar métodos de pagamento aceitos - -### 3. No Frontend -- URLs de sucesso e erro configuradas -- Componente de botão implementado -- Serviço de API implementado - -## Monitoramento e Debug - -### 1. Logs Implementados -- Criação de preferências -- Respostas da API -- Erros e exceções -- Redirecionamentos - -### 2. Informações para Debug -- IDs de transação -- Status detalhados -- Parâmetros de retorno -- Dados técnicos nas páginas de erro - -## Próximos Passos - -### 1. Testes -- Testar fluxo completo em sandbox -- Validar webhooks -- Testar cenários de erro - -### 2. Monitoramento -- Implementar métricas de conversão -- Monitorar erros e falhas -- Acompanhar performance - -### 3. Melhorias -- Implementar retry automático -- Adicionar analytics -- Otimizar UX baseado em dados - -## Conclusão - -A implementação do Mercado Pago está completa e seguindo as melhores práticas: - -- ✅ Integração via BFF existente -- ✅ Componentes reutilizáveis -- ✅ Tratamento completo de erros -- ✅ Páginas de retorno implementadas -- ✅ Validações robustas -- ✅ Logging detalhado -- ✅ Interface intuitiva - -O sistema está pronto para testes e deploy, oferecendo uma experiência de pagamento moderna e segura aos usuários do SaveInMed. \ No newline at end of file +Se este documento for usado para retomada da implementação: +1. substituir base URLs de BFF pela API principal +2. validar contratos reais dos endpoints antes de codificar +3. não reintroduzir dependência em BFF no frontend ativo \ No newline at end of file diff --git a/frontend/IMPLEMENTACAO_PAGAMENTOS_CHECKOUT.md b/frontend/IMPLEMENTACAO_PAGAMENTOS_CHECKOUT.md index 4abca5a..36f48e5 100644 --- a/frontend/IMPLEMENTACAO_PAGAMENTOS_CHECKOUT.md +++ b/frontend/IMPLEMENTACAO_PAGAMENTOS_CHECKOUT.md @@ -1,275 +1,35 @@ -# IMPLEMENTAÇÃO DE PAGAMENTOS - CHECKOUT +# Implementação de Pagamentos - Checkout -## 🎯 Funcionalidade Implementada +## Nota de Atualização -Integração completa de pagamentos na página `/checkout` com API BFF, incluindo criação de pagamentos e mock de processamento. +Este documento descreve um fluxo antigo que citava BFF. -## 🛠️ Arquivos Criados/Modificados +Estado atual esperado: +- o checkout ativo deve usar API direta +- referências a `bff-dev.saveinmed.com.br` são históricas +- o documento serve como referência funcional, não como contrato de infraestrutura -### 1. Novo Serviço de Pagamentos +## Resumo -#### `src/services/pagamentoApiService.ts` -**Funcionalidades principais:** -- ✅ **Criar pagamento**: `POST /pagamentos` -- ✅ **Confirmar pagamento**: `PATCH /pagamentos/:id/confirmar` -- ✅ **Buscar pagamento**: `GET /pagamentos/:id` -- ✅ **Listar por pedido**: `GET /pagamentos?pedidos=ID` -- ✅ **Mock de processamento**: Simulação temporária +O checkout cobre: +- criação de pagamento +- confirmação de pagamento +- associação com pedido +- feedback de loading e erro -**Interface de dados:** -```typescript -interface PagamentoApiData { - status: 'pendente' | 'pago' | 'falhou'; - metodo: 'pix' | 'credito' | 'debito'; - valor: number; - pedidos: string; // ID do pedido -} +## Diretriz atual + +Os endpoints de pagamento devem sair da API principal, não de BFF. + +Exemplo de base esperada: + +```text +https://api-dev.saveinmed.com.br/api/v1 ``` -### 2. Página de Checkout Atualizada +## Observação -#### `src/app/checkout/page.tsx` -**Novos estados:** -- `pagamentoId`: ID do pagamento criado -- `processandoPagamento`: Loading durante criação - -**Função atualizada:** -- `proximaEtapa()`: Agora async, cria pagamento na etapa 2→3 - -## 🔄 Fluxo de Pagamento - -### Etapa 1: Dados de Entrega -``` -Usuário preenche endereço → Clica "Continuar" → Avança para Etapa 2 -``` - -### Etapa 2: Forma de Pagamento -``` -Usuário seleciona método (PIX/Crédito/Débito) → -Clica "Continuar" → -[NOVO] Cria pagamento na API → -[NOVO] Processa mock → -Avança para Etapa 3 -``` - -### Etapa 3: Confirmação -``` -Mostra resumo completo + status do pagamento → -Usuário confirma pedido final -``` - -## 📊 Dados Enviados para API - -### Payload de Criação -```json -{ - "status": "pendente", - "metodo": "pix", // ou "credito", "debito" - "valor": 71.85, - "pedidos": "68efaeb000194d1a94bf" -} -``` - -### Mapeamento de Métodos -- **Interface → API**: - - `"cartao"` → `"credito"` - - `"pix"` → `"pix"` - - `"boleto"` → `"debito"` - -### Resposta da API -```json -{ - "$id": "pagamento_id_123456", - "status": "pendente", - "metodo": "pix", - "valor": 71.85, - "pedidos": "68efaeb000194d1a94bf", - "$createdAt": "2025-10-15T10:30:00.000Z" -} -``` - -## 🎭 Mock de Processamento - -### Funcionalidade Temporária -```typescript -processarPagamentoMock: async (metodo, valor) => { - // Simula delay de 2 segundos - await new Promise(resolve => setTimeout(resolve, 2000)); - - // 90% de sucesso simulado - const sucesso = Math.random() > 0.1; - - if (sucesso) { - return { - success: true, - transactionId: `mock_${Date.now()}_${randomId}` - }; - } else { - return { - success: false, - error: 'Falha na simulação do pagamento' - }; - } -} -``` - -**Objetivo**: Simular processamento real até integração com gateway de pagamento. - -## 🎨 Interface Atualizada - -### Botão "Continuar" na Etapa 2 -#### Estado Normal: -```jsx - -``` - -#### Estado Loading: -```jsx - -``` - -### Etapa 3 - Confirmação -#### Informações do Pagamento: -``` -Forma de Pagamento -├── Método: PIX -├── Valor: R$ 71,85 -└── ID do Pagamento: 68efaeb00019... - -Status do Pagamento -✅ Pagamento criado com sucesso! -Status: Pendente - Aguardando confirmação -💡 Para PIX: Escaneie o QR Code ou copie o código quando disponível -``` - -## 🔍 Logs de Debug - -### Console Output Esperado -``` -💳 [CHECKOUT] Criando pagamento: {metodo: "pix", valor: 71.85, pedidoId: "..."} -💳 Criando pagamento na API: {status: "pendente", metodo: "pix", valor: 71.85, pedidos: "..."} -✅ Pagamento criado com sucesso: {$id: "...", status: "pendente", ...} -🎭 [CHECKOUT] Iniciando processamento mock... -🎭 MOCK: Processando pagamento... {metodo: "pix", valor: 71.85} -✅ MOCK: Pagamento processado com sucesso: mock_1729012345_abc123 -✅ [CHECKOUT] Pagamento processado (mock): mock_1729012345_abc123 -``` - -## 🌐 Requisições de Rede - -### Criação de Pagamento -``` -POST https://bff-dev.saveinmed.com.br/api/v1/pagamentos -Authorization: Bearer -Content-Type: application/json - -{ - "status": "pendente", - "metodo": "pix", - "valor": 71.85, - "pedidos": "68efaeb000194d1a94bf" -} -``` - -### Futura Confirmação (endpoint disponível) -``` -PATCH https://bff-dev.saveinmed.com.br/api/v1/pagamentos/{id}/confirmar -Authorization: Bearer -``` - -## 🛡️ Tratamento de Erros - -### Cenários Cobertos -1. **Token ausente/inválido** → Erro de autenticação -2. **Pedido ID não encontrado** → Erro antes da criação -3. **Falha na API** → Mensagem de erro específica -4. **Falha no mock** → Simulação de erro de pagamento -5. **Erro de rede** → Erro de conexão - -### Mensagens de Feedback -- ✅ **Sucesso**: "Pagamento criado com sucesso!" -- ✅ **Mock sucesso**: "Pagamento processado! ID: mock_12345..." -- ❌ **Erro API**: "Erro ao criar pagamento: [mensagem]" -- ❌ **Erro mock**: "Falha no processamento do pagamento (simulação)" -- ❌ **Erro geral**: "Erro ao processar pagamento. Tente novamente." - -## 🧪 Como Testar - -### Teste Completo do Fluxo -1. **Adicione produtos** ao carrinho -2. **Clique "Finalizar Compra"** (cria pedido) -3. **Preencha dados de entrega** e clique "Continuar" -4. **Selecione método de pagamento** (PIX/Crédito/Débito) -5. **Clique "Continuar"** → Observe criação do pagamento -6. **Aguarde processamento mock** (2 segundos) -7. **Verifique informações** na etapa de confirmação - -### Verificações no Network -- ✅ `POST /pagamentos` → Status 200 -- ✅ Body com dados corretos -- ✅ Response com ID do pagamento - -### Verificações na Interface -- ✅ Loading no botão durante processamento -- ✅ Toast de sucesso/erro -- ✅ ID do pagamento na confirmação -- ✅ Status "Pendente" exibido - -## 📱 Estados da Interface - -### Durante Criação de Pagamento -``` -[Botão] ⟳ Processando Pagamento... (disabled) -[Toast] 💳 Criando pagamento... -``` - -### Após Sucesso -``` -[Toast] ✅ Pagamento criado com sucesso! -[Toast] ✅ Pagamento processado! ID: mock_... -[Tela] Avança para etapa 3 com informações do pagamento -``` - -### Após Erro -``` -[Toast] ❌ Erro ao criar pagamento: [detalhes] -[Botão] Volta ao estado normal para retry -``` - -## 🔮 Próximos Passos - -### Integração Real de Pagamento -1. **Substituir mock** por gateway real (Stripe, PagSeguro, etc.) -2. **Implementar webhooks** para confirmação automática -3. **Adicionar QR Code** para PIX -4. **Implementar retry** de pagamentos falhados - -### Funcionalidades Adicionais -1. **Histórico de pagamentos** por pedido -2. **Cancelamento de pagamentos** -3. **Reembolsos** via API -4. **Notificações** de status - -## ✅ Resultados - -### Funcionalidade -- ✅ **API BFF integrada** para pagamentos -- ✅ **Fluxo completo** implementado -- ✅ **Mock funcional** até integração real -- ✅ **Estados de loading** e feedback - -### UX/UI -- ✅ **Feedback visual** durante processamento -- ✅ **Informações claras** na confirmação -- ✅ **Tratamento de erros** robusto -- ✅ **Flow intuitivo** para o usuário - -### Integração -- ✅ **Dados consistentes** entre pedido e pagamento -- ✅ **Autenticação** via JWT -- ✅ **Logs detalhados** para debug -- ✅ **Preparado** para gateway real - -O sistema de pagamentos está **100% funcional** com mock e pronto para integração real com gateways de pagamento! 🚀 \ No newline at end of file +Antes de usar este documento para implementação nova: +1. validar endpoint real +2. validar autenticação JWT +3. confirmar shape de request/response \ No newline at end of file diff --git a/frontend/MARKETPLACE.md b/frontend/MARKETPLACE.md index 05dfe86..c7ca7f2 100644 --- a/frontend/MARKETPLACE.md +++ b/frontend/MARKETPLACE.md @@ -3,121 +3,121 @@ ## Status (pronto x faltando) **Pronto** -- Conteúdo descrito neste documento. +- Conteúdo descrito neste documento. **Faltando** -- Confirmar no código o estado real das funcionalidades e atualizar esta seção conforme necessário. +- Confirmar no código o estado real das funcionalidades e atualizar esta seção conforme necessário. --- -Interface do usuário do marketplace B2B farmacêutico SaveInMed, desenvolvida com React e Vite. +Interface do usuário do marketplace B2B farmacêutico SaveInMed, desenvolvida com React e Vite. -## 🎯 Propósito +## 🎯 Propósito -Este é o frontend do marketplace SaveInMed, onde farmácias e distribuidoras podem: -- Navegar e pesquisar produtos farmacêuticos +Este é o frontend do marketplace SaveInMed, onde farmácias e distribuidoras podem: +- Navegar e pesquisar produtos farmacêuticos - Adicionar produtos ao carrinho - Realizar pedidos e checkout -- Gerenciar perfil e histórico de compras +- Gerenciar perfil e histórico de compras - Acompanhar status de pedidos - Processar pagamentos via Mercado Pago -## 🚀 Tecnologias +## 🚀 Tecnologias - **React 18** - Biblioteca UI -- **TypeScript** - Tipagem estática -- **Vite 5** - Build tool e dev server ultra-rápido +- **TypeScript** - Tipagem estática +- **Vite 5** - Build tool e dev server ultra-rápido - **React Router DOM 6** - Roteamento - **TailwindCSS 3** - Framework CSS utility-first - **Zustand 4** - Gerenciamento de estado - **Axios** - Cliente HTTP -- **Mercado Pago SDK React** - Integração de pagamentos -- **React Window** - Virtualização de listas para performance +- **Mercado Pago SDK React** - Integração de pagamentos +- **React Window** - Virtualização de listas para performance -## 📋 Funcionalidades +## 📋 Funcionalidades -### Catálogo de Produtos -- Listagem de produtos com virtualização -- Busca e filtros avançados +### Catálogo de Produtos +- Listagem de produtos com virtualização +- Busca e filtros avançados - Detalhes de produtos -- Informações de lote e validade +- Informações de lote e validade ### Carrinho de Compras - Adicionar/remover produtos - Atualizar quantidades -- Persistência local com Zustand -- Cálculo automático de totais +- Persistência local com Zustand +- Cálculo automático de totais ### Checkout e Pagamentos - Fluxo de checkout simplificado -- Integração com Mercado Pago -- Múltiplas formas de pagamento -- Confirmação de pedido +- Integração com Mercado Pago +- Múltiplas formas de pagamento +- Confirmação de pedido -### Autenticação -- Login de usuários +### Autenticação +- Login de usuários - Rotas protegidas -- Contexto de autenticação -- Persistência de sessão +- Contexto de autenticação +- Persistência de sessão ### Dashboard -- Visão geral de pedidos -- Histórico de compras -- Estatísticas de uso +- Visão geral de pedidos +- Histórico de compras +- Estatísticas de uso ### Perfil - Gerenciamento de dados pessoais -- Endereços de entrega -- Preferências +- Endereços de entrega +- Preferências -## 🏗️ Arquitetura +## 🏗️ Arquitetura ``` marketplace/ -├── src/ -│ ├── components/ -│ │ └── ProtectedRoute.tsx # Componente de rota protegida -│ ├── context/ -│ │ └── AuthContext.tsx # Contexto de autenticação -│ ├── hooks/ -│ │ └── usePersistentFilters.ts # Hook para filtros persistentes -│ ├── layouts/ -│ │ └── Shell.tsx # Layout principal -│ ├── pages/ -│ │ ├── Cart.tsx # Página do carrinho -│ │ ├── Checkout.tsx # Página de checkout -│ │ ├── Company.tsx # Perfil da empresa [NEW] -│ │ ├── Dashboard.tsx # Dashboard do usuário -│ │ ├── Inventory.tsx # Gestão de estoque [NEW] -│ │ ├── Login.tsx # Página de login -│ │ ├── Orders.tsx # Pedidos [NEW] -│ │ ├── Profile.tsx # Página de perfil -│ │ └── SellerDashboard.tsx # Dashboard vendedor [NEW] -│ ├── services/ -│ │ └── apiClient.ts # Cliente API configurado -│ ├── stores/ -│ │ └── cartStore.ts # Store Zustand do carrinho -│ ├── test/ -│ │ └── setup.ts # Setup Vitest -│ ├── types/ -│ │ └── product.ts # Tipos TypeScript -│ ├── App.tsx # Componente raiz -│ ├── main.tsx # Entry point -│ └── index.css # Estilos globais -├── index.html -├── vite.config.ts -├── vitest.config.ts # Config de testes -├── tailwind.config.ts -├── tsconfig.json -└── README.md +├── src/ +│ ├── components/ +│ │ └── ProtectedRoute.tsx # Componente de rota protegida +│ ├── context/ +│ │ └── AuthContext.tsx # Contexto de autenticação +│ ├── hooks/ +│ │ └── usePersistentFilters.ts # Hook para filtros persistentes +│ ├── layouts/ +│ │ └── Shell.tsx # Layout principal +│ ├── pages/ +│ │ ├── Cart.tsx # Página do carrinho +│ │ ├── Checkout.tsx # Página de checkout +│ │ ├── Company.tsx # Perfil da empresa [NEW] +│ │ ├── Dashboard.tsx # Dashboard do usuário +│ │ ├── Inventory.tsx # Gestão de estoque [NEW] +│ │ ├── Login.tsx # Página de login +│ │ ├── Orders.tsx # Pedidos [NEW] +│ │ ├── Profile.tsx # Página de perfil +│ │ └── SellerDashboard.tsx # Dashboard vendedor [NEW] +│ ├── services/ +│ │ └── apiClient.ts # Cliente API configurado +│ ├── stores/ +│ │ └── cartStore.ts # Store Zustand do carrinho +│ ├── test/ +│ │ └── setup.ts # Setup Vitest +│ ├── types/ +│ │ └── product.ts # Tipos TypeScript +│ ├── App.tsx # Componente raiz +│ ├── main.tsx # Entry point +│ └── index.css # Estilos globais +├── index.html +├── vite.config.ts +├── vitest.config.ts # Config de testes +├── tailwind.config.ts +├── tsconfig.json +└── README.md ``` -## 🎨 Assets +## 🎨 Assets -Os arquivos de assets estão em `src/assets/`: +Os arquivos de assets estão em `src/assets/`: -| Arquivo | Descrição | +| Arquivo | Descrição | |---------|-----------| | `logo.png` | Logo oficial SaveInMed | @@ -131,9 +131,9 @@ colors: { } ``` -## 🧪 Testes +## 🧪 Testes -O projeto utiliza **Vitest** para testes unitários: +O projeto utiliza **Vitest** para testes unitários: ```bash # Executar testes @@ -150,14 +150,14 @@ npm test -- --run | Categoria | Testes | |-----------|--------| -| `cartStore` | 15 ✅ | -| `apiClient` | 7 ✅ | -| `usePersistentFilters` | 5 ✅ | -| **Total** | **27** ✅ | +| `cartStore` | 15 ✅ | +| `apiClient` | 7 ✅ | +| `usePersistentFilters` | 5 ✅ | +| **Total** | **27** ✅ | -## 🔧 Configuração +## 🔧 Configuração -### Variáveis de Ambiente +### Variáveis de Ambiente Crie um arquivo `.env` na raiz do projeto: @@ -172,43 +172,43 @@ VITE_MERCADOPAGO_PUBLIC_KEY=your-public-key-here VITE_ENV=development ``` -### Pré-requisitos +### Pré-requisitos - Node.js 20+ - npm ou yarn -## 🏃 Execução Local +## 🏃 Execução Local ```bash -# Instalar dependências +# Instalar dependências npm install # Modo desenvolvimento npm run dev -# Aplicação estará disponível em http://localhost:5173 +# Aplicação estará disponível em http://localhost:5173 ``` -## 🏗️ Build e Produção +## 🏗️ Build e Produção ```bash -# Build para produção +# Build para produção npm run build # Preview do build npm run preview -# Arquivos de produção estarão em ./dist +# Arquivos de produção estarão em ./dist ``` -## 🎨 Estilização +## 🎨 Estilização -O projeto utiliza TailwindCSS para estilização. Principais recursos: +O projeto utiliza TailwindCSS para estilização. Principais recursos: -- **Utility-first**: Classes utilitárias para estilização rápida +- **Utility-first**: Classes utilitárias para estilização rápida - **Responsivo**: Design mobile-first - **Dark mode**: Suporte a tema escuro (se implementado) -- **Customização**: Configuração em `tailwind.config.ts` +- **Customização**: Configuração em `tailwind.config.ts` ### Exemplo de Componente @@ -231,9 +231,9 @@ export function ProductCard({ product }: { product: Product }) { } ``` -## 🔐 Autenticação +## 🔐 Autenticação -O sistema de autenticação utiliza Context API: +O sistema de autenticação utiliza Context API: ```tsx import { useAuth } from './context/AuthContext'; @@ -253,9 +253,9 @@ function MyComponent() { } ``` -## 🛒 Gerenciamento de Estado (Zustand) +## 🛒 Gerenciamento de Estado (Zustand) -O carrinho de compras é gerenciado com Zustand: +O carrinho de compras é gerenciado com Zustand: ```tsx import { useCartStore } from './stores/cartStore'; @@ -271,7 +271,7 @@ function ProductPage() { } ``` -## 🧪 Testes +## 🧪 Testes ```bash # Executar testes (quando configurados) @@ -281,25 +281,25 @@ npm test npm run test:coverage ``` -## 📱 Responsividade +## 📱 Responsividade -O marketplace é totalmente responsivo, com breakpoints: +O marketplace é totalmente responsivo, com breakpoints: - **Mobile**: < 640px - **Tablet**: 640px - 1024px - **Desktop**: > 1024px -## ⚡ Performance +## âš¡ Performance -Otimizações implementadas: +Otimizações implementadas: -- **Virtualização de listas**: React Window para listas longas +- **Virtualização de listas**: React Window para listas longas - **Code splitting**: Lazy loading de rotas -- **Vite**: Build ultra-rápido -- **Zustand**: State management leve e performático -- **Memoização**: React.memo e useMemo onde apropriado +- **Vite**: Build ultra-rápido +- **Zustand**: State management leve e performático +- **Memoização**: React.memo e useMemo onde apropriado -## 🔗 Integração com APIs +## 🔗 Integração com APIs ### Backend Go API ```typescript @@ -323,7 +323,7 @@ function CheckoutButton({ preferenceId }: { preferenceId: string }) { } ``` -## 🚀 Deploy +## 🚀 Deploy ### Vercel ```bash @@ -346,12 +346,12 @@ docker build -t saveinmed-marketplace:latest . docker run -p 80:80 saveinmed-marketplace:latest ``` -## 🔗 Integração com Outros Componentes +## 🔗 Integração com Outros Componentes - **Backend (Go API)**: Consome endpoints de produtos, pedidos e pagamentos - **Backoffice (NestJS)**: Consome endpoints administrativos -- **SaveInMed BFF**: Pode usar como proxy para múltiplas APIs +- **SaveInMed BFF**: Pode usar como proxy para múltiplas APIs -## 📝 Licença +## 📝 Licença MIT diff --git a/frontend/README.md b/frontend/README.md index 04638f3..0adb12b 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -1,30 +1,37 @@ -# Frontend — SaveInMed Marketplace +# Frontend - SaveInMed Marketplace React + Vite + TypeScript + Tailwind CSS +## Estado Atual + +- Fluxo ativo de autenticação: API direta via `VITE_API_URL` +- Fluxo ativo não depende de BFF +- Papéis suportados no frontend ativo: `admin`, `owner`, `employee`, `delivery` +- `superadmin` e aliases antigos (`seller`, `colaborador`, `entregador`, `dono`) existem apenas como compatibilidade de legado + ## Estrutura de `src/` -``` +```text src/ -├── assets/ → Logo, imagens estáticas -├── components/ → Componentes reutilizáveis -├── context/ → React Context (auth, tema) — estado global estável -├── hooks/ → Custom hooks -├── layouts/ → Layouts de página (Shell, DashboardLayout) -├── pages/ → Páginas organizadas por contexto e perfil -│ ├── auth/ → Login -│ ├── marketplace/ → Search, Cart, Checkout, Orders, OrderDetails -│ └── dashboard/ -│ ├── admin/ → Painel administrativo (role admin) -│ ├── seller/ → Inventário, Produtos, Carteira, Equipe -│ ├── employee/ → Dashboard do colaborador -│ ├── delivery/ → Dashboard do entregador -│ ├── Company.tsx -│ └── MyProfile.tsx -├── services/ → Clientes HTTP por domínio -├── stores/ → Zustand (carrinho, filtros, UI global) -├── types/ → Tipos TypeScript compartilhados -└── utils/ → format, jwt, logger +|-- assets/ -> Logo, imagens estáticas +|-- components/ -> Componentes reutilizáveis +|-- context/ -> React Context (auth, tema) +|-- hooks/ -> Custom hooks +|-- layouts/ -> Layouts de página +|-- pages/ -> Páginas organizadas por contexto e perfil +| |-- auth/ -> Login +| |-- marketplace/ -> Search, Cart, Checkout, Orders, OrderDetails +| `-- dashboard/ +| |-- admin/ -> Painel administrativo +| |-- seller/ -> Área do `owner` (nome de pasta legado) +| |-- employee/ -> Área do `employee` +| |-- delivery/ -> Área do `delivery` +| |-- Company.tsx +| `-- MyProfile.tsx +|-- services/ -> Clientes HTTP por domínio +|-- stores/ -> Zustand (carrinho, filtros, UI global) +|-- types/ -> Tipos TypeScript compartilhados +`-- utils/ -> format, jwt, logger ``` ## Importações absolutas @@ -32,30 +39,51 @@ src/ Utilize o alias `@/` (aponta para `src/`): ```tsx -// ✅ Correto import { useAuth } from '@/context/AuthContext' - -// ❌ Evitar (quebra ao mover o arquivo) -import { useAuth } from '../../context/AuthContext' ``` ## Gerenciamento de estado | Estado | Estratégia | |--------|-----------| -| Auth (JWT, user) | Context API (`AuthContext`) | +| Auth (JWT, user) | Context API (`AuthContext`) + `apiClient` | | Tema claro/escuro | Context API (`ThemeContext`) | | Carrinho | Zustand (`cartStore`) | | Filtros de busca | Zustand / `usePersistentFilters` | | Estado UI local | `useState` no componente | -> **Regra:** Context apenas para auth e tema. Tudo mais vai para Zustand. +> Regra: Context apenas para auth e tema. O restante fica em Zustand ou estado local. ## Scripts ```bash -pnpm dev # Dev server (proxy → :8214) -pnpm build # Build produção -pnpm test # Testes (Vitest) -pnpm lint # ESLint +pnpm dev +pnpm build +pnpm test +pnpm lint ``` + +## Autenticação e API + +- O app Vite usa [src/services/apiClient.ts](./src/services/apiClient.ts) +- O base URL do fluxo ativo vem de `VITE_API_URL` +- Exemplo esperado: + +```bash +VITE_API_URL=https://api-dev.saveinmed.com.br +``` + +- O login ativo chama `POST /v1/auth/login` +- O frontend injeta o token JWT em `Authorization: Bearer ` +- Não usar `NEXT_PUBLIC_BFF_API_URL` para o app Vite ativo + +## Roles suportadas + +- `admin` +- `owner` +- `employee` +- `delivery` + +## Observação sobre legado + +O repositório ainda contém páginas e serviços legados em `src/app/...` e stubs antigos. Esses arquivos não devem ser usados como referência de arquitetura nova sem revisão. \ No newline at end of file diff --git a/frontend/src/app/login/page.tsx b/frontend/src/app/login/page.tsx index 5f7a5fa..828e0cd 100644 --- a/frontend/src/app/login/page.tsx +++ b/frontend/src/app/login/page.tsx @@ -6,11 +6,7 @@ import { useEmpresa } from "@/contexts/EmpresaContext"; import { translateError } from "@/lib/error-translator"; import Image from "next/image"; -const BFF_BASE_URL = - process.env.NEXT_PUBLIC_BFF_API_URL || - (process.env.NEXT_PUBLIC_API_URL - ? `${process.env.NEXT_PUBLIC_API_URL}/api/v1` - : "https://api-dev.saveinmed.com.br/api/v1"); +const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL ? process.env.NEXT_PUBLIC_API_URL + '/api/v1' : 'https://api-dev.saveinmed.com.br/api/v1'; /** * Componente interno que usa useSearchParams @@ -20,21 +16,21 @@ const LoginPageContent = () => { const { setEmpresaId } = useEmpresa(); const searchParams = useSearchParams(); - // Estados do formulário - const [email, setEmail] = useState(""); // Email do usuário - const [password, setPassword] = useState(""); // Senha do usuário + // Estados do formulário + const [email, setEmail] = useState(""); // Email do usuário + const [password, setPassword] = useState(""); // Senha do usuário const [name, setName] = useState(""); // Nome completo (apenas para registro) const [loading, setLoading] = useState(false); // Estado de carregamento const [error, setError] = useState(""); // Mensagens de erro const [isLogin, setIsLogin] = useState(true); // Alterna entre login e registro - const [checkingAuth, setCheckingAuth] = useState(true); // Verificação inicial de autenticação + const [checkingAuth, setCheckingAuth] = useState(true); // Verificação inicial de autenticação const [showPassword, setShowPassword] = useState(false); // Controla visibilidade da senha const [accessToken, setAccessToken] = useState(""); // Token de acesso do BFF const [showSuccessModal, setShowSuccessModal] = useState(false); // Modal de sucesso do cadastro const [showPendingModal, setShowPendingModal] = useState(false); // Modal de cadastro pendente /** - * Verifica parâmetros da URL para definir aba inicial + * Verifica parâmetros da URL para definir aba inicial */ useEffect(() => { const tab = searchParams.get('tab'); @@ -44,13 +40,13 @@ const LoginPageContent = () => { }, [searchParams]); /** - * Verifica se o usuário já está autenticado ao carregar a página + * Verifica se o usuário já está autenticado ao carregar a página * Se estiver autenticado, redireciona para o dashboard */ useEffect(() => { const checkAuth = async () => { try { - // Verificar se há token armazenado + // Verificar se há token armazenado const storedToken = localStorage.getItem('access_token'); if (!storedToken) { @@ -58,14 +54,14 @@ const LoginPageContent = () => { return; } - // Verificar autenticação usando BFF com o token no header Authorization + // Verificar autenticação usando API com o token no header Authorization const response = await fetch( - `${BFF_BASE_URL}/auth/me`, + `${API_BASE_URL}/auth/me`, { method: "GET", headers: { "accept": "application/json", - "Authorization": `Bearer ${storedToken}`, // Usar Authorization ao invés de Cookie + "Authorization": `Bearer ${storedToken}`, // Usar Authorization ao invés de Cookie }, } ); @@ -76,7 +72,7 @@ const LoginPageContent = () => { router.push("/dashboard"); } else { const errorText = await response.text(); - // Limpar token inválido + // Limpar token inválido localStorage.removeItem('access_token'); } } catch (error) { @@ -88,17 +84,17 @@ const LoginPageContent = () => { }, [router]); /** - * Função para realizar login do usuário usando BFF - * @param email - Email do usuário (usado como identificador) - * @param password - Senha do usuário + * Função para realizar login do usuário usando API + * @param email - Email do usuário (usado como identificador) + * @param password - Senha do usuário */ const login = async (email: string, password: string) => { setLoading(true); setError(""); try { - // 1. Fazer login no BFF - const baseUrl = BFF_BASE_URL; + // 1. Fazer login na API + const baseUrl = API_BASE_URL; const response = await fetch(`${baseUrl}/auth/login`, { method: 'POST', headers: { @@ -113,32 +109,32 @@ const LoginPageContent = () => { }) }); - // Ler e logar o corpo da resposta (usando clone para não consumir o body original) + // Ler e logar o corpo da resposta (usando clone para não consumir o body original) const respClone = response.clone(); const respText = await respClone.text(); let respBody: any = respText; try { respBody = JSON.parse(respText); } catch { - // corpo não é JSON, manter como texto + // corpo não é JSON, manter como texto } if (!response.ok) { // Extrair mensagem de erro do backend let errorMessage = respBody?.message || respBody?.error || respBody?.detail || respText; - // Tratar códigos de status específicos + // Tratar códigos de status específicos if (response.status === 401) { errorMessage = "Email ou senha incorretos. Verifique suas credenciais."; } else if (response.status === 403) { errorMessage = "Acesso negado. Sua conta pode estar inativa."; } else if (response.status === 404) { - errorMessage = "Usuário não encontrado. Verifique o email informado."; + errorMessage = "Usuário não encontrado. Verifique o email informado."; } else if (response.status >= 500) { errorMessage = "Erro interno do servidor. Tente novamente em alguns minutos."; } - // Aplicar tradução se disponível + // Aplicar tradução se disponível const translatedError = translateError(errorMessage); throw new Error(translatedError); } @@ -149,8 +145,7 @@ const LoginPageContent = () => { if (loginData.access_token) { const token = loginData.access_token; localStorage.setItem('access_token', token); - setAccessToken(token); - + // 3. Verificar imediatamente se o /me funciona com o token const meResponse = await fetch(`${baseUrl}/auth/me`, { method: "GET", @@ -164,24 +159,24 @@ const LoginPageContent = () => { if (meResponse.ok) { const userData = await meResponse.json(); } else { - console.log("❌ Falha no /me:", await meResponse.text()); + console.log("❌ Falha no /me:", await meResponse.text()); } } else { - throw new Error("Token não recebido do servidor"); + throw new Error("Token não recebido do servidor"); } - // 4. Armazenar informações do usuário no localStorage + // 4. Armazenar informações do usuário no localStorage if (loginData.user) { localStorage.setItem('user', JSON.stringify(loginData.user)); - // Verificar se o registro está completo + // Verificar se o registro está completo if (loginData.user["registro-completo"] === false) { setShowPendingModal(true); - return; // Não continuar com o redirecionamento + return; // Não continuar com o redirecionamento } - // Armazenar ID do endereço se disponível + // Armazenar ID do endereço se disponível // Backend pode retornar "endereco" (singular) ou "enderecos" (plural array) let enderecoId = loginData.user.endereco; @@ -195,7 +190,7 @@ const LoginPageContent = () => { } } - // 5. Verificar e armazenar empresa ID se disponível + // 5. Verificar e armazenar empresa ID se disponível if (loginData.user?.empresaId) { setEmpresaId(loginData.user.empresaId); } @@ -204,16 +199,16 @@ const LoginPageContent = () => { router.push("/dashboard"); } catch (error: any) { - console.error("❌ Erro no login:", error); + console.error("❌ Erro no login:", error); - // Definir mensagem de erro amigável + // Definir mensagem de erro amigável let friendlyMessage = error.message; // Se for um erro de rede if (error.name === 'TypeError' || error.message.includes('fetch')) { - friendlyMessage = "Erro de conexão. Verifique sua internet e tente novamente."; + friendlyMessage = "Erro de conexão. Verifique sua internet e tente novamente."; } - // Se for um erro genérico sem mensagem clara + // Se for um erro genérico sem mensagem clara else if (!error.message || error.message.length < 5) { friendlyMessage = "Erro inesperado. Verifique suas credenciais e tente novamente."; } @@ -225,7 +220,7 @@ const LoginPageContent = () => { }; /** - * Função para registrar novo usuário usando BFF + * Função para registrar novo usuário usando API * Cria conta e mostra mensagem de sucesso */ const register = async () => { @@ -233,21 +228,20 @@ const LoginPageContent = () => { setError(""); try { - // 1. Fazer registro no BFF com dados corretos - const baseUrl = BFF_BASE_URL; - const response = await fetch(`${baseUrl}/auth/register`, { - method: 'POST', + // 1. Fazer registro na API com dados corretos + const baseUrl = API_BASE_URL; + const response = await fetch(baseUrl + '/auth/register', { headers: { 'accept': 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ - identificador: email, // identificador = email do usuário (usado no login) + identificador: email, // identificador = email do usuário (usado no login) email: email, - nome: name, // nome = nome completo do usuário + nome: name, // nome = nome completo do usuário senha: password, - nivel: "admin", // valor estático - "registro-completo": false // valor estático - registro incompleto por padrão + nivel: "owner", // valor estático + "registro-completo": false // valor estático - registro incompleto por padrão }) }); @@ -255,25 +249,25 @@ const LoginPageContent = () => { if (!response.ok) { const errorData = await response.json().catch(() => ({})); - // Tratar códigos de status específicos + // Tratar códigos de status específicos let errorMessage = errorData.message || 'Falha no registro'; - if (response.status === 409 || errorMessage.includes('already exists') || errorMessage.includes('já existe')) { - errorMessage = 'Este email já está cadastrado. Tente fazer login ou use outro email.'; + if (response.status === 409 || errorMessage.includes('already exists') || errorMessage.includes('já existe')) { + errorMessage = 'Este email já está cadastrado. Tente fazer login ou use outro email.'; } else if (response.status === 400) { - errorMessage = 'Dados inválidos. Verifique se todos os campos estão preenchidos corretamente.'; + errorMessage = 'Dados inválidos. Verifique se todos os campos estão preenchidos corretamente.'; } else if (response.status >= 500) { errorMessage = 'Erro interno do servidor. Tente novamente em alguns minutos.'; } - // Aplicar tradução se disponível + // Aplicar tradução se disponível const translatedError = translateError(errorMessage); throw new Error(translatedError); } const registerData = await response.json(); - // 2. Fazer login automático após registro para obter token + // 2. Fazer login automático após registro para obter token const loginResponse = await fetch(`${baseUrl}/auth/login`, { method: 'POST', headers: { @@ -289,13 +283,13 @@ const LoginPageContent = () => { }); if (!loginResponse.ok) { - console.error("❌ Erro no login automático:", loginResponse.status); - throw new Error('Erro ao fazer login automático após registro'); + console.error("❌ Erro no login automático:", loginResponse.status); + throw new Error('Erro ao fazer login automático após registro'); } const loginData = await loginResponse.json(); - // 3. Armazenar token e dados do usuário + // 3. Armazenar token e dados do usuário if (loginData.access_token) { localStorage.setItem('access_token', loginData.access_token); } @@ -304,20 +298,20 @@ const LoginPageContent = () => { localStorage.setItem('user', JSON.stringify(loginData.user)); } - // 4. Redirecionar para completar registro com token válido + // 4. Redirecionar para completar registro com token válido router.push(`/completar-registro?nome=${encodeURIComponent(name)}&email=${encodeURIComponent(email)}`); } catch (error: any) { - console.error("❌ Erro no registro:", error); + console.error("❌ Erro no registro:", error); - // Definir mensagem de erro amigável + // Definir mensagem de erro amigável let friendlyMessage = error.message; // Se for um erro de rede if (error.name === 'TypeError' || error.message.includes('fetch')) { - friendlyMessage = "Erro de conexão. Verifique sua internet e tente novamente."; + friendlyMessage = "Erro de conexão. Verifique sua internet e tente novamente."; } - // Se for um erro genérico sem mensagem clara + // Se for um erro genérico sem mensagem clara else if (!error.message || error.message.length < 5) { friendlyMessage = "Erro inesperado durante o cadastro. Tente novamente."; } @@ -329,11 +323,11 @@ const LoginPageContent = () => { }; /** - * Função para notificar administrador sobre novo cadastro + * Função para notificar administrador sobre novo cadastro */ const notifyAdmin = async (userData: { nome: string, email: string, identificador: string }) => { try { - // Enviar notificações via API (usando Resend para emails reais) + // Enviar notificações via API (usando Resend para emails reais) await fetch('/api/notify-admin-resend', { method: 'POST', headers: { @@ -342,13 +336,13 @@ const LoginPageContent = () => { body: JSON.stringify(userData) }); } catch (error) { - console.error("Erro ao enviar notificações:", error); - // Não bloquear o cadastro por erro de notificação + console.error("Erro ao enviar notificações:", error); + // Não bloquear o cadastro por erro de notificação } }; /** - * Função para fechar modal de sucesso e redirecionar + * Função para fechar modal de sucesso e redirecionar */ const handleSuccessModalClose = () => { setShowSuccessModal(false); @@ -356,25 +350,25 @@ const LoginPageContent = () => { }; /** - * Função para fechar modal de cadastro pendente + * Função para fechar modal de cadastro pendente */ const handlePendingModalClose = () => { setShowPendingModal(false); - // Fazer logout para limpar dados do usuário + // Fazer logout para limpar dados do usuário localStorage.removeItem('access_token'); localStorage.removeItem('user'); setAccessToken(""); - // Redirecionar para página inicial + // Redirecionar para página inicial router.push('/'); }; - // Tela de carregamento durante verificação de autenticação + // Tela de carregamento durante verificação de autenticação if (checkingAuth) { return (
-

Verificando autenticação...

+

Verificando autenticação...

); @@ -383,7 +377,7 @@ const LoginPageContent = () => { return (
- {/* Cabeçalho com logo e slogan */} + {/* Cabeçalho com logo e slogan */}
{

Plataforma B2B de Medicamentos

- {/* Formulário de login/registro */} + {/* Formulário de login/registro */}
- {/* Botões de alternância entre Login e Cadastro */} + {/* Botões de alternância entre Login e Cadastro */}
setName(e.target.value)} className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-colors text-gray-900 placeholder-gray-500" @@ -534,7 +528,7 @@ const LoginPageContent = () => {
setPassword(e.target.value)} className="w-full pl-10 pr-12 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-colors text-gray-900 placeholder-gray-500" @@ -583,7 +577,7 @@ const LoginPageContent = () => {
- {/* Botões de Submit */} + {/* Botões de Submit */}
{isLogin ? (
- {/* Conteúdo do Modal */} + {/* Conteúdo do Modal */}

Seu cadastro foi enviado com sucesso!

- Nossa equipe entrará em contato em breve para finalizar seu acesso à plataforma. + Nossa equipe entrará em contato em breve para finalizar seu acesso à plataforma.

- {/* Ícone decorativo */} + {/* Ícone decorativo */}
@@ -735,7 +729,7 @@ const LoginPageContent = () => {
- {/* Botão de OK */} + {/* Botão de OK */}
- {/* Conteúdo do Modal */} + {/* Conteúdo do Modal */}

- Seu cadastro está pendente de validação! + Seu cadastro está pendente de validação!

- Nossa equipe ainda está analisando suas informações. Você receberá uma confirmação em breve. + Nossa equipe ainda está analisando suas informações. Você receberá uma confirmação em breve.

- Qualquer dúvida, entre em contato conosco. + Qualquer dúvida, entre em contato conosco.

- {/* Ícone decorativo */} + {/* Ícone decorativo */}
@@ -796,7 +790,7 @@ const LoginPageContent = () => {
- {/* Botão de OK */} + {/* Botão de OK */}
@@ -102,14 +91,14 @@ const LaboratorioList: React.FC = ({
- Criando novo laboratório... + Criando novo laboratório...
)} {loading ? (
-
Carregando laboratórios...
+
Carregando laboratórios...
) : ( <> @@ -117,51 +106,39 @@ const LaboratorioList: React.FC = ({ - - - - + + + + {laboratorios.length === 0 ? ( ) : ( laboratorios.map((lab) => ( - - + + + - @@ -171,33 +148,31 @@ const LaboratorioList: React.FC = ({
- Nome - - ID - - Data de Criação - - Ações - NomeIDData de CriaçãoAções
- 📭 Nenhum laboratório encontrado. + Nenhum laboratório encontrado.
- {lab.nome || 'N/A'} -
{lab.nome || 'N/A'}{lab.id} - {lab.$id} - - {new Date(lab.$createdAt).toLocaleDateString('pt-BR')} + {lab.createdAt ? new Date(lab.createdAt).toLocaleDateString('pt-BR') : '-'}
-
+
{totalLaboratorios > 0 ? ( - <>Mostrando {startItem} - {endItem} de {totalLaboratorios} laboratórios + <>Mostrando {startItem} - {endItem} de {totalLaboratorios} laboratórios ) : ( - 'Total de laboratórios: 0' + 'Total de laboratórios: 0' )}
- + {totalPages > 1 && (
- - Página {currentPage} de {totalPages} - + Página {currentPage} de {totalPages}
)} @@ -208,5 +183,4 @@ const LaboratorioList: React.FC = ({ ); }; -export default LaboratorioList; - +export default LaboratorioList; \ No newline at end of file diff --git a/frontend/src/components/UsuarioForm.tsx b/frontend/src/components/UsuarioForm.tsx index e332814..1109cca 100644 --- a/frontend/src/components/UsuarioForm.tsx +++ b/frontend/src/components/UsuarioForm.tsx @@ -1,5 +1,4 @@ -// @ts-nocheck -import React, { useState, useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; import { Models } from 'appwrite'; import { UsuarioFormData } from '@/hooks/useUsuarios'; @@ -10,102 +9,115 @@ interface UsuarioFormProps { loading?: boolean; } +type UsuarioDocument = Models.Document & UsuarioFormData; + +const buildEmptyUsuario = (): UsuarioFormData => ({ + 'nome-civil': '', + 'nome-social': '', + cpf: '', + 'auth-id-appwrite': '', + enderecos: [], + empresas: [], + email: '', +}); + const UsuarioForm: React.FC = ({ onSubmit, onCancel, initialData, loading = false, }) => { - - - const [formData, setFormData] = useState({ - 'nome-civil': '', - 'nome-social': '', - cpf: '', - 'auth-id-appwrite': '', - enderecos: [], - empresas: [], - email: '', - }); + const [formData, setFormData] = useState(buildEmptyUsuario); const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null); useEffect(() => { - if (initialData) { - setFormData({ - 'nome-civil': initialData['nome-civil'] || '', - 'nome-social': initialData['nome-social'] || '', - cpf: initialData.cpf || '', - 'auth-id-appwrite': initialData['auth-id-appwrite'] || '', - enderecos: initialData.enderecos || [], - empresas: initialData.empresas || [], - email: initialData.email || '', - }); - } else { - setFormData({ - 'nome-civil': '', - 'nome-social': '', - cpf: '', - 'auth-id-appwrite': '', - enderecos: [], - empresas: [], - email: '', - }); + if (!initialData) { + setFormData(buildEmptyUsuario()); + return; } + + const document = initialData as UsuarioDocument; + setFormData({ + 'nome-civil': document['nome-civil'] || '', + 'nome-social': document['nome-social'] || '', + cpf: document.cpf || '', + 'auth-id-appwrite': document['auth-id-appwrite'] || '', + enderecos: document.enderecos || [], + empresas: document.empresas || [], + email: document.email || '', + }); }, [initialData]); - const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - - const payload = { ...formData, cpf: formData.cpf.replace(/\D/g, '') }; - const success = await onSubmit(payload); - - if (success) { - setMessage({ - type: 'success', - text: initialData ? '🔄 Usuário atualizado com sucesso!' : '🎉 Usuário cadastrado com sucesso!', - }); - - if (!initialData) { - setFormData({ - 'nome-civil': '', - 'nome-social': '', - cpf: '', - 'auth-id-appwrite': '', - enderecos: [], - empresas: [], - email: '', - }); - } - - setTimeout(() => setMessage(null), 3000); - } else { - setMessage({ - type: 'error', - text: initialData ? 'Erro ao atualizar usuário' : 'Erro ao cadastrar usuário', - }); - } - }; - - const formatCpf = (val: string) => { - const digits = val.replace(/\D/g, '').slice(0, 11); + const formatCpf = (value: string) => { + const digits = value.replace(/\D/g, '').slice(0, 11); return digits .replace(/(\d{3})(\d)/, '$1.$2') .replace(/(\d{3})(\d)/, '$1.$2') .replace(/(\d{3})(\d{1,2})$/, '$1-$2'); }; + const parseList = (value: string) => + value + .split(',') + .map((item) => item.trim()) + .filter(Boolean); + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + + const payload: UsuarioFormData = { + ...formData, + cpf: formData.cpf.replace(/\D/g, ''), + enderecos: [...(formData.enderecos || [])], + empresas: [...(formData.empresas || [])], + }; + + const success = await onSubmit(payload); + if (success) { + setMessage({ + type: 'success', + text: initialData ? 'Usuário atualizado com sucesso!' : 'Usuário cadastrado com sucesso!', + }); + + if (!initialData) { + setFormData(buildEmptyUsuario()); + } + + setTimeout(() => setMessage(null), 3000); + return; + } + + setMessage({ + type: 'error', + text: initialData ? 'Erro ao atualizar usuário' : 'Erro ao cadastrar usuário', + }); + }; + const handleInputChange = (e: React.ChangeEvent) => { const { name, value } = e.target; - const val = name === 'cpf' ? formatCpf(value) : value; - setFormData(prev => ({ ...prev, [name]: val })); - if (message) setMessage(null); + + setFormData((prev) => { + if (name === 'cpf') { + return { ...prev, cpf: formatCpf(value) }; + } + + if (name === 'enderecos' || name === 'empresas') { + return { ...prev, [name]: parseList(value) }; + } + + return { ...prev, [name]: value }; + }); + + if (message) { + setMessage(null); + } }; return (

- {initialData ? '✏️ Editar Usuário' : ' Novo Usuário'} + {initialData ? 'Editar Usuário' : 'Novo Usuário'}

{initialData ? 'Atualize os dados do usuário.' : 'Cadastre um novo usuário na plataforma SaveInMed.'} @@ -113,9 +125,12 @@ const UsuarioForm: React.FC = ({

{message && ( -
{message.text}
@@ -166,7 +181,7 @@ const UsuarioForm: React.FC = ({ value={formData.cpf} onChange={handleInputChange} required - maxLength={11} + maxLength={14} disabled={loading} className="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:bg-gray-100 disabled:cursor-not-allowed" placeholder="Digite o CPF" @@ -190,34 +205,34 @@ const UsuarioForm: React.FC = ({
@@ -244,7 +259,7 @@ const UsuarioForm: React.FC = ({ disabled={loading} className="flex-1 bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors cursor-pointer" > - {loading ? '⏳ Processando...' : initialData ? '🔄 Atualizar' : '➕ Cadastrar'} + {loading ? 'Processando...' : initialData ? 'Atualizar' : 'Cadastrar'} {onCancel && ( @@ -254,7 +269,7 @@ const UsuarioForm: React.FC = ({ disabled={loading} className="flex-1 bg-gray-600 text-white py-2 px-4 rounded-md hover:bg-gray-700 focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors cursor-pointer" > - ❌ Cancelar + Cancelar )}
@@ -263,5 +278,4 @@ const UsuarioForm: React.FC = ({ ); }; -export default UsuarioForm; - +export default UsuarioForm; \ No newline at end of file diff --git a/frontend/src/services/usuarioService.ts b/frontend/src/services/usuarioService.ts index ade0654..15cd170 100644 --- a/frontend/src/services/usuarioService.ts +++ b/frontend/src/services/usuarioService.ts @@ -1,10 +1,11 @@ -// SERVIÇO DESABILITADO - MIGRADO PARA BFF -// Este serviço não é mais usado após migração para BFF +// SERVIÇO DESABILITADO - MIGRADO PARA BFF +// Este serviço não é mais usado após migração para BFF export interface UsuarioData { 'nome-civil': string; 'nome-social': string; cpf: string; + 'auth-id-appwrite'?: string; email: string; enderecos?: string[]; empresas?: string[]; @@ -14,6 +15,7 @@ export interface UsuarioUpdateData { 'nome-civil'?: string; 'nome-social'?: string; cpf?: string; + 'auth-id-appwrite'?: string; email?: string; enderecos?: string[]; empresas?: string[]; @@ -31,7 +33,7 @@ export interface PaginatedResponse extends ApiResponse { total: number; } -// Funções desabilitadas - retornam dados vazios +// Funções desabilitadas - retornam dados vazios class UsuarioService { async listar(page = 1, limit = 10): Promise> { console.warn('UsuarioService DESABILITADO - use BFF'); @@ -55,7 +57,7 @@ class UsuarioService { console.warn('UsuarioService DESABILITADO - use BFF'); return { success: false, - error: 'Serviço desabilitado - use BFF' + error: 'Serviço desabilitado - use BFF' }; } @@ -63,7 +65,7 @@ class UsuarioService { console.warn('UsuarioService DESABILITADO - use BFF'); return { success: false, - error: 'Serviço desabilitado - use BFF' + error: 'Serviço desabilitado - use BFF' }; } @@ -71,7 +73,7 @@ class UsuarioService { console.warn('UsuarioService DESABILITADO - use BFF'); return { success: false, - error: 'Serviço desabilitado - use BFF' + error: 'Serviço desabilitado - use BFF' }; } @@ -79,7 +81,7 @@ class UsuarioService { console.warn('UsuarioService DESABILITADO - use BFF'); return { success: false, - error: 'Serviço desabilitado - use BFF' + error: 'Serviço desabilitado - use BFF' }; } }