diff --git a/MEDICONNECT 2.zip b/MEDICONNECT 2.zip new file mode 100644 index 000000000..ae842b600 --- /dev/null +++ b/MEDICONNECT 2.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50fbfa0b9343001fbf0b803364ec8a0fe48bcc62537eb59a31abc74674d80d0a +size 807015226 diff --git a/MEDICONNECT 2/GUILHERME-README.md b/MEDICONNECT 2/GUILHERME-README.md deleted file mode 100644 index e57c1ce6e..000000000 --- a/MEDICONNECT 2/GUILHERME-README.md +++ /dev/null @@ -1,218 +0,0 @@ -# 👤 Usuário Guilherme - Configuração Completa - -## ✅ Status: CONFIGURADO E TESTADO - -### 📋 Credenciais de Login - -- **Email:** `guilhermesilvagomes1020@gmail.com` -- **Senha:** `guilherme123` -- **Role:** `user` (acesso ao painel do paciente) - -### 👨‍⚕️ Dados do Paciente - -- **Nome:** Guilherme Silva Gomes - SQUAD 18 -- **Telefone:** 79999521847 -- **CPF:** 11144477735 -- **Email original:** guilherme@paciente.com -- **Patient ID:** `864b1785-461f-4e92-8b74-2a6f17c58a80` -- **User ID:** `0550f1dc-649a-4186-a256-3bd4e50e5bdc` - -### 🩺 Médico Responsável - -- **Nome:** Fernando Pirichowski - Squad 18 -- **Médico ID:** `be1e3cba-534e-48c3-9590-b7e55861cade` - -## 📅 Consultas de Demonstração - -O sistema possui **3 consultas** criadas para demonstração: - -### Consulta 1 - Agendada - -- **Data/Hora:** 05/10/2025 às 10:00 -- **Status:** Agendada -- **Tipo:** Consulta -- **Observações:** Primeira consulta - Check-up geral - -### Consulta 2 - Realizada - -- **Data/Hora:** 28/09/2025 às 14:30 -- **Status:** Realizada -- **Tipo:** Retorno -- **Observações:** Consulta de retorno - Avaliação de exames - -### Consulta 3 - Confirmada - -- **Data/Hora:** 10/10/2025 às 09:00 -- **Status:** Confirmada -- **Tipo:** Consulta -- **Observações:** Consulta de acompanhamento mensal - -## 🚀 Como Usar - -### 1. Acessar o Login do Paciente - -``` -http://localhost:5173/paciente -``` - -### 2. Fazer Login - -Use as credenciais: - -- Email: `guilhermesilvagomes1020@gmail.com` -- Senha: `guilherme123` - -### 3. Visualizar as Consultas - -Após o login, você será redirecionado para o painel do paciente onde verá: - -- Dashboard com estatísticas das consultas -- Lista completa de consultas (agendadas, realizadas, confirmadas) -- Filtros por status e período -- Cards informativos com totais - -## 📂 Arquivos Relacionados - -### Dados - -- **Consultas:** `src/data/consultas-demo.json` -- **Utilitário:** `src/lib/consultasDemo.ts` - -### Scripts - -- **Criar usuário:** `scripts/criar-guilherme-completo.js` -- **Testar acesso:** `scripts/testar-guilherme.js` - -## 🔧 Comandos Úteis - -### Recriar o usuário - -```bash -node scripts/criar-guilherme-completo.js -``` - -### Testar o acesso - -```bash -node scripts/testar-guilherme.js -``` - -## 📊 Onde as Consultas Aparecem - -As consultas do Guilherme com o Dr. Fernando aparecerão em: - -1. **✅ Painel do Paciente (Guilherme)** - - - Login: guilhermesilvagomes1020@gmail.com - - URL: `/paciente` → `/acompanhamento` - -2. **✅ Painel do Médico (Fernando)** - - - Login: fernando.pirichowski@souunit.com.br - - URL: `/painel-medico` - -3. **✅ Painel da Secretária** - - Login com usuário de secretária - - URL: `/painel-secretaria` - -## 🔐 Configuração Técnica - -### Tabela `auth.users` - -```json -{ - "id": "0550f1dc-649a-4186-a256-3bd4e50e5bdc", - "email": "guilhermesilvagomes1020@gmail.com", - "role": "user" -} -``` - -### Tabela `patients` - -```json -{ - "id": "864b1785-461f-4e92-8b74-2a6f17c58a80", - "full_name": "Guilherme Silva Gomes - SQUAD 18", - "email": "guilherme@paciente.com", - "phone_mobile": "79999521847", - "cpf": "11144477735" -} -``` - -### Tabela `patient_assignments` - -```json -{ - "user_id": "0550f1dc-649a-4186-a256-3bd4e50e5bdc", - "patient_id": "864b1785-461f-4e92-8b74-2a6f17c58a80", - "role": "user" -} -``` - -## 💾 Armazenamento Local - -As consultas são armazenadas em: - -- **Arquivo:** `src/data/consultas-demo.json` -- **LocalStorage:** `consultas_local` (carregado automaticamente) - -### Carregar consultas manualmente no navegador - -Abra o console (F12) e execute: - -```javascript -fetch("/src/data/consultas-demo.json") - .then((r) => r.json()) - .then((consultas) => { - localStorage.setItem("consultas_local", JSON.stringify(consultas)); - console.log("✅ Consultas carregadas!"); - location.reload(); - }); -``` - -### Limpar consultas - -```javascript -localStorage.removeItem("consultas_local"); -location.reload(); -``` - -## ✅ Checklist de Verificação - -- [x] Usuário criado com role "user" -- [x] Paciente Guilherme cadastrado -- [x] Atribuição paciente → usuário configurada -- [x] 3 consultas de demonstração criadas -- [x] Consultas vinculadas ao Dr. Fernando -- [x] Arquivo JSON de consultas criado -- [x] Utilitário de carregamento criado -- [x] Login testado e funcionando -- [x] Pacientes atribuídos verificados - -## 🎯 Resultado Esperado - -Ao fazer login como Guilherme, você deverá ver: - -1. **Header personalizado:** "Olá, Guilherme Silva Gomes - SQUAD 18!" -2. **4 cards de estatísticas:** - - Total: 3 consultas - - Agendadas: 1 - - Realizadas: 1 - - Canceladas: 0 -3. **Lista de consultas** com as 3 consultas criadas -4. **Filtros funcionais** por status e período - -## 📞 Suporte - -Se houver algum problema: - -1. Verifique se o servidor está rodando: `npm run dev` -2. Execute o teste: `node scripts/testar-guilherme.js` -3. Recarregue as consultas no localStorage -4. Verifique o console do navegador para erros - ---- - -**Criado em:** 02/10/2025 -**Última atualização:** 02/10/2025 -**Status:** ✅ Operacional diff --git a/MEDICONNECT 2/PRONTO.md b/MEDICONNECT 2/PRONTO.md deleted file mode 100644 index 909697a8c..000000000 --- a/MEDICONNECT 2/PRONTO.md +++ /dev/null @@ -1,129 +0,0 @@ -# ✅ LIMPEZA COMPLETA - MEDICONNECT - -## 🎉 TUDO PRONTO! - -Todo o site está **100% conectado à API** e o código foi completamente limpo e otimizado! - ---- - -## 📋 O QUE FOI FEITO: - -### 1. ✅ Arquivos Obsoletos Removidos - -**16 arquivos deletados:** - -- `api.js`, `api.js.d.ts`, `api.d.ts`, `api.types.d.ts` ❌ -- `pacientes.js`, `listarPacientes.js`, `listarPacientes.d.ts` ❌ -- 8 arquivos de documentação obsoletos ❌ - -### 2. ✅ Logs de Debug Limpos - -**90% dos logs removidos:** - -- Antes: ~10 logs por requisição 😵 -- Depois: 0-2 logs (apenas erros críticos) 😎 - -### 3. ✅ Código Otimizado - -- Headers `apikey` e `Authorization` sempre presentes ✅ -- Interceptors funcionando perfeitamente ✅ -- Não há mais conflitos entre .js e .ts ✅ -- Validação de token expirado antes de enviar ✅ - -### 4. ✅ Documentação Consolidada - -- **TECH_SUMMARY.md** - Resumo técnico completo -- **CLEANUP_REPORT.md** - Relatório detalhado da limpeza - ---- - -## 🚀 ESTRUTURA FINAL: - -``` -src/services/ -├── api.ts ✅ Instância axios configurada (COM apikey) -├── http.ts ✅ Wrapper com retry e refresh automático -├── authService.ts ✅ Login, logout, refresh token -├── medicoService.ts ✅ CRUD de médicos -├── pacienteService.ts ✅ CRUD de pacientes -├── consultaService.ts ✅ CRUD de consultas -└── ...outros services ✅ Todos usando api.ts corretamente -``` - ---- - -## 🎯 BENEFÍCIOS: - -### Performance: - -- ⚡ Console 90% mais limpo -- ⚡ Bundler mais rápido (menos arquivos) -- ⚡ Menos operações de I/O - -### Confiabilidade: - -- ✅ Headers sempre configurados -- ✅ Interceptors sempre executados -- ✅ Não há mais conflitos de código - -### Manutenibilidade: - -- 📝 Documentação consolidada -- 🔍 Erros fáceis de identificar -- 🧹 Código limpo e organizado - ---- - -## 📊 ESTATÍSTICAS: - -| Item | Antes | Depois | Melhoria | -| ------------------- | ----- | ---------- | -------- | -| Arquivos .js | 7 | 0 | 100% ✅ | -| Logs por request | ~10 | 0-2 | 90% ✅ | -| Docs obsoletos | 8 | 0 | 100% ✅ | -| Erros de compilação | 389 | 0 críticos | ✅ | - ---- - -## ✅ VALIDAÇÃO: - -### Tudo Funcionando: - -- [x] API conectada corretamente -- [x] Headers `apikey` + `Authorization` presentes -- [x] Token expirado detectado antes de enviar -- [x] Refresh automático funcionando -- [x] Console limpo (apenas erros essenciais) -- [x] Sem arquivos obsoletos -- [x] Zero erros de compilação críticos - ---- - -## 🎯 PRÓXIMOS PASSOS (OPCIONAL): - -Se quiser ir além: - -1. Testar com diferentes usuários -2. Validar RLS policies no Supabase -3. Adicionar testes automatizados -4. Implementar cache de requisições - ---- - -## 🚀 ESTÁ PRONTO PARA USAR! - -O sistema está: - -- ✅ Limpo -- ✅ Otimizado -- ✅ Funcionando perfeitamente -- ✅ Pronto para produção - -**Pode usar tranquilo!** 🎉 - ---- - -**Dúvidas?** Consulte: - -- `TECH_SUMMARY.md` - Documentação técnica -- `CLEANUP_REPORT.md` - Detalhes da limpeza diff --git a/MEDICONNECT 2/docs/api/openapi.partial.json b/MEDICONNECT 2/docs/api/openapi.partial.json deleted file mode 100644 index 360848f03..000000000 --- a/MEDICONNECT 2/docs/api/openapi.partial.json +++ /dev/null @@ -1,1088 +0,0 @@ -{ - "openapi": "3.0.1", - "info": { - "title": "MediConnect API (Partial Spec)", - "version": "0.1.0-draft", - "description": "Spec consolidada a partir dos blocos fornecidos. Contém TODOs para endpoints não formalizados (foto/anexos/CPF/SMS)." - }, - "servers": [ - { - "url": "https://yuanqfswhberkoevtmfr.supabase.co", - "description": "Prod Env" - } - ], - "tags": [ - { "name": "Authentication" }, - { "name": "Usuários" }, - { "name": "Perfis" }, - { "name": "Médicos" }, - { "name": "Pacientes" }, - { "name": "Relatórios" }, - { "name": "Atribuições" }, - { "name": "TODO" } - ], - "paths": { - "/auth/v1/token": { - "post": { - "tags": ["Authentication"], - "summary": "Fazer login e obter token JWT", - "parameters": [ - { - "name": "grant_type", - "in": "query", - "required": true, - "schema": { "type": "string", "enum": ["password"] } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/LoginRequest" } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/LoginResponse" } - } - } - }, - "400": { "description": "Credenciais inválidas" }, - "401": { "description": "Email ou senha incorretos" } - } - } - }, - "/auth/v1/logout": { - "post": { - "tags": ["Authentication"], - "summary": "Logout do usuário", - "responses": { - "204": { "description": "Logout realizado" }, - "401": { "description": "Token inválido" } - } - } - }, - "/auth/v1/user": { - "get": { - "tags": ["Authentication", "Usuários"], - "summary": "Obter dados do usuário atual", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/User" } - } - } - }, - "401": { "description": "Token inválido" } - } - } - }, - "/functions/v1/user-info": { - "get": { - "tags": ["Usuários"], - "summary": "Obter informações completas do usuário", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/UserInfoResponse" } - } - } - }, - "401": { "description": "Não autorizado" }, - "500": { "description": "Erro interno" } - } - } - }, - "/functions/v1/create-user": { - "post": { - "tags": ["Usuários"], - "summary": "Criar novo usuário", - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/CreateUserRequest" } - } - } - }, - "responses": { - "200": { - "description": "Criado", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/CreateUserResponse" } - } - } - }, - "400": { "description": "Dados inválidos" }, - "401": { "description": "Não autorizado" }, - "403": { "description": "Sem permissão" }, - "500": { "description": "Erro interno" } - } - } - }, - "/rest/v1/user_roles": { - "get": { - "tags": ["Usuários"], - "summary": "Listar roles de usuários", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { "$ref": "#/components/schemas/UserRole" } - } - } - } - } - } - } - }, - "/rest/v1/profiles": { - "get": { - "tags": ["Perfis"], - "summary": "Listar perfis", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { "$ref": "#/components/schemas/Profile" } - } - } - } - } - } - }, - "patch": { - "tags": ["Perfis"], - "summary": "Atualizar perfil (apenas próprio)", - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/ProfileInput" } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/Profile" } - } - } - } - } - } - }, - "/rest/v1/doctors": { - "get": { - "tags": ["Médicos"], - "summary": "Listar médicos", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { "$ref": "#/components/schemas/Doctor" } - } - } - } - } - } - }, - "post": { - "tags": ["Médicos"], - "summary": "Criar médico", - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/DoctorCreate" } - } - } - }, - "responses": { - "201": { - "description": "Criado", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/Doctor" } - } - } - } - } - } - }, - "/rest/v1/doctors/{id}": { - "get": { - "tags": ["Médicos"], - "summary": "Buscar médico por ID", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { "type": "string", "format": "uuid" } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/Doctor" } - } - } - }, - "404": { "description": "Não encontrado" } - } - }, - "patch": { - "tags": ["Médicos"], - "summary": "Atualizar médico", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { "type": "string", "format": "uuid" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/DoctorUpdate" } - } - } - }, - "responses": { - "200": { "description": "OK" }, - "404": { "description": "Não encontrado" } - } - }, - "delete": { - "tags": ["Médicos"], - "summary": "Deletar médico", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { "type": "string", "format": "uuid" } - } - ], - "responses": { - "204": { "description": "Removido" }, - "404": { "description": "Não encontrado" } - } - } - }, - "/rest/v1/patients": { - "get": { - "tags": ["Pacientes"], - "summary": "Listar pacientes", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { "$ref": "#/components/schemas/Patient" } - } - } - } - } - } - }, - "post": { - "tags": ["Pacientes"], - "summary": "Criar paciente", - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/PatientInput" } - } - } - }, - "responses": { - "201": { - "description": "Criado", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/Patient" } - } - } - } - } - } - }, - "/rest/v1/patients/{id}": { - "get": { - "tags": ["Pacientes"], - "summary": "Obter paciente por ID", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { "type": "string", "format": "uuid" } - } - ], - "responses": { - "200": { "description": "OK" }, - "404": { "description": "Não encontrado" } - } - }, - "patch": { - "tags": ["Pacientes"], - "summary": "Atualizar paciente", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { "type": "string", "format": "uuid" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/PatientInput" } - } - } - }, - "responses": { - "200": { "description": "OK" }, - "404": { "description": "Não encontrado" } - } - }, - "delete": { - "tags": ["Pacientes"], - "summary": "Deletar paciente", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { "type": "string", "format": "uuid" } - } - ], - "responses": { - "204": { "description": "Removido" }, - "404": { "description": "Não encontrado" } - } - } - }, - "/rest/v1/reports": { - "get": { - "tags": ["Relatórios"], - "summary": "Listar relatórios", - "parameters": [ - { - "name": "patient_id", - "in": "query", - "schema": { "type": "string", "format": "uuid" } - }, - { - "name": "status", - "in": "query", - "schema": { - "type": "string", - "enum": ["draft", "pending", "completed", "cancelled"] - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { "$ref": "#/components/schemas/Report" } - } - } - } - } - } - }, - "post": { - "tags": ["Relatórios"], - "summary": "Criar relatório", - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/ReportInput" } - } - } - }, - "responses": { - "201": { - "description": "Criado", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/Report" } - } - } - } - } - } - }, - "/rest/v1/reports/{id}": { - "get": { - "tags": ["Relatórios"], - "summary": "Obter relatório por ID", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { "type": "string", "format": "uuid" } - } - ], - "responses": { - "200": { "description": "OK" }, - "404": { "description": "Não encontrado" } - } - }, - "patch": { - "tags": ["Relatórios"], - "summary": "Atualizar relatório", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { "type": "string", "format": "uuid" } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/ReportInput" } - } - } - }, - "responses": { - "200": { "description": "OK" }, - "404": { "description": "Não encontrado" } - } - } - }, - "/rest/v1/patient_assignments": { - "get": { - "tags": ["Atribuições"], - "summary": "Listar atribuições", - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { "$ref": "#/components/schemas/PatientAssignment" } - } - } - } - } - } - }, - "post": { - "tags": ["Atribuições"], - "summary": "Criar atribuição", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PatientAssignmentInput" - } - } - } - }, - "responses": { - "201": { - "description": "Criado", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/PatientAssignment" } - } - } - } - } - } - }, - "/auth/v1/pacientes/{id}/foto": { - "post": { - "tags": ["Pacientes"], - "summary": "Upload foto paciente", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { "type": "string", "format": "uuid" } - } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "foto": { "type": "string", "format": "binary" } - }, - "required": ["foto"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "foto_url": { "type": "string", "nullable": true }, - "thumbnail_url": { "type": "string", "nullable": true } - } - } - } - } - }, - "401": { "description": "Não autorizado" }, - "404": { "description": "Paciente não encontrado" } - } - }, - "delete": { - "tags": ["Pacientes"], - "summary": "Remover foto paciente", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { "type": "string", "format": "uuid" } - } - ], - "responses": { - "204": { "description": "Removido" }, - "401": { "description": "Não autorizado" }, - "404": { "description": "Paciente não encontrado" } - } - } - }, - "/auth/v1/pacientes/{id}/anexos": { - "get": { - "tags": ["Pacientes"], - "summary": "Listar anexos do paciente", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { "type": "string", "format": "uuid" } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { "$ref": "#/components/schemas/PacienteAnexo" } - } - } - } - }, - "401": { "description": "Não autorizado" }, - "404": { "description": "Paciente não encontrado" } - } - }, - "post": { - "tags": ["Pacientes"], - "summary": "Adicionar anexo ao paciente", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { "type": "string", "format": "uuid" } - } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "arquivo": { "type": "string", "format": "binary" } - }, - "required": ["arquivo"] - } - } - } - }, - "responses": { - "201": { - "description": "Criado", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/PacienteAnexo" } - } - } - }, - "401": { "description": "Não autorizado" }, - "404": { "description": "Paciente não encontrado" } - } - } - }, - "/auth/v1/pacientes/{id}/anexos/{anexoId}": { - "delete": { - "tags": ["Pacientes"], - "summary": "Remover anexo do paciente", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { "type": "string", "format": "uuid" } - }, - { - "name": "anexoId", - "in": "path", - "required": true, - "schema": { "type": "string" } - } - ], - "responses": { - "204": { "description": "Removido" }, - "401": { "description": "Não autorizado" }, - "404": { "description": "Não encontrado" } - } - } - }, - "/pacientes/validar-cpf": { - "post": { - "tags": ["Pacientes"], - "summary": "Validar CPF de paciente (existência e formato)", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { "cpf": { "type": "string" } }, - "required": ["cpf"] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/ValidacaoCPF" } - } - } - }, - "400": { "description": "CPF inválido" } - } - } - }, - "/functions/v1/sms": { - "post": { - "tags": ["TODO"], - "summary": "[FUTURO] Enviar SMS", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "to": { "type": "string" }, - "message": { "type": "string" } - }, - "required": ["to", "message"] - } - } - } - }, - "responses": { - "202": { "description": "Aceito para processamento" }, - "400": { "description": "Payload inválido" } - } - } - } - }, - "components": { - "schemas": { - "LoginRequest": { - "type": "object", - "required": ["email", "password"], - "properties": { - "email": { "type": "string", "format": "email" }, - "password": { "type": "string", "minLength": 6 } - } - }, - "AuthUser": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "email": { "type": "string", "format": "email" }, - "email_confirmed_at": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "created_at": { "type": "string", "format": "date-time" } - } - }, - "LoginResponse": { - "type": "object", - "properties": { - "access_token": { "type": "string" }, - "token_type": { "type": "string" }, - "expires_in": { "type": "integer" }, - "refresh_token": { "type": "string" }, - "user": { "$ref": "#/components/schemas/AuthUser" } - } - }, - "Error": { - "type": "object", - "properties": { - "error": { "type": "string" }, - "message": { "type": "string" } - } - }, - "User": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "email": { "type": "string", "format": "email" }, - "email_confirmed_at": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "created_at": { "type": "string", "format": "date-time" }, - "last_sign_in_at": { - "type": "string", - "format": "date-time", - "nullable": true - } - } - }, - "Profile": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "full_name": { "type": "string", "nullable": true }, - "email": { "type": "string", "nullable": true }, - "phone": { "type": "string", "nullable": true }, - "avatar_url": { "type": "string", "nullable": true }, - "disabled": { "type": "boolean" }, - "created_at": { "type": "string" }, - "updated_at": { "type": "string" } - } - }, - "ProfileInput": { - "type": "object", - "properties": { - "full_name": { "type": "string" }, - "avatar_url": { "type": "string" }, - "phone": { "type": "string" } - } - }, - "DoctorCreate": { - "type": "object", - "required": ["crm", "crm_uf", "full_name", "cpf", "email"], - "properties": { - "user_id": { "type": "string", "nullable": true }, - "crm": { "type": "string" }, - "crm_uf": { "type": "string" }, - "specialty": { "type": "string", "nullable": true }, - "full_name": { "type": "string" }, - "cpf": { "type": "string" }, - "email": { "type": "string" }, - "phone_mobile": { "type": "string", "nullable": true }, - "phone2": { "type": "string", "nullable": true }, - "cep": { "type": "string", "nullable": true }, - "street": { "type": "string", "nullable": true }, - "number": { "type": "string", "nullable": true }, - "complement": { "type": "string", "nullable": true }, - "neighborhood": { "type": "string", "nullable": true }, - "city": { "type": "string", "nullable": true }, - "state": { "type": "string", "nullable": true }, - "birth_date": { "type": "string", "nullable": true }, - "rg": { "type": "string", "nullable": true }, - "active": { "type": "boolean" } - } - }, - "DoctorUpdate": { - "type": "object", - "properties": { - "user_id": { "type": "string", "nullable": true }, - "crm": { "type": "string" }, - "crm_uf": { "type": "string" }, - "specialty": { "type": "string", "nullable": true }, - "full_name": { "type": "string" }, - "cpf": { "type": "string" }, - "email": { "type": "string" }, - "phone_mobile": { "type": "string", "nullable": true }, - "phone2": { "type": "string", "nullable": true }, - "cep": { "type": "string", "nullable": true }, - "street": { "type": "string", "nullable": true }, - "number": { "type": "string", "nullable": true }, - "complement": { "type": "string", "nullable": true }, - "neighborhood": { "type": "string", "nullable": true }, - "city": { "type": "string", "nullable": true }, - "state": { "type": "string", "nullable": true }, - "birth_date": { "type": "string", "nullable": true }, - "rg": { "type": "string", "nullable": true }, - "active": { "type": "boolean" } - } - }, - "Doctor": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "user_id": { "type": "string", "nullable": true }, - "crm": { "type": "string" }, - "crm_uf": { "type": "string" }, - "specialty": { "type": "string", "nullable": true }, - "full_name": { "type": "string" }, - "cpf": { "type": "string" }, - "email": { "type": "string" }, - "phone_mobile": { "type": "string", "nullable": true }, - "phone2": { "type": "string", "nullable": true }, - "cep": { "type": "string", "nullable": true }, - "street": { "type": "string", "nullable": true }, - "number": { "type": "string", "nullable": true }, - "complement": { "type": "string", "nullable": true }, - "neighborhood": { "type": "string", "nullable": true }, - "city": { "type": "string", "nullable": true }, - "state": { "type": "string", "nullable": true }, - "birth_date": { "type": "string", "nullable": true }, - "rg": { "type": "string", "nullable": true }, - "active": { "type": "boolean" }, - "created_at": { "type": "string" }, - "updated_at": { "type": "string" }, - "created_by": { "type": "string" }, - "updated_by": { "type": "string", "nullable": true } - } - }, - "PatientInput": { - "type": "object", - "required": ["full_name", "cpf", "email", "phone_mobile"], - "properties": { - "full_name": { "type": "string" }, - "cpf": { "type": "string" }, - "email": { "type": "string" }, - "phone_mobile": { "type": "string" }, - "birth_date": { "type": "string", "nullable": true }, - "social_name": { "type": "string", "nullable": true }, - "sex": { "type": "string", "nullable": true }, - "blood_type": { "type": "string", "nullable": true }, - "weight_kg": { "type": "number", "nullable": true }, - "height_m": { "type": "number", "nullable": true }, - "street": { "type": "string", "nullable": true }, - "number": { "type": "string", "nullable": true }, - "complement": { "type": "string", "nullable": true }, - "neighborhood": { "type": "string", "nullable": true }, - "city": { "type": "string", "nullable": true }, - "state": { "type": "string", "nullable": true }, - "cep": { "type": "string", "nullable": true } - } - }, - "Patient": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "full_name": { "type": "string" }, - "cpf": { "type": "string" }, - "email": { "type": "string" }, - "phone_mobile": { "type": "string" }, - "birth_date": { "type": "string", "nullable": true }, - "social_name": { "type": "string", "nullable": true }, - "sex": { "type": "string", "nullable": true }, - "blood_type": { "type": "string", "nullable": true }, - "weight_kg": { "type": "number", "nullable": true }, - "height_m": { "type": "number", "nullable": true }, - "bmi": { "type": "number", "nullable": true }, - "street": { "type": "string", "nullable": true }, - "number": { "type": "string", "nullable": true }, - "complement": { "type": "string", "nullable": true }, - "neighborhood": { "type": "string", "nullable": true }, - "city": { "type": "string", "nullable": true }, - "state": { "type": "string", "nullable": true }, - "cep": { "type": "string", "nullable": true }, - "created_at": { "type": "string" }, - "updated_at": { "type": "string" }, - "created_by": { "type": "string" } - } - }, - "ReportInput": { - "type": "object", - "required": ["patient_id", "order_number"], - "properties": { - "patient_id": { "type": "string" }, - "order_number": { "type": "string" }, - "exam": { "type": "string", "nullable": true }, - "diagnosis": { "type": "string", "nullable": true }, - "conclusion": { "type": "string", "nullable": true }, - "cid_code": { "type": "string", "nullable": true }, - "content_html": { "type": "string", "nullable": true }, - "content_json": { "type": "object", "nullable": true }, - "status": { - "type": "string", - "enum": ["draft", "pending", "completed", "cancelled"], - "nullable": true - }, - "requested_by": { "type": "string", "nullable": true }, - "due_at": { "type": "string", "nullable": true }, - "hide_date": { "type": "boolean", "nullable": true }, - "hide_signature": { "type": "boolean", "nullable": true } - } - }, - "Report": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "patient_id": { "type": "string" }, - "order_number": { "type": "string" }, - "exam": { "type": "string", "nullable": true }, - "diagnosis": { "type": "string", "nullable": true }, - "conclusion": { "type": "string", "nullable": true }, - "cid_code": { "type": "string", "nullable": true }, - "content_html": { "type": "string", "nullable": true }, - "content_json": { "type": "object", "nullable": true }, - "status": { "type": "string" }, - "requested_by": { "type": "string", "nullable": true }, - "due_at": { "type": "string", "nullable": true }, - "hide_date": { "type": "boolean", "nullable": true }, - "hide_signature": { "type": "boolean", "nullable": true }, - "created_at": { "type": "string" }, - "updated_at": { "type": "string" }, - "created_by": { "type": "string" } - } - }, - "PatientAssignmentInput": { - "type": "object", - "required": ["patient_id", "user_id", "role"], - "properties": { - "patient_id": { "type": "string" }, - "user_id": { "type": "string" }, - "role": { "type": "string", "enum": ["medico", "enfermeiro"] } - } - }, - "PatientAssignment": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "patient_id": { "type": "string" }, - "user_id": { "type": "string" }, - "role": { "type": "string" }, - "created_at": { "type": "string" }, - "created_by": { "type": "string" } - } - }, - "UserRole": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "user_id": { "type": "string" }, - "role": { "type": "string" }, - "created_at": { "type": "string" } - } - }, - "CreateUserRequest": { - "type": "object", - "required": ["email", "password", "full_name", "role"], - "properties": { - "email": { "type": "string" }, - "password": { "type": "string" }, - "full_name": { "type": "string" }, - "phone": { "type": "string", "nullable": true }, - "role": { - "type": "string", - "enum": ["admin", "gestor", "medico", "secretaria", "user"] - } - } - }, - "CreateUserResponse": { - "type": "object", - "properties": { - "success": { "type": "boolean" }, - "user": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "email": { "type": "string" }, - "full_name": { "type": "string" }, - "phone": { "type": "string", "nullable": true }, - "role": { "type": "string" } - } - } - } - }, - "UserInfoResponse": { - "type": "object", - "properties": { - "user": { "$ref": "#/components/schemas/User" }, - "profile": { "$ref": "#/components/schemas/Profile" }, - "roles": { "type": "array", "items": { "type": "string" } }, - "permissions": { - "type": "object", - "properties": { - "isAdmin": { "type": "boolean" }, - "isManager": { "type": "boolean" }, - "isDoctor": { "type": "boolean" }, - "isSecretary": { "type": "boolean" }, - "isAdminOrManager": { "type": "boolean" } - } - } - } - }, - "PacienteAnexo": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "nome": { "type": "string" }, - "url": { "type": "string", "nullable": true }, - "tipo": { "type": "string", "nullable": true }, - "tamanho": { "type": "integer", "nullable": true }, - "categoria": { "type": "string", "nullable": true }, - "uploaded_at": { "type": "string", "nullable": true }, - "uploaded_by": { "type": "string", "nullable": true } - } - }, - "ValidacaoCPF": { - "type": "object", - "properties": { - "valido": { "type": "boolean" }, - "existe": { "type": "boolean" }, - "paciente_id": { "type": "string", "nullable": true } - } - } - }, - "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer" } } - }, - "security": [{ "bearerAuth": [] }] -} diff --git a/MEDICONNECT 2/listar-pacientes-api.js b/MEDICONNECT 2/listar-pacientes-api.js deleted file mode 100644 index 62fa08906..000000000 --- a/MEDICONNECT 2/listar-pacientes-api.js +++ /dev/null @@ -1,112 +0,0 @@ -// Script para listar todos os usuários/pacientes na API Supabase -import axios from "axios"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -async function listarPacientes() { - try { - console.log("\n🔍 Buscando pacientes na API Supabase...\n"); - - // Primeiro, fazer login como admin para obter token - console.log("1️⃣ Fazendo login como admin..."); - const loginResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: "riseup@popcode.com.br", - password: "riseup", - }, - { - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - }, - } - ); - - const adminToken = loginResponse.data.access_token; - console.log("✅ Login realizado com sucesso!\n"); - - // Tentar buscar na tabela de profiles ou users - console.log("2️⃣ Buscando usuários na tabela profiles..."); - try { - const profilesResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/profiles`, - { - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${adminToken}`, - }, - } - ); - - console.log("\n📊 USUÁRIOS ENCONTRADOS NA TABELA PROFILES:"); - console.log("Total:", profilesResponse.data.length); - console.log("\n" + "=".repeat(80) + "\n"); - - profilesResponse.data.forEach((user, index) => { - console.log(`${index + 1}. ${user.full_name || "Sem nome"}`); - console.log(` 📧 Email: ${user.email}`); - console.log(` 🆔 ID: ${user.id}`); - console.log(` 👤 Role: ${user.role || "Não definido"}`); - console.log(` 📞 Telefone: ${user.phone || "Não informado"}`); - console.log(` 📅 Criado em: ${user.created_at}`); - console.log(""); - }); - - // Filtrar apenas pacientes - const pacientes = profilesResponse.data.filter( - (u) => u.role === "paciente" || u.role === "user" - ); - console.log(`\n👥 TOTAL DE PACIENTES: ${pacientes.length}`); - } catch (error) { - if (error.response && error.response.status === 404) { - console.log('❌ Tabela "profiles" não existe\n'); - } else { - throw error; - } - } - - // Tentar buscar usuários via função - console.log("\n3️⃣ Tentando buscar via função list-users..."); - try { - const usersResponse = await axios.get( - `${SUPABASE_URL}/functions/v1/list-users`, - { - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${adminToken}`, - }, - } - ); - - console.log("\n📊 USUÁRIOS VIA FUNÇÃO:"); - console.log(JSON.stringify(usersResponse.data, null, 2)); - } catch (error) { - if (error.response && error.response.status === 404) { - console.log('❌ Função "list-users" não existe\n'); - } else { - console.log( - "⚠️ Erro ao buscar via função:", - error.response?.data || error.message - ); - } - } - - console.log("\n" + "=".repeat(80)); - console.log("✨ Busca concluída!\n"); - } catch (error) { - console.error("❌ Erro ao listar pacientes:"); - if (error.response) { - console.error(" Status:", error.response.status); - console.error(" Dados:", JSON.stringify(error.response.data, null, 2)); - } else { - console.error(" Mensagem:", error.message); - } - } -} - -listarPacientes(); diff --git a/MEDICONNECT 2/netlify/functions/consultas.ts b/MEDICONNECT 2/netlify/functions/consultas.ts index 8b48c62c4..e89eaeb14 100644 --- a/MEDICONNECT 2/netlify/functions/consultas.ts +++ b/MEDICONNECT 2/netlify/functions/consultas.ts @@ -20,7 +20,7 @@ const consultas: Consulta[] = []; const handler: Handler = async ( event: HandlerEvent, - _context: HandlerContext + context: HandlerContext ) => { const headers = { "Access-Control-Allow-Origin": "*", @@ -34,6 +34,7 @@ const handler: Handler = async ( return { statusCode: 204, headers, body: "" }; } + void context; // not used currently const path = event.path.replace("/.netlify/functions/consultas", ""); const method = event.httpMethod; diff --git a/MEDICONNECT 2/package.json b/MEDICONNECT 2/package.json index 9f9fb7daa..0915339f0 100644 --- a/MEDICONNECT 2/package.json +++ b/MEDICONNECT 2/package.json @@ -8,15 +8,8 @@ "build": "vite build", "lint": "eslint .", "preview": "vite preview", - "export:guia": "node scripts/export-guia.mjs", - "diagnose:login": "node --experimental-fetch scripts/diagnose-login.ts", "deploy:netlify": "netlify deploy --prod --dir=dist", - "deploy:netlify:build": "pnpm build && netlify deploy --prod --dir=dist", - "gen:api-types": "openapi-typescript docs/api/openapi.partial.json --output src/types/api.d.ts", - "test": "vitest run", - "test:watch": "vitest", - "test:e2e-menu": "vitest run src/__tests__/accessibilityMenu.e2e.test.ts", - "check:api-drift": "node scripts/check-api-drift.cjs" + "deploy:netlify:build": "pnpm build && netlify deploy --prod --dir=dist" }, "dependencies": { "@lumi.new/sdk": "^0.1.5", @@ -32,34 +25,28 @@ "zod": "^3.23.8" }, "devDependencies": { - "@axe-core/react": "^4.8.3", "@eslint/js": "^9.9.1", "@netlify/functions": "^4.2.7", - "@testing-library/dom": "^10.4.0", - "@testing-library/react": "^16.0.0", - "@testing-library/user-event": "^14.5.2", "@types/node": "^24.6.1", "@types/react": "^18.3.5", "@types/react-dom": "^18.3.0", - "@vitejs/plugin-react": "^4.3.1", - "@vitest/coverage-v8": "^2.1.4", + "@vitejs/plugin-react": "4.3.2", "autoprefixer": "^10.4.21", - "axe-core": "^4.10.0", "eslint": "^9.9.1", "eslint-plugin-react-hooks": "^5.1.0-rc.0", "eslint-plugin-react-refresh": "^0.4.11", - "finalhandler": "^1.2.0", "globals": "^15.9.0", - "happy-dom": "^19.0.2", - "jsdom": "^25.0.0", - "openapi-typescript": "^7.5.2", "postcss": "^8.5.6", - "puppeteer": "^22.15.0", - "serve-static": "^1.15.0", "tailwindcss": "^3.4.17", "typescript": "^5.5.3", "typescript-eslint": "^8.3.0", - "vite": "5.4.10", - "vitest": "^2.1.4" + "vite": "5.4.10" + }, + "pnpm": { + "overrides": { + "lru-cache": "7.18.3", + "@babel/helper-compilation-targets": "7.25.9", + "@asamuzakjp/css-color": "3.2.0" + } } } diff --git a/MEDICONNECT 2/paginaaleatoria.html b/MEDICONNECT 2/paginaaleatoria.html deleted file mode 100644 index e69de29bb..000000000 diff --git a/MEDICONNECT 2/pnpm-lock.yaml b/MEDICONNECT 2/pnpm-lock.yaml index 59402dff5..cfe07aa85 100644 --- a/MEDICONNECT 2/pnpm-lock.yaml +++ b/MEDICONNECT 2/pnpm-lock.yaml @@ -4,13 +4,18 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + lru-cache: 7.18.3 + '@babel/helper-compilation-targets': 7.25.9 + '@asamuzakjp/css-color': 3.2.0 + importers: .: dependencies: '@lumi.new/sdk': specifier: ^0.1.5 - version: 0.1.7 + version: 0.1.11 axios: specifier: ^1.12.2 version: 1.12.2 @@ -40,95 +45,56 @@ importers: version: 11.0.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) zod: specifier: ^3.23.8 - version: 3.23.8 + version: 3.25.76 devDependencies: - '@axe-core/react': - specifier: ^4.8.3 - version: 4.10.2 '@eslint/js': specifier: ^9.9.1 - version: 9.35.0 + version: 9.37.0 '@netlify/functions': specifier: ^4.2.7 - version: 4.2.7(rollup@4.50.1) - '@testing-library/dom': - specifier: ^10.4.0 - version: 10.4.1 - '@testing-library/react': - specifier: ^16.0.0 - version: 16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@testing-library/user-event': - specifier: ^14.5.2 - version: 14.6.1(@testing-library/dom@10.4.1) + version: 4.3.0(rollup@4.52.4) '@types/node': specifier: ^24.6.1 - version: 24.6.2 + version: 24.7.2 '@types/react': specifier: ^18.3.5 - version: 18.3.24 + version: 18.3.26 '@types/react-dom': specifier: ^18.3.0 - version: 18.3.7(@types/react@18.3.24) + version: 18.3.7(@types/react@18.3.26) '@vitejs/plugin-react': - specifier: ^4.3.1 - version: 4.7.0(vite@5.4.10(@types/node@24.6.2)) - '@vitest/coverage-v8': - specifier: ^2.1.4 - version: 2.1.9(vitest@2.1.9(@types/node@24.6.2)(happy-dom@19.0.2)(jsdom@25.0.1)) + specifier: 4.3.2 + version: 4.3.2(vite@5.4.10(@types/node@24.7.2)) autoprefixer: specifier: ^10.4.21 version: 10.4.21(postcss@8.5.6) - axe-core: - specifier: ^4.10.0 - version: 4.10.3 eslint: specifier: ^9.9.1 - version: 9.35.0(jiti@1.21.7) + version: 9.37.0(jiti@1.21.7) eslint-plugin-react-hooks: specifier: ^5.1.0-rc.0 - version: 5.2.0(eslint@9.35.0(jiti@1.21.7)) + version: 5.2.0(eslint@9.37.0(jiti@1.21.7)) eslint-plugin-react-refresh: specifier: ^0.4.11 - version: 0.4.20(eslint@9.35.0(jiti@1.21.7)) - finalhandler: - specifier: ^1.2.0 - version: 1.3.1 + version: 0.4.23(eslint@9.37.0(jiti@1.21.7)) globals: specifier: ^15.9.0 version: 15.15.0 - happy-dom: - specifier: ^19.0.2 - version: 19.0.2 - jsdom: - specifier: ^25.0.0 - version: 25.0.1 - openapi-typescript: - specifier: ^7.5.2 - version: 7.9.1(typescript@5.9.2) postcss: specifier: ^8.5.6 version: 8.5.6 - puppeteer: - specifier: ^22.15.0 - version: 22.15.0(typescript@5.9.2) - serve-static: - specifier: ^1.15.0 - version: 1.16.2 tailwindcss: specifier: ^3.4.17 - version: 3.4.17 + version: 3.4.18 typescript: specifier: ^5.5.3 - version: 5.9.2 + version: 5.9.3 typescript-eslint: specifier: ^8.3.0 - version: 8.43.0(eslint@9.35.0(jiti@1.21.7))(typescript@5.9.2) + version: 8.46.0(eslint@9.37.0(jiti@1.21.7))(typescript@5.9.3) vite: specifier: 5.4.10 - version: 5.4.10(@types/node@24.6.2) - vitest: - specifier: ^2.1.4 - version: 2.1.9(@types/node@24.6.2)(happy-dom@19.0.2)(jsdom@25.0.1) + version: 5.4.10(@types/node@24.7.2) packages: @@ -136,16 +102,6 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - - '@asamuzakjp/css-color@3.2.0': - resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} - - '@axe-core/react@4.10.2': - resolution: {integrity: sha512-BIHQ+kMtOpPTmtMrJDGQMkXQT8C3YX5GIUmqXQ6tCAUaK7ZwhfbyNBaYlG0h0IdC7mHL0uxTXYxOI6r4Lgnw6w==} - '@babel/code-frame@7.27.1': resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} @@ -162,8 +118,8 @@ packages: resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.27.2': - resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + '@babel/helper-compilation-targets@7.25.9': + resolution: {integrity: sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==} engines: {node: '>=6.9.0'} '@babel/helper-globals@7.28.0': @@ -233,41 +189,10 @@ packages: resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} engines: {node: '>=6.9.0'} - '@bcoe/v8-coverage@0.2.3': - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - '@colors/colors@1.6.0': resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} engines: {node: '>=0.1.90'} - '@csstools/color-helpers@5.1.0': - resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} - engines: {node: '>=18'} - - '@csstools/css-calc@2.1.4': - resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} - engines: {node: '>=18'} - peerDependencies: - '@csstools/css-parser-algorithms': ^3.0.5 - '@csstools/css-tokenizer': ^3.0.4 - - '@csstools/css-color-parser@3.1.0': - resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} - engines: {node: '>=18'} - peerDependencies: - '@csstools/css-parser-algorithms': ^3.0.5 - '@csstools/css-tokenizer': ^3.0.4 - - '@csstools/css-parser-algorithms@3.0.5': - resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} - engines: {node: '>=18'} - peerDependencies: - '@csstools/css-tokenizer': ^3.0.4 - - '@csstools/css-tokenizer@3.0.4': - resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} - engines: {node: '>=18'} - '@dabh/diagnostics@2.0.8': resolution: {integrity: sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==} @@ -587,28 +512,28 @@ packages: resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/config-helpers@0.3.1': - resolution: {integrity: sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==} + '@eslint/config-helpers@0.4.0': + resolution: {integrity: sha512-WUFvV4WoIwW8Bv0KeKCIIEgdSiFOsulyN0xrMu+7z43q/hkOLXjvb5u7UC9jDxvRzcrbEmuZBX5yJZz1741jog==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.15.2': - resolution: {integrity: sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==} + '@eslint/core@0.16.0': + resolution: {integrity: sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/eslintrc@3.3.1': resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.35.0': - resolution: {integrity: sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw==} + '@eslint/js@9.37.0': + resolution: {integrity: sha512-jaS+NJ+hximswBG6pjNX0uEJZkrT0zwpVi3BA3vX22aFGjJjmgSTSmPpZCRKmoBL5VY/M6p0xsSJx7rk7sy5gg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.6': resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.3.5': - resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==} + '@eslint/plugin-kit@0.4.0': + resolution: {integrity: sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@fastify/busboy@3.2.0': @@ -638,10 +563,6 @@ packages: resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} engines: {node: '>=18.0.0'} - '@istanbuljs/schema@0.1.3': - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} - '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -655,11 +576,11 @@ packages: '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.30': - resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@lumi.new/sdk@0.1.7': - resolution: {integrity: sha512-lRj4g4Sexss8gUa59IAFBVFyyOjekNAIjDSJJkXz1Cx8kJTrUFsczZk0nkAljJnjbFKBw3Vou7ziEXv55Fg9ZQ==} + '@lumi.new/sdk@0.1.11': + resolution: {integrity: sha512-y4hgZYVDIPIzCV7oF5g0dAYfEsTqkdX/IQWQn8yyQX8D5PcD6NPrhVKCoGWzwm5RtRkzEmU0diIuTfDVNk5JDA==} '@mapbox/node-pre-gyp@2.0.0': resolution: {integrity: sha512-llMXd39jtP0HpQLVI37Bf1m2ADlEb35GYSh1SDSLsBhR+5iCxiNGlT31yqbNtVHygHAtMy6dWFERpU2JgufhPg==} @@ -669,28 +590,28 @@ packages: '@netlify/binary-info@1.0.0': resolution: {integrity: sha512-4wMPu9iN3/HL97QblBsBay3E1etIciR84izI3U+4iALY+JHCrI+a2jO0qbAZ/nxKoegypYEaiiqWXylm+/zfrw==} - '@netlify/blobs@10.0.11': - resolution: {integrity: sha512-/pa7eD2gxkhJ6aUIJULrRu3tvAaimy+sA6vHUuGRMvncjOuRpeatXLHxuzdn8DyK1CZCjN3E33oXsdEpoqG7SA==} + '@netlify/blobs@10.1.0': + resolution: {integrity: sha512-dFpqDc6/x5LEu9L7kblCQu00CFEchH8J42jmQoXPuhKoE7avajzeLTbVKA8Olk3S/c2m9ejegrgbhL8NRA2Jyw==} engines: {node: ^14.16.0 || >=16.0.0} - '@netlify/dev-utils@4.2.0': - resolution: {integrity: sha512-P/uLJ5IKB4DhUOd6Q4Mpk7N0YKrnijUhAL3C05dEftNi3U3xJB98YekYfsL3G6GkS3L35pKGMx+vKJRwUHpP1Q==} + '@netlify/dev-utils@4.3.0': + resolution: {integrity: sha512-vZAL8pMuj3yPQlmHSgyaA/UQFxc6pZgU0LucFJ1+IPWGJtIzBXHRvuR4acpoP72HtyQPUHJ42s7U9GaaSGVNHg==} engines: {node: ^18.14.0 || >=20} - '@netlify/functions@4.2.7': - resolution: {integrity: sha512-TN2sijuyrEejhLfataxAKSFjFi8ZC0IMqrubg3Rz3ROBBwk54vdLwxibHxnKexou75MXsrpCotsEzm/V0xZwBA==} + '@netlify/functions@4.3.0': + resolution: {integrity: sha512-m00J4hO/AL+1mAD4jCia1kg2jIoO3S9+DXCge58n5tTqPlWt42Vgig5zm0ICJoAyjMKw2bGzfVw9a/s/x6d1+Q==} engines: {node: '>=18.0.0'} - '@netlify/runtime-utils@2.1.0': - resolution: {integrity: sha512-z1h+wjB7IVYUsFZsuIYyNxiw5WWuylseY+eXaUDHBxNeLTlqziy+lz03QkR67CUR4Y790xGIhaHV00aOR2KAtw==} + '@netlify/runtime-utils@2.2.0': + resolution: {integrity: sha512-K3kWIxIMucibzQsATU2xw2JI+OpS9PZfPW/a+81gmeLC8tLv5YAxTVT0NFY/3imk1kcOJb9g7658jPLqDJaiAw==} engines: {node: ^18.14.0 || >=20} - '@netlify/serverless-functions-api@2.5.0': - resolution: {integrity: sha512-0Hl6POpkEs3aan8T+EQvPIj5/gNc+64nwNv93VY4JoxFSrLPKYWmUyXJhT9lG93VxwGfmbxrCOV8U4sq2eWgTw==} + '@netlify/serverless-functions-api@2.6.0': + resolution: {integrity: sha512-/m4HO0MNb7nBsHWKQ7JTeTZ3jDZpfQxs0LOn9h/+aPzGcdYW7DwKNudGq8NXYY5NPtRE3C+8qtr3xLfN9VOU6g==} engines: {node: '>=18.0.0'} - '@netlify/types@2.0.3': - resolution: {integrity: sha512-OcV8ivKTdsyANqVSQzbusOA7FVtE9s6zwxNCGR/aNnQaVxMUgm93UzKgfR7cZ1nnQNZHAbjd0dKJKaAUqrzbMw==} + '@netlify/types@2.1.0': + resolution: {integrity: sha512-ktUb5d58pt1lQGXO5E9S0F1ljM0g+CoQuGTVII0IxBc0apmPq5RI0o3OWLY7U3ZERRiYTg5UfjiMihBEzuZsuw==} engines: {node: ^18.14.0 || >=20} '@netlify/zip-it-and-ship-it@14.1.8': @@ -714,28 +635,10 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@puppeteer/browsers@2.3.0': - resolution: {integrity: sha512-ioXoq9gPxkss4MYhD+SFaU9p1IHFUX0ILAWFPyjGaBdjLsYAlZw6j1iLA0N/m12uVHLFDfSYNF7EQccjinIMDA==} - engines: {node: '>=18'} - hasBin: true - - '@redocly/ajv@8.11.3': - resolution: {integrity: sha512-4P3iZse91TkBiY+Dx5DUgxQ9GXkVJf++cmI0MOyLDxV9b5MUBI4II6ES8zA5JCbO72nKAJxWrw4PUPW+YP3ZDQ==} - - '@redocly/config@0.22.2': - resolution: {integrity: sha512-roRDai8/zr2S9YfmzUfNhKjOF0NdcOIqF7bhf4MVC5UxpjIysDjyudvlAiVbpPHp3eDRWbdzUgtkK1a7YiDNyQ==} - - '@redocly/openapi-core@1.34.5': - resolution: {integrity: sha512-0EbE8LRbkogtcCXU7liAyC00n9uNG9hJ+eMyHFdUsy9lB/WGqnEBgwjA9q2cyzAVcdTkQqTBBU1XePNnN3OijA==} - engines: {node: '>=18.17.0', npm: '>=9.5.0'} - '@remix-run/router@1.23.0': resolution: {integrity: sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==} engines: {node: '>=14.0.0'} - '@rolldown/pluginutils@1.0.0-beta.27': - resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} - '@rollup/pluginutils@5.3.0': resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} engines: {node: '>=14.0.0'} @@ -745,145 +648,119 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.50.1': - resolution: {integrity: sha512-HJXwzoZN4eYTdD8bVV22DN8gsPCAj3V20NHKOs8ezfXanGpmVPR7kalUHd+Y31IJp9stdB87VKPFbsGY3H/2ag==} + '@rollup/rollup-android-arm-eabi@4.52.4': + resolution: {integrity: sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.50.1': - resolution: {integrity: sha512-PZlsJVcjHfcH53mOImyt3bc97Ep3FJDXRpk9sMdGX0qgLmY0EIWxCag6EigerGhLVuL8lDVYNnSo8qnTElO4xw==} + '@rollup/rollup-android-arm64@4.52.4': + resolution: {integrity: sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.50.1': - resolution: {integrity: sha512-xc6i2AuWh++oGi4ylOFPmzJOEeAa2lJeGUGb4MudOtgfyyjr4UPNK+eEWTPLvmPJIY/pgw6ssFIox23SyrkkJw==} + '@rollup/rollup-darwin-arm64@4.52.4': + resolution: {integrity: sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.50.1': - resolution: {integrity: sha512-2ofU89lEpDYhdLAbRdeyz/kX3Y2lpYc6ShRnDjY35bZhd2ipuDMDi6ZTQ9NIag94K28nFMofdnKeHR7BT0CATw==} + '@rollup/rollup-darwin-x64@4.52.4': + resolution: {integrity: sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.50.1': - resolution: {integrity: sha512-wOsE6H2u6PxsHY/BeFHA4VGQN3KUJFZp7QJBmDYI983fgxq5Th8FDkVuERb2l9vDMs1D5XhOrhBrnqcEY6l8ZA==} + '@rollup/rollup-freebsd-arm64@4.52.4': + resolution: {integrity: sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.50.1': - resolution: {integrity: sha512-A/xeqaHTlKbQggxCqispFAcNjycpUEHP52mwMQZUNqDUJFFYtPHCXS1VAG29uMlDzIVr+i00tSFWFLivMcoIBQ==} + '@rollup/rollup-freebsd-x64@4.52.4': + resolution: {integrity: sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.50.1': - resolution: {integrity: sha512-54v4okehwl5TaSIkpp97rAHGp7t3ghinRd/vyC1iXqXMfjYUTm7TfYmCzXDoHUPTTf36L8pr0E7YsD3CfB3ZDg==} + '@rollup/rollup-linux-arm-gnueabihf@4.52.4': + resolution: {integrity: sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.50.1': - resolution: {integrity: sha512-p/LaFyajPN/0PUHjv8TNyxLiA7RwmDoVY3flXHPSzqrGcIp/c2FjwPPP5++u87DGHtw+5kSH5bCJz0mvXngYxw==} + '@rollup/rollup-linux-arm-musleabihf@4.52.4': + resolution: {integrity: sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.50.1': - resolution: {integrity: sha512-2AbMhFFkTo6Ptna1zO7kAXXDLi7H9fGTbVaIq2AAYO7yzcAsuTNWPHhb2aTA6GPiP+JXh85Y8CiS54iZoj4opw==} + '@rollup/rollup-linux-arm64-gnu@4.52.4': + resolution: {integrity: sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.50.1': - resolution: {integrity: sha512-Cgef+5aZwuvesQNw9eX7g19FfKX5/pQRIyhoXLCiBOrWopjo7ycfB292TX9MDcDijiuIJlx1IzJz3IoCPfqs9w==} + '@rollup/rollup-linux-arm64-musl@4.52.4': + resolution: {integrity: sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.50.1': - resolution: {integrity: sha512-RPhTwWMzpYYrHrJAS7CmpdtHNKtt2Ueo+BlLBjfZEhYBhK00OsEqM08/7f+eohiF6poe0YRDDd8nAvwtE/Y62Q==} + '@rollup/rollup-linux-loong64-gnu@4.52.4': + resolution: {integrity: sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.50.1': - resolution: {integrity: sha512-eSGMVQw9iekut62O7eBdbiccRguuDgiPMsw++BVUg+1K7WjZXHOg/YOT9SWMzPZA+w98G+Fa1VqJgHZOHHnY0Q==} + '@rollup/rollup-linux-ppc64-gnu@4.52.4': + resolution: {integrity: sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.50.1': - resolution: {integrity: sha512-S208ojx8a4ciIPrLgazF6AgdcNJzQE4+S9rsmOmDJkusvctii+ZvEuIC4v/xFqzbuP8yDjn73oBlNDgF6YGSXQ==} + '@rollup/rollup-linux-riscv64-gnu@4.52.4': + resolution: {integrity: sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.50.1': - resolution: {integrity: sha512-3Ag8Ls1ggqkGUvSZWYcdgFwriy2lWo+0QlYgEFra/5JGtAd6C5Hw59oojx1DeqcA2Wds2ayRgvJ4qxVTzCHgzg==} + '@rollup/rollup-linux-riscv64-musl@4.52.4': + resolution: {integrity: sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.50.1': - resolution: {integrity: sha512-t9YrKfaxCYe7l7ldFERE1BRg/4TATxIg+YieHQ966jwvo7ddHJxPj9cNFWLAzhkVsbBvNA4qTbPVNsZKBO4NSg==} + '@rollup/rollup-linux-s390x-gnu@4.52.4': + resolution: {integrity: sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.50.1': - resolution: {integrity: sha512-MCgtFB2+SVNuQmmjHf+wfI4CMxy3Tk8XjA5Z//A0AKD7QXUYFMQcns91K6dEHBvZPCnhJSyDWLApk40Iq/H3tA==} + '@rollup/rollup-linux-x64-gnu@4.52.4': + resolution: {integrity: sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.50.1': - resolution: {integrity: sha512-nEvqG+0jeRmqaUMuwzlfMKwcIVffy/9KGbAGyoa26iu6eSngAYQ512bMXuqqPrlTyfqdlB9FVINs93j534UJrg==} + '@rollup/rollup-linux-x64-musl@4.52.4': + resolution: {integrity: sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==} cpu: [x64] os: [linux] - '@rollup/rollup-openharmony-arm64@4.50.1': - resolution: {integrity: sha512-RDsLm+phmT3MJd9SNxA9MNuEAO/J2fhW8GXk62G/B4G7sLVumNFbRwDL6v5NrESb48k+QMqdGbHgEtfU0LCpbA==} + '@rollup/rollup-openharmony-arm64@4.52.4': + resolution: {integrity: sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.50.1': - resolution: {integrity: sha512-hpZB/TImk2FlAFAIsoElM3tLzq57uxnGYwplg6WDyAxbYczSi8O2eQ+H2Lx74504rwKtZ3N2g4bCUkiamzS6TQ==} + '@rollup/rollup-win32-arm64-msvc@4.52.4': + resolution: {integrity: sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.50.1': - resolution: {integrity: sha512-SXjv8JlbzKM0fTJidX4eVsH+Wmnp0/WcD8gJxIZyR6Gay5Qcsmdbi9zVtnbkGPG8v2vMR1AD06lGWy5FLMcG7A==} + '@rollup/rollup-win32-ia32-msvc@4.52.4': + resolution: {integrity: sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.50.1': - resolution: {integrity: sha512-StxAO/8ts62KZVRAm4JZYq9+NqNsV7RvimNK+YM7ry//zebEH6meuugqW/P5OFUCjyQgui+9fUxT6d5NShvMvA==} + '@rollup/rollup-win32-x64-gnu@4.52.4': + resolution: {integrity: sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.52.4': + resolution: {integrity: sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==} cpu: [x64] os: [win32] '@so-ric/colorspace@1.1.6': resolution: {integrity: sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==} - '@testing-library/dom@10.4.1': - resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} - engines: {node: '>=18'} - - '@testing-library/react@16.3.0': - resolution: {integrity: sha512-kFSyxiEDwv1WLl2fgsq6pPBbw5aWKrsY2/noi1Id0TK0UParSF62oFQFGHXIyaG4pp2tEub/Zlel+fjjZILDsw==} - engines: {node: '>=18'} - peerDependencies: - '@testing-library/dom': ^10.0.0 - '@types/react': ^18.0.0 || ^19.0.0 - '@types/react-dom': ^18.0.0 || ^19.0.0 - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@testing-library/user-event@14.6.1': - resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} - engines: {node: '>=12', npm: '>=6'} - peerDependencies: - '@testing-library/dom': '>=7.21.4' - - '@tootallnate/quickjs-emscripten@0.23.0': - resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} - - '@types/aria-query@5.0.4': - resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} - '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -902,11 +779,8 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/node@20.19.19': - resolution: {integrity: sha512-pb1Uqj5WJP7wrcbLU7Ru4QtA0+3kAXrkutGiD26wUKzSMgNNaPARTUDQmElUXp64kh3cWdou3Q0C7qwwxqSFmg==} - - '@types/node@24.6.2': - resolution: {integrity: sha512-d2L25Y4j+W3ZlNAeMKcy7yDsK425ibcAOO2t7aPTz6gNMH0z2GThtwENCDc0d/Pw9wgyRqE5Px1wkV7naz8ang==} + '@types/node@24.7.2': + resolution: {integrity: sha512-/NbVmcGTP+lj5oa4yiYxxeBjRivKQ5Ns1eSZeB99ExsEQ6rX5XYU1Zy/gGxY/ilqtD4Etx9mKyrPxZRetiahhA==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -919,75 +793,72 @@ packages: peerDependencies: '@types/react': ^18.0.0 - '@types/react@18.3.24': - resolution: {integrity: sha512-0dLEBsA1kI3OezMBF8nSsb7Nk19ZnsyE1LLhB8r27KbgU5H4pvuqZLdtE+aUkJVoXgTVuA+iLIwmZ0TuK4tx6A==} + '@types/react@18.3.26': + resolution: {integrity: sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA==} '@types/triple-beam@1.3.5': resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} - '@types/whatwg-mimetype@3.0.2': - resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} - '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@typescript-eslint/eslint-plugin@8.43.0': - resolution: {integrity: sha512-8tg+gt7ENL7KewsKMKDHXR1vm8tt9eMxjJBYINf6swonlWgkYn5NwyIgXpbbDxTNU5DgpDFfj95prcTq2clIQQ==} + '@typescript-eslint/eslint-plugin@8.46.0': + resolution: {integrity: sha512-hA8gxBq4ukonVXPy0OKhiaUh/68D0E88GSmtC1iAEnGaieuDi38LhS7jdCHRLi6ErJBNDGCzvh5EnzdPwUc0DA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.43.0 + '@typescript-eslint/parser': ^8.46.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.43.0': - resolution: {integrity: sha512-B7RIQiTsCBBmY+yW4+ILd6mF5h1FUwJsVvpqkrgpszYifetQ2Ke+Z4u6aZh0CblkUGIdR59iYVyXqqZGkZ3aBw==} + '@typescript-eslint/parser@8.46.0': + resolution: {integrity: sha512-n1H6IcDhmmUEG7TNVSspGmiHHutt7iVKtZwRppD7e04wha5MrkV1h3pti9xQLcCMt6YWsncpoT0HMjkH1FNwWQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.43.0': - resolution: {integrity: sha512-htB/+D/BIGoNTQYffZw4uM4NzzuolCoaA/BusuSIcC8YjmBYQioew5VUZAYdAETPjeed0hqCaW7EHg+Robq8uw==} + '@typescript-eslint/project-service@8.46.0': + resolution: {integrity: sha512-OEhec0mH+U5Je2NZOeK1AbVCdm0ChyapAyTeXVIYTPXDJ3F07+cu87PPXcGoYqZ7M9YJVvFnfpGg1UmCIqM+QQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.43.0': - resolution: {integrity: sha512-daSWlQ87ZhsjrbMLvpuuMAt3y4ba57AuvadcR7f3nl8eS3BjRc8L9VLxFLk92RL5xdXOg6IQ+qKjjqNEimGuAg==} + '@typescript-eslint/scope-manager@8.46.0': + resolution: {integrity: sha512-lWETPa9XGcBes4jqAMYD9fW0j4n6hrPtTJwWDmtqgFO/4HF4jmdH/Q6wggTw5qIT5TXjKzbt7GsZUBnWoO3dqw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.43.0': - resolution: {integrity: sha512-ALC2prjZcj2YqqL5X/bwWQmHA2em6/94GcbB/KKu5SX3EBDOsqztmmX1kMkvAJHzxk7TazKzJfFiEIagNV3qEA==} + '@typescript-eslint/tsconfig-utils@8.46.0': + resolution: {integrity: sha512-WrYXKGAHY836/N7zoK/kzi6p8tXFhasHh8ocFL9VZSAkvH956gfeRfcnhs3xzRy8qQ/dq3q44v1jvQieMFg2cw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.43.0': - resolution: {integrity: sha512-qaH1uLBpBuBBuRf8c1mLJ6swOfzCXryhKND04Igr4pckzSEW9JX5Aw9AgW00kwfjWJF0kk0ps9ExKTfvXfw4Qg==} + '@typescript-eslint/type-utils@8.46.0': + resolution: {integrity: sha512-hy+lvYV1lZpVs2jRaEYvgCblZxUoJiPyCemwbQZ+NGulWkQRy0HRPYAoef/CNSzaLt+MLvMptZsHXHlkEilaeg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.43.0': - resolution: {integrity: sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw==} + '@typescript-eslint/types@8.46.0': + resolution: {integrity: sha512-bHGGJyVjSE4dJJIO5yyEWt/cHyNwga/zXGJbJJ8TiO01aVREK6gCTu3L+5wrkb1FbDkQ+TKjMNe9R/QQQP9+rA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.43.0': - resolution: {integrity: sha512-7Vv6zlAhPb+cvEpP06WXXy/ZByph9iL6BQRBDj4kmBsW98AqEeQHlj/13X+sZOrKSo9/rNKH4Ul4f6EICREFdw==} + '@typescript-eslint/typescript-estree@8.46.0': + resolution: {integrity: sha512-ekDCUfVpAKWJbRfm8T1YRrCot1KFxZn21oV76v5Fj4tr7ELyk84OS+ouvYdcDAwZL89WpEkEj2DKQ+qg//+ucg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.43.0': - resolution: {integrity: sha512-S1/tEmkUeeswxd0GGcnwuVQPFWo8NzZTOMxCvw8BX7OMxnNae+i8Tm7REQen/SwUIPoPqfKn7EaZ+YLpiB3k9g==} + '@typescript-eslint/utils@8.46.0': + resolution: {integrity: sha512-nD6yGWPj1xiOm4Gk0k6hLSZz2XkNXhuYmyIrOWcHoPuAhjT9i5bAG+xbWPgFeNR8HPHHtpNKdYUXJl/D3x7f5g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.43.0': - resolution: {integrity: sha512-T+S1KqRD4sg/bHfLwrpF/K3gQLBM1n7Rp7OjjikjTEssI2YJzQpi5WXoynOaQ93ERIuq3O8RBTOUYDKszUCEHw==} + '@typescript-eslint/visitor-keys@8.46.0': + resolution: {integrity: sha512-FrvMpAK+hTbFy7vH5j1+tMYHMSKLE6RzluFJlkFNKD0p9YsUT75JlBSmr5so3QRzvMwU5/bIEdeNrxm8du8l3Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@vercel/nft@0.29.4': @@ -995,49 +866,11 @@ packages: engines: {node: '>=18'} hasBin: true - '@vitejs/plugin-react@4.7.0': - resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} + '@vitejs/plugin-react@4.3.2': + resolution: {integrity: sha512-hieu+o05v4glEBucTcKMK3dlES0OeJlD9YVOAPraVMOInBCwzumaIFiUjr4bHK7NPgnAHgiskUoceKercrN8vg==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 - - '@vitest/coverage-v8@2.1.9': - resolution: {integrity: sha512-Z2cOr0ksM00MpEfyVE8KXIYPEcBFxdbLSs56L8PO0QQMxt/6bDj45uQfxoc96v05KW3clk7vvgP0qfDit9DmfQ==} - peerDependencies: - '@vitest/browser': 2.1.9 - vitest: 2.1.9 - peerDependenciesMeta: - '@vitest/browser': - optional: true - - '@vitest/expect@2.1.9': - resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==} - - '@vitest/mocker@2.1.9': - resolution: {integrity: sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==} - peerDependencies: - msw: ^2.4.9 - vite: ^5.0.0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true - - '@vitest/pretty-format@2.1.9': - resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} - - '@vitest/runner@2.1.9': - resolution: {integrity: sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==} - - '@vitest/snapshot@2.1.9': - resolution: {integrity: sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==} - - '@vitest/spy@2.1.9': - resolution: {integrity: sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==} - - '@vitest/utils@2.1.9': - resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + vite: ^4.2.0 || ^5.0.0 '@vue/compiler-core@3.5.22': resolution: {integrity: sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==} @@ -1062,16 +895,16 @@ packages: resolution: {integrity: sha512-eR8SYtf9Nem1Tnl0IWrY33qJ5wCtIWlt3Fs3c6V4aAaTFLtkEQErXu3SSZg/XCHrj9hXSJ8/8t+CdMk5Qec/ZA==} engines: {node: '>=18.0.0'} - '@whatwg-node/node-fetch@0.8.0': - resolution: {integrity: sha512-+z00GpWxKV/q8eMETwbdi80TcOoVEVZ4xSRkxYOZpn3kbV3nej5iViNzXVke/j3v4y1YpO5zMS/CVDIASvJnZQ==} + '@whatwg-node/node-fetch@0.8.1': + resolution: {integrity: sha512-cQmQEo7IsI0EPX9VrwygXVzrVlX43Jb7/DBZSmpnC7xH4xkyOnn/HykHpTaQk7TUs7zh59A5uTGqx3p2Ouzffw==} engines: {node: '>=18.0.0'} '@whatwg-node/promise-helpers@1.3.2': resolution: {integrity: sha512-Nst5JdK47VIl9UcGwtv2Rcgyn5lWtZ0/mhRQ4G8NN2isxpq2TO30iqHzmwoJycjWuyUfg3GFXqP/gFHXeV57IA==} engines: {node: '>=16.0.0'} - '@whatwg-node/server@0.10.12': - resolution: {integrity: sha512-MQIvvQyPvKGna586MzXhgwnEbGtbm7QtOgJ/KPd/tC70M/jbhd1xHdIQQbh3okBw+MrDF/EvaC2vB5oRC7QdlQ==} + '@whatwg-node/server@0.10.13': + resolution: {integrity: sha512-Otmxo+0mp8az3B48pLI1I4msNOXPIoP7TLm6h5wOEQmynqHt8oP9nR6NJUeJk6iI5OtFpQtkbJFwfGkmplvc3Q==} engines: {node: '>=18.0.0'} abbrev@3.0.1: @@ -1104,10 +937,6 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - ansi-colors@4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} - engines: {node: '>=6'} - ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -1120,10 +949,6 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - ansi-styles@6.2.3: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} @@ -1153,21 +978,10 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - aria-query@5.3.0: - resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} - - assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} - ast-module-types@6.0.1: resolution: {integrity: sha512-WHw67kLXYbZuHTmcdbIrVArCq5wxo6NEuj3hiYAWr8mwJeC+C2mMCIBIWCiDoCye/OF/xelc+teJ1ERoWmnEIA==} engines: {node: '>=18'} - ast-types@0.13.4: - resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} - engines: {node: '>=4'} - async-sema@3.1.1: resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==} @@ -1184,15 +998,11 @@ packages: peerDependencies: postcss: ^8.1.0 - axe-core@4.10.3: - resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==} - engines: {node: '>=4'} - axios@1.12.2: resolution: {integrity: sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==} - b4a@1.7.2: - resolution: {integrity: sha512-DyUOdz+E8R6+sruDpQNOaV0y/dBbV6X/8ZkxrDcR0Ifc3BgKlpgG0VAtfOozA0eMtJO5GGe9FsZhueLs00pTww==} + b4a@1.7.3: + resolution: {integrity: sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==} peerDependencies: react-native-b4a: '*' peerDependenciesMeta: @@ -1202,45 +1012,20 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - bare-events@2.7.0: - resolution: {integrity: sha512-b3N5eTW1g7vXkw+0CXh/HazGTcO5KYuu/RCNaJbDMPI6LHDi+7qe8EmxKUVe1sUbY2KZOVZFyj62x0OEz9qyAA==} - - bare-fs@4.4.4: - resolution: {integrity: sha512-Q8yxM1eLhJfuM7KXVP3zjhBvtMJCYRByoTT+wHXjpdMELv0xICFJX+1w4c7csa+WZEOsq4ItJ4RGwvzid6m/dw==} - engines: {bare: '>=1.16.0'} + bare-events@2.8.0: + resolution: {integrity: sha512-AOhh6Bg5QmFIXdViHbMc2tLDsBIRxdkIaIddPslJF9Z5De3APBScuqGP2uThXnIpqFrgoxMNC6km7uXNIMLHXA==} peerDependencies: - bare-buffer: '*' + bare-abort-controller: '*' peerDependenciesMeta: - bare-buffer: + bare-abort-controller: optional: true - bare-os@3.6.2: - resolution: {integrity: sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==} - engines: {bare: '>=1.14.0'} - - bare-path@3.0.0: - resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} - - bare-stream@2.7.0: - resolution: {integrity: sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==} - peerDependencies: - bare-buffer: '*' - bare-events: '*' - peerDependenciesMeta: - bare-buffer: - optional: true - bare-events: - optional: true - - bare-url@2.2.2: - resolution: {integrity: sha512-g+ueNGKkrjMazDG3elZO1pNs3HY5+mMmOet1jtKyhOaCnkLzitxf26z7hoAEkDNgdNmnc1KIlt/dw6Po6xZMpA==} - base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - basic-ftp@5.0.5: - resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==} - engines: {node: '>=10.0.0'} + baseline-browser-mapping@2.8.16: + resolution: {integrity: sha512-OMu3BGQ4E7P1ErFsIPpbJh0qvDudM/UuJeHgkAvfWe+0HFJCXh+t/l8L6fVLR55RI/UbKrVLnAXZSVwd9ysWYw==} + hasBin: true binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} @@ -1259,8 +1044,8 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.25.4: - resolution: {integrity: sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg==} + browserslist@4.26.3: + resolution: {integrity: sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -1274,16 +1059,9 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} - call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} @@ -1299,24 +1077,13 @@ packages: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} - caniuse-lite@1.0.30001741: - resolution: {integrity: sha512-QGUGitqsc8ARjLdgAfxETDhRbJ0REsP6O3I96TAth/mVjh2cYzN2u+3AzPP3aVSm2FehEItaJw1xd+IGBXWeSw==} - - chai@5.3.3: - resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} - engines: {node: '>=18'} + caniuse-lite@1.0.30001750: + resolution: {integrity: sha512-cuom0g5sdX6rw00qOoLNSFCJ9/mYIsuSOA+yzpDw8eopiFqcVwQvZHqov0vmEighRxX++cfC0Vg1G+1Iy/mSpQ==} chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - change-case@5.4.4: - resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==} - - check-error@2.1.1: - resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} - engines: {node: '>= 16'} - chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -1329,11 +1096,6 @@ packages: resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} engines: {node: '>=18'} - chromium-bidi@0.6.3: - resolution: {integrity: sha512-qXlsCmpCZJAnoTYI83Iu6EdYQpMYdVkCfq08KDh2pmlVqK5t5IA9mGs4/LwCwp4fqisSOMXZxP3HIh8w8aRn0A==} - peerDependencies: - devtools-protocol: '*' - cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -1365,9 +1127,6 @@ packages: resolution: {integrity: sha512-e2hz5BzbUPcYlIRHo8ieAhYgoajrJr+hWoceg6E345TPsATMUKqDgzt8fSXZJJbxfpiPzkWyphz8yn8At7q3fA==} engines: {node: '>=18'} - colorette@1.4.0: - resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==} - combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} @@ -1408,15 +1167,6 @@ packages: core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - cosmiconfig@9.0.0: - resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} - engines: {node: '>=14'} - peerDependencies: - typescript: '>=4.9.5' - peerDependenciesMeta: - typescript: - optional: true - crc-32@1.2.2: resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} engines: {node: '>=0.8'} @@ -1442,35 +1192,15 @@ packages: engines: {node: '>=4'} hasBin: true - cssstyle@4.6.0: - resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==} - engines: {node: '>=18'} - csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - data-uri-to-buffer@6.0.2: - resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} - engines: {node: '>= 14'} - - data-urls@5.0.0: - resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} - engines: {node: '>=18'} - date-fns@2.30.0: resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} engines: {node: '>=0.11'} - debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -1481,41 +1211,18 @@ packages: decache@4.6.2: resolution: {integrity: sha512-2LPqkLeu8XWHU8qNCS3kcF6sCcb5zIzvWaAHYSvPfwhdd7mHuah29NssMzrTYyHN4F5oFy2ko9OBYxegtU0FEw==} - decimal.js@10.6.0: - resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} - - deep-eql@5.0.2: - resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} - engines: {node: '>=6'} - deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - degenerator@5.0.1: - resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} - engines: {node: '>= 14'} - delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} - depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - - dequal@2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} - destr@2.0.5: resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} - destroy@1.2.0: - resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - - detect-libc@2.1.1: - resolution: {integrity: sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw==} + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} detective-amd@6.0.1: @@ -1564,18 +1271,12 @@ packages: dettle@1.0.5: resolution: {integrity: sha512-ZVyjhAJ7sCe1PNXEGveObOH9AC8QvMga3HJIghHawtG7mE4K5pW9nz/vDGAr/U7a3LWgdOzEE7ac9MURnyfaTA==} - devtools-protocol@0.0.1312386: - resolution: {integrity: sha512-DPnhUXvmvKT2dFA/j7B+riVLUt9Q6RKJlcppojL5CoRywJJKLDYnRlw0gTFKfgDPHP5E04UoB71SxoJlVZy8FA==} - didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} - dom-accessibility-api@0.5.16: - resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} - dot-prop@9.0.0: resolution: {integrity: sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==} engines: {node: '>=18'} @@ -1591,11 +1292,8 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - - electron-to-chromium@1.5.215: - resolution: {integrity: sha512-TIvGp57UpeNetj/wV/xpFNpWGb0b/ROw372lHPx5Aafx02gjTBtWnEEcaSX3W2dLM3OSdGGyHX/cHl01JQsLaQ==} + electron-to-chromium@1.5.234: + resolution: {integrity: sha512-RXfEp2x+VRYn8jbKfQlRImzoJU01kyDvVPBmG39eU2iuRVhuS6vQNocB8J0/8GrIMLnPzgz4eW6WiRnJkTuNWg==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1610,14 +1308,6 @@ packages: enabled@2.0.0: resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==} - encodeurl@1.0.2: - resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} - engines: {node: '>= 0.8'} - - encodeurl@2.0.0: - resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} - engines: {node: '>= 0.8'} - end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} @@ -1625,21 +1315,10 @@ packages: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} - entities@6.0.1: - resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} - engines: {node: '>=0.12'} - - env-paths@2.2.1: - resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} - engines: {node: '>=6'} - env-paths@3.0.0: resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - error-ex@1.3.4: - resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} - es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} @@ -1673,9 +1352,6 @@ packages: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} - escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} @@ -1691,8 +1367,8 @@ packages: peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 - eslint-plugin-react-refresh@0.4.20: - resolution: {integrity: sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==} + eslint-plugin-react-refresh@0.4.23: + resolution: {integrity: sha512-G4j+rv0NmbIR45kni5xJOrYvCtyD3/7LjpVH8MPPcudXDcNu8gv+4ATTDXTtbRR8rTCM5HxECvCSsRmxKnWDsA==} peerDependencies: eslint: '>=8.40' @@ -1708,8 +1384,8 @@ packages: resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.35.0: - resolution: {integrity: sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg==} + eslint@9.37.0: + resolution: {integrity: sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -1742,17 +1418,10 @@ packages: estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} - etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} @@ -1768,10 +1437,6 @@ packages: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} - expect-type@1.2.2: - resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} - engines: {node: '>=12.0.0'} - extract-zip@2.0.1: resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} engines: {node: '>= 10.17.0'} @@ -1817,10 +1482,6 @@ packages: resolution: {integrity: sha512-xdMtCAODmPloU9qtmPcdBV9Kd27NtMse+4ayThxqIHUES5Z2S6bGpap5PpdmNM56ub7y3i1eyr+vJJIIgWGKmA==} engines: {node: '>=18'} - finalhandler@1.3.1: - resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} - engines: {node: '>= 0.8'} - find-up-simple@1.0.1: resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==} engines: {node: '>=18'} @@ -1863,10 +1524,6 @@ packages: fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} - fresh@0.5.2: - resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} - engines: {node: '>= 0.6'} - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1903,10 +1560,6 @@ packages: resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} engines: {node: '>=16'} - get-uri@6.0.5: - resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==} - engines: {node: '>= 14'} - glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1932,8 +1585,8 @@ packages: engines: {node: '>=0.6.0'} hasBin: true - goober@2.1.16: - resolution: {integrity: sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==} + goober@2.1.18: + resolution: {integrity: sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw==} peerDependencies: csstype: ^3.0.10 @@ -1947,10 +1600,6 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - happy-dom@19.0.2: - resolution: {integrity: sha512-831CLbgDyjRbd2lApHZFsBDe56onuFcjsCBPodzWpzedTpeDr8CGZjs7iEIdNW1DVwSFRecfwzLpVyGBPamwGA==} - engines: {node: '>=20.0.0'} - has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -1971,21 +1620,6 @@ packages: resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} engines: {node: ^16.14.0 || >=18.0.0} - html-encoding-sniffer@4.0.0: - resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} - engines: {node: '>=18'} - - html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - - http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} - - http-proxy-agent@7.0.2: - resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} - engines: {node: '>= 14'} - https-proxy-agent@7.0.6: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} @@ -1994,10 +1628,6 @@ packages: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} - iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -2029,13 +1659,6 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - ip-address@10.0.1: - resolution: {integrity: sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==} - engines: {node: '>= 12'} - - is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -2068,9 +1691,6 @@ packages: resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} engines: {node: '>=8'} - is-potential-custom-element-name@1.0.1: - resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} - is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} @@ -2096,22 +1716,6 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} - engines: {node: '>=8'} - - istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} - engines: {node: '>=10'} - - istanbul-lib-source-maps@5.0.6: - resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} - engines: {node: '>=10'} - - istanbul-reports@3.2.0: - resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} - engines: {node: '>=8'} - jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} @@ -2125,10 +1729,6 @@ packages: js-image-generator@1.0.4: resolution: {integrity: sha512-ckb7kyVojGAnArouVR+5lBIuwU1fcrn7E/YYSd0FK7oIngAkMmRvHASLro9Zt5SQdWToaI66NybG+OGxPw/HlQ==} - js-levenshtein@1.1.6: - resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==} - engines: {node: '>=0.10.0'} - js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -2136,15 +1736,6 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true - jsdom@25.0.1: - resolution: {integrity: sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==} - engines: {node: '>=18'} - peerDependencies: - canvas: ^2.11.2 - peerDependenciesMeta: - canvas: - optional: true - jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -2153,15 +1744,9 @@ packages: json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - json-schema-traverse@1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -2226,15 +1811,6 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true - loupe@3.2.1: - resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} - - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - - lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lru-cache@7.18.3: resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} engines: {node: '>=12'} @@ -2248,20 +1824,9 @@ packages: resolution: {integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==} engines: {node: '>=12'} - lz-string@1.5.0: - resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} - hasBin: true - magic-string@0.30.19: resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} - magicast@0.3.5: - resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} - - make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} - engines: {node: '>=10'} - math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -2289,11 +1854,6 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} - mime@1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} - engines: {node: '>=4'} - hasBin: true - mimic-fn@4.0.0: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} @@ -2320,17 +1880,11 @@ packages: resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} engines: {node: '>= 18'} - mitt@3.0.1: - resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} - module-definition@6.0.1: resolution: {integrity: sha512-FeVc50FTfVVQnolk/WQT8MX+2WVcDnTGiq6Wo+/+lJ2ET1bRVi3HG3YlJUfqagNMc/kUlFSoR96AJkxGpKz13g==} engines: {node: '>=18'} hasBin: true - ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -2345,10 +1899,6 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - netmask@2.0.2: - resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} - engines: {node: '>= 0.4.0'} - node-fetch-native@1.6.7: resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} @@ -2365,8 +1915,8 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-releases@2.0.20: - resolution: {integrity: sha512-7gK6zSXEH6neM212JgfYFXe+GmZQM+fia5SsusuBIUgnPheLFBmIPhtFoAQRj8/7wASYQnbDlHPVwY0BefoFgA==} + node-releases@2.0.23: + resolution: {integrity: sha512-cCmFDMSm26S6tQSDpBCg/NR8NENrVPhAJSf+XbxBG4rPFaaonlEoE9wHQmun+cls499TQGSb7ZyPBRlzgKfpeg==} node-source-walk@7.0.1: resolution: {integrity: sha512-3VW/8JpPqPvnJvseXowjZcirPisssnBuDikk6JIZ8jQzF7KJQX52iPFX4RYYxLycYH7IbMRSPUOga/esVjy5Yg==} @@ -2397,9 +1947,6 @@ packages: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - nwsapi@2.2.22: - resolution: {integrity: sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ==} - object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -2411,10 +1958,6 @@ packages: ofetch@1.4.1: resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==} - on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} - once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -2425,12 +1968,6 @@ packages: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} - openapi-typescript@7.9.1: - resolution: {integrity: sha512-9gJtoY04mk6iPMbToPjPxEAtfXZ0dTsMZtsgUI8YZta0btPPig9DJFP4jlerQD/7QOwYgb0tl+zLUpDf7vb7VA==} - hasBin: true - peerDependencies: - typescript: ^5.x - optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -2463,14 +2000,6 @@ packages: resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} engines: {node: '>=14.16'} - pac-proxy-agent@7.2.0: - resolution: {integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==} - engines: {node: '>= 14'} - - pac-resolver@7.0.1: - resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} - engines: {node: '>= 14'} - package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} @@ -2482,21 +2011,10 @@ packages: resolution: {integrity: sha512-RmVuCHWsfu0QPNW+mraxh/xjQVw/lhUCUru8Zni3Ctq3AoMhpDTq0OVdKS6iesd6Kqb7viCV3isAL43dciOSog==} engines: {node: '>=14'} - parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} - parse-json@8.3.0: resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==} engines: {node: '>=18'} - parse5@7.3.0: - resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} - - parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -2520,13 +2038,6 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} - pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - - pathval@2.0.1: - resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} - engines: {node: '>= 14.16'} - pend@1.2.0: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} @@ -2549,32 +2060,34 @@ packages: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} - pluralize@8.0.0: - resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} - engines: {node: '>=4'} - postcss-import@15.1.0: resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} engines: {node: '>=14.0.0'} peerDependencies: postcss: ^8.0.0 - postcss-js@4.0.1: - resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + postcss-js@4.1.0: + resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} engines: {node: ^12 || ^14 || >= 16} peerDependencies: postcss: ^8.4.21 - postcss-load-config@4.0.2: - resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} - engines: {node: '>= 14'} + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} peerDependencies: + jiti: '>=1.21.0' postcss: '>=8.0.9' - ts-node: '>=9.0.0' + tsx: ^4.8.1 + yaml: ^2.4.2 peerDependenciesMeta: + jiti: + optional: true postcss: optional: true - ts-node: + tsx: + optional: true + yaml: optional: true postcss-nested@6.2.0: @@ -2609,10 +2122,6 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - pretty-format@27.5.1: - resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} - engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} - process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} @@ -2620,14 +2129,6 @@ packages: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} - progress@2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} - - proxy-agent@6.5.0: - resolution: {integrity: sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==} - engines: {node: '>= 14'} - proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} @@ -2638,26 +2139,12 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - puppeteer-core@22.15.0: - resolution: {integrity: sha512-cHArnywCiAAVXa3t4GGL2vttNxh7GqXtIYGym99egkNJ3oG//wL9LkvO4WE8W1TJe95t1F1ocu9X4xWaGsOKOA==} - engines: {node: '>=18'} - - puppeteer@22.15.0: - resolution: {integrity: sha512-XjCY1SiSEi1T7iSYuxS82ft85kwDJUS7wj1Z0eGVXKdtr5g4xnVcbjwxhq5xBnpK/E7x1VZZoJDxpjAOasHT4Q==} - engines: {node: '>=18'} - deprecated: < 24.10.2 is no longer supported - hasBin: true - queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} quote-unquote@1.0.0: resolution: {integrity: sha512-twwRO/ilhlG/FIgYeKGFqyHhoEhqgnKVkcmqMKi2r524gz3ZbDTcyFt38E9xjJI2vT+KbRNHVbnJ/e0I25Azwg==} - range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - react-dom@18.3.1: resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} peerDependencies: @@ -2670,11 +2157,8 @@ packages: react: '>=16' react-dom: '>=16' - react-is@17.0.2: - resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} - - react-refresh@0.17.0: - resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} + react-refresh@0.14.2: + resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} react-router-dom@6.30.1: @@ -2736,17 +2220,10 @@ packages: remove-trailing-separator@1.1.0: resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} - requestidlecallback@0.3.0: - resolution: {integrity: sha512-TWHFkT7S9p7IxLC5A1hYmAYQx2Eb9w1skrXmQ+dS1URyvR8tenMLl4lHbqEOUnpEYxNKpkVMXUgknVpBZWXXfQ==} - require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} - require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} - require-package-name@2.0.1: resolution: {integrity: sha512-uuoJ1hU/k6M0779t3VMVIYpb2VMJk05cehCaABFhXaibcbvfgR8wKiozLjVFSzJPmQMRqIcO0HMyTFqfV09V6Q==} @@ -2771,17 +2248,11 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rollup@4.50.1: - resolution: {integrity: sha512-78E9voJHwnXQMiQdiqswVLZwJIzdBKJ1GdI5Zx6XwoFKUIk09/sSrr+05QFzvYb8q6Y9pPV45zzDuYa3907TZA==} + rollup@4.52.4: + resolution: {integrity: sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - rrweb-cssom@0.7.1: - resolution: {integrity: sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==} - - rrweb-cssom@0.8.0: - resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} - run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -2795,13 +2266,6 @@ packages: resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} engines: {node: '>=10'} - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - saxes@6.0.0: - resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} - engines: {node: '>=v12.22.7'} - scheduler@0.23.2: resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} @@ -2809,22 +2273,11 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} hasBin: true - send@0.19.0: - resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} - engines: {node: '>= 0.8.0'} - - serve-static@1.16.2: - resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} - engines: {node: '>= 0.8.0'} - - setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2833,25 +2286,10 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - smart-buffer@4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - - socks-proxy-agent@8.0.5: - resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} - engines: {node: '>= 14'} - - socks@2.8.7: - resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==} - engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} - source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -2878,16 +2316,6 @@ packages: stack-trace@0.0.10: resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - - statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} - - std-env@3.9.0: - resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} - streamx@2.23.0: resolution: {integrity: sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==} @@ -2926,10 +2354,6 @@ packages: engines: {node: '>=16 || 14 >=14.17'} hasBin: true - supports-color@10.2.2: - resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} - engines: {node: '>=18'} - supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -2938,17 +2362,11 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - symbol-tree@3.2.4: - resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - - tailwindcss@3.4.17: - resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} + tailwindcss@3.4.18: + resolution: {integrity: sha512-6A2rnmW5xZMdw11LYjhcI5846rt9pbLSabY5XPxo+XWdxwZaFEn47Go4NzFiHu9sNNmr/kXivP1vStfvMaK1GQ==} engines: {node: '>=14.0.0'} hasBin: true - tar-fs@3.1.1: - resolution: {integrity: sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==} - tar-stream@3.1.7: resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} @@ -2956,10 +2374,6 @@ packages: resolution: {integrity: sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g==} engines: {node: '>=18'} - test-exclude@7.0.1: - resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} - engines: {node: '>=18'} - text-decoder@1.2.3: resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} @@ -2973,34 +2387,6 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - - tinyexec@0.3.2: - resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - - tinypool@1.1.1: - resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} - engines: {node: ^18.0.0 || >=20.0.0} - - tinyrainbow@1.2.0: - resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} - engines: {node: '>=14.0.0'} - - tinyspy@3.0.2: - resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} - engines: {node: '>=14.0.0'} - - tldts-core@6.1.86: - resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} - - tldts@6.1.86: - resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} - hasBin: true - tmp-promise@3.0.3: resolution: {integrity: sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==} @@ -3012,24 +2398,12 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - toml@3.0.0: resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} - tough-cookie@5.1.2: - resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} - engines: {node: '>=16'} - tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - tr46@5.1.1: - resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} - engines: {node: '>=18'} - triple-beam@1.4.1: resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} engines: {node: '>= 14.0.0'} @@ -3054,29 +2428,23 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} - typescript-eslint@8.43.0: - resolution: {integrity: sha512-FyRGJKUGvcFekRRcBKFBlAhnp4Ng8rhe8tuvvkR9OiU0gfd4vyvTRQHEckO6VDlH57jbeUQem2IpqPq9kLJH+w==} + typescript-eslint@8.46.0: + resolution: {integrity: sha512-6+ZrB6y2bT2DX3K+Qd9vn7OFOJR+xSLDj+Aw/N3zBwUt27uTw2sw2TE2+UcY1RiyBZkaGbTkVg9SSdPNUG6aUw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - typescript@5.9.2: - resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} hasBin: true ufo@1.6.1: resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} - unbzip2-stream@1.4.3: - resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} - - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - - undici-types@7.13.0: - resolution: {integrity: sha512-Ov2Rr9Sx+fRgagJ5AX0qvItZG/JKKoBRAVITs1zk7IqZGTJUwgUr7qoYBpWwakpWilTZFM98rG/AFRocu10iIQ==} + undici-types@7.14.0: + resolution: {integrity: sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA==} unicorn-magic@0.1.0: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} @@ -3086,24 +2454,17 @@ packages: resolution: {integrity: sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==} engines: {node: '>=0.10.0'} - unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - update-browserslist-db@1.1.3: resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' - uri-js-replace@1.0.1: - resolution: {integrity: sha512-W+C9NWNLFOoBI2QWDp4UT9pv65r2w5Cx+3sTYFvtMdDBxkKt1syCqsUdSFAChbEe1uK5TfS04wt/nGwmaeIQ0g==} - uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - urlpattern-polyfill@10.0.0: - resolution: {integrity: sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==} + urlpattern-polyfill@10.1.0: + resolution: {integrity: sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==} urlpattern-polyfill@8.0.2: resolution: {integrity: sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==} @@ -3118,11 +2479,6 @@ packages: validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - vite-node@2.1.9: - resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - vite@5.4.10: resolution: {integrity: sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==} engines: {node: ^18.0.0 || >=20.0.0} @@ -3154,58 +2510,9 @@ packages: terser: optional: true - vitest@2.1.9: - resolution: {integrity: sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 2.1.9 - '@vitest/ui': 2.1.9 - happy-dom: '*' - jsdom: '*' - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@types/node': - optional: true - '@vitest/browser': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - - w3c-xmlserializer@5.0.0: - resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} - engines: {node: '>=18'} - webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - webidl-conversions@7.0.0: - resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} - engines: {node: '>=12'} - - whatwg-encoding@3.1.1: - resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} - engines: {node: '>=18'} - - whatwg-mimetype@3.0.0: - resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} - engines: {node: '>=12'} - - whatwg-mimetype@4.0.0: - resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} - engines: {node: '>=18'} - - whatwg-url@14.2.0: - resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} - engines: {node: '>=18'} - whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} @@ -3214,11 +2521,6 @@ packages: engines: {node: '>= 8'} hasBin: true - why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} - hasBin: true - winston-transport@4.9.0: resolution: {integrity: sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==} engines: {node: '>= 12.0.0'} @@ -3246,44 +2548,14 @@ packages: resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - ws@8.18.3: - resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - xml-name-validator@5.0.0: - resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} - engines: {node: '>=18'} - - xmlchars@2.2.0: - resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} - y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} - yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yallist@5.0.0: resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} engines: {node: '>=18'} - yaml-ast-parser@0.0.43: - resolution: {integrity: sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==} - - yaml@2.8.1: - resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} - engines: {node: '>= 14.6'} - hasBin: true - yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} @@ -3307,31 +2579,13 @@ packages: resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} engines: {node: '>= 14'} - zod@3.23.8: - resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} snapshots: '@alloc/quick-lru@5.2.0': {} - '@ampproject/remapping@2.3.0': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 - - '@asamuzakjp/css-color@3.2.0': - dependencies: - '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) - '@csstools/css-tokenizer': 3.0.4 - lru-cache: 10.4.3 - - '@axe-core/react@4.10.2': - dependencies: - axe-core: 4.10.3 - requestidlecallback: 0.3.0 - '@babel/code-frame@7.27.1': dependencies: '@babel/helper-validator-identifier': 7.27.1 @@ -3344,7 +2598,7 @@ snapshots: dependencies: '@babel/code-frame': 7.27.1 '@babel/generator': 7.28.3 - '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-compilation-targets': 7.25.9 '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) '@babel/helpers': 7.28.4 '@babel/parser': 7.28.4 @@ -3353,7 +2607,7 @@ snapshots: '@babel/types': 7.28.4 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.1(supports-color@10.2.2) + debug: 4.4.3 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -3365,15 +2619,15 @@ snapshots: '@babel/parser': 7.28.4 '@babel/types': 7.28.4 '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 - '@babel/helper-compilation-targets@7.27.2': + '@babel/helper-compilation-targets@7.25.9': dependencies: '@babel/compat-data': 7.28.4 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.25.4 - lru-cache: 5.1.1 + browserslist: 4.26.3 + lru-cache: 7.18.3 semver: 6.3.1 '@babel/helper-globals@7.28.0': {} @@ -3437,7 +2691,7 @@ snapshots: '@babel/parser': 7.28.4 '@babel/template': 7.27.2 '@babel/types': 7.28.4 - debug: 4.4.1(supports-color@10.2.2) + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -3446,30 +2700,8 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@bcoe/v8-coverage@0.2.3': {} - '@colors/colors@1.6.0': {} - '@csstools/color-helpers@5.1.0': {} - - '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': - dependencies: - '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) - '@csstools/css-tokenizer': 3.0.4 - - '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': - dependencies: - '@csstools/color-helpers': 5.1.0 - '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) - '@csstools/css-tokenizer': 3.0.4 - - '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': - dependencies: - '@csstools/css-tokenizer': 3.0.4 - - '@csstools/css-tokenizer@3.0.4': {} - '@dabh/diagnostics@2.0.8': dependencies: '@so-ric/colorspace': 1.1.6 @@ -3633,9 +2865,9 @@ snapshots: '@esbuild/win32-x64@0.25.10': optional: true - '@eslint-community/eslint-utils@4.9.0(eslint@9.35.0(jiti@1.21.7))': + '@eslint-community/eslint-utils@4.9.0(eslint@9.37.0(jiti@1.21.7))': dependencies: - eslint: 9.35.0(jiti@1.21.7) + eslint: 9.37.0(jiti@1.21.7) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} @@ -3643,21 +2875,23 @@ snapshots: '@eslint/config-array@0.21.0': dependencies: '@eslint/object-schema': 2.1.6 - debug: 4.4.1(supports-color@10.2.2) + debug: 4.4.3 minimatch: 3.1.2 transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.3.1': {} + '@eslint/config-helpers@0.4.0': + dependencies: + '@eslint/core': 0.16.0 - '@eslint/core@0.15.2': + '@eslint/core@0.16.0': dependencies: '@types/json-schema': 7.0.15 '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 - debug: 4.4.1(supports-color@10.2.2) + debug: 4.4.3 espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 @@ -3668,13 +2902,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.35.0': {} + '@eslint/js@9.37.0': {} '@eslint/object-schema@2.1.6': {} - '@eslint/plugin-kit@0.3.5': + '@eslint/plugin-kit@0.4.0': dependencies: - '@eslint/core': 0.15.2 + '@eslint/core': 0.16.0 levn: 0.4.1 '@fastify/busboy@3.2.0': {} @@ -3703,41 +2937,40 @@ snapshots: dependencies: minipass: 7.1.2 - '@istanbuljs/schema@0.1.3': {} - '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/remapping@2.3.5': dependencies: '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.30': + '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@lumi.new/sdk@0.1.7': + '@lumi.new/sdk@0.1.11': dependencies: crypto-js: 4.2.0 + object-hash: 3.0.0 ofetch: 1.4.1 uuid: 11.1.0 '@mapbox/node-pre-gyp@2.0.0': dependencies: consola: 3.4.2 - detect-libc: 2.1.1 - https-proxy-agent: 7.0.6(supports-color@10.2.2) + detect-libc: 2.1.2 + https-proxy-agent: 7.0.6 node-fetch: 2.7.0 nopt: 8.1.0 - semver: 7.7.2 + semver: 7.7.3 tar: 7.5.1 transitivePeerDependencies: - encoding @@ -3745,14 +2978,14 @@ snapshots: '@netlify/binary-info@1.0.0': {} - '@netlify/blobs@10.0.11': + '@netlify/blobs@10.1.0': dependencies: - '@netlify/dev-utils': 4.2.0 - '@netlify/runtime-utils': 2.1.0 + '@netlify/dev-utils': 4.3.0 + '@netlify/runtime-utils': 2.2.0 - '@netlify/dev-utils@4.2.0': + '@netlify/dev-utils@4.3.0': dependencies: - '@whatwg-node/server': 0.10.12 + '@whatwg-node/server': 0.10.13 ansis: 4.2.0 chokidar: 4.0.3 decache: 4.6.2 @@ -3763,17 +2996,17 @@ snapshots: image-size: 2.0.2 js-image-generator: 1.0.4 parse-gitignore: 2.0.0 - semver: 7.7.2 + semver: 7.7.3 tmp-promise: 3.0.3 uuid: 11.1.0 write-file-atomic: 5.0.1 - '@netlify/functions@4.2.7(rollup@4.50.1)': + '@netlify/functions@4.3.0(rollup@4.52.4)': dependencies: - '@netlify/blobs': 10.0.11 - '@netlify/dev-utils': 4.2.0 - '@netlify/types': 2.0.3 - '@netlify/zip-it-and-ship-it': 14.1.8(rollup@4.50.1) + '@netlify/blobs': 10.1.0 + '@netlify/dev-utils': 4.3.0 + '@netlify/types': 2.1.0 + '@netlify/zip-it-and-ship-it': 14.1.8(rollup@4.52.4) cron-parser: 4.9.0 decache: 4.6.2 extract-zip: 2.0.1 @@ -3783,24 +3016,25 @@ snapshots: read-package-up: 11.0.0 source-map-support: 0.5.21 transitivePeerDependencies: + - bare-abort-controller - encoding - react-native-b4a - rollup - supports-color - '@netlify/runtime-utils@2.1.0': {} + '@netlify/runtime-utils@2.2.0': {} - '@netlify/serverless-functions-api@2.5.0': {} + '@netlify/serverless-functions-api@2.6.0': {} - '@netlify/types@2.0.3': {} + '@netlify/types@2.1.0': {} - '@netlify/zip-it-and-ship-it@14.1.8(rollup@4.50.1)': + '@netlify/zip-it-and-ship-it@14.1.8(rollup@4.52.4)': dependencies: '@babel/parser': 7.28.4 '@babel/types': 7.28.4 '@netlify/binary-info': 1.0.0 - '@netlify/serverless-functions-api': 2.5.0 - '@vercel/nft': 0.29.4(rollup@4.50.1) + '@netlify/serverless-functions-api': 2.6.0 + '@vercel/nft': 0.29.4(rollup@4.52.4) archiver: 7.0.1 common-path-prefix: 3.0.0 copy-file: 11.1.0 @@ -3821,14 +3055,15 @@ snapshots: precinct: 12.2.0 require-package-name: 2.0.1 resolve: 2.0.0-next.5 - semver: 7.7.2 + semver: 7.7.3 tmp-promise: 3.0.3 toml: 3.0.0 unixify: 1.0.0 urlpattern-polyfill: 8.0.2 yargs: 17.7.2 - zod: 3.23.8 + zod: 3.25.76 transitivePeerDependencies: + - bare-abort-controller - encoding - react-native-b4a - rollup @@ -3849,117 +3084,80 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@puppeteer/browsers@2.3.0': - dependencies: - debug: 4.4.1(supports-color@10.2.2) - extract-zip: 2.0.1 - progress: 2.0.3 - proxy-agent: 6.5.0 - semver: 7.7.2 - tar-fs: 3.1.1 - unbzip2-stream: 1.4.3 - yargs: 17.7.2 - transitivePeerDependencies: - - bare-buffer - - react-native-b4a - - supports-color - - '@redocly/ajv@8.11.3': - dependencies: - fast-deep-equal: 3.1.3 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - uri-js-replace: 1.0.1 - - '@redocly/config@0.22.2': {} - - '@redocly/openapi-core@1.34.5(supports-color@10.2.2)': - dependencies: - '@redocly/ajv': 8.11.3 - '@redocly/config': 0.22.2 - colorette: 1.4.0 - https-proxy-agent: 7.0.6(supports-color@10.2.2) - js-levenshtein: 1.1.6 - js-yaml: 4.1.0 - minimatch: 5.1.6 - pluralize: 8.0.0 - yaml-ast-parser: 0.0.43 - transitivePeerDependencies: - - supports-color - '@remix-run/router@1.23.0': {} - '@rolldown/pluginutils@1.0.0-beta.27': {} - - '@rollup/pluginutils@5.3.0(rollup@4.50.1)': + '@rollup/pluginutils@5.3.0(rollup@4.52.4)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 picomatch: 4.0.3 optionalDependencies: - rollup: 4.50.1 + rollup: 4.52.4 - '@rollup/rollup-android-arm-eabi@4.50.1': + '@rollup/rollup-android-arm-eabi@4.52.4': optional: true - '@rollup/rollup-android-arm64@4.50.1': + '@rollup/rollup-android-arm64@4.52.4': optional: true - '@rollup/rollup-darwin-arm64@4.50.1': + '@rollup/rollup-darwin-arm64@4.52.4': optional: true - '@rollup/rollup-darwin-x64@4.50.1': + '@rollup/rollup-darwin-x64@4.52.4': optional: true - '@rollup/rollup-freebsd-arm64@4.50.1': + '@rollup/rollup-freebsd-arm64@4.52.4': optional: true - '@rollup/rollup-freebsd-x64@4.50.1': + '@rollup/rollup-freebsd-x64@4.52.4': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.50.1': + '@rollup/rollup-linux-arm-gnueabihf@4.52.4': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.50.1': + '@rollup/rollup-linux-arm-musleabihf@4.52.4': optional: true - '@rollup/rollup-linux-arm64-gnu@4.50.1': + '@rollup/rollup-linux-arm64-gnu@4.52.4': optional: true - '@rollup/rollup-linux-arm64-musl@4.50.1': + '@rollup/rollup-linux-arm64-musl@4.52.4': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.50.1': + '@rollup/rollup-linux-loong64-gnu@4.52.4': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.50.1': + '@rollup/rollup-linux-ppc64-gnu@4.52.4': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.50.1': + '@rollup/rollup-linux-riscv64-gnu@4.52.4': optional: true - '@rollup/rollup-linux-riscv64-musl@4.50.1': + '@rollup/rollup-linux-riscv64-musl@4.52.4': optional: true - '@rollup/rollup-linux-s390x-gnu@4.50.1': + '@rollup/rollup-linux-s390x-gnu@4.52.4': optional: true - '@rollup/rollup-linux-x64-gnu@4.50.1': + '@rollup/rollup-linux-x64-gnu@4.52.4': optional: true - '@rollup/rollup-linux-x64-musl@4.50.1': + '@rollup/rollup-linux-x64-musl@4.52.4': optional: true - '@rollup/rollup-openharmony-arm64@4.50.1': + '@rollup/rollup-openharmony-arm64@4.52.4': optional: true - '@rollup/rollup-win32-arm64-msvc@4.50.1': + '@rollup/rollup-win32-arm64-msvc@4.52.4': optional: true - '@rollup/rollup-win32-ia32-msvc@4.50.1': + '@rollup/rollup-win32-ia32-msvc@4.52.4': optional: true - '@rollup/rollup-win32-x64-msvc@4.50.1': + '@rollup/rollup-win32-x64-gnu@4.52.4': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.52.4': optional: true '@so-ric/colorspace@1.1.6': @@ -3967,35 +3165,6 @@ snapshots: color: 5.0.2 text-hex: 1.0.0 - '@testing-library/dom@10.4.1': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/runtime': 7.28.4 - '@types/aria-query': 5.0.4 - aria-query: 5.3.0 - dom-accessibility-api: 0.5.16 - lz-string: 1.5.0 - picocolors: 1.1.1 - pretty-format: 27.5.1 - - '@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@babel/runtime': 7.28.4 - '@testing-library/dom': 10.4.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@types/react': 18.3.24 - '@types/react-dom': 18.3.7(@types/react@18.3.24) - - '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1)': - dependencies: - '@testing-library/dom': 10.4.1 - - '@tootallnate/quickjs-emscripten@0.23.0': {} - - '@types/aria-query@5.0.4': {} - '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.28.4 @@ -4021,133 +3190,127 @@ snapshots: '@types/json-schema@7.0.15': {} - '@types/node@20.19.19': + '@types/node@24.7.2': dependencies: - undici-types: 6.21.0 - - '@types/node@24.6.2': - dependencies: - undici-types: 7.13.0 + undici-types: 7.14.0 '@types/normalize-package-data@2.4.4': {} '@types/prop-types@15.7.15': {} - '@types/react-dom@18.3.7(@types/react@18.3.24)': + '@types/react-dom@18.3.7(@types/react@18.3.26)': dependencies: - '@types/react': 18.3.24 + '@types/react': 18.3.26 - '@types/react@18.3.24': + '@types/react@18.3.26': dependencies: '@types/prop-types': 15.7.15 csstype: 3.1.3 '@types/triple-beam@1.3.5': {} - '@types/whatwg-mimetype@3.0.2': {} - '@types/yauzl@2.10.3': dependencies: - '@types/node': 24.6.2 + '@types/node': 24.7.2 optional: true - '@typescript-eslint/eslint-plugin@8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.35.0(jiti@1.21.7))(typescript@5.9.2)': + '@typescript-eslint/eslint-plugin@8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.37.0(jiti@1.21.7))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.43.0(eslint@9.35.0(jiti@1.21.7))(typescript@5.9.2) - '@typescript-eslint/scope-manager': 8.43.0 - '@typescript-eslint/type-utils': 8.43.0(eslint@9.35.0(jiti@1.21.7))(typescript@5.9.2) - '@typescript-eslint/utils': 8.43.0(eslint@9.35.0(jiti@1.21.7))(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.43.0 - eslint: 9.35.0(jiti@1.21.7) + '@typescript-eslint/parser': 8.46.0(eslint@9.37.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.46.0 + '@typescript-eslint/type-utils': 8.46.0(eslint@9.37.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.46.0 + eslint: 9.37.0(jiti@1.21.7) graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.9.2) - typescript: 5.9.2 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@1.21.7))(typescript@5.9.2)': + '@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@1.21.7))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.43.0 - '@typescript-eslint/types': 8.43.0 - '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.43.0 - debug: 4.4.1(supports-color@10.2.2) - eslint: 9.35.0(jiti@1.21.7) - typescript: 5.9.2 + '@typescript-eslint/scope-manager': 8.46.0 + '@typescript-eslint/types': 8.46.0 + '@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.46.0 + debug: 4.4.3 + eslint: 9.37.0(jiti@1.21.7) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.43.0(typescript@5.9.2)': + '@typescript-eslint/project-service@8.46.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.9.2) - '@typescript-eslint/types': 8.43.0 - debug: 4.4.1(supports-color@10.2.2) - typescript: 5.9.2 + '@typescript-eslint/tsconfig-utils': 8.46.0(typescript@5.9.3) + '@typescript-eslint/types': 8.46.0 + debug: 4.4.3 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.43.0': + '@typescript-eslint/scope-manager@8.46.0': dependencies: - '@typescript-eslint/types': 8.43.0 - '@typescript-eslint/visitor-keys': 8.43.0 + '@typescript-eslint/types': 8.46.0 + '@typescript-eslint/visitor-keys': 8.46.0 - '@typescript-eslint/tsconfig-utils@8.43.0(typescript@5.9.2)': + '@typescript-eslint/tsconfig-utils@8.46.0(typescript@5.9.3)': dependencies: - typescript: 5.9.2 + typescript: 5.9.3 - '@typescript-eslint/type-utils@8.43.0(eslint@9.35.0(jiti@1.21.7))(typescript@5.9.2)': + '@typescript-eslint/type-utils@8.46.0(eslint@9.37.0(jiti@1.21.7))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.43.0 - '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2) - '@typescript-eslint/utils': 8.43.0(eslint@9.35.0(jiti@1.21.7))(typescript@5.9.2) - debug: 4.4.1(supports-color@10.2.2) - eslint: 9.35.0(jiti@1.21.7) - ts-api-utils: 2.1.0(typescript@5.9.2) - typescript: 5.9.2 + '@typescript-eslint/types': 8.46.0 + '@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@1.21.7))(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.37.0(jiti@1.21.7) + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.43.0': {} + '@typescript-eslint/types@8.46.0': {} - '@typescript-eslint/typescript-estree@8.43.0(typescript@5.9.2)': + '@typescript-eslint/typescript-estree@8.46.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.43.0(typescript@5.9.2) - '@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.9.2) - '@typescript-eslint/types': 8.43.0 - '@typescript-eslint/visitor-keys': 8.43.0 - debug: 4.4.1(supports-color@10.2.2) + '@typescript-eslint/project-service': 8.46.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.46.0(typescript@5.9.3) + '@typescript-eslint/types': 8.46.0 + '@typescript-eslint/visitor-keys': 8.46.0 + debug: 4.4.3 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.2 - ts-api-utils: 2.1.0(typescript@5.9.2) - typescript: 5.9.2 + semver: 7.7.3 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.43.0(eslint@9.35.0(jiti@1.21.7))(typescript@5.9.2)': + '@typescript-eslint/utils@8.46.0(eslint@9.37.0(jiti@1.21.7))(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@1.21.7)) - '@typescript-eslint/scope-manager': 8.43.0 - '@typescript-eslint/types': 8.43.0 - '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2) - eslint: 9.35.0(jiti@1.21.7) - typescript: 5.9.2 + '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(jiti@1.21.7)) + '@typescript-eslint/scope-manager': 8.46.0 + '@typescript-eslint/types': 8.46.0 + '@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3) + eslint: 9.37.0(jiti@1.21.7) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.43.0': + '@typescript-eslint/visitor-keys@8.46.0': dependencies: - '@typescript-eslint/types': 8.43.0 + '@typescript-eslint/types': 8.46.0 eslint-visitor-keys: 4.2.1 - '@vercel/nft@0.29.4(rollup@4.50.1)': + '@vercel/nft@0.29.4(rollup@4.52.4)': dependencies: '@mapbox/node-pre-gyp': 2.0.0 - '@rollup/pluginutils': 5.3.0(rollup@4.50.1) + '@rollup/pluginutils': 5.3.0(rollup@4.52.4) acorn: 8.15.0 acorn-import-attributes: 1.9.5(acorn@8.15.0) async-sema: 3.1.1 @@ -4163,76 +3326,17 @@ snapshots: - rollup - supports-color - '@vitejs/plugin-react@4.7.0(vite@5.4.10(@types/node@24.6.2))': + '@vitejs/plugin-react@4.3.2(vite@5.4.10(@types/node@24.7.2))': dependencies: '@babel/core': 7.28.4 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.4) '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.4) - '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 - react-refresh: 0.17.0 - vite: 5.4.10(@types/node@24.6.2) + react-refresh: 0.14.2 + vite: 5.4.10(@types/node@24.7.2) transitivePeerDependencies: - supports-color - '@vitest/coverage-v8@2.1.9(vitest@2.1.9(@types/node@24.6.2)(happy-dom@19.0.2)(jsdom@25.0.1))': - dependencies: - '@ampproject/remapping': 2.3.0 - '@bcoe/v8-coverage': 0.2.3 - debug: 4.4.1(supports-color@10.2.2) - istanbul-lib-coverage: 3.2.2 - istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 5.0.6 - istanbul-reports: 3.2.0 - magic-string: 0.30.19 - magicast: 0.3.5 - std-env: 3.9.0 - test-exclude: 7.0.1 - tinyrainbow: 1.2.0 - vitest: 2.1.9(@types/node@24.6.2)(happy-dom@19.0.2)(jsdom@25.0.1) - transitivePeerDependencies: - - supports-color - - '@vitest/expect@2.1.9': - dependencies: - '@vitest/spy': 2.1.9 - '@vitest/utils': 2.1.9 - chai: 5.3.3 - tinyrainbow: 1.2.0 - - '@vitest/mocker@2.1.9(vite@5.4.10(@types/node@24.6.2))': - dependencies: - '@vitest/spy': 2.1.9 - estree-walker: 3.0.3 - magic-string: 0.30.19 - optionalDependencies: - vite: 5.4.10(@types/node@24.6.2) - - '@vitest/pretty-format@2.1.9': - dependencies: - tinyrainbow: 1.2.0 - - '@vitest/runner@2.1.9': - dependencies: - '@vitest/utils': 2.1.9 - pathe: 1.1.2 - - '@vitest/snapshot@2.1.9': - dependencies: - '@vitest/pretty-format': 2.1.9 - magic-string: 0.30.19 - pathe: 1.1.2 - - '@vitest/spy@2.1.9': - dependencies: - tinyspy: 3.0.2 - - '@vitest/utils@2.1.9': - dependencies: - '@vitest/pretty-format': 2.1.9 - loupe: 3.2.1 - tinyrainbow: 1.2.0 - '@vue/compiler-core@3.5.22': dependencies: '@babel/parser': 7.28.4 @@ -4272,10 +3376,10 @@ snapshots: '@whatwg-node/fetch@0.10.11': dependencies: - '@whatwg-node/node-fetch': 0.8.0 - urlpattern-polyfill: 10.0.0 + '@whatwg-node/node-fetch': 0.8.1 + urlpattern-polyfill: 10.1.0 - '@whatwg-node/node-fetch@0.8.0': + '@whatwg-node/node-fetch@0.8.1': dependencies: '@fastify/busboy': 3.2.0 '@whatwg-node/disposablestack': 0.0.6 @@ -4286,7 +3390,7 @@ snapshots: dependencies: tslib: 2.8.1 - '@whatwg-node/server@0.10.12': + '@whatwg-node/server@0.10.13': dependencies: '@envelop/instrumentation': 1.0.0 '@whatwg-node/disposablestack': 0.0.6 @@ -4319,8 +3423,6 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 - ansi-colors@4.1.3: {} - ansi-regex@5.0.1: {} ansi-regex@6.2.2: {} @@ -4329,8 +3431,6 @@ snapshots: dependencies: color-convert: 2.0.1 - ansi-styles@5.2.0: {} - ansi-styles@6.2.3: {} ansis@4.2.0: {} @@ -4362,24 +3462,15 @@ snapshots: tar-stream: 3.1.7 zip-stream: 6.0.1 transitivePeerDependencies: + - bare-abort-controller - react-native-b4a arg@5.0.2: {} argparse@2.0.1: {} - aria-query@5.3.0: - dependencies: - dequal: 2.0.3 - - assertion-error@2.0.1: {} - ast-module-types@6.0.1: {} - ast-types@0.13.4: - dependencies: - tslib: 2.8.1 - async-sema@3.1.1: {} async@3.2.6: {} @@ -4388,16 +3479,14 @@ snapshots: autoprefixer@10.4.21(postcss@8.5.6): dependencies: - browserslist: 4.25.4 - caniuse-lite: 1.0.30001741 + browserslist: 4.26.3 + caniuse-lite: 1.0.30001750 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 postcss: 8.5.6 postcss-value-parser: 4.2.0 - axe-core@4.10.3: {} - axios@1.12.2: dependencies: follow-redirects: 1.15.11 @@ -4406,48 +3495,15 @@ snapshots: transitivePeerDependencies: - debug - b4a@1.7.2: {} + b4a@1.7.3: {} balanced-match@1.0.2: {} - bare-events@2.7.0: {} - - bare-fs@4.4.4: - dependencies: - bare-events: 2.7.0 - bare-path: 3.0.0 - bare-stream: 2.7.0(bare-events@2.7.0) - bare-url: 2.2.2 - fast-fifo: 1.3.2 - transitivePeerDependencies: - - react-native-b4a - optional: true - - bare-os@3.6.2: - optional: true - - bare-path@3.0.0: - dependencies: - bare-os: 3.6.2 - optional: true - - bare-stream@2.7.0(bare-events@2.7.0): - dependencies: - streamx: 2.23.0 - optionalDependencies: - bare-events: 2.7.0 - transitivePeerDependencies: - - react-native-b4a - optional: true - - bare-url@2.2.2: - dependencies: - bare-path: 3.0.0 - optional: true + bare-events@2.8.0: {} base64-js@1.5.1: {} - basic-ftp@5.0.5: {} + baseline-browser-mapping@2.8.16: {} binary-extensions@2.3.0: {} @@ -4468,12 +3524,13 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.25.4: + browserslist@4.26.3: dependencies: - caniuse-lite: 1.0.30001741 - electron-to-chromium: 1.5.215 - node-releases: 2.0.20 - update-browserslist-db: 1.1.3(browserslist@4.25.4) + baseline-browser-mapping: 2.8.16 + caniuse-lite: 1.0.30001750 + electron-to-chromium: 1.5.234 + node-releases: 2.0.23 + update-browserslist-db: 1.1.3(browserslist@4.26.3) buffer-crc32@0.2.13: {} @@ -4481,18 +3538,11 @@ snapshots: buffer-from@1.1.2: {} - buffer@5.7.1: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - buffer@6.0.3: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 - cac@6.7.14: {} - call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 @@ -4504,25 +3554,13 @@ snapshots: camelcase-css@2.0.1: {} - caniuse-lite@1.0.30001741: {} - - chai@5.3.3: - dependencies: - assertion-error: 2.0.1 - check-error: 2.1.1 - deep-eql: 5.0.2 - loupe: 3.2.1 - pathval: 2.0.1 + caniuse-lite@1.0.30001750: {} chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 - change-case@5.4.4: {} - - check-error@2.1.1: {} - chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -4541,13 +3579,6 @@ snapshots: chownr@3.0.0: {} - chromium-bidi@0.6.3(devtools-protocol@0.0.1312386): - dependencies: - devtools-protocol: 0.0.1312386 - mitt: 3.0.1 - urlpattern-polyfill: 10.0.0 - zod: 3.23.8 - cliui@8.0.1: dependencies: string-width: 4.2.3 @@ -4577,8 +3608,6 @@ snapshots: color-convert: 3.1.2 color-string: 2.1.2 - colorette@1.4.0: {} - combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 @@ -4612,15 +3641,6 @@ snapshots: core-util-is@1.0.3: {} - cosmiconfig@9.0.0(typescript@5.9.2): - dependencies: - env-paths: 2.2.1 - import-fresh: 3.3.1 - js-yaml: 4.1.0 - parse-json: 5.2.0 - optionalDependencies: - typescript: 5.9.2 - crc-32@1.2.2: {} crc32-stream@6.0.0: @@ -4642,61 +3662,27 @@ snapshots: cssesc@3.0.0: {} - cssstyle@4.6.0: - dependencies: - '@asamuzakjp/css-color': 3.2.0 - rrweb-cssom: 0.8.0 - csstype@3.1.3: {} - data-uri-to-buffer@6.0.2: {} - - data-urls@5.0.0: - dependencies: - whatwg-mimetype: 4.0.0 - whatwg-url: 14.2.0 - date-fns@2.30.0: dependencies: '@babel/runtime': 7.28.4 - debug@2.6.9: - dependencies: - ms: 2.0.0 - - debug@4.4.1(supports-color@10.2.2): + debug@4.4.3: dependencies: ms: 2.1.3 - optionalDependencies: - supports-color: 10.2.2 decache@4.6.2: dependencies: callsite: 1.0.0 - decimal.js@10.6.0: {} - - deep-eql@5.0.2: {} - deep-is@0.1.4: {} - degenerator@5.0.1: - dependencies: - ast-types: 0.13.4 - escodegen: 2.1.0 - esprima: 4.0.1 - delayed-stream@1.0.0: {} - depd@2.0.0: {} - - dequal@2.0.3: {} - destr@2.0.5: {} - destroy@1.2.0: {} - - detect-libc@2.1.1: {} + detect-libc@2.1.2: {} detective-amd@6.0.1: dependencies: @@ -4732,16 +3718,16 @@ snapshots: detective-stylus@5.0.1: {} - detective-typescript@14.0.0(typescript@5.9.2): + detective-typescript@14.0.0(typescript@5.9.3): dependencies: - '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2) + '@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3) ast-module-types: 6.0.1 node-source-walk: 7.0.1 - typescript: 5.9.2 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - detective-vue2@2.2.0(typescript@5.9.2): + detective-vue2@2.2.0(typescript@5.9.3): dependencies: '@dependents/detective-less': 5.0.1 '@vue/compiler-sfc': 3.5.22 @@ -4749,21 +3735,17 @@ snapshots: detective-sass: 6.0.1 detective-scss: 5.0.1 detective-stylus: 5.0.1 - detective-typescript: 14.0.0(typescript@5.9.2) - typescript: 5.9.2 + detective-typescript: 14.0.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color dettle@1.0.5: {} - devtools-protocol@0.0.1312386: {} - didyoumean@1.2.2: {} dlv@1.1.3: {} - dom-accessibility-api@0.5.16: {} - dot-prop@9.0.0: dependencies: type-fest: 4.41.0 @@ -4778,9 +3760,7 @@ snapshots: eastasianwidth@0.2.0: {} - ee-first@1.1.1: {} - - electron-to-chromium@1.5.215: {} + electron-to-chromium@1.5.234: {} emoji-regex@8.0.0: {} @@ -4790,26 +3770,14 @@ snapshots: enabled@2.0.0: {} - encodeurl@1.0.2: {} - - encodeurl@2.0.0: {} - end-of-stream@1.4.5: dependencies: once: 1.4.0 entities@4.5.0: {} - entities@6.0.1: {} - - env-paths@2.2.1: {} - env-paths@3.0.0: {} - error-ex@1.3.4: - dependencies: - is-arrayish: 0.2.1 - es-define-property@1.0.1: {} es-errors@1.3.0: {} @@ -4884,8 +3852,6 @@ snapshots: escalade@3.2.0: {} - escape-html@1.0.3: {} - escape-string-regexp@4.0.0: {} escodegen@2.1.0: @@ -4896,13 +3862,13 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-plugin-react-hooks@5.2.0(eslint@9.35.0(jiti@1.21.7)): + eslint-plugin-react-hooks@5.2.0(eslint@9.37.0(jiti@1.21.7)): dependencies: - eslint: 9.35.0(jiti@1.21.7) + eslint: 9.37.0(jiti@1.21.7) - eslint-plugin-react-refresh@0.4.20(eslint@9.35.0(jiti@1.21.7)): + eslint-plugin-react-refresh@0.4.23(eslint@9.37.0(jiti@1.21.7)): dependencies: - eslint: 9.35.0(jiti@1.21.7) + eslint: 9.37.0(jiti@1.21.7) eslint-scope@8.4.0: dependencies: @@ -4913,16 +3879,16 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.35.0(jiti@1.21.7): + eslint@9.37.0(jiti@1.21.7): dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@1.21.7)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(jiti@1.21.7)) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.21.0 - '@eslint/config-helpers': 0.3.1 - '@eslint/core': 0.15.2 + '@eslint/config-helpers': 0.4.0 + '@eslint/core': 0.16.0 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.35.0 - '@eslint/plugin-kit': 0.3.5 + '@eslint/js': 9.37.0 + '@eslint/plugin-kit': 0.4.0 '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 @@ -4931,7 +3897,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.1(supports-color@10.2.2) + debug: 4.4.3 escape-string-regexp: 4.0.0 eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -4975,19 +3941,15 @@ snapshots: estree-walker@2.0.2: {} - estree-walker@3.0.3: - dependencies: - '@types/estree': 1.0.8 - esutils@2.0.3: {} - etag@1.8.1: {} - event-target-shim@5.0.1: {} events-universal@1.0.1: dependencies: - bare-events: 2.7.0 + bare-events: 2.8.0 + transitivePeerDependencies: + - bare-abort-controller events@3.3.0: {} @@ -5003,11 +3965,9 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 - expect-type@1.2.2: {} - extract-zip@2.0.1: dependencies: - debug: 4.4.1(supports-color@10.2.2) + debug: 4.4.3 get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -5053,18 +4013,6 @@ snapshots: filter-obj@6.1.0: {} - finalhandler@1.3.1: - dependencies: - debug: 2.6.9 - encodeurl: 2.0.0 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.1 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - find-up-simple@1.0.1: {} find-up@5.0.0: @@ -5104,8 +4052,6 @@ snapshots: fraction.js@4.3.7: {} - fresh@0.5.2: {} - fsevents@2.3.3: optional: true @@ -5144,14 +4090,6 @@ snapshots: get-stream@8.0.1: {} - get-uri@6.0.5: - dependencies: - basic-ftp: 5.0.5 - data-uri-to-buffer: 6.0.2 - debug: 4.4.1(supports-color@10.2.2) - transitivePeerDependencies: - - supports-color - glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -5177,7 +4115,7 @@ snapshots: dependencies: minimist: 1.2.8 - goober@2.1.16(csstype@3.1.3): + goober@2.1.18(csstype@3.1.3): dependencies: csstype: 3.1.3 @@ -5187,12 +4125,6 @@ snapshots: graphemer@1.4.0: {} - happy-dom@19.0.2: - dependencies: - '@types/node': 20.19.19 - '@types/whatwg-mimetype': 3.0.2 - whatwg-mimetype: 3.0.0 - has-flag@4.0.0: {} has-symbols@1.1.0: {} @@ -5207,42 +4139,17 @@ snapshots: hosted-git-info@7.0.2: dependencies: - lru-cache: 10.4.3 + lru-cache: 7.18.3 - html-encoding-sniffer@4.0.0: - dependencies: - whatwg-encoding: 3.1.1 - - html-escaper@2.0.2: {} - - http-errors@2.0.0: - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.1 - toidentifier: 1.0.1 - - http-proxy-agent@7.0.2: + https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.4 - debug: 4.4.1(supports-color@10.2.2) - transitivePeerDependencies: - - supports-color - - https-proxy-agent@7.0.6(supports-color@10.2.2): - dependencies: - agent-base: 7.1.4 - debug: 4.4.1(supports-color@10.2.2) + debug: 4.4.3 transitivePeerDependencies: - supports-color human-signals@5.0.0: {} - iconv-lite@0.6.3: - dependencies: - safer-buffer: 2.1.2 - ieee754@1.2.1: {} ignore@5.3.2: {} @@ -5262,10 +4169,6 @@ snapshots: inherits@2.0.4: {} - ip-address@10.0.1: {} - - is-arrayish@0.2.1: {} - is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 @@ -5288,8 +4191,6 @@ snapshots: is-plain-obj@2.1.0: {} - is-potential-custom-element-name@1.0.1: {} - is-stream@2.0.1: {} is-stream@3.0.0: {} @@ -5304,27 +4205,6 @@ snapshots: isexe@2.0.0: {} - istanbul-lib-coverage@3.2.2: {} - - istanbul-lib-report@3.0.1: - dependencies: - istanbul-lib-coverage: 3.2.2 - make-dir: 4.0.0 - supports-color: 7.2.0 - - istanbul-lib-source-maps@5.0.6: - dependencies: - '@jridgewell/trace-mapping': 0.3.30 - debug: 4.4.1(supports-color@10.2.2) - istanbul-lib-coverage: 3.2.2 - transitivePeerDependencies: - - supports-color - - istanbul-reports@3.2.0: - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.1 - jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 @@ -5339,52 +4219,18 @@ snapshots: dependencies: jpeg-js: 0.4.4 - js-levenshtein@1.1.6: {} - js-tokens@4.0.0: {} js-yaml@4.1.0: dependencies: argparse: 2.0.1 - jsdom@25.0.1: - dependencies: - cssstyle: 4.6.0 - data-urls: 5.0.0 - decimal.js: 10.6.0 - form-data: 4.0.4 - html-encoding-sniffer: 4.0.0 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6(supports-color@10.2.2) - is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.22 - parse5: 7.3.0 - rrweb-cssom: 0.7.1 - saxes: 6.0.0 - symbol-tree: 3.2.4 - tough-cookie: 5.1.2 - w3c-xmlserializer: 5.0.0 - webidl-conversions: 7.0.0 - whatwg-encoding: 3.1.1 - whatwg-mimetype: 4.0.0 - whatwg-url: 14.2.0 - ws: 8.18.3 - xml-name-validator: 5.0.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - jsesc@3.1.0: {} json-buffer@3.0.1: {} - json-parse-even-better-errors@2.3.1: {} - json-schema-traverse@0.4.1: {} - json-schema-traverse@1.0.0: {} - json-stable-stringify-without-jsonify@1.0.1: {} json5@2.2.3: {} @@ -5443,14 +4289,6 @@ snapshots: dependencies: js-tokens: 4.0.0 - loupe@3.2.1: {} - - lru-cache@10.4.3: {} - - lru-cache@5.1.1: - dependencies: - yallist: 3.1.1 - lru-cache@7.18.3: {} lucide-react@0.540.0(react@18.3.1): @@ -5459,22 +4297,10 @@ snapshots: luxon@3.7.2: {} - lz-string@1.5.0: {} - magic-string@0.30.19: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - magicast@0.3.5: - dependencies: - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 - source-map-js: 1.2.1 - - make-dir@4.0.0: - dependencies: - semver: 7.7.2 - math-intrinsics@1.1.0: {} merge-options@3.0.4: @@ -5496,8 +4322,6 @@ snapshots: dependencies: mime-db: 1.52.0 - mime@1.6.0: {} - mimic-fn@4.0.0: {} minimatch@3.1.2: @@ -5520,15 +4344,11 @@ snapshots: dependencies: minipass: 7.1.2 - mitt@3.0.1: {} - module-definition@6.0.1: dependencies: ast-module-types: 6.0.1 node-source-walk: 7.0.1 - ms@2.0.0: {} - ms@2.1.3: {} mz@2.7.0: @@ -5541,8 +4361,6 @@ snapshots: natural-compare@1.4.0: {} - netmask@2.0.2: {} - node-fetch-native@1.6.7: {} node-fetch@2.7.0: @@ -5551,7 +4369,7 @@ snapshots: node-gyp-build@4.8.4: {} - node-releases@2.0.20: {} + node-releases@2.0.23: {} node-source-walk@7.0.1: dependencies: @@ -5564,7 +4382,7 @@ snapshots: normalize-package-data@6.0.2: dependencies: hosted-git-info: 7.0.2 - semver: 7.7.2 + semver: 7.7.3 validate-npm-package-license: 3.0.4 normalize-path@2.1.1: @@ -5579,8 +4397,6 @@ snapshots: dependencies: path-key: 4.0.0 - nwsapi@2.2.22: {} - object-assign@4.1.1: {} object-hash@3.0.0: {} @@ -5591,10 +4407,6 @@ snapshots: node-fetch-native: 1.6.7 ufo: 1.6.1 - on-finished@2.4.1: - dependencies: - ee-first: 1.1.1 - once@1.4.0: dependencies: wrappy: 1.0.2 @@ -5607,16 +4419,6 @@ snapshots: dependencies: mimic-fn: 4.0.0 - openapi-typescript@7.9.1(typescript@5.9.2): - dependencies: - '@redocly/openapi-core': 1.34.5(supports-color@10.2.2) - ansi-colors: 4.1.3 - change-case: 5.4.4 - parse-json: 8.3.0 - supports-color: 10.2.2 - typescript: 5.9.2 - yargs-parser: 21.1.1 - optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -5650,24 +4452,6 @@ snapshots: p-timeout@6.1.4: {} - pac-proxy-agent@7.2.0: - dependencies: - '@tootallnate/quickjs-emscripten': 0.23.0 - agent-base: 7.1.4 - debug: 4.4.1(supports-color@10.2.2) - get-uri: 6.0.5 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6(supports-color@10.2.2) - pac-resolver: 7.0.1 - socks-proxy-agent: 8.0.5 - transitivePeerDependencies: - - supports-color - - pac-resolver@7.0.1: - dependencies: - degenerator: 5.0.1 - netmask: 2.0.2 - package-json-from-dist@1.0.1: {} parent-module@1.0.1: @@ -5676,25 +4460,12 @@ snapshots: parse-gitignore@2.0.0: {} - parse-json@5.2.0: - dependencies: - '@babel/code-frame': 7.27.1 - error-ex: 1.3.4 - json-parse-even-better-errors: 2.3.1 - lines-and-columns: 1.2.4 - parse-json@8.3.0: dependencies: '@babel/code-frame': 7.27.1 index-to-position: 1.2.0 type-fest: 4.41.0 - parse5@7.3.0: - dependencies: - entities: 6.0.1 - - parseurl@1.3.3: {} - path-exists@4.0.0: {} path-exists@5.0.0: {} @@ -5707,13 +4478,9 @@ snapshots: path-scurry@1.11.1: dependencies: - lru-cache: 10.4.3 + lru-cache: 7.18.3 minipass: 7.1.2 - pathe@1.1.2: {} - - pathval@2.0.1: {} - pend@1.2.0: {} picocolors@1.1.1: {} @@ -5726,8 +4493,6 @@ snapshots: pirates@4.0.7: {} - pluralize@8.0.0: {} - postcss-import@15.1.0(postcss@8.5.6): dependencies: postcss: 8.5.6 @@ -5735,16 +4500,16 @@ snapshots: read-cache: 1.0.0 resolve: 1.22.10 - postcss-js@4.0.1(postcss@8.5.6): + postcss-js@4.1.0(postcss@8.5.6): dependencies: camelcase-css: 2.0.1 postcss: 8.5.6 - postcss-load-config@4.0.2(postcss@8.5.6): + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6): dependencies: lilconfig: 3.1.3 - yaml: 2.8.1 optionalDependencies: + jiti: 1.21.7 postcss: 8.5.6 postcss-nested@6.2.0(postcss@8.5.6): @@ -5783,42 +4548,21 @@ snapshots: detective-sass: 6.0.1 detective-scss: 5.0.1 detective-stylus: 5.0.1 - detective-typescript: 14.0.0(typescript@5.9.2) - detective-vue2: 2.2.0(typescript@5.9.2) + detective-typescript: 14.0.0(typescript@5.9.3) + detective-vue2: 2.2.0(typescript@5.9.3) module-definition: 6.0.1 node-source-walk: 7.0.1 postcss: 8.5.6 - typescript: 5.9.2 + typescript: 5.9.3 transitivePeerDependencies: - supports-color prelude-ls@1.2.1: {} - pretty-format@27.5.1: - dependencies: - ansi-regex: 5.0.1 - ansi-styles: 5.2.0 - react-is: 17.0.2 - process-nextick-args@2.0.1: {} process@0.11.10: {} - progress@2.0.3: {} - - proxy-agent@6.5.0: - dependencies: - agent-base: 7.1.4 - debug: 4.4.1(supports-color@10.2.2) - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6(supports-color@10.2.2) - lru-cache: 7.18.3 - pac-proxy-agent: 7.2.0 - proxy-from-env: 1.1.0 - socks-proxy-agent: 8.0.5 - transitivePeerDependencies: - - supports-color - proxy-from-env@1.1.0: {} pump@3.0.3: @@ -5828,40 +4572,10 @@ snapshots: punycode@2.3.1: {} - puppeteer-core@22.15.0: - dependencies: - '@puppeteer/browsers': 2.3.0 - chromium-bidi: 0.6.3(devtools-protocol@0.0.1312386) - debug: 4.4.1(supports-color@10.2.2) - devtools-protocol: 0.0.1312386 - ws: 8.18.3 - transitivePeerDependencies: - - bare-buffer - - bufferutil - - react-native-b4a - - supports-color - - utf-8-validate - - puppeteer@22.15.0(typescript@5.9.2): - dependencies: - '@puppeteer/browsers': 2.3.0 - cosmiconfig: 9.0.0(typescript@5.9.2) - devtools-protocol: 0.0.1312386 - puppeteer-core: 22.15.0 - transitivePeerDependencies: - - bare-buffer - - bufferutil - - react-native-b4a - - supports-color - - typescript - - utf-8-validate - queue-microtask@1.2.3: {} quote-unquote@1.0.0: {} - range-parser@1.2.1: {} - react-dom@18.3.1(react@18.3.1): dependencies: loose-envify: 1.4.0 @@ -5871,13 +4585,11 @@ snapshots: react-hot-toast@2.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: csstype: 3.1.3 - goober: 2.1.16(csstype@3.1.3) + goober: 2.1.18(csstype@3.1.3) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-is@17.0.2: {} - - react-refresh@0.17.0: {} + react-refresh@0.14.2: {} react-router-dom@6.30.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: @@ -5955,12 +4667,8 @@ snapshots: remove-trailing-separator@1.1.0: {} - requestidlecallback@0.3.0: {} - require-directory@2.1.1: {} - require-from-string@2.0.2: {} - require-package-name@2.0.1: {} resolve-from@4.0.0: {} @@ -5981,37 +4689,34 @@ snapshots: reusify@1.1.0: {} - rollup@4.50.1: + rollup@4.52.4: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.50.1 - '@rollup/rollup-android-arm64': 4.50.1 - '@rollup/rollup-darwin-arm64': 4.50.1 - '@rollup/rollup-darwin-x64': 4.50.1 - '@rollup/rollup-freebsd-arm64': 4.50.1 - '@rollup/rollup-freebsd-x64': 4.50.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.50.1 - '@rollup/rollup-linux-arm-musleabihf': 4.50.1 - '@rollup/rollup-linux-arm64-gnu': 4.50.1 - '@rollup/rollup-linux-arm64-musl': 4.50.1 - '@rollup/rollup-linux-loongarch64-gnu': 4.50.1 - '@rollup/rollup-linux-ppc64-gnu': 4.50.1 - '@rollup/rollup-linux-riscv64-gnu': 4.50.1 - '@rollup/rollup-linux-riscv64-musl': 4.50.1 - '@rollup/rollup-linux-s390x-gnu': 4.50.1 - '@rollup/rollup-linux-x64-gnu': 4.50.1 - '@rollup/rollup-linux-x64-musl': 4.50.1 - '@rollup/rollup-openharmony-arm64': 4.50.1 - '@rollup/rollup-win32-arm64-msvc': 4.50.1 - '@rollup/rollup-win32-ia32-msvc': 4.50.1 - '@rollup/rollup-win32-x64-msvc': 4.50.1 + '@rollup/rollup-android-arm-eabi': 4.52.4 + '@rollup/rollup-android-arm64': 4.52.4 + '@rollup/rollup-darwin-arm64': 4.52.4 + '@rollup/rollup-darwin-x64': 4.52.4 + '@rollup/rollup-freebsd-arm64': 4.52.4 + '@rollup/rollup-freebsd-x64': 4.52.4 + '@rollup/rollup-linux-arm-gnueabihf': 4.52.4 + '@rollup/rollup-linux-arm-musleabihf': 4.52.4 + '@rollup/rollup-linux-arm64-gnu': 4.52.4 + '@rollup/rollup-linux-arm64-musl': 4.52.4 + '@rollup/rollup-linux-loong64-gnu': 4.52.4 + '@rollup/rollup-linux-ppc64-gnu': 4.52.4 + '@rollup/rollup-linux-riscv64-gnu': 4.52.4 + '@rollup/rollup-linux-riscv64-musl': 4.52.4 + '@rollup/rollup-linux-s390x-gnu': 4.52.4 + '@rollup/rollup-linux-x64-gnu': 4.52.4 + '@rollup/rollup-linux-x64-musl': 4.52.4 + '@rollup/rollup-openharmony-arm64': 4.52.4 + '@rollup/rollup-win32-arm64-msvc': 4.52.4 + '@rollup/rollup-win32-ia32-msvc': 4.52.4 + '@rollup/rollup-win32-x64-gnu': 4.52.4 + '@rollup/rollup-win32-x64-msvc': 4.52.4 fsevents: 2.3.3 - rrweb-cssom@0.7.1: {} - - rrweb-cssom@0.8.0: {} - run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -6022,48 +4727,13 @@ snapshots: safe-stable-stringify@2.5.0: {} - safer-buffer@2.1.2: {} - - saxes@6.0.0: - dependencies: - xmlchars: 2.2.0 - scheduler@0.23.2: dependencies: loose-envify: 1.4.0 semver@6.3.1: {} - semver@7.7.2: {} - - send@0.19.0: - dependencies: - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 0.5.2 - http-errors: 2.0.0 - mime: 1.6.0 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.1 - transitivePeerDependencies: - - supports-color - - serve-static@1.16.2: - dependencies: - encodeurl: 2.0.0 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 0.19.0 - transitivePeerDependencies: - - supports-color - - setprototypeof@1.2.0: {} + semver@7.7.3: {} shebang-command@2.0.0: dependencies: @@ -6071,25 +4741,8 @@ snapshots: shebang-regex@3.0.0: {} - siginfo@2.0.0: {} - signal-exit@4.1.0: {} - smart-buffer@4.2.0: {} - - socks-proxy-agent@8.0.5: - dependencies: - agent-base: 7.1.4 - debug: 4.4.1(supports-color@10.2.2) - socks: 2.8.7 - transitivePeerDependencies: - - supports-color - - socks@2.8.7: - dependencies: - ip-address: 10.0.1 - smart-buffer: 4.2.0 - source-map-js@1.2.1: {} source-map-support@0.5.21: @@ -6115,18 +4768,13 @@ snapshots: stack-trace@0.0.10: {} - stackback@0.0.2: {} - - statuses@2.0.1: {} - - std-env@3.9.0: {} - streamx@2.23.0: dependencies: events-universal: 1.0.1 fast-fifo: 1.3.2 text-decoder: 1.2.3 transitivePeerDependencies: + - bare-abort-controller - react-native-b4a string-width@4.2.3: @@ -6171,17 +4819,13 @@ snapshots: pirates: 4.0.7 ts-interface-checker: 0.1.13 - supports-color@10.2.2: {} - supports-color@7.2.0: dependencies: has-flag: 4.0.0 supports-preserve-symlinks-flag@1.0.0: {} - symbol-tree@3.2.4: {} - - tailwindcss@3.4.17: + tailwindcss@3.4.18: dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -6199,32 +4843,23 @@ snapshots: picocolors: 1.1.1 postcss: 8.5.6 postcss-import: 15.1.0(postcss@8.5.6) - postcss-js: 4.0.1(postcss@8.5.6) - postcss-load-config: 4.0.2(postcss@8.5.6) + postcss-js: 4.1.0(postcss@8.5.6) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6) postcss-nested: 6.2.0(postcss@8.5.6) postcss-selector-parser: 6.1.2 resolve: 1.22.10 sucrase: 3.35.0 transitivePeerDependencies: - - ts-node - - tar-fs@3.1.1: - dependencies: - pump: 3.0.3 - tar-stream: 3.1.7 - optionalDependencies: - bare-fs: 4.4.4 - bare-path: 3.0.0 - transitivePeerDependencies: - - bare-buffer - - react-native-b4a + - tsx + - yaml tar-stream@3.1.7: dependencies: - b4a: 1.7.2 + b4a: 1.7.3 fast-fifo: 1.3.2 streamx: 2.23.0 transitivePeerDependencies: + - bare-abort-controller - react-native-b4a tar@7.5.1: @@ -6235,15 +4870,9 @@ snapshots: minizlib: 3.1.0 yallist: 5.0.0 - test-exclude@7.0.1: - dependencies: - '@istanbuljs/schema': 0.1.3 - glob: 10.4.5 - minimatch: 9.0.5 - text-decoder@1.2.3: dependencies: - b4a: 1.7.2 + b4a: 1.7.3 transitivePeerDependencies: - react-native-b4a @@ -6257,24 +4886,6 @@ snapshots: dependencies: any-promise: 1.3.0 - through@2.3.8: {} - - tinybench@2.9.0: {} - - tinyexec@0.3.2: {} - - tinypool@1.1.1: {} - - tinyrainbow@1.2.0: {} - - tinyspy@3.0.2: {} - - tldts-core@6.1.86: {} - - tldts@6.1.86: - dependencies: - tldts-core: 6.1.86 - tmp-promise@3.0.3: dependencies: tmp: 0.2.5 @@ -6285,25 +4896,15 @@ snapshots: dependencies: is-number: 7.0.0 - toidentifier@1.0.1: {} - toml@3.0.0: {} - tough-cookie@5.1.2: - dependencies: - tldts: 6.1.86 - tr46@0.0.3: {} - tr46@5.1.1: - dependencies: - punycode: 2.3.1 - triple-beam@1.4.1: {} - ts-api-utils@2.1.0(typescript@5.9.2): + ts-api-utils@2.1.0(typescript@5.9.3): dependencies: - typescript: 5.9.2 + typescript: 5.9.3 ts-interface-checker@0.1.13: {} @@ -6315,29 +4916,22 @@ snapshots: type-fest@4.41.0: {} - typescript-eslint@8.43.0(eslint@9.35.0(jiti@1.21.7))(typescript@5.9.2): + typescript-eslint@8.46.0(eslint@9.37.0(jiti@1.21.7))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.35.0(jiti@1.21.7))(typescript@5.9.2) - '@typescript-eslint/parser': 8.43.0(eslint@9.35.0(jiti@1.21.7))(typescript@5.9.2) - '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2) - '@typescript-eslint/utils': 8.43.0(eslint@9.35.0(jiti@1.21.7))(typescript@5.9.2) - eslint: 9.35.0(jiti@1.21.7) - typescript: 5.9.2 + '@typescript-eslint/eslint-plugin': 8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.37.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': 8.46.0(eslint@9.37.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@1.21.7))(typescript@5.9.3) + eslint: 9.37.0(jiti@1.21.7) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - typescript@5.9.2: {} + typescript@5.9.3: {} ufo@1.6.1: {} - unbzip2-stream@1.4.3: - dependencies: - buffer: 5.7.1 - through: 2.3.8 - - undici-types@6.21.0: {} - - undici-types@7.13.0: {} + undici-types@7.14.0: {} unicorn-magic@0.1.0: {} @@ -6345,21 +4939,17 @@ snapshots: dependencies: normalize-path: 2.1.1 - unpipe@1.0.0: {} - - update-browserslist-db@1.1.3(browserslist@4.25.4): + update-browserslist-db@1.1.3(browserslist@4.26.3): dependencies: - browserslist: 4.25.4 + browserslist: 4.26.3 escalade: 3.2.0 picocolors: 1.1.1 - uri-js-replace@1.0.1: {} - uri-js@4.4.1: dependencies: punycode: 2.3.1 - urlpattern-polyfill@10.0.0: {} + urlpattern-polyfill@10.1.0: {} urlpattern-polyfill@8.0.2: {} @@ -6372,91 +4962,17 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - vite-node@2.1.9(@types/node@24.6.2): - dependencies: - cac: 6.7.14 - debug: 4.4.1(supports-color@10.2.2) - es-module-lexer: 1.7.0 - pathe: 1.1.2 - vite: 5.4.10(@types/node@24.6.2) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - vite@5.4.10(@types/node@24.6.2): + vite@5.4.10(@types/node@24.7.2): dependencies: esbuild: 0.21.5 postcss: 8.5.6 - rollup: 4.50.1 + rollup: 4.52.4 optionalDependencies: - '@types/node': 24.6.2 + '@types/node': 24.7.2 fsevents: 2.3.3 - vitest@2.1.9(@types/node@24.6.2)(happy-dom@19.0.2)(jsdom@25.0.1): - dependencies: - '@vitest/expect': 2.1.9 - '@vitest/mocker': 2.1.9(vite@5.4.10(@types/node@24.6.2)) - '@vitest/pretty-format': 2.1.9 - '@vitest/runner': 2.1.9 - '@vitest/snapshot': 2.1.9 - '@vitest/spy': 2.1.9 - '@vitest/utils': 2.1.9 - chai: 5.3.3 - debug: 4.4.1(supports-color@10.2.2) - expect-type: 1.2.2 - magic-string: 0.30.19 - pathe: 1.1.2 - std-env: 3.9.0 - tinybench: 2.9.0 - tinyexec: 0.3.2 - tinypool: 1.1.1 - tinyrainbow: 1.2.0 - vite: 5.4.10(@types/node@24.6.2) - vite-node: 2.1.9(@types/node@24.6.2) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 24.6.2 - happy-dom: 19.0.2 - jsdom: 25.0.1 - transitivePeerDependencies: - - less - - lightningcss - - msw - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - w3c-xmlserializer@5.0.0: - dependencies: - xml-name-validator: 5.0.0 - webidl-conversions@3.0.1: {} - webidl-conversions@7.0.0: {} - - whatwg-encoding@3.1.1: - dependencies: - iconv-lite: 0.6.3 - - whatwg-mimetype@3.0.0: {} - - whatwg-mimetype@4.0.0: {} - - whatwg-url@14.2.0: - dependencies: - tr46: 5.1.1 - webidl-conversions: 7.0.0 - whatwg-url@5.0.0: dependencies: tr46: 0.0.3 @@ -6466,11 +4982,6 @@ snapshots: dependencies: isexe: 2.0.0 - why-is-node-running@2.3.0: - dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 - winston-transport@4.9.0: dependencies: logform: 2.7.0 @@ -6512,22 +5023,10 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 4.1.0 - ws@8.18.3: {} - - xml-name-validator@5.0.0: {} - - xmlchars@2.2.0: {} - y18n@5.0.8: {} - yallist@3.1.1: {} - yallist@5.0.0: {} - yaml-ast-parser@0.0.43: {} - - yaml@2.8.1: {} - yargs-parser@21.1.1: {} yargs@17.7.2: @@ -6555,4 +5054,4 @@ snapshots: compress-commons: 6.0.2 readable-stream: 4.7.0 - zod@3.23.8: {} + zod@3.25.76: {} diff --git a/MEDICONNECT 2/scripts/atribuir-guilherme-fernando.js b/MEDICONNECT 2/scripts/atribuir-guilherme-fernando.js deleted file mode 100644 index 91a91f042..000000000 --- a/MEDICONNECT 2/scripts/atribuir-guilherme-fernando.js +++ /dev/null @@ -1,186 +0,0 @@ -// Script para atribuir o paciente Guilherme ao Fernando -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -// Admin credentials -const ADMIN_EMAIL = "riseup@popcode.com.br"; -const ADMIN_PASSWORD = "riseup"; - -// Fernando user ID -const FERNANDO_USER_ID = "be1e3cba-534e-48c3-9590-b7e55861cade"; - -// Guilherme patient ID (do teste anterior) -const GUILHERME_ID = "864b1785-461f-4e92-8b74-2a6f17c58a80"; -const GUILHERME_NOME = "Guilherme Silva Gomes - SQUAD 18"; - -async function atribuirGuilherme() { - try { - console.log("\n🔐 === ATRIBUIR GUILHERME AO FERNANDO ===\n"); - - // 1. Login como admin - console.log("1️⃣ Fazendo login como admin..."); - const loginResponse = await fetch( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - }, - body: JSON.stringify({ - email: ADMIN_EMAIL, - password: ADMIN_PASSWORD, - }), - } - ); - - if (!loginResponse.ok) { - throw new Error( - `Erro no login: ${loginResponse.status} - ${await loginResponse.text()}` - ); - } - - const loginData = await loginResponse.json(); - const accessToken = loginData.access_token; - const adminUserId = loginData.user.id; - - console.log(`✅ Login admin realizado!`); - console.log(` Admin User ID: ${adminUserId}`); - - // 2. Verificar se a atribuição já existe - console.log(`\n2️⃣ Verificando atribuições existentes...`); - - const checkResponse = await fetch( - `${SUPABASE_URL}/rest/v1/patient_assignments?user_id=eq.${FERNANDO_USER_ID}&patient_id=eq.${GUILHERME_ID}`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${accessToken}`, - }, - } - ); - - if (checkResponse.ok) { - const existing = await checkResponse.json(); - if (existing.length > 0) { - console.log(`⚠️ Atribuição já existe!`); - console.log(` Assignment ID: ${existing[0].id}`); - console.log(` Criado em: ${existing[0].created_at}`); - console.log(`\n✅ Guilherme já está atribuído ao Fernando!`); - return; - } - } - - console.log(` ℹ️ Nenhuma atribuição existente encontrada.`); - - // 3. Criar nova atribuição - console.log(`\n3️⃣ Criando nova atribuição...`); - console.log(` Paciente: ${GUILHERME_NOME}`); - console.log(` Médico: Fernando (${FERNANDO_USER_ID})`); - - const atribuicao = { - patient_id: GUILHERME_ID, - user_id: FERNANDO_USER_ID, - role: "medico", - created_by: adminUserId, - }; - - const createResponse = await fetch( - `${SUPABASE_URL}/rest/v1/patient_assignments`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${accessToken}`, - Prefer: "return=representation", - }, - body: JSON.stringify(atribuicao), - } - ); - - if (!createResponse.ok) { - const errorText = await createResponse.text(); - throw new Error( - `Erro ao criar atribuição: ${createResponse.status} - ${errorText}` - ); - } - - const result = await createResponse.json(); - const assignment = Array.isArray(result) ? result[0] : result; - - console.log(`✅ Atribuição criada com sucesso!`); - console.log(` Assignment ID: ${assignment.id}`); - console.log(` Patient ID: ${assignment.patient_id}`); - console.log(` User ID: ${assignment.user_id}`); - console.log(` Role: ${assignment.role}`); - console.log(` Created At: ${assignment.created_at}`); - - // 4. Verificar todas as atribuições do Fernando - console.log(`\n4️⃣ Verificando todas as atribuições do Fernando...`); - - const allAssignmentsResponse = await fetch( - `${SUPABASE_URL}/rest/v1/patient_assignments?user_id=eq.${FERNANDO_USER_ID}&select=*`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${accessToken}`, - }, - } - ); - - if (allAssignmentsResponse.ok) { - const assignments = await allAssignmentsResponse.json(); - console.log( - `✅ Fernando possui ${assignments.length} paciente(s) atribuído(s):` - ); - - for (let i = 0; i < assignments.length; i++) { - const a = assignments[i]; - - // Buscar nome do paciente - const patientResponse = await fetch( - `${SUPABASE_URL}/rest/v1/patients?id=eq.${a.patient_id}&select=full_name`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${accessToken}`, - }, - } - ); - - let patientName = "Nome não encontrado"; - if (patientResponse.ok) { - const patients = await patientResponse.json(); - if (patients.length > 0) { - patientName = patients[0].full_name; - } - } - - console.log(` ${i + 1}. ${patientName}`); - console.log(` ID: ${a.patient_id}`); - console.log(` Role: ${a.role}`); - } - } - - console.log(`\n🎉 SUCESSO!`); - console.log(` Guilherme agora está atribuído ao Fernando!`); - console.log(` Fernando pode vê-lo no painel médico.`); - console.log(`\n Para testar:`); - console.log( - ` 1. Faça login: fernando.pirichowski@souunit.com.br / fernando` - ); - console.log(` 2. Acesse o painel médico`); - console.log(` 3. Clique em "Novo Relatório"`); - console.log(` 4. Guilherme deve aparecer na lista de pacientes!`); - } catch (error) { - console.error("\n❌ Erro:", error); - if (error instanceof Error) { - console.error(" Mensagem:", error.message); - } - } -} - -// Executar -atribuirGuilherme(); diff --git a/MEDICONNECT 2/scripts/cadastrar-guilherme.js b/MEDICONNECT 2/scripts/cadastrar-guilherme.js deleted file mode 100644 index b4e59373c..000000000 --- a/MEDICONNECT 2/scripts/cadastrar-guilherme.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Script para cadastrar o paciente Guilherme Silva Gomes - SQUAD 18 - */ - -import axios from "axios"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -// Credenciais do admin -const ADMIN_EMAIL = "riseup@popcode.com.br"; -const ADMIN_PASSWORD = "riseup"; - -async function main() { - try { - console.log("🔐 Fazendo login como admin..."); - - // 1. Login do admin - const loginResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: ADMIN_EMAIL, - password: ADMIN_PASSWORD, - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - } - ); - - const token = loginResponse.data.access_token; - console.log("✅ Login realizado com sucesso!\n"); - - // 2. Dados do paciente Guilherme Silva Gomes - SQUAD 18 - const pacienteData = { - full_name: "Guilherme Silva Gomes - SQUAD 18", - email: "guilherme@paciente.com", - phone_mobile: "79999521847", - cpf: "11144477735", // CPF válido para teste (validado por algoritmo) - birth_date: "2000-01-01", - sex: "M", - }; - - console.log("📝 Cadastrando paciente:"); - console.log(JSON.stringify(pacienteData, null, 2)); - console.log(""); - - // 3. Cadastrar o paciente - const cadastroResponse = await axios.post( - `${SUPABASE_URL}/rest/v1/patients`, - pacienteData, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${token}`, - "Content-Type": "application/json", - Prefer: "return=representation", - }, - } - ); - - console.log("✅ Paciente cadastrado com sucesso!"); - console.log("Dados retornados:"); - console.log(JSON.stringify(cadastroResponse.data, null, 2)); - console.log(""); - - // 4. Verificar se o paciente aparece na API - console.log("🔍 Verificando se o paciente aparece na lista..."); - - const listaResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/patients?select=*`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${token}`, - }, - } - ); - - const guilherme = listaResponse.data.find( - (p) => p.email === "guilherme@paciente.com" - ); - - if (guilherme) { - console.log("✅ SUCESSO! Paciente encontrado na API:"); - console.log(JSON.stringify(guilherme, null, 2)); - } else { - console.log("❌ Paciente não encontrado na lista."); - } - - console.log(""); - console.log(`📊 Total de pacientes na base: ${listaResponse.data.length}`); - } catch (error) { - console.error("❌ Erro:", error.response?.data || error.message); - if (error.response) { - console.error("Status:", error.response.status); - console.error("Headers:", error.response.headers); - } - } -} - -main(); diff --git a/MEDICONNECT 2/scripts/check-api-drift.cjs b/MEDICONNECT 2/scripts/check-api-drift.cjs deleted file mode 100644 index 4ae618cab..000000000 --- a/MEDICONNECT 2/scripts/check-api-drift.cjs +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env node -/* - Verifica se a saída gerada de openapi-typescript difere do arquivo commitado. - Estratégia: - 1. Gera tipos em memória (spawn openapi-typescript) para stdout. - 2. Lê conteúdo atual de src/types/api.d.ts. - 3. Compara strings normalizando quebras de linha. - 4. Se diferente -> exit 1 com mensagem. -*/ - -const { spawnSync } = require("node:child_process"); -const { readFileSync } = require("node:fs"); -const path = require("node:path"); - -const SPEC = path.resolve(process.cwd(), "docs/api/openapi.partial.json"); -const TARGET = path.resolve(process.cwd(), "src/types/api.d.ts"); - -function generateTypes() { - const result = spawnSync("npx", ["openapi-typescript", SPEC], { - encoding: "utf-8", - }); - if (result.status !== 0) { - console.error( - "[check:api-drift] Falha ao gerar tipos:", - result.stderr || result.stdout - ); - process.exit(2); - } - return result.stdout; -} - -function normalize(str) { - return str.replace(/\r\n?/g, "\n").trim(); -} - -try { - const generated = normalize(generateTypes()); - const current = normalize(readFileSync(TARGET, "utf-8")); - if (generated !== current) { - console.error( - "\n[check:api-drift] Diferença detectada entre spec e tipos commitados." - ); - console.error("Execute: pnpm gen:api-types"); - process.exit(1); - } - console.log("[check:api-drift] OK - tipos sincronizados."); -} catch (e) { - console.error("[check:api-drift] Erro inesperado:", e.message); - process.exit(2); -} diff --git a/MEDICONNECT 2/scripts/clear-expired-tokens.ts b/MEDICONNECT 2/scripts/clear-expired-tokens.ts deleted file mode 100644 index 838ef8388..000000000 --- a/MEDICONNECT 2/scripts/clear-expired-tokens.ts +++ /dev/null @@ -1,58 +0,0 @@ -// Script para diagnosticar localStorage e limpar tokens expirados -console.log("\n========== DIAGNÓSTICO LOCALSTORAGE =========="); - -const keys = ["authToken", "token", "refreshToken", "authUser", "appSession"]; -keys.forEach((k) => { - const val = localStorage.getItem(k); - if (val) { - console.log( - `${k}:`, - val.length > 100 ? val.substring(0, 100) + "..." : val - ); - } else { - console.log(`${k}: (ausente)`); - } -}); - -// Decode JWT se existir -function decodeJwt(token: string | null): { - valid: boolean; - payload?: { exp?: number; role?: string; sub?: string }; - expired?: boolean; -} { - if (!token) return { valid: false }; - try { - const parts = token.split("."); - if (parts.length !== 3) return { valid: false }; - const payload = JSON.parse(atob(parts[1])); - const now = Math.floor(Date.now() / 1000); - const expired = payload.exp ? payload.exp < now : false; - return { valid: true, payload, expired }; - } catch { - return { valid: false }; - } -} - -const tok = localStorage.getItem("authToken") || localStorage.getItem("token"); -if (tok) { - const decoded = decodeJwt(tok); - console.log("\n[Decode token]", decoded); - if (decoded.expired) { - console.warn("⚠️ Token expirado! Limpando..."); - localStorage.removeItem("authToken"); - localStorage.removeItem("token"); - localStorage.removeItem("refreshToken"); - localStorage.removeItem("authUser"); - console.log( - "✅ Tokens removidos. Recarregue a página e faça login novamente." - ); - } else { - console.log("✅ Token ainda válido."); - } -} else { - console.log( - "\n[Diagnóstico] Nenhum authToken encontrado. Usuário não autenticado." - ); -} - -console.log("==============================================\n"); diff --git a/MEDICONNECT 2/scripts/configurar-rls-secretaria.sql b/MEDICONNECT 2/scripts/configurar-rls-secretaria.sql deleted file mode 100644 index ea0eacaef..000000000 --- a/MEDICONNECT 2/scripts/configurar-rls-secretaria.sql +++ /dev/null @@ -1,116 +0,0 @@ --- ========================================= --- POLÍTICAS RLS PARA SECRETÁRIA CADASTRAR --- ========================================= --- Execute este SQL no Supabase SQL Editor --- URL: https://app.supabase.com/project/yuanqfswhberkoevtmfr/sql/new - --- ========================================= --- TABELA DOCTORS (Médicos) --- ========================================= - --- SELECT: Qualquer um autenticado pode ler -DROP POLICY IF EXISTS "doctors_select_authenticated" ON doctors; -CREATE POLICY "doctors_select_authenticated" -ON doctors FOR SELECT -TO authenticated -USING (true); - --- INSERT: Qualquer usuário autenticado pode criar -DROP POLICY IF EXISTS "doctors_insert_authenticated" ON doctors; -CREATE POLICY "doctors_insert_authenticated" -ON doctors FOR INSERT -TO authenticated -WITH CHECK (true); - --- UPDATE: Qualquer usuário autenticado pode atualizar -DROP POLICY IF EXISTS "doctors_update_authenticated" ON doctors; -CREATE POLICY "doctors_update_authenticated" -ON doctors FOR UPDATE -TO authenticated -USING (true) -WITH CHECK (true); - --- DELETE: Qualquer usuário autenticado pode deletar -DROP POLICY IF EXISTS "doctors_delete_authenticated" ON doctors; -CREATE POLICY "doctors_delete_authenticated" -ON doctors FOR DELETE -TO authenticated -USING (true); - --- ========================================= --- TABELA PATIENTS (Pacientes) --- ========================================= - --- SELECT: Qualquer um autenticado pode ler -DROP POLICY IF EXISTS "patients_select_authenticated" ON patients; -CREATE POLICY "patients_select_authenticated" -ON patients FOR SELECT -TO authenticated -USING (true); - --- INSERT: Qualquer usuário autenticado pode criar -DROP POLICY IF EXISTS "patients_insert_authenticated" ON patients; -CREATE POLICY "patients_insert_authenticated" -ON patients FOR INSERT -TO authenticated -WITH CHECK (true); - --- UPDATE: Qualquer usuário autenticado pode atualizar -DROP POLICY IF EXISTS "patients_update_authenticated" ON patients; -CREATE POLICY "patients_update_authenticated" -ON patients FOR UPDATE -TO authenticated -USING (true) -WITH CHECK (true); - --- DELETE: Qualquer usuário autenticado pode deletar -DROP POLICY IF EXISTS "patients_delete_authenticated" ON patients; -CREATE POLICY "patients_delete_authenticated" -ON patients FOR DELETE -TO authenticated -USING (true); - --- ========================================= --- TABELA PROFILES (Perfis - se existir) --- ========================================= - --- SELECT: Qualquer um autenticado pode ler -DROP POLICY IF EXISTS "profiles_select_authenticated" ON profiles; -CREATE POLICY "profiles_select_authenticated" -ON profiles FOR SELECT -TO authenticated -USING (true); - --- INSERT: Pode criar próprio perfil -DROP POLICY IF EXISTS "profiles_insert_own" ON profiles; -CREATE POLICY "profiles_insert_own" -ON profiles FOR INSERT -TO authenticated -WITH CHECK (auth.uid() = id); - --- UPDATE: Pode atualizar próprio perfil ou qualquer se for admin -DROP POLICY IF EXISTS "profiles_update_own_or_admin" ON profiles; -CREATE POLICY "profiles_update_own_or_admin" -ON profiles FOR UPDATE -TO authenticated -USING (auth.uid() = id OR true) -WITH CHECK (auth.uid() = id OR true); - --- ========================================= --- GARANTIR QUE RLS ESTÁ ATIVADO --- ========================================= - -ALTER TABLE doctors ENABLE ROW LEVEL SECURITY; -ALTER TABLE patients ENABLE ROW LEVEL SECURITY; -ALTER TABLE profiles ENABLE ROW LEVEL SECURITY; - --- ========================================= --- RESULTADO ESPERADO --- ========================================= --- Após executar este script: --- ✅ Secretária pode cadastrar médicos --- ✅ Secretária pode cadastrar pacientes --- ✅ Secretária pode editar médicos e pacientes --- ✅ Secretária pode deletar médicos e pacientes --- ✅ Admin pode fazer tudo --- ✅ RLS continua protegendo acesso não autenticado diff --git a/MEDICONNECT 2/scripts/criar-atribuicoes-fernando.js b/MEDICONNECT 2/scripts/criar-atribuicoes-fernando.js deleted file mode 100644 index a27e5672a..000000000 --- a/MEDICONNECT 2/scripts/criar-atribuicoes-fernando.js +++ /dev/null @@ -1,170 +0,0 @@ -// Script para criar atribuições de pacientes para o Fernando -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -// Admin credentials -const ADMIN_EMAIL = "riseup@popcode.com.br"; -const ADMIN_PASSWORD = "riseup"; - -// Fernando user ID (do teste anterior) -const FERNANDO_USER_ID = "be1e3cba-534e-48c3-9590-b7e55861cade"; - -// IDs dos pacientes (do teste anterior) -const PACIENTES = [ - { - id: "27aff771-8297-4ab2-8886-de8cf09c3895", - nome: "Isaac Kauã Barrozo Oliveira", - }, - { - id: "5236952f-efdd-4af6-b94b-0b28a89cb06c", - nome: "João Pedro Lima dos Santos", - }, - { - id: "7ddbd1e2-1aee-4f7a-94f9-ee4c735ca276", - nome: "Gabriel Nascimento Correia", - }, - { id: "1f5ac462-faf1-4290-ac55-d1900afb074e", nome: "Danilo Santos" }, - { - id: "cf835709-616f-428f-8055-1acf53ee24bb", - nome: "Jonas Francisco Nascimento Bonfim", - }, -]; - -async function criarAtribuicoes() { - try { - console.log("\n🔐 === CRIAR ATRIBUIÇÕES PARA FERNANDO ===\n"); - - // 1. Login como admin - console.log("1️⃣ Fazendo login como admin..."); - const loginResponse = await fetch( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - }, - body: JSON.stringify({ - email: ADMIN_EMAIL, - password: ADMIN_PASSWORD, - }), - } - ); - - if (!loginResponse.ok) { - throw new Error( - `Erro no login: ${loginResponse.status} - ${await loginResponse.text()}` - ); - } - - const loginData = await loginResponse.json(); - const accessToken = loginData.access_token; - const adminUserId = loginData.user.id; - - console.log(`✅ Login admin realizado!`); - console.log(` Admin User ID: ${adminUserId}`); - - // 2. Criar atribuições para cada paciente - console.log( - `\n2️⃣ Criando atribuições para Fernando (${FERNANDO_USER_ID})...\n` - ); - - let sucessos = 0; - let erros = 0; - - for (let i = 0; i < PACIENTES.length; i++) { - const paciente = PACIENTES[i]; - console.log( - ` [${i + 1}/${PACIENTES.length}] Atribuindo: ${paciente.nome}...` - ); - - try { - const atribuicao = { - patient_id: paciente.id, - user_id: FERNANDO_USER_ID, - role: "medico", - created_by: adminUserId, - }; - - const response = await fetch( - `${SUPABASE_URL}/rest/v1/patient_assignments`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${accessToken}`, - Prefer: "return=representation", - }, - body: JSON.stringify(atribuicao), - } - ); - - if (!response.ok) { - const errorText = await response.text(); - throw new Error(`${response.status} - ${errorText}`); - } - - const result = await response.json(); - console.log( - ` ✅ Sucesso! Assignment ID: ${ - result[0]?.id || result.id || "N/A" - }` - ); - sucessos++; - } catch (error) { - console.error( - ` ❌ Erro:`, - error instanceof Error ? error.message : error - ); - erros++; - } - } - - // 3. Verificar atribuições criadas - console.log(`\n3️⃣ Verificando atribuições criadas...\n`); - - const verificarResponse = await fetch( - `${SUPABASE_URL}/rest/v1/patient_assignments?user_id=eq.${FERNANDO_USER_ID}&select=*`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${accessToken}`, - }, - } - ); - - if (verificarResponse.ok) { - const assignments = await verificarResponse.json(); - console.log(`✅ Total de atribuições do Fernando: ${assignments.length}`); - - assignments.forEach((a, i) => { - console.log(` ${i + 1}. Patient: ${a.patient_id} | Role: ${a.role}`); - }); - } - - // 4. Resumo - console.log(`\n📊 === RESUMO ===`); - console.log(` ✅ Sucessos: ${sucessos}`); - console.log(` ❌ Erros: ${erros}`); - console.log(` 📋 Total tentados: ${PACIENTES.length}`); - - if (sucessos > 0) { - console.log( - `\n🎉 Fernando agora pode ver ${sucessos} pacientes no painel médico!` - ); - console.log( - ` Faça login com: fernando.pirichowski@souunit.com.br / fernando` - ); - } - } catch (error) { - console.error("\n❌ Erro geral:", error); - if (error instanceof Error) { - console.error(" Mensagem:", error.message); - } - } -} - -// Executar -criarAtribuicoes(); diff --git a/MEDICONNECT 2/scripts/criar-consultas-pedro.js b/MEDICONNECT 2/scripts/criar-consultas-pedro.js deleted file mode 100644 index 516babceb..000000000 --- a/MEDICONNECT 2/scripts/criar-consultas-pedro.js +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Script para criar 3 consultas de exemplo para o usuário/paciente Pedro Araujo. - * Credenciais locais fornecidas: Email: pedro.araujo@mediconnect.com Senha: local123 - * Este script NÃO cria o usuário nem o paciente se não existirem; apenas tenta - * localizar o paciente por email e gerar um arquivo local de demonstração - * (src/data/consultas-pedro.json) e opcionalmente mesclar no consultas-demo.json. - * - * Modo 1 (arquivo local): Gera JSON com consultas fictícias. - * Modo 2 (Supabase) - opcional futuro: Inserir via REST (requer tabela appointments e RLS configurada). - */ - -import fs from 'fs'; -import path from 'path'; -import fetch from 'node-fetch'; - -const SUPABASE_URL = 'https://yuanqfswhberkoevtmfr.supabase.co'; -const SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ'; - -const PEDRO_EMAIL = 'pedro.araujo@mediconnect.com'; -// Placeholder: se souber o ID real do paciente no Supabase, coloque aqui para futura inserção -let pedroPatientId = null; - -async function tentarLocalizarPaciente() { - try { - const res = await fetch(`${SUPABASE_URL}/rest/v1/patients?select=id,email&email=eq.${encodeURIComponent(PEDRO_EMAIL)}`, { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${SUPABASE_ANON_KEY}`, - } - }); - if (!res.ok) return null; - const data = await res.json(); - if (Array.isArray(data) && data.length > 0) { - return data[0].id; - } - return null; - } catch (e) { - return null; - } -} - -function criarConsultasLocais(patientIdOrEmail) { - const agora = new Date(); - const isoFuturo = (dias, hora) => { - const d = new Date(agora.getTime() + dias * 86400000); - d.setHours(hora, 0, 0, 0); - return d.toISOString(); - }; - - const medicoFernandoId = 'be1e3cba-534e-48c3-9590-b7e55861cade'; - const medicoFernandoNome = 'Fernando Pirichowski - Squad 18'; - const pacientePedroNome = 'Pedro Araujo'; - - const consultas = [ - { - id: 'consulta-demo-pedro-001', - pacienteId: patientIdOrEmail, - medicoId: medicoFernandoId, - pacienteNome: pacientePedroNome, - medicoNome: medicoFernandoNome, - dataHora: isoFuturo(2, 10), - status: 'agendada', - tipo: 'Consulta', - observacoes: 'Primeira avaliação clínica do Pedro.' - }, - { - id: 'consulta-demo-pedro-002', - pacienteId: patientIdOrEmail, - medicoId: medicoFernandoId, - pacienteNome: pacientePedroNome, - medicoNome: medicoFernandoNome, - dataHora: isoFuturo(7, 9), - status: 'confirmada', - tipo: 'Retorno', - observacoes: 'Retorno para revisar sintomas.' - }, - { - id: 'consulta-demo-pedro-003', - pacienteId: patientIdOrEmail, - medicoId: medicoFernandoId, - pacienteNome: pacientePedroNome, - medicoNome: medicoFernandoNome, - dataHora: isoFuturo(14, 11), - status: 'agendada', - tipo: 'Exame', - observacoes: 'Agendamento de exame complementar.' - } - ]; - return consultas; -} - -function salvarArquivoJson(fileName, data) { - const dataDir = path.join(process.cwd(), 'src', 'data'); - if (!fs.existsSync(dataDir)) fs.mkdirSync(dataDir, { recursive: true }); - const fullPath = path.join(dataDir, fileName); - fs.writeFileSync(fullPath, JSON.stringify(data, null, 2)); - console.log(`✅ Arquivo gerado: ${fullPath}`); - return fullPath; -} - -function mesclarNoConsultasDemo(novas) { - const demoPath = path.join(process.cwd(), 'src', 'data', 'consultas-demo.json'); - if (!fs.existsSync(demoPath)) { - console.log('ℹ️ consultas-demo.json não encontrado, pulando mescla.'); - return; - } - try { - const atual = JSON.parse(fs.readFileSync(demoPath, 'utf-8')); - const idsExistentes = new Set(atual.map(c => c.id)); - const filtradas = novas.filter(c => !idsExistentes.has(c.id)); - const combinado = [...atual, ...filtradas]; - fs.writeFileSync(demoPath, JSON.stringify(combinado, null, 2)); - console.log(`✅ ${filtradas.length} consultas adicionadas a consultas-demo.json`); - } catch (e) { - console.warn('⚠️ Falha ao mesclar no consultas-demo.json:', e.message); - } -} - -async function main() { - console.log('\n📁 Criando consultas de exemplo para Pedro...'); - const pacienteId = await tentarLocalizarPaciente(); - if (pacienteId) { - pedroPatientId = pacienteId; - console.log(`✅ Paciente encontrado no Supabase: ${pacienteId}`); - } else { - console.log('ℹ️ Paciente Pedro não encontrado no Supabase — usando email como identificador local.'); - } - const ident = pedroPatientId || PEDRO_EMAIL; - const consultas = criarConsultasLocais(ident); - salvarArquivoJson('consultas-pedro.json', consultas); - mesclarNoConsultasDemo(consultas); - console.log('\n✨ Concluído. Você pode agora:'); - console.log(' 1. Rodar a aplicação (pnpm dev)'); - console.log(' 2. Verificar se seu código carrega dados de src/data/consultas-demo.json'); - console.log(' 3. (Se não carregar automaticamente) Injetar via console usando snippet que fornecerei.'); -} - -main().catch(e => { - console.error('❌ Erro no script:', e.message); - process.exit(1); -}); diff --git a/MEDICONNECT 2/scripts/criar-dados-teste.js b/MEDICONNECT 2/scripts/criar-dados-teste.js deleted file mode 100644 index 6543350f7..000000000 --- a/MEDICONNECT 2/scripts/criar-dados-teste.js +++ /dev/null @@ -1,181 +0,0 @@ -import fetch from "node-fetch"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -// Credenciais admin para realizar INSERTs autenticados (RLS exige usuário autenticado) -const ADMIN_EMAIL = process.env.TEST_ADMIN_EMAIL || "riseup@popcode.com.br"; -const ADMIN_PASSWORD = - process.env.TEST_ADMIN_PASSWORD || "riseup"; - -console.log("\n🔧 CRIANDO DADOS DE TESTE\n"); - -async function loginAdmin() { - console.log("🔐 Fazendo login como admin para inserir dados (RLS)..."); - const res = await fetch( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - }, - body: JSON.stringify({ email: ADMIN_EMAIL, password: ADMIN_PASSWORD }), - } - ); - if (!res.ok) { - const txt = await res.text(); - throw new Error(`Falha no login admin (${res.status}): ${txt}`); - } - const data = await res.json(); - console.log("✅ Login admin OK\n"); - return data.access_token; -} - -async function criarMedicoTeste(adminToken) { - console.log("👨‍⚕️ Criando médico de teste..."); - - const medico = { - full_name: "Dr. João Silva", - email: "drjoao@mediconnect.com", - crm: "12345", - crm_uf: "SE", - specialty: "Cardiologia", - phone_mobile: "79999999999", - cpf: "12345678900", - active: true, - }; - - try { - const response = await fetch(`${SUPABASE_URL}/rest/v1/doctors`, { - method: "POST", - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - // IMPORTANTE: usar token do admin autenticado para permitir INSERT (RLS) - Authorization: `Bearer ${adminToken}`, - Prefer: "return=representation", - }, - body: JSON.stringify(medico), - }); - - if (response.ok) { - const data = await response.json(); - console.log("✅ Médico criado com sucesso!"); - console.log(" ID:", data[0]?.id); - console.log(" Nome:", data[0]?.full_name); - return data[0]; - } else { - console.log("❌ Erro ao criar médico:", response.status); - const error = await response.text(); - console.log(error); - return null; - } - } catch (error) { - console.error("❌ Erro:", error.message); - return null; - } -} - -async function criarPacienteTeste(adminToken) { - console.log("\n👤 Criando paciente de teste..."); - - const paciente = { - full_name: "Maria Santos", - email: "maria@example.com", - phone_mobile: "79988888888", - cpf: "98765432100", - birth_date: "1990-05-15", - street: "Rua das Flores", - number: "100", - neighborhood: "Centro", - city: "Aracaju", - state: "SE", - cep: "49000-000", - }; - - try { - const response = await fetch(`${SUPABASE_URL}/rest/v1/patients`, { - method: "POST", - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - // IMPORTANTE: usar token do admin autenticado para permitir INSERT (RLS) - Authorization: `Bearer ${adminToken}`, - Prefer: "return=representation", - }, - body: JSON.stringify(paciente), - }); - - if (response.ok) { - const data = await response.json(); - console.log("✅ Paciente criado com sucesso!"); - console.log(" ID:", data[0]?.id); - console.log(" Nome:", data[0]?.full_name); - return data[0]; - } else { - console.log("❌ Erro ao criar paciente:", response.status); - const error = await response.text(); - console.log(error); - - if (response.status === 403 || response.status === 401) { - console.log("\n⚠️ RLS está bloqueando a inserção anônima!"); - console.log(" Você precisa:"); - console.log(" 1. Criar uma política RLS que permita INSERT público"); - console.log( - " 2. Ou usar a service_role key (não recomendado para front-end)" - ); - console.log( - " 3. Ou criar através da interface de cadastro (com autenticação)" - ); - } - - return null; - } - } catch (error) { - console.error("❌ Erro:", error.message); - return null; - } -} - -async function criar() { - const adminToken = await loginAdmin(); - await criarMedicoTeste(adminToken); - await criarPacienteTeste(adminToken); - - console.log("\n\n📊 VERIFICANDO RESULTADOS...\n"); - - // Verificar médicos - const respMedicos = await fetch(`${SUPABASE_URL}/rest/v1/doctors?select=*`, { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${SUPABASE_ANON_KEY}`, - }, - }); - - if (respMedicos.ok) { - const medicos = await respMedicos.json(); - console.log(`✅ Médicos cadastrados: ${medicos.length}`); - } - - // Verificar pacientes - const respPacientes = await fetch( - `${SUPABASE_URL}/rest/v1/patients?select=*`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${SUPABASE_ANON_KEY}`, - }, - } - ); - - if (respPacientes.ok) { - const pacientes = await respPacientes.json(); - console.log(`✅ Pacientes cadastrados: ${pacientes.length}`); - } - - console.log("\n✨ Pronto! Agora os painéis devem mostrar os dados.\n"); -} - -criar(); diff --git a/MEDICONNECT 2/scripts/criar-guilherme-completo.js b/MEDICONNECT 2/scripts/criar-guilherme-completo.js deleted file mode 100644 index 8d78caa2f..000000000 --- a/MEDICONNECT 2/scripts/criar-guilherme-completo.js +++ /dev/null @@ -1,413 +0,0 @@ -/** - * Script completo para criar usuário Guilherme com role "user" - * Email: guilhermesilvagomes1020@gmail.com - * Telefone: 79999521847 - */ - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -// Admin credentials -const ADMIN_EMAIL = "riseup@popcode.com.br"; -const ADMIN_PASSWORD = "riseup"; - -// Guilherme dados atualizados -const GUILHERME_EMAIL = "guilhermesilvagomes1020@gmail.com"; -const GUILHERME_PASSWORD = "guilherme123"; -const GUILHERME_NOME = "Guilherme Silva Gomes - SQUAD 18"; -const GUILHERME_TELEFONE = "79999521847"; -const GUILHERME_CPF = "11144477735"; // CPF válido para teste - -// Fernando dados -const FERNANDO_USER_ID = "be1e3cba-534e-48c3-9590-b7e55861cade"; -const FERNANDO_NOME = "Fernando Pirichowski - Squad 18"; - -async function criarGuilhermeCompleto() { - try { - console.log("\n🔐 === CRIAR GUILHERME COMPLETO ===\n"); - - // 1. Login como admin - console.log("1️⃣ Fazendo login como admin..."); - const loginResponse = await fetch( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - }, - body: JSON.stringify({ - email: ADMIN_EMAIL, - password: ADMIN_PASSWORD, - }), - } - ); - - if (!loginResponse.ok) { - throw new Error(`Erro no login: ${loginResponse.status}`); - } - - const loginData = await loginResponse.json(); - const adminToken = loginData.access_token; - console.log("✅ Login admin realizado!\n"); - - // 2. Criar paciente Guilherme - console.log("2️⃣ Criando paciente Guilherme..."); - console.log(` Nome: ${GUILHERME_NOME}`); - console.log(` Email: ${GUILHERME_EMAIL}`); - console.log(` Telefone: ${GUILHERME_TELEFONE}`); - console.log(` CPF: ${GUILHERME_CPF}\n`); - - // Verificar se paciente já existe - const checkPatientResponse = await fetch( - `${SUPABASE_URL}/rest/v1/patients?email=eq.${encodeURIComponent( - GUILHERME_EMAIL - )}`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${adminToken}`, - }, - } - ); - - let existingPatients = await checkPatientResponse.json(); - let guilhermePatientId; - - // Verificar por email ou CPF - if (!existingPatients || existingPatients.length === 0) { - const checkByCpfResponse = await fetch( - `${SUPABASE_URL}/rest/v1/patients?cpf=eq.${GUILHERME_CPF}`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${adminToken}`, - }, - } - ); - existingPatients = await checkByCpfResponse.json(); - } - - if (existingPatients && existingPatients.length > 0) { - guilhermePatientId = existingPatients[0].id; - console.log("✅ Paciente já existe!"); - console.log(` Patient ID: ${guilhermePatientId}`); - console.log(` Nome: ${existingPatients[0].full_name}`); - console.log(` Email: ${existingPatients[0].email}\n`); - } else { - // Criar paciente - const createPatientResponse = await fetch( - `${SUPABASE_URL}/rest/v1/patients`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${adminToken}`, - apikey: SUPABASE_ANON_KEY, - Prefer: "return=representation", - }, - body: JSON.stringify({ - full_name: GUILHERME_NOME, - email: GUILHERME_EMAIL, - phone_mobile: GUILHERME_TELEFONE, - cpf: GUILHERME_CPF, - birth_date: "2000-10-20", - sex: "M", - }), - } - ); - - if (!createPatientResponse.ok) { - const error = await createPatientResponse.text(); - console.error("❌ Erro ao criar paciente:", error); - throw new Error(error); - } - - const patientData = await createPatientResponse.json(); - guilhermePatientId = patientData[0]?.id || patientData.id; - console.log("✅ Paciente criado!"); - console.log(` Patient ID: ${guilhermePatientId}\n`); - } - - // 3. Criar usuário com role "user" - console.log("3️⃣ Criando usuário com role 'user'..."); - console.log(` Email: ${GUILHERME_EMAIL}`); - console.log(` Senha: ${GUILHERME_PASSWORD}`); - console.log(` Role: user\n`); - - // Verificar se usuário já existe - try { - const checkUserLogin = await fetch( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - }, - body: JSON.stringify({ - email: GUILHERME_EMAIL, - password: GUILHERME_PASSWORD, - }), - } - ); - - if (checkUserLogin.ok) { - const userData = await checkUserLogin.json(); - console.log("✅ Usuário já existe!"); - console.log(` User ID: ${userData.user.id}\n`); - - // Atribuir paciente ao usuário - await atribuirPaciente( - adminToken, - userData.user.id, - guilhermePatientId - ); - await criarConsultas(guilhermePatientId); - mostrarResumo(); - return; - } - } catch (e) { - console.log("ℹ️ Usuário não existe, criando...\n"); - } - - // Criar usuário via Edge Function - const createUserResponse = await fetch( - `${SUPABASE_URL}/functions/v1/create-user`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${adminToken}`, - apikey: SUPABASE_ANON_KEY, - }, - body: JSON.stringify({ - email: GUILHERME_EMAIL, - password: GUILHERME_PASSWORD, - full_name: GUILHERME_NOME, - role: "user", - }), - } - ); - - const createUserText = await createUserResponse.text(); - console.log(" Resposta da criação:", createUserText); - - let createUserData; - try { - createUserData = JSON.parse(createUserText); - } catch (e) { - console.error("❌ Erro ao parsear resposta:", createUserText); - throw new Error("Resposta inválida da API"); - } - - if (!createUserResponse.ok) { - console.error("❌ Erro ao criar usuário:", createUserData); - throw new Error(JSON.stringify(createUserData)); - } - - // Tentar obter user_id de várias formas - let guilhermeUserId = - createUserData.user_id || - createUserData.id || - createUserData.userId || - createUserData.user?.id; - - if (!guilhermeUserId) { - // Tentar fazer login para obter o ID - console.log(" Tentando obter ID via login..."); - const loginGuilherme = await fetch( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - }, - body: JSON.stringify({ - email: GUILHERME_EMAIL, - password: GUILHERME_PASSWORD, - }), - } - ); - - if (loginGuilherme.ok) { - const loginData = await loginGuilherme.json(); - guilhermeUserId = loginData.user.id; - } - } - - if (!guilhermeUserId) { - console.error("❌ Não foi possível obter o User ID!"); - console.error(" Resposta:", createUserData); - throw new Error("User ID não disponível"); - } - - console.log("✅ Usuário criado com sucesso!"); - console.log(` User ID: ${guilhermeUserId}\n`); - - // 4. Atribuir paciente ao usuário - await atribuirPaciente(adminToken, guilhermeUserId, guilhermePatientId); - - // 5. Criar consultas - await criarConsultas(guilhermePatientId); - - // 6. Mostrar resumo - mostrarResumo(); - } catch (error) { - console.error("\n❌ ERRO:", error.message); - if (error.stack) { - console.error(error.stack); - } - process.exit(1); - } -} - -async function atribuirPaciente(adminToken, userId, patientId) { - console.log("4️⃣ Atribuindo paciente ao usuário..."); - - // Verificar se atribuição já existe - const checkResponse = await fetch( - `${SUPABASE_URL}/rest/v1/patient_assignments?user_id=eq.${userId}&patient_id=eq.${patientId}`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${adminToken}`, - }, - } - ); - - const existing = await checkResponse.json(); - - if (existing && existing.length > 0) { - console.log("✅ Atribuição já existe!\n"); - return; - } - - // Criar atribuição - const assignResponse = await fetch( - `${SUPABASE_URL}/rest/v1/patient_assignments`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${adminToken}`, - apikey: SUPABASE_ANON_KEY, - Prefer: "return=representation", - }, - body: JSON.stringify({ - user_id: userId, - patient_id: patientId, - role: "user", // Adicionar role na atribuição - }), - } - ); - - if (!assignResponse.ok) { - const error = await assignResponse.text(); - console.error("⚠️ Erro ao criar atribuição:", error); - } else { - console.log("✅ Paciente atribuído ao usuário!\n"); - } -} - -async function criarConsultas(guilhermePatientId) { - console.log("5️⃣ Criando consultas de demonstração...\n"); - - const consultas = [ - { - id: "consulta-demo-guilherme-001", - pacienteId: guilhermePatientId, - medicoId: FERNANDO_USER_ID, - pacienteNome: GUILHERME_NOME, - medicoNome: FERNANDO_NOME, - dataHora: "2025-10-05T10:00:00", - status: "agendada", - tipo: "Consulta", - observacoes: "Primeira consulta - Check-up geral", - }, - { - id: "consulta-demo-guilherme-002", - pacienteId: guilhermePatientId, - medicoId: FERNANDO_USER_ID, - pacienteNome: GUILHERME_NOME, - medicoNome: FERNANDO_NOME, - dataHora: "2025-09-28T14:30:00", - status: "realizada", - tipo: "Retorno", - observacoes: "Consulta de retorno - Avaliação de exames", - }, - { - id: "consulta-demo-guilherme-003", - pacienteId: guilhermePatientId, - medicoId: FERNANDO_USER_ID, - pacienteNome: GUILHERME_NOME, - medicoNome: FERNANDO_NOME, - dataHora: "2025-10-10T09:00:00", - status: "confirmada", - tipo: "Consulta", - observacoes: "Consulta de acompanhamento mensal", - }, - ]; - - // Usar import dinâmico para módulos ES - const fs = await import("fs"); - const path = await import("path"); - const { fileURLToPath } = await import("url"); - const { dirname } = await import("path"); - - const __filename = fileURLToPath(import.meta.url); - const __dirname = dirname(__filename); - - const dataDir = path.join(__dirname, "..", "src", "data"); - - if (!fs.existsSync(dataDir)) { - fs.mkdirSync(dataDir, { recursive: true }); - console.log(" 📁 Diretório src/data criado"); - } - - const consultasPath = path.join(dataDir, "consultas-demo.json"); - fs.writeFileSync(consultasPath, JSON.stringify(consultas, null, 2)); - - console.log(" ✅ Consultas salvas em src/data/consultas-demo.json"); - console.log(` 📊 ${consultas.length} consultas criadas:`); - consultas.forEach((c, i) => { - console.log(` ${i + 1}. ${c.dataHora} - ${c.status} - ${c.tipo}`); - }); - console.log(); -} - -function mostrarResumo() { - console.log("\n✅ === CONFIGURAÇÃO CONCLUÍDA COM SUCESSO! ===\n"); - console.log("📋 CREDENCIAIS DE LOGIN:\n"); - console.log(" Email: guilhermesilvagomes1020@gmail.com"); - console.log(" Senha: guilherme123"); - console.log(" Role: user (acesso ao painel paciente)\n"); - console.log("📱 DADOS DO PACIENTE:\n"); - console.log(" Nome: Guilherme Silva Gomes - SQUAD 18"); - console.log(" Telefone: 79999521847"); - console.log(" Médico: Fernando Pirichowski - Squad 18\n"); - console.log("🔗 PRÓXIMOS PASSOS:\n"); - console.log(" 1. Acesse http://localhost:5173/paciente no navegador"); - console.log( - " 2. Faça login com: guilhermesilvagomes1020@gmail.com / guilherme123" - ); - console.log(" 3. Você verá o painel do paciente com as consultas"); - console.log(" 4. As consultas também aparecem no painel do Dr. Fernando"); - console.log(" 5. E no painel da secretária\n"); - console.log("💡 PARA CARREGAR AS CONSULTAS NO NAVEGADOR:\n"); - console.log(" - Abra o console (F12)"); - console.log( - " - Execute: fetch('/src/data/consultas-demo.json').then(r=>r.json()).then(c=>{" - ); - console.log( - " localStorage.setItem('consultas_local', JSON.stringify(c));" - ); - console.log(" location.reload();"); - console.log(" })"); - console.log(); -} - -// Executar -criarGuilhermeCompleto(); diff --git a/MEDICONNECT 2/scripts/criar-julia-admin.js b/MEDICONNECT 2/scripts/criar-julia-admin.js deleted file mode 100644 index 67ef45a41..000000000 --- a/MEDICONNECT 2/scripts/criar-julia-admin.js +++ /dev/null @@ -1,220 +0,0 @@ -import axios from "axios"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -async function criarJuliaComAdmin() { - try { - console.log("═══════════════════════════════════════════════════"); - console.log("🔐 CRIANDO USUÁRIA JULIA CARVALHO"); - console.log("═══════════════════════════════════════════════════\n"); - - // 1. Login como admin - console.log("🔑 Fazendo login como admin (riseup@popcode.com.br)..."); - - const loginResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: "riseup@popcode.com.br", - password: "riseup", - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - } - ); - - const adminToken = loginResponse.data.access_token; - const adminUserId = loginResponse.data.user.id; - - console.log("✅ Login admin realizado com sucesso!"); - console.log(` Admin ID: ${adminUserId}\n`); - - // 2. Criar usuário Julia no Supabase Auth - console.log("👤 Criando usuária Julia na autenticação..."); - - const signupResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/signup`, - { - email: "secretaria.mediconnect@gmail.com", - password: "secretaria@mediconnect", - data: { - full_name: "Julia Carvalho", - role: "admin", - }, - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - } - ); - - const juliaUserId = signupResponse.data.user?.id; - const juliaToken = signupResponse.data.access_token; - - if (!juliaUserId) { - throw new Error("Não foi possível obter o ID da usuária criada"); - } - - console.log("✅ Usuária criada na autenticação!"); - console.log(` Julia ID: ${juliaUserId}\n`); - - // 3. Criar perfil na tabela profiles usando token admin - console.log("📋 Criando perfil na tabela profiles..."); - - try { - await axios.post( - `${SUPABASE_URL}/rest/v1/profiles`, - { - id: juliaUserId, - email: "secretaria.mediconnect@gmail.com", - full_name: "Julia Carvalho", - is_admin: true, - is_secretary: true, - is_admin_or_manager: true, - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${adminToken}`, - "Content-Type": "application/json", - Prefer: "return=representation", - }, - } - ); - console.log("✅ Perfil criado com sucesso!\n"); - } catch (error) { - if (error.response?.status === 409) { - console.log("⚠️ Perfil já existe, atualizando..."); - await axios.patch( - `${SUPABASE_URL}/rest/v1/profiles?id=eq.${juliaUserId}`, - { - full_name: "Julia Carvalho", - is_admin: true, - is_secretary: true, - is_admin_or_manager: true, - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${adminToken}`, - "Content-Type": "application/json", - }, - } - ); - console.log("✅ Perfil atualizado!\n"); - } else { - throw error; - } - } - - // 4. Adicionar role admin na tabela user_roles - console.log("🎭 Adicionando role admin..."); - - try { - await axios.post( - `${SUPABASE_URL}/rest/v1/user_roles`, - { - user_id: juliaUserId, - role: "admin", - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${adminToken}`, - "Content-Type": "application/json", - Prefer: "return=representation", - }, - } - ); - console.log("✅ Role admin adicionada!\n"); - } catch (error) { - if (error.response?.status === 409) { - console.log("⚠️ Role admin já existe!\n"); - } else { - throw error; - } - } - - // 5. Verificar se Julia consegue acessar pacientes - console.log("🏥 Testando acesso aos pacientes..."); - - const pacientesResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/patients?select=id,full_name,email&limit=5`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${juliaToken}`, - }, - } - ); - - console.log( - `✅ Julia consegue acessar pacientes! (${pacientesResponse.data.length} encontrados)\n` - ); - - if (pacientesResponse.data.length > 0) { - console.log("📋 Pacientes acessíveis:"); - pacientesResponse.data.forEach((p) => { - console.log( - ` • ${p.full_name || "Sem nome"} - ${p.email || "Sem email"}` - ); - }); - console.log(""); - } - - // 6. Resumo final - console.log("═══════════════════════════════════════════════════"); - console.log("✅ USUÁRIA JULIA CRIADA COM SUCESSO!"); - console.log("═══════════════════════════════════════════════════"); - console.log(""); - console.log("👤 Nome: Julia Carvalho"); - console.log("📧 Email: secretaria.mediconnect@gmail.com"); - console.log("🔑 Senha: secretaria@mediconnect"); - console.log("🎭 Role: admin"); - console.log(""); - console.log("✨ Permissões:"); - console.log(" ✅ is_admin: true"); - console.log(" ✅ is_secretary: true"); - console.log(" ✅ is_admin_or_manager: true"); - console.log(" ✅ Acesso completo aos pacientes"); - console.log(""); - console.log("🌐 Faça login em:"); - console.log(" http://localhost:5173/login-secretaria"); - console.log(""); - console.log("═══════════════════════════════════════════════════"); - } catch (error) { - console.error( - "\n❌ ERRO ao criar usuária:", - error.response?.data || error.message - ); - - if (error.response?.data?.code === "23505") { - console.log("\n⚠️ USUÁRIA JÁ EXISTE!"); - console.log(""); - console.log("Você pode fazer login com:"); - console.log("📧 Email: secretaria.mediconnect@gmail.com"); - console.log("🔑 Senha: secretaria@mediconnect"); - console.log("🌐 URL: http://localhost:5173/login-secretaria"); - } else if (error.response?.status === 422) { - console.log("\n⚠️ USUÁRIA JÁ EXISTE (email já cadastrado)"); - console.log(""); - console.log("Tente fazer login com:"); - console.log("📧 Email: secretaria.mediconnect@gmail.com"); - console.log("🔑 Senha: secretaria@mediconnect"); - } else if (error.code === "ENOTFOUND") { - console.log("\n⚠️ ERRO DE CONEXÃO"); - console.log("Verifique sua conexão com a internet e tente novamente."); - } else { - console.log("\n📋 Detalhes do erro:"); - console.log(JSON.stringify(error.response?.data, null, 2)); - } - } -} - -criarJuliaComAdmin(); diff --git a/MEDICONNECT 2/scripts/criar-julia-secretaria.js b/MEDICONNECT 2/scripts/criar-julia-secretaria.js deleted file mode 100644 index e102e5dbf..000000000 --- a/MEDICONNECT 2/scripts/criar-julia-secretaria.js +++ /dev/null @@ -1,188 +0,0 @@ -import axios from "axios"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -async function criarJuliaSecretaria() { - try { - console.log("═══════════════════════════════════════════════════"); - console.log("🔐 CRIANDO JULIA CARVALHO - ROLE SECRETARIA"); - console.log("═══════════════════════════════════════════════════\n"); - - // Login como admin - console.log("🔑 Login admin..."); - const login = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { email: "riseup@popcode.com.br", password: "riseup" }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - } - ); - const adminToken = login.data.access_token; - console.log("✅ Admin logado!\n"); - - // Criar Julia - console.log("👤 Criando Julia..."); - let juliaUserId; - let juliaToken; - - try { - const signup = await axios.post( - `${SUPABASE_URL}/auth/v1/signup`, - { - email: "secretaria.mediconnect@gmail.com", - password: "secretaria@mediconnect", - data: { full_name: "Julia Carvalho", role: "secretaria" }, - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - } - ); - juliaUserId = signup.data.user.id; - juliaToken = signup.data.access_token; - console.log("✅ Julia criada!"); - } catch (err) { - if (err.response?.status === 422) { - console.log("⚠️ Julia já existe, fazendo login..."); - const juliaLogin = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: "secretaria.mediconnect@gmail.com", - password: "secretaria@mediconnect", - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - } - ); - juliaUserId = juliaLogin.data.user.id; - juliaToken = juliaLogin.data.access_token; - console.log("✅ Julia já existe!"); - } else { - throw err; - } - } - - console.log(` ID: ${juliaUserId}\n`); - - // Criar/atualizar perfil - console.log("📋 Criando perfil..."); - try { - await axios.post( - `${SUPABASE_URL}/rest/v1/profiles`, - { - id: juliaUserId, - email: "secretaria.mediconnect@gmail.com", - full_name: "Julia Carvalho", - is_admin: false, - is_secretary: true, - is_admin_or_manager: false, - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${adminToken}`, - "Content-Type": "application/json", - Prefer: "return=representation", - }, - } - ); - console.log("✅ Perfil criado!\n"); - } catch (err) { - if (err.response?.status === 409) { - console.log("⚠️ Perfil existe, atualizando..."); - await axios.patch( - `${SUPABASE_URL}/rest/v1/profiles?id=eq.${juliaUserId}`, - { - full_name: "Julia Carvalho", - is_admin: false, - is_secretary: true, - is_admin_or_manager: false, - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${adminToken}`, - "Content-Type": "application/json", - }, - } - ); - console.log("✅ Perfil atualizado!\n"); - } else { - console.log( - "⚠️ Aviso perfil:", - err.response?.data?.message || err.message - ); - } - } - - // Adicionar role - console.log("🎭 Adicionando role secretaria..."); - try { - await axios.post( - `${SUPABASE_URL}/rest/v1/user_roles`, - { user_id: juliaUserId, role: "secretaria" }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${adminToken}`, - "Content-Type": "application/json", - Prefer: "return=representation", - }, - } - ); - console.log("✅ Role adicionada!\n"); - } catch (err) { - if (err.response?.status === 409) { - console.log("⚠️ Role já existe!\n"); - } else { - console.log( - "⚠️ Aviso role:", - err.response?.data?.message || err.message - ); - } - } - - // Testar acesso - console.log("🏥 Testando acesso aos pacientes..."); - const pacientes = await axios.get( - `${SUPABASE_URL}/rest/v1/patients?select=id,full_name,email&limit=3`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${juliaToken}`, - }, - } - ); - console.log(`✅ Acesso OK! (${pacientes.data.length} pacientes)\n`); - - console.log("═══════════════════════════════════════════════════"); - console.log("✅ JULIA CRIADA COM SUCESSO!"); - console.log("═══════════════════════════════════════════════════"); - console.log(""); - console.log("👤 Nome: Julia Carvalho"); - console.log("📧 Email: secretaria.mediconnect@gmail.com"); - console.log("🔑 Senha: secretaria@mediconnect"); - console.log("🎭 Role: secretaria"); - console.log(""); - console.log("🌐 Login: http://localhost:5173/login-secretaria"); - console.log(""); - } catch (error) { - console.error("\n❌ ERRO:", error.response?.data || error.message); - if (error.code === "ENOTFOUND") { - console.log("\n⚠️ Problema de conexão com Supabase"); - console.log("Use a página HTML: criar-julia.html"); - } - } -} - -criarJuliaSecretaria(); diff --git a/MEDICONNECT 2/scripts/criar-julia-sql.sql b/MEDICONNECT 2/scripts/criar-julia-sql.sql deleted file mode 100644 index 12584e809..000000000 --- a/MEDICONNECT 2/scripts/criar-julia-sql.sql +++ /dev/null @@ -1,100 +0,0 @@ --- ============================================================ --- Script SQL para criar usuária Julia Carvalho com role ADMIN --- Execute este script no Supabase Dashboard > SQL Editor --- ============================================================ - --- 1. Criar usuário no auth.users (SUBSTITUA O ID abaixo por um UUID gerado) --- Você pode gerar um UUID em: https://www.uuidgenerator.net/ --- Ou usar: gen_random_uuid() - -INSERT INTO auth.users ( - id, - instance_id, - email, - encrypted_password, - email_confirmed_at, - created_at, - updated_at, - raw_app_meta_data, - raw_user_meta_data, - role, - aud -) -VALUES ( - gen_random_uuid(), -- Gera um UUID automaticamente - '00000000-0000-0000-0000-000000000000', - 'secretaria.mediconnect@gmail.com', - crypt('secretaria@mediconnect', gen_salt('bf')), -- Hash bcrypt da senha - NOW(), - NOW(), - NOW(), - '{"provider": "email", "providers": ["email"]}', - '{"full_name": "Julia Carvalho", "role": "admin"}', - 'authenticated', - 'authenticated' -) -ON CONFLICT (email) DO NOTHING -RETURNING id; - --- 2. Obter o ID do usuário criado (copie este ID para usar nos próximos passos) --- Execute esta query separadamente e copie o resultado: -SELECT id, email, raw_user_meta_data -FROM auth.users -WHERE email = 'secretaria.mediconnect@gmail.com'; - --- 3. Criar perfil na tabela users (SUBSTITUA 'UUID_AQUI' pelo ID obtido acima) -INSERT INTO public.users ( - id, - email, - full_name, - is_admin, - is_secretary, - is_admin_or_manager, - created_at, - updated_at -) -VALUES ( - (SELECT id FROM auth.users WHERE email = 'secretaria.mediconnect@gmail.com'), - 'secretaria.mediconnect@gmail.com', - 'Julia Carvalho', - true, - true, - true, - NOW(), - NOW() -) -ON CONFLICT (id) DO UPDATE SET - is_admin = true, - is_secretary = true, - is_admin_or_manager = true; - --- 4. Adicionar role admin na tabela user_roles -INSERT INTO public.user_roles ( - user_id, - role, - created_at -) -VALUES ( - (SELECT id FROM auth.users WHERE email = 'secretaria.mediconnect@gmail.com'), - 'admin', - NOW() -) -ON CONFLICT (user_id, role) DO NOTHING; - --- 5. Verificar criação -SELECT - u.id, - u.email, - u.full_name, - u.is_admin, - u.is_secretary, - ur.role -FROM public.users u -LEFT JOIN public.user_roles ur ON ur.user_id = u.id -WHERE u.email = 'secretaria.mediconnect@gmail.com'; - --- ============================================================ --- CREDENCIAIS PARA LOGIN: --- Email: secretaria.mediconnect@gmail.com --- Senha: secretaria@mediconnect --- ============================================================ diff --git a/MEDICONNECT 2/scripts/criar-medico-fernando.js b/MEDICONNECT 2/scripts/criar-medico-fernando.js deleted file mode 100644 index d585ba5de..000000000 --- a/MEDICONNECT 2/scripts/criar-medico-fernando.js +++ /dev/null @@ -1,260 +0,0 @@ -/** - * Script para criar médico Fernando Pirichowski - Squad 18 - * Cria usuário auth + registro na tabela doctors + atualiza profile com role - */ - -import axios from "axios"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -// Credenciais do admin para operações autenticadas -const ADMIN_EMAIL = "riseup@popcode.com.br"; -const ADMIN_PASSWORD = "riseup"; - -// Dados do médico Fernando -const FERNANDO_EMAIL = "fernando.pirichowski@souunit.com.br"; -const FERNANDO_PASSWORD = "fernando"; -const FERNANDO_NOME = "Fernando Pirichowski - Squad 18"; - -async function main() { - try { - console.log("🔐 Fazendo login como admin...\n"); - - // 1. Login do admin - const loginResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: ADMIN_EMAIL, - password: ADMIN_PASSWORD, - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - } - ); - - const adminToken = loginResponse.data.access_token; - console.log("✅ Login admin realizado com sucesso!\n"); - - // 2. Verificar se usuário já existe tentando fazer login primeiro - console.log("👤 Verificando se usuário Fernando já existe...\n"); - - let fernandoUserId; - let fernandoToken; - let usuarioJaExiste = false; - - try { - // Tentar login primeiro - const loginFernando = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: FERNANDO_EMAIL, - password: FERNANDO_PASSWORD, - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - } - ); - fernandoUserId = loginFernando.data.user.id; - fernandoToken = loginFernando.data.access_token; - usuarioJaExiste = true; - console.log("✅ Usuário já existe! Login realizado com sucesso."); - console.log(` User ID: ${fernandoUserId}\n`); - } catch (loginError) { - // Se login falhar, tentar criar - console.log(" Usuário não existe, criando novo...\n"); - try { - const signupResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/signup`, - { - email: FERNANDO_EMAIL, - password: FERNANDO_PASSWORD, - data: { - full_name: FERNANDO_NOME, - }, - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - } - ); - - fernandoUserId = signupResponse.data.user?.id || signupResponse.data.id; - fernandoToken = - signupResponse.data.access_token || - signupResponse.data.session?.access_token; - - if (!fernandoUserId) { - throw new Error("Não foi possível obter o User ID do signup"); - } - - console.log("✅ Usuário criado com sucesso!"); - console.log(` User ID: ${fernandoUserId}`); - console.log(` Email: ${FERNANDO_EMAIL}\n`); - } catch (signupError) { - throw signupError; - } - } - - // 3. Criar registro na tabela doctors - console.log("🏥 Criando registro na tabela doctors...\n"); - - const doctorData = { - user_id: fernandoUserId, - full_name: FERNANDO_NOME, - email: FERNANDO_EMAIL, - cpf: "12345678901", // CPF válido para teste - crm: "SQUAD18", - crm_uf: "SE", - specialty: "Clínico Geral", - phone_mobile: "79999999999", - active: true, - }; - - let doctorId; - try { - const doctorResponse = await axios.post( - `${SUPABASE_URL}/rest/v1/doctors`, - doctorData, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${adminToken}`, - "Content-Type": "application/json", - Prefer: "return=representation", - }, - } - ); - - doctorId = Array.isArray(doctorResponse.data) - ? doctorResponse.data[0].id - : doctorResponse.data.id; - - console.log("✅ Médico cadastrado na tabela doctors!"); - console.log(` Doctor ID: ${doctorId}`); - console.log(` Nome: ${FERNANDO_NOME}`); - console.log(` CRM: ${doctorData.crm}-${doctorData.crm_uf}\n`); - } catch (error) { - if (error.response?.data?.message?.includes("duplicate key")) { - console.log("⚠️ Registro de médico já existe na tabela doctors\n"); - // Buscar o ID do médico existente - const existingDoctor = await axios.get( - `${SUPABASE_URL}/rest/v1/doctors?email=eq.${FERNANDO_EMAIL}&select=id`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${adminToken}`, - }, - } - ); - if (existingDoctor.data.length > 0) { - doctorId = existingDoctor.data[0].id; - console.log(` Doctor ID existente: ${doctorId}\n`); - } - } else { - throw error; - } - } - - // 4. Atualizar profile com role 'medico' - console.log('🔧 Atualizando profile com role "medico"...\n'); - - try { - await axios.patch( - `${SUPABASE_URL}/rest/v1/profiles?id=eq.${fernandoUserId}`, - { - role: "medico", - full_name: FERNANDO_NOME, - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${adminToken}`, - "Content-Type": "application/json", - Prefer: "return=representation", - }, - } - ); - console.log('✅ Profile atualizado com role "medico"!\n'); - } catch (error) { - console.log( - "⚠️ Erro ao atualizar profile:", - error.response?.data?.message || error.message - ); - console.log(" (Profile pode ter sido criado automaticamente)\n"); - } - - // 5. Verificar criação - console.log("🔍 VERIFICANDO CADASTRO COMPLETO:\n"); - - const verificarDoctor = await axios.get( - `${SUPABASE_URL}/rest/v1/doctors?user_id=eq.${fernandoUserId}&select=*`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${adminToken}`, - }, - } - ); - - const verificarProfile = await axios.get( - `${SUPABASE_URL}/rest/v1/profiles?id=eq.${fernandoUserId}&select=*`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${adminToken}`, - }, - } - ); - - console.log("✅ MÉDICO FERNANDO CRIADO COM SUCESSO!\n"); - console.log("📋 Detalhes do cadastro:\n"); - console.log("Auth User:"); - console.log(` - ID: ${fernandoUserId}`); - console.log(` - Email: ${FERNANDO_EMAIL}`); - console.log(` - Senha: ${FERNANDO_PASSWORD}\n`); - - if (verificarDoctor.data.length > 0) { - console.log("Tabela Doctors:"); - console.log(` - ID: ${verificarDoctor.data[0].id}`); - console.log(` - Nome: ${verificarDoctor.data[0].full_name}`); - console.log( - ` - CRM: ${verificarDoctor.data[0].crm}-${verificarDoctor.data[0].crm_uf}` - ); - console.log(` - Especialidade: ${verificarDoctor.data[0].specialty}`); - console.log( - ` - Ativo: ${verificarDoctor.data[0].active ? "Sim" : "Não"}\n` - ); - } - - if (verificarProfile.data.length > 0) { - console.log("Tabela Profiles:"); - console.log(` - User ID: ${verificarProfile.data[0].id}`); - console.log(` - Nome: ${verificarProfile.data[0].full_name}`); - console.log( - ` - Role: ${verificarProfile.data[0].role || "não definida"}\n` - ); - } - - console.log("🎉 Agora você pode fazer login com:"); - console.log(` Email: ${FERNANDO_EMAIL}`); - console.log(` Senha: ${FERNANDO_PASSWORD}\n`); - } catch (error) { - console.error("❌ Erro:", error.response?.data || error.message); - if (error.response) { - console.error("Status:", error.response.status); - console.error("Data:", JSON.stringify(error.response.data, null, 2)); - } - } -} - -main(); diff --git a/MEDICONNECT 2/scripts/criar-secretaria.js b/MEDICONNECT 2/scripts/criar-secretaria.js deleted file mode 100644 index dae40e7dd..000000000 --- a/MEDICONNECT 2/scripts/criar-secretaria.js +++ /dev/null @@ -1,107 +0,0 @@ -import fetch from "node-fetch"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -console.log("\n👩‍💼 CRIAR USUÁRIO SECRETÁRIA\n"); - -async function criarSecretaria() { - // Dados da secretária - const secretariaData = { - email: "secretaria@mediconnect.com", - password: "secretaria123", - nome: "Maria Secretária", - telefone: "79999998888", - cpf: "11111111111", - }; - - console.log("📝 Criando secretária..."); - console.log(` Email: ${secretariaData.email}`); - console.log(` Senha: ${secretariaData.password}`); - console.log(` Nome: ${secretariaData.nome}\n`); - - try { - // PASSO 1: Criar usuário no auth - console.log("🔐 Criando usuário de autenticação...\n"); - - const signupResponse = await fetch(`${SUPABASE_URL}/auth/v1/signup`, { - method: "POST", - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email: secretariaData.email, - password: secretariaData.password, - data: { - full_name: secretariaData.nome, - phone: secretariaData.telefone, - cpf: secretariaData.cpf, - role: "secretaria", - }, - }), - }); - - if (!signupResponse.ok) { - const error = await signupResponse.text(); - console.log("❌ Erro ao criar usuário:", signupResponse.status); - console.log(error); - return; - } - - const signupData = await signupResponse.json(); - const userId = signupData.user?.id; - const accessToken = signupData.access_token; - - console.log("✅ Usuário criado com sucesso!"); - console.log(` User ID: ${userId}`); - console.log(` Token: ${accessToken?.substring(0, 50)}...\n`); - - // PASSO 2: Criar perfil na tabela profiles (se existir) - console.log("📋 Criando perfil...\n"); - - const profileResponse = await fetch(`${SUPABASE_URL}/rest/v1/profiles`, { - method: "POST", - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${accessToken}`, - "Content-Type": "application/json", - Prefer: "return=representation", - }, - body: JSON.stringify({ - id: userId, - full_name: secretariaData.nome, - email: secretariaData.email, - phone: secretariaData.telefone, - role: "secretaria", - }), - }); - - if (profileResponse.ok || profileResponse.status === 201) { - console.log("✅ Perfil criado com sucesso!\n"); - } else if (profileResponse.status === 409) { - console.log("⚠️ Perfil já existe (isso é normal)\n"); - } else { - const error = await profileResponse.text(); - console.log("⚠️ Aviso ao criar perfil:", profileResponse.status); - console.log(error); - console.log( - "(Isso pode ser normal se a tabela profiles não existir ou tiver trigger)\n" - ); - } - - // PASSO 3: Verificar se foi criado - console.log("📊 RESUMO:\n"); - console.log("✅ Secretária criada com sucesso!"); - console.log("\n📝 Credenciais para login:"); - console.log(` Email: ${secretariaData.email}`); - console.log(` Senha: ${secretariaData.password}`); - console.log("\n🔗 Acesse: http://localhost:5173/secretaria"); - console.log("\n"); - } catch (error) { - console.error("❌ Erro:", error.message); - } -} - -criarSecretaria(); diff --git a/MEDICONNECT 2/scripts/criar-usuario-guilherme.js b/MEDICONNECT 2/scripts/criar-usuario-guilherme.js deleted file mode 100644 index ef3e51b0a..000000000 --- a/MEDICONNECT 2/scripts/criar-usuario-guilherme.js +++ /dev/null @@ -1,266 +0,0 @@ -/** - * Script para criar usuário com role "user" para o paciente Guilherme - * e configurar consultas de demonstração - */ - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -// Admin credentials -const ADMIN_EMAIL = "riseup@popcode.com.br"; -const ADMIN_PASSWORD = "riseup"; - -// Guilherme dados -const GUILHERME_ID = "864b1785-461f-4e92-8b74-2a6f17c58a80"; -const GUILHERME_EMAIL = "guilherme@paciente.com"; -const GUILHERME_PASSWORD = "guilherme123"; -const GUILHERME_NOME = "Guilherme Silva Gomes - SQUAD 18"; - -// Fernando dados -const FERNANDO_USER_ID = "be1e3cba-534e-48c3-9590-b7e55861cade"; -const FERNANDO_NOME = "Fernando Pirichowski - Squad 18"; - -async function criarUsuarioGuilherme() { - try { - console.log("\n🔐 === CRIAR USUÁRIO GUILHERME COM ROLE USER ===\n"); - - // 1. Login como admin - console.log("1️⃣ Fazendo login como admin..."); - const loginResponse = await fetch( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - }, - body: JSON.stringify({ - email: ADMIN_EMAIL, - password: ADMIN_PASSWORD, - }), - } - ); - - if (!loginResponse.ok) { - throw new Error(`Erro no login: ${loginResponse.status}`); - } - - const loginData = await loginResponse.json(); - const adminToken = loginData.access_token; - console.log("✅ Login admin realizado com sucesso!\n"); - - // 2. Verificar se usuário Guilherme já existe - console.log("2️⃣ Verificando se usuário Guilherme já existe..."); - - try { - const loginGuilherme = await fetch( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - }, - body: JSON.stringify({ - email: GUILHERME_EMAIL, - password: GUILHERME_PASSWORD, - }), - } - ); - - if (loginGuilherme.ok) { - const guilhermeData = await loginGuilherme.json(); - console.log("✅ Usuário Guilherme já existe!"); - console.log(` User ID: ${guilhermeData.user.id}`); - console.log(` Email: ${guilhermeData.user.email}\n`); - return guilhermeData.user.id; - } - } catch (error) { - console.log("ℹ️ Usuário não existe, criando...\n"); - } - - // 3. Criar usuário Guilherme via Edge Function - console.log("3️⃣ Criando usuário Guilherme..."); - console.log(` Email: ${GUILHERME_EMAIL}`); - console.log(` Senha: ${GUILHERME_PASSWORD}`); - console.log(` Role: user\n`); - - const createUserResponse = await fetch( - `${SUPABASE_URL}/functions/v1/create-user`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${adminToken}`, - apikey: SUPABASE_ANON_KEY, - }, - body: JSON.stringify({ - email: GUILHERME_EMAIL, - password: GUILHERME_PASSWORD, - full_name: GUILHERME_NOME, - role: "user", // Role "user" para paciente - }), - } - ); - - const createUserData = await createUserResponse.json(); - - if (!createUserResponse.ok) { - console.error("❌ Erro ao criar usuário:", createUserData); - throw new Error(JSON.stringify(createUserData)); - } - - console.log( - " Resposta da criação:", - JSON.stringify(createUserData, null, 2) - ); - - const guilhermeUserId = - createUserData.user_id || createUserData.id || createUserData.userId; - - if (!guilhermeUserId) { - console.error("❌ User ID não encontrado na resposta!"); - console.error(" Resposta completa:", createUserData); - throw new Error("User ID não retornado pela API"); - } - - console.log("✅ Usuário criado com sucesso!"); - console.log(` User ID: ${guilhermeUserId}\n`); - - // 4. Atribuir paciente ao usuário - console.log("4️⃣ Atribuindo paciente ao usuário..."); - - // Verificar se atribuição já existe - const checkAssignment = await fetch( - `${SUPABASE_URL}/rest/v1/patient_assignments?user_id=eq.${guilhermeUserId}&patient_id=eq.${GUILHERME_ID}`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${adminToken}`, - }, - } - ); - - const existingAssignments = await checkAssignment.json(); - - if (existingAssignments.length > 0) { - console.log("✅ Atribuição já existe!\n"); - } else { - const assignResponse = await fetch( - `${SUPABASE_URL}/rest/v1/patient_assignments`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${adminToken}`, - apikey: SUPABASE_ANON_KEY, - Prefer: "return=representation", - }, - body: JSON.stringify({ - user_id: guilhermeUserId, - patient_id: GUILHERME_ID, - }), - } - ); - - if (!assignResponse.ok) { - const error = await assignResponse.text(); - console.error("❌ Erro ao criar atribuição:", error); - } else { - console.log("✅ Paciente atribuído ao usuário!\n"); - } - } - - // 5. Criar consultas de demonstração - console.log("5️⃣ Criando consultas de demonstração...\n"); - await criarConsultasDemo(); - - console.log("\n✅ === CONFIGURAÇÃO CONCLUÍDA COM SUCESSO! ===\n"); - console.log("📋 INFORMAÇÕES PARA LOGIN:\n"); - console.log(" Email: guilherme@paciente.com"); - console.log(" Senha: guilherme123"); - console.log(" Role: user (acesso ao painel paciente)\n"); - console.log("🔗 Próximos passos:"); - console.log(" 1. Acesse /paciente no navegador"); - console.log(" 2. Faça login com as credenciais acima"); - console.log(" 3. Você verá as consultas no painel do paciente"); - console.log( - " 4. As consultas também aparecerão no painel do médico Fernando" - ); - console.log(" 5. E no painel da secretária\n"); - - return guilhermeUserId; - } catch (error) { - console.error("\n❌ Erro:", error.message); - console.error(error); - process.exit(1); - } -} - -async function criarConsultasDemo() { - const fs = await import("fs"); - const path = await import("path"); - - // Criar arquivo de consultas locais para demonstração - const consultas = [ - { - id: "consulta-demo-001", - pacienteId: GUILHERME_ID, - medicoId: FERNANDO_USER_ID, - pacienteNome: GUILHERME_NOME, - medicoNome: FERNANDO_NOME, - dataHora: "2025-10-05T10:00:00", - status: "agendada", - tipo: "Consulta", - observacoes: "Primeira consulta - Check-up geral", - }, - { - id: "consulta-demo-002", - pacienteId: GUILHERME_ID, - medicoId: FERNANDO_USER_ID, - pacienteNome: GUILHERME_NOME, - medicoNome: FERNANDO_NOME, - dataHora: "2025-09-28T14:30:00", - status: "realizada", - tipo: "Retorno", - observacoes: "Consulta de retorno - Avaliação de exames", - }, - { - id: "consulta-demo-003", - pacienteId: GUILHERME_ID, - medicoId: FERNANDO_USER_ID, - pacienteNome: GUILHERME_NOME, - medicoNome: FERNANDO_NOME, - dataHora: "2025-10-10T09:00:00", - status: "confirmada", - tipo: "Consulta", - observacoes: "Consulta de acompanhamento mensal", - }, - ]; - - // Caminho para a pasta src/data - const dataDir = path.join(process.cwd(), "src", "data"); - - // Criar diretório se não existir - if (!fs.existsSync(dataDir)) { - fs.mkdirSync(dataDir, { recursive: true }); - console.log(" 📁 Diretório src/data criado"); - } - - // Salvar consultas - const consultasPath = path.join(dataDir, "consultas-demo.json"); - fs.writeFileSync(consultasPath, JSON.stringify(consultas, null, 2)); - console.log(" ✅ Consultas salvas em src/data/consultas-demo.json"); - console.log(` 📊 ${consultas.length} consultas criadas\n`); - - // Também salvar no localStorage (simulado) - console.log(" 💡 Para usar as consultas:"); - console.log(" - Importe de src/data/consultas-demo.json"); - console.log( - " - Ou use localStorage.setItem('consultas_local', JSON.stringify(consultas))" - ); -} - -// Executar -criarUsuarioGuilherme(); diff --git a/MEDICONNECT 2/scripts/criar-usuario-julia.js b/MEDICONNECT 2/scripts/criar-usuario-julia.js deleted file mode 100644 index 8f22cdd98..000000000 --- a/MEDICONNECT 2/scripts/criar-usuario-julia.js +++ /dev/null @@ -1,158 +0,0 @@ -import axios from "axios"; - -const SUPABASE_URL = "https://rjzjnbzjsdxgidxvmsmx.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InJqempuYnpqc2R4Z2lkeHZtc214Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDUwNzIyNzYsImV4cCI6MjA2MDY0ODI3Nn0.S6xtAkEZZq5W2qjSFu9xoTQCrJ8VJpIoRiDn65gvZNM"; - -async function criarUsuarioJulia() { - try { - console.log("📝 Criando usuária Julia Carvalho...\n"); - - // 1. Criar usuário no Supabase Auth - console.log("🔐 Criando usuário na autenticação..."); - - const signupResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/signup`, - { - email: "secretaria.mediconnect@gmail.com", - password: "secretaria@mediconnect", - data: { - full_name: "Julia Carvalho", - role: "admin", - }, - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - } - ); - - const userId = signupResponse.data.user?.id; - const accessToken = signupResponse.data.access_token; - - if (!userId) { - throw new Error("Não foi possível obter o ID do usuário criado"); - } - - console.log(`✅ Usuário criado com sucesso!`); - console.log(` ID: ${userId}`); - console.log(` Email: secretaria.mediconnect@gmail.com\n`); - - // 2. Criar perfil do usuário na tabela users - console.log("👤 Criando perfil na tabela users..."); - - const userResponse = await axios.post( - `${SUPABASE_URL}/rest/v1/users`, - { - id: userId, - email: "secretaria.mediconnect@gmail.com", - full_name: "Julia Carvalho", - is_admin: true, - is_secretary: true, - is_admin_or_manager: true, - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${accessToken}`, - "Content-Type": "application/json", - Prefer: "return=representation", - }, - } - ); - - console.log("✅ Perfil criado com sucesso!\n"); - - // 3. Adicionar role na tabela user_roles - console.log("🎭 Adicionando role admin..."); - - const roleResponse = await axios.post( - `${SUPABASE_URL}/rest/v1/user_roles`, - { - user_id: userId, - role: "admin", - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${accessToken}`, - "Content-Type": "application/json", - Prefer: "return=representation", - }, - } - ); - - console.log("✅ Role admin adicionada com sucesso!\n"); - - // 4. Testar login - console.log("🔑 Testando login..."); - - const loginResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: "secretaria.mediconnect@gmail.com", - password: "secretaria@mediconnect", - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - } - ); - - console.log("✅ Login realizado com sucesso!\n"); - - // 5. Verificar permissões de acesso aos pacientes - console.log("🏥 Verificando acesso aos pacientes..."); - - const pacientesResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/patients?select=id,full_name,email&limit=5`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${loginResponse.data.access_token}`, - }, - } - ); - - console.log( - `✅ Acesso aos pacientes OK! (${pacientesResponse.data.length} pacientes encontrados)\n` - ); - - if (pacientesResponse.data.length > 0) { - console.log("📋 Primeiros pacientes:"); - pacientesResponse.data.forEach((p) => { - console.log(` • ${p.full_name} - ${p.email}`); - }); - console.log(""); - } - - console.log("═══════════════════════════════════════════════════"); - console.log("✅ USUÁRIA JULIA CARVALHO CRIADA COM SUCESSO!"); - console.log("═══════════════════════════════════════════════════"); - console.log(""); - console.log("📧 Email: secretaria.mediconnect@gmail.com"); - console.log("🔑 Senha: secretaria@mediconnect"); - console.log("👤 Nome: Julia Carvalho"); - console.log("🎭 Role: admin (permissões completas)"); - console.log(""); - console.log("🌐 Login em: http://localhost:5173/login-secretaria"); - console.log(""); - } catch (error) { - console.error( - "❌ Erro ao criar usuária:", - error.response?.data || error.message - ); - - if (error.response?.data?.code === "23505") { - console.log("\n⚠️ Usuária já existe! Tente fazer login com:"); - console.log(" Email: secretaria.mediconnect@gmail.com"); - console.log(" Senha: secretaria@mediconnect"); - } - } -} - -criarUsuarioJulia(); diff --git a/MEDICONNECT 2/scripts/deletar-usuarios-admin.js b/MEDICONNECT 2/scripts/deletar-usuarios-admin.js deleted file mode 100644 index 1132d68a8..000000000 --- a/MEDICONNECT 2/scripts/deletar-usuarios-admin.js +++ /dev/null @@ -1,159 +0,0 @@ -import fetch from "node-fetch"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -// Credenciais de admin -const ADMIN_EMAIL = "riseup@popcode.com.br"; -const ADMIN_PASSWORD = "riseup"; - -console.log("\n🗑️ DELETAR USUÁRIOS DE TESTE COM ADMIN\n"); - -async function deletarUsuariosTeste() { - // PASSO 1: Fazer login como admin - console.log("🔐 Fazendo login como admin...\n"); - - try { - const loginResponse = await fetch( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - method: "POST", - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email: ADMIN_EMAIL, - password: ADMIN_PASSWORD, - }), - } - ); - - if (!loginResponse.ok) { - console.log("❌ Login falhou:", loginResponse.status); - return; - } - - const loginData = await loginResponse.json(); - const adminToken = loginData.access_token; - console.log("✅ Login admin bem-sucedido!\n"); - - // PASSO 2: Buscar pacientes de teste - console.log('📋 Buscando pacientes de teste (email contém "teste")...\n'); - - const pacientesResponse = await fetch( - `${SUPABASE_URL}/rest/v1/patients?email=ilike.*teste*&select=id,full_name,email`, - { - method: "GET", - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${adminToken}`, - "Content-Type": "application/json", - }, - } - ); - - if (!pacientesResponse.ok) { - console.log("❌ Erro ao buscar pacientes:", pacientesResponse.status); - const error = await pacientesResponse.text(); - console.log(error); - return; - } - - const pacientes = await pacientesResponse.json(); - console.log(`Encontrados ${pacientes.length} paciente(s) de teste:\n`); - - if (pacientes.length > 0) { - pacientes.forEach((p, index) => { - console.log(`${index + 1}. ${p.full_name || "Sem nome"}`); - console.log(` Email: ${p.email}`); - console.log(` ID: ${p.id}\n`); - }); - - // PASSO 3: Deletar pacientes de teste - console.log("🗑️ Deletando pacientes de teste...\n"); - - for (const paciente of pacientes) { - try { - const deleteResponse = await fetch( - `${SUPABASE_URL}/rest/v1/patients?id=eq.${paciente.id}`, - { - method: "DELETE", - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${adminToken}`, - "Content-Type": "application/json", - }, - } - ); - - if (deleteResponse.ok || deleteResponse.status === 204) { - console.log(`✅ Deletado: ${paciente.email}`); - } else { - console.log( - `❌ Erro ao deletar ${paciente.email}:`, - deleteResponse.status - ); - const error = await deleteResponse.text(); - console.log(error); - } - } catch (error) { - console.log(`❌ Erro ao deletar ${paciente.email}:`, error.message); - } - } - } else { - console.log("✅ Nenhum paciente de teste encontrado!\n"); - } - - // PASSO 4: Tentar deletar usuários de auth (pode não funcionar sem service_role) - console.log("\n📋 Tentando deletar usuários do auth.users...\n"); - console.log( - "⚠️ NOTA: A API pública normalmente NÃO permite deletar usuários." - ); - console.log(" Isso requer service_role key ou acesso ao Dashboard.\n"); - - const emailsParaDeletar = [ - "testefinal@gmail.com", - "teste1759356178698@gmail.com", - "pacienteteste", - ]; - - console.log("Emails que deveriam ser deletados manualmente no Dashboard:"); - emailsParaDeletar.forEach((email) => { - console.log(` - ${email}`); - }); - - console.log("\n💡 Para deletar usuários do auth.users:"); - console.log( - " 1. Acesse: https://app.supabase.com/project/yuanqfswhberkoevtmfr/auth/users" - ); - console.log(" 2. Busque pelos emails acima"); - console.log(" 3. Clique nos 3 pontos → Delete user\n"); - - // Verificar resultado - console.log("\n📊 VERIFICANDO RESULTADO...\n"); - - const verificarResponse = await fetch( - `${SUPABASE_URL}/rest/v1/patients?email=ilike.*teste*&select=count`, - { - method: "GET", - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${adminToken}`, - "Content-Type": "application/json", - Prefer: "count=exact", - }, - } - ); - - if (verificarResponse.ok) { - const countHeader = verificarResponse.headers.get("content-range"); - console.log(`✅ Pacientes de teste restantes: ${countHeader || "0"}\n`); - } - } catch (error) { - console.error("❌ Erro:", error.message); - } -} - -deletarUsuariosTeste(); diff --git a/MEDICONNECT 2/scripts/deletar-usuarios-teste.js b/MEDICONNECT 2/scripts/deletar-usuarios-teste.js deleted file mode 100644 index 8d2725301..000000000 --- a/MEDICONNECT 2/scripts/deletar-usuarios-teste.js +++ /dev/null @@ -1,77 +0,0 @@ -import fetch from "node-fetch"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -console.log("\n🗑️ DELETAR USUÁRIOS DE TESTE\n"); -console.log( - "❌ ATENÇÃO: A API pública do Supabase não permite deletar usuários!" -); -console.log(""); -console.log("Para deletar usuários de teste, você precisa:"); -console.log(""); -console.log("1️⃣ Acessar o Dashboard do Supabase:"); -console.log( - " https://app.supabase.com/project/yuanqfswhberkoevtmfr/auth/users" -); -console.log(""); -console.log('2️⃣ Na aba "Authentication" → "Users"'); -console.log(""); -console.log("3️⃣ Buscar pelos usuários de teste e deletar manualmente:"); -console.log(' - Emails com "pacienteteste" ou "teste"'); -console.log(" - testefinal@gmail.com"); -console.log(" - teste1759356178698@gmail.com"); -console.log(""); -console.log("📋 Listando usuários de teste nos registros de pacientes...\n"); - -async function listarPacientesTeste() { - try { - const response = await fetch( - `${SUPABASE_URL}/rest/v1/patients?select=id,full_name,email&email=ilike.*teste*`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - } - ); - - if (response.ok) { - const pacientes = await response.json(); - - if (pacientes.length === 0) { - console.log( - "✅ Nenhum paciente de teste encontrado na tabela patients\n" - ); - } else { - console.log( - `📊 ${pacientes.length} paciente(s) de teste encontrado(s):\n` - ); - pacientes.forEach((p, index) => { - console.log(`${index + 1}. ${p.full_name || "Sem nome"}`); - console.log(` Email: ${p.email}`); - console.log(` ID: ${p.id}\n`); - }); - - console.log( - "ℹ️ Para deletar esses registros de pacientes, você pode:" - ); - console.log( - ' - Deletar via Dashboard do Supabase na tabela "patients"' - ); - console.log( - " - Ou criar um Edge Function com permissões de service_role\n" - ); - } - } else { - console.log("❌ Erro ao listar pacientes:", response.status); - const error = await response.text(); - console.log(error); - } - } catch (error) { - console.error("❌ Erro:", error.message); - } -} - -listarPacientesTeste(); diff --git a/MEDICONNECT 2/scripts/diagnose-login.ts b/MEDICONNECT 2/scripts/diagnose-login.ts deleted file mode 100644 index 46f19b5b1..000000000 --- a/MEDICONNECT 2/scripts/diagnose-login.ts +++ /dev/null @@ -1,77 +0,0 @@ -// Script diagnóstico para testar login Supabase password grant -// Executar com: npx ts-node scripts/diagnose-login.ts (ou adicionar script no package.json) - -// Node 18+ possui fetch nativo; sem dependência externa -// Declaração mínima para evitar erro de tipos sem adicionar @types/node -// eslint-disable-next-line @typescript-eslint/no-explicit-any -declare const process: any | undefined; - -const SUPABASE_URL = - (typeof process !== "undefined" && process.env.VITE_SUPABASE_URL) || - "https://yuanqfswhberkoevtmfr.supabase.co"; -const ANON_KEY = - (typeof process !== "undefined" && process.env.VITE_SUPABASE_ANON_KEY) || - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -// Credenciais admin de desenvolvimento (fornecidas) -const EMAIL = - (typeof process !== "undefined" && process.env.TEST_ADMIN_EMAIL) || - "riseup@popcode.com.br"; -const PASSWORD = - (typeof process !== "undefined" && process.env.TEST_ADMIN_PASSWORD) || - "riseup"; - -async function attemptLogin() { - const url = `${SUPABASE_URL}/auth/v1/token?grant_type=password`; - const body = { email: EMAIL, password: PASSWORD }; - try { - const res = await fetch(url, { - method: "POST", - headers: { - "Content-Type": "application/json", - apikey: ANON_KEY, - Authorization: `Bearer ${ANON_KEY}`, - }, - body: JSON.stringify(body), - }); - const text = await res.text(); - let parsed: unknown = null; - try { - parsed = JSON.parse(text); - } catch { - /* plain text */ - } - console.log("STATUS", res.status); - console.log("RAW", text); - if ( - res.ok && - typeof parsed === "object" && - parsed && - "access_token" in parsed - ) { - const token = (parsed as { access_token: string }).access_token; - console.log("LOGIN OK: access_token prefix", token.slice(0, 20)); - return true; - } - // Erro comum: user not confirmed / invalid login - if (parsed && typeof parsed === "object") { - const p = parsed as Record; - if (p.error) console.log("ERROR CODE:", p.error); - if (p.msg) console.log("MSG:", p.msg); - } - if (/email/i.test(text) && /confirm/i.test(text)) { - console.log( - "Possível conta não confirmada. Verifique no painel Supabase se o email foi confirmado." - ); - } - return false; - } catch (e) { - console.error("Falha inesperada:", e); - return false; - } -} - -(async () => { - const ok = await attemptLogin(); - if (!ok && typeof process !== "undefined") process.exit(1); -})(); diff --git a/MEDICONNECT 2/scripts/diagnosticar-listagem.js b/MEDICONNECT 2/scripts/diagnosticar-listagem.js deleted file mode 100644 index f634a03e3..000000000 --- a/MEDICONNECT 2/scripts/diagnosticar-listagem.js +++ /dev/null @@ -1,82 +0,0 @@ -import fetch from "node-fetch"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -console.log("\n🔍 DIAGNOSTICANDO PROBLEMAS DE LISTAGEM\n"); - -async function testarEndpoint(nome, url) { - console.log(`\n📋 Testando ${nome}: ${url}`); - console.log("─".repeat(60)); - - try { - const response = await fetch(url, { - method: "GET", - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - Authorization: `Bearer ${SUPABASE_ANON_KEY}`, - }, - }); - - console.log(`Status: ${response.status} ${response.statusText}`); - - if (response.ok) { - const data = await response.json(); - const count = Array.isArray(data) ? data.length : "Não é array"; - console.log(`✅ SUCESSO - Registros: ${count}`); - - if (Array.isArray(data) && data.length > 0) { - console.log("\n📄 Primeiro registro:"); - console.log(JSON.stringify(data[0], null, 2)); - } else if (Array.isArray(data)) { - console.log("⚠️ Array vazio - tabela não tem registros"); - } else { - console.log("📄 Resposta:"); - console.log(JSON.stringify(data, null, 2)); - } - } else { - console.log("❌ ERRO"); - const errorText = await response.text(); - console.log(errorText); - } - } catch (error) { - console.log("❌ ERRO DE CONEXÃO"); - console.error(error.message); - } -} - -async function diagnosticar() { - // Testar pacientes - await testarEndpoint("PATIENTS", `${SUPABASE_URL}/rest/v1/patients?select=*`); - await testarEndpoint( - "PACIENTES (alternativa)", - `${SUPABASE_URL}/rest/v1/pacientes?select=*` - ); - - // Testar médicos - await testarEndpoint("DOCTORS", `${SUPABASE_URL}/rest/v1/doctors?select=*`); - await testarEndpoint( - "MEDICOS (alternativa)", - `${SUPABASE_URL}/rest/v1/medicos?select=*` - ); - - // Testar profiles - await testarEndpoint("PROFILES", `${SUPABASE_URL}/rest/v1/profiles?select=*`); - - console.log("\n\n📊 RESUMO DO DIAGNÓSTICO"); - console.log("═".repeat(60)); - console.log("Se alguma tabela retornou 404, ela não existe no Supabase."); - console.log( - "Se retornou 200 mas array vazio, a tabela existe mas não tem dados." - ); - console.log("Se retornou 401/403, há problema de permissões (RLS)."); - console.log("\n💡 PRÓXIMOS PASSOS:"); - console.log("1. Verifique quais tabelas existem no Supabase Dashboard"); - console.log("2. Se necessário, crie as tabelas doctors/patients"); - console.log("3. Configure as políticas RLS para permitir SELECT público"); - console.log("4. Insira dados de teste nas tabelas\n"); -} - -diagnosticar(); diff --git a/MEDICONNECT 2/scripts/listar-pacientes-simples.js b/MEDICONNECT 2/scripts/listar-pacientes-simples.js deleted file mode 100644 index 87668f631..000000000 --- a/MEDICONNECT 2/scripts/listar-pacientes-simples.js +++ /dev/null @@ -1,32 +0,0 @@ -import axios from "axios"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -async function listarPacientes() { - try { - const response = await axios.get( - `${SUPABASE_URL}/rest/v1/patients?select=id,full_name,email,cpf&limit=10`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - }, - } - ); - - console.log("📋 Pacientes cadastrados:\n"); - if (response.data.length === 0) { - console.log("❌ Nenhum paciente encontrado!"); - } else { - response.data.forEach((p) => { - console.log(`• ${p.full_name} - ${p.email} - CPF: ${p.cpf}`); - console.log(` ID: ${p.id}\n`); - }); - } - } catch (error) { - console.error("❌ Erro:", error.response?.data || error.message); - } -} - -listarPacientes(); diff --git a/MEDICONNECT 2/scripts/listar-usuarios.js b/MEDICONNECT 2/scripts/listar-usuarios.js deleted file mode 100644 index 951a5bc04..000000000 --- a/MEDICONNECT 2/scripts/listar-usuarios.js +++ /dev/null @@ -1,146 +0,0 @@ -/** - * Script para listar todos os usuários do sistema - * Lista informações de auth.users, doctors e patients - */ - -import axios from "axios"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -// Credenciais do admin -const ADMIN_EMAIL = "riseup@popcode.com.br"; -const ADMIN_PASSWORD = "riseup"; - -async function main() { - try { - console.log("🔐 Fazendo login como admin...\n"); - - // 1. Login do admin - const loginResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: ADMIN_EMAIL, - password: ADMIN_PASSWORD, - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - } - ); - - const token = loginResponse.data.access_token; - const userId = loginResponse.data.user.id; - console.log("✅ Login realizado com sucesso!"); - console.log(`User ID: ${userId}\n`); - - // 2. Listar todos os médicos - console.log("👨‍⚕️ LISTANDO MÉDICOS:\n"); - const medicosResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/doctors?select=*`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${token}`, - }, - } - ); - - console.log(`Total de médicos: ${medicosResponse.data.length}\n`); - medicosResponse.data.forEach((medico, index) => { - console.log( - `${index + 1}. ${medico.full_name || medico.nome || "Sem nome"}` - ); - console.log(` ID: ${medico.id}`); - console.log(` User ID: ${medico.user_id || "não vinculado"}`); - console.log(` Email: ${medico.email}`); - console.log(` CRM: ${medico.crm} - ${medico.crm_uf || ""}`); - console.log( - ` Especialidade: ${medico.specialty || medico.especialidade}` - ); - console.log(` Ativo: ${medico.active ? "Sim" : "Não"}`); - console.log(""); - }); - - // 3. Listar todos os pacientes - console.log("👥 LISTANDO PACIENTES:\n"); - const pacientesResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/patients?select=*`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${token}`, - }, - } - ); - - console.log(`Total de pacientes: ${pacientesResponse.data.length}\n`); - pacientesResponse.data.forEach((paciente, index) => { - console.log(`${index + 1}. ${paciente.full_name}`); - console.log(` ID: ${paciente.id}`); - console.log(` Email: ${paciente.email}`); - console.log(` CPF: ${paciente.cpf}`); - console.log(` Telefone: ${paciente.phone_mobile}`); - console.log(""); - }); - - // 4. Verificar se existe tabela de roles/profiles - console.log("🔍 VERIFICANDO ESTRUTURA DE ROLES:\n"); - try { - const profilesResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/profiles?select=*`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${token}`, - }, - } - ); - console.log( - `✅ Tabela profiles encontrada com ${profilesResponse.data.length} registros` - ); - console.log("Profiles:"); - profilesResponse.data.forEach((profile) => { - console.log(` - User ID: ${profile.id || profile.user_id}`); - console.log(` Role: ${profile.role || "não definida"}`); - console.log(` Nome: ${profile.full_name || "não definido"}`); - console.log(""); - }); - } catch (error) { - if (error.response?.status === 404) { - console.log("⚠️ Tabela profiles não encontrada ou não acessível"); - console.log( - "💡 Sugestão: Criar tabela profiles com campos: id (uuid), user_id (uuid), role (text), full_name (text)\n" - ); - } else { - console.log( - "❌ Erro ao acessar profiles:", - error.response?.data?.message || error.message - ); - } - } - - // 5. Resumo - console.log("📊 RESUMO:\n"); - console.log(`✅ ${medicosResponse.data.length} médicos cadastrados`); - console.log(`✅ ${pacientesResponse.data.length} pacientes cadastrados`); - - const medicosComUser = medicosResponse.data.filter((m) => m.user_id).length; - console.log(`\n🔗 ${medicosComUser} médicos vinculados a usuários auth`); - console.log( - `⚠️ ${ - medicosResponse.data.length - medicosComUser - } médicos SEM vinculação auth\n` - ); - } catch (error) { - console.error("❌ Erro:", error.response?.data || error.message); - if (error.response) { - console.error("Status:", error.response.status); - } - } -} - -main(); diff --git a/MEDICONNECT 2/scripts/rls-policies.sql b/MEDICONNECT 2/scripts/rls-policies.sql deleted file mode 100644 index 244bac3a7..000000000 --- a/MEDICONNECT 2/scripts/rls-policies.sql +++ /dev/null @@ -1,118 +0,0 @@ --- ========================================= --- POLÍTICAS RLS PARA MEDICONNECT --- ========================================= --- Execute este SQL no SQL Editor do Supabase Dashboard: --- https://app.supabase.com/project/yuanqfswhberkoevtmfr/sql/new - --- ========================================= --- 1. TABELA DOCTORS (Médicos) --- ========================================= - --- Remover políticas antigas se existirem -DROP POLICY IF EXISTS "doctors_select_all" ON doctors; -DROP POLICY IF EXISTS "doctors_insert_authenticated" ON doctors; -DROP POLICY IF EXISTS "doctors_update_authenticated" ON doctors; - --- SELECT: Todos podem ler médicos (necessário para listagens públicas) -CREATE POLICY "doctors_select_all" -ON doctors FOR SELECT -TO public -USING (true); - --- INSERT: Apenas usuários autenticados podem criar médicos -CREATE POLICY "doctors_insert_authenticated" -ON doctors FOR INSERT -TO authenticated -WITH CHECK (true); - --- UPDATE: Apenas usuários autenticados podem atualizar médicos -CREATE POLICY "doctors_update_authenticated" -ON doctors FOR UPDATE -TO authenticated -USING (true) -WITH CHECK (true); - --- DELETE: Apenas usuários autenticados podem deletar médicos -CREATE POLICY "doctors_delete_authenticated" -ON doctors FOR DELETE -TO authenticated -USING (true); - --- ========================================= --- 2. TABELA PATIENTS (Pacientes) --- ========================================= - --- Remover políticas antigas se existirem -DROP POLICY IF EXISTS "patients_select_all" ON patients; -DROP POLICY IF EXISTS "patients_insert_authenticated" ON patients; -DROP POLICY IF EXISTS "patients_update_authenticated" ON patients; -DROP POLICY IF EXISTS "patients_update_own" ON patients; - --- SELECT: Todos podem ler pacientes (necessário para listagens) -CREATE POLICY "patients_select_all" -ON patients FOR SELECT -TO public -USING (true); - --- INSERT: Usuários autenticados podem criar pacientes -CREATE POLICY "patients_insert_authenticated" -ON patients FOR INSERT -TO authenticated -WITH CHECK (true); - --- UPDATE: Usuários autenticados podem atualizar qualquer paciente --- (ideal para secretárias e médicos) -CREATE POLICY "patients_update_authenticated" -ON patients FOR UPDATE -TO authenticated -USING (true) -WITH CHECK (true); - --- DELETE: Apenas usuários autenticados podem deletar -CREATE POLICY "patients_delete_authenticated" -ON patients FOR DELETE -TO authenticated -USING (true); - --- ========================================= --- 3. TABELA PROFILES (Se existir) --- ========================================= - --- SELECT: Todos podem ler profiles -DROP POLICY IF EXISTS "profiles_select_all" ON profiles; -CREATE POLICY "profiles_select_all" -ON profiles FOR SELECT -TO public -USING (true); - --- INSERT: Apenas ao criar próprio perfil -DROP POLICY IF EXISTS "profiles_insert_own" ON profiles; -CREATE POLICY "profiles_insert_own" -ON profiles FOR INSERT -TO authenticated -WITH CHECK (auth.uid() = id); - --- UPDATE: Apenas próprio perfil -DROP POLICY IF EXISTS "profiles_update_own" ON profiles; -CREATE POLICY "profiles_update_own" -ON profiles FOR UPDATE -TO authenticated -USING (auth.uid() = id) -WITH CHECK (auth.uid() = id); - --- ========================================= --- VERIFICAR SE RLS ESTÁ ATIVADO --- ========================================= - -ALTER TABLE doctors ENABLE ROW LEVEL SECURITY; -ALTER TABLE patients ENABLE ROW LEVEL SECURITY; -ALTER TABLE profiles ENABLE ROW LEVEL SECURITY; - --- ========================================= --- RESULTADO ESPERADO --- ========================================= --- Após executar este script: --- ✅ Qualquer um pode LER médicos e pacientes (necessário para UI pública) --- ✅ Apenas usuários AUTENTICADOS podem CRIAR/EDITAR/DELETAR --- ✅ A secretária poderá adicionar médicos e pacientes quando estiver logada --- ✅ O painel mostrará os dados corretamente diff --git a/MEDICONNECT 2/scripts/test-cadastro-e-login.js b/MEDICONNECT 2/scripts/test-cadastro-e-login.js deleted file mode 100644 index 470cec489..000000000 --- a/MEDICONNECT 2/scripts/test-cadastro-e-login.js +++ /dev/null @@ -1,126 +0,0 @@ -import fetch from "node-fetch"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -const timestamp = Date.now(); -const email = `teste${timestamp}@gmail.com`; -const password = "SenhaSegura123!"; - -async function cadastrarUsuario() { - console.log("\n📝 ETAPA 1: Cadastrando novo usuário...\n"); - console.log(`Email: ${email}`); - console.log(`Senha: ${password}\n`); - - try { - const response = await fetch(`${SUPABASE_URL}/auth/v1/signup`, { - method: "POST", - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email: email, - password: password, - data: { - nome: "Teste Login", - telefone: "79999999999", - cpf: "12345678900", - dataNascimento: "1990-01-01", - endereco: JSON.stringify({ - rua: "Rua Teste", - numero: "123", - bairro: "Centro", - cidade: "Aracaju", - estado: "SE", - cep: "49000-000", - }), - }, - }), - }); - - const data = await response.json(); - - if (response.ok) { - console.log("✅ CADASTRO SUCESSO!"); - console.log(`User ID: ${data.user?.id}`); - console.log(`Email: ${data.user?.email}`); - console.log( - `Email confirmado: ${data.user?.email_confirmed_at ? "SIM" : "NÃO"}` - ); - return data; - } else { - console.log("❌ CADASTRO FALHOU"); - console.log(JSON.stringify(data, null, 2)); - return null; - } - } catch (error) { - console.error("❌ Erro no cadastro:", error.message); - return null; - } -} - -async function fazerLogin() { - console.log("\n\n🔐 ETAPA 2: Fazendo login com o usuário cadastrado...\n"); - console.log(`Email: ${email}`); - console.log(`Senha: ${password}\n`); - - try { - const response = await fetch( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - method: "POST", - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email: email, - password: password, - }), - } - ); - - const data = await response.json(); - - console.log(`Status: ${response.status}\n`); - - if (response.ok) { - console.log("✅ LOGIN SUCESSO!"); - console.log(`\nToken JWT: ${data.access_token?.substring(0, 50)}...`); - console.log(`User ID: ${data.user?.id}`); - console.log(`Email: ${data.user?.email}`); - console.log( - `Email confirmado: ${data.user?.email_confirmed_at ? "SIM" : "NÃO"}` - ); - console.log( - "\n✅ CONCLUSÃO: Sistema funcionando 100%! Login imediato após cadastro.\n" - ); - } else { - console.log("❌ LOGIN FALHOU"); - console.log("\nResposta completa:"); - console.log(JSON.stringify(data, null, 2)); - } - } catch (error) { - console.error("❌ Erro ao fazer login:", error.message); - } -} - -async function testarFluxoCompleto() { - const cadastroResult = await cadastrarUsuario(); - - if (cadastroResult) { - // Aguardar 2 segundos para garantir que o usuário está no banco - console.log("\n⏳ Aguardando 2 segundos..."); - await new Promise((resolve) => setTimeout(resolve, 2000)); - - await fazerLogin(); - } else { - console.log( - "\n❌ Não foi possível prosseguir com o login porque o cadastro falhou." - ); - } -} - -testarFluxoCompleto(); diff --git a/MEDICONNECT 2/scripts/test-cadastro-paciente-completo.js b/MEDICONNECT 2/scripts/test-cadastro-paciente-completo.js deleted file mode 100644 index ec8c4b388..000000000 --- a/MEDICONNECT 2/scripts/test-cadastro-paciente-completo.js +++ /dev/null @@ -1,338 +0,0 @@ -/** - * Script de teste: Cadastro completo de paciente - * Verifica se: - * 1. Paciente é cadastrado via signup - * 2. Usuário é criado automaticamente no Supabase Auth - * 3. Registro do paciente é criado na tabela patients - */ - -import fetch from "node-fetch"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -// Gerar dados únicos para o teste -const timestamp = Date.now(); -const testEmail = `pacienteteste${timestamp}@gmail.com`; -const testPassword = "TestePaciente123!"; - -console.log("\n🧪 TESTE DE CADASTRO COMPLETO DE PACIENTE\n"); -console.log("=".repeat(60)); -console.log(`Email de teste: ${testEmail}`); -console.log(`Senha: ${testPassword}`); -console.log("=".repeat(60)); - -async function signupPaciente() { - console.log("\n📝 ETAPA 1: Cadastrar paciente via /auth/v1/signup..."); - - const signupData = { - email: testEmail, - password: testPassword, - options: { - data: { - role: "paciente", - full_name: "Paciente Teste Automático", - cpf: "12345678901", - telefone: "11999999999", - data_nascimento: "1990-01-01", - endereco: { - rua: "Rua de Teste", - numero: "123", - bairro: "Centro", - cidade: "São Paulo", - estado: "SP", - cep: "01000-000", - }, - }, - }, - }; - - try { - const response = await fetch(`${SUPABASE_URL}/auth/v1/signup`, { - method: "POST", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - }, - body: JSON.stringify(signupData), - }); - - const data = await response.json(); - - if (!response.ok) { - console.error("❌ Erro no signup:", data); - return null; - } - - console.log("✅ Signup bem-sucedido!"); - console.log(" User ID:", data.id); - console.log(" Email:", data.email); - - return data; - } catch (error) { - console.error("❌ Erro na requisição de signup:", error.message); - return null; - } -} - -async function createPatient(userId) { - console.log("\n📝 ETAPA 2: Criar registro na tabela patients..."); - console.log( - " ℹ️ Nota: Removendo user_id do payload (não existe na tabela)" - ); - - const patientData = { - full_name: "Paciente Teste Automático", - cpf: "12345678901", - email: testEmail, - phone_mobile: "11999999999", - birth_date: "1990-01-01", - street: "Rua de Teste", - number: "123", - neighborhood: "Centro", - city: "São Paulo", - state: "SP", - cep: "01000-000", - }; - - try { - const response = await fetch(`${SUPABASE_URL}/rest/v1/patients`, { - method: "POST", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${SUPABASE_ANON_KEY}`, - Prefer: "return=representation", - }, - body: JSON.stringify(patientData), - }); - - const data = await response.json(); - - if (!response.ok) { - console.error("❌ Erro ao criar patient:", data); - console.log( - " ℹ️ Isso é normal - a tabela pode ter estrutura diferente" - ); - return null; - } - - console.log("✅ Registro do paciente criado!"); - console.log(" Patient ID:", data[0]?.id || data.id); - console.log(" Nome:", data[0]?.full_name || data.full_name); - - return data; - } catch (error) { - console.error( - "❌ Erro na requisição de criação do patient:", - error.message - ); - return null; - } -} - -async function loginPaciente() { - console.log("\n🔐 ETAPA 3: Fazer login com o paciente criado..."); - - const loginData = { - email: testEmail, - password: testPassword, - }; - - try { - const response = await fetch( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - }, - body: JSON.stringify(loginData), - } - ); - - const data = await response.json(); - - if (!response.ok) { - console.error("❌ Erro no login:", data); - if (data.error_code === "email_not_confirmed") { - console.log( - " ℹ️ Email não confirmado - isso é configuração do Supabase" - ); - console.log( - " ℹ️ Para produção, configure SMTP ou desabilite confirmação" - ); - } - return null; - } - - console.log("✅ Login bem-sucedido!"); - console.log(" Access Token:", data.access_token.substring(0, 30) + "..."); - console.log(" Token Type:", data.token_type); - - return data; - } catch (error) { - console.error("❌ Erro na requisição de login:", error.message); - return null; - } -} - -async function getUserInfo(accessToken) { - console.log("\n👤 ETAPA 4: Buscar informações do usuário autenticado..."); - - try { - const response = await fetch(`${SUPABASE_URL}/auth/v1/user`, { - method: "GET", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${accessToken}`, - }, - }); - - const data = await response.json(); - - if (!response.ok) { - console.error("❌ Erro ao buscar user info:", data); - return null; - } - - console.log("✅ Informações do usuário obtidas!"); - console.log(" ID:", data.id); - console.log(" Email:", data.email); - console.log(" Role:", data.user_metadata?.role); - console.log(" Nome:", data.user_metadata?.full_name); - - return data; - } catch (error) { - console.error("❌ Erro na requisição de user info:", error.message); - return null; - } -} - -async function listPatients(accessToken) { - console.log("\n📋 ETAPA 5: Verificar se paciente aparece na lista..."); - - try { - const response = await fetch( - `${SUPABASE_URL}/rest/v1/patients?email=eq.${testEmail}`, - { - method: "GET", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${accessToken}`, - }, - } - ); - - const data = await response.json(); - - if (!response.ok) { - console.error("❌ Erro ao listar patients:", data); - return null; - } - - if (data.length === 0) { - console.log("⚠️ Paciente não encontrado na lista!"); - return null; - } - - console.log("✅ Paciente encontrado na lista!"); - console.log(" Total de registros:", data.length); - console.log(" Dados:", JSON.stringify(data[0], null, 2)); - - return data; - } catch (error) { - console.error("❌ Erro na requisição de listagem:", error.message); - return null; - } -} - -async function runTest() { - try { - // NOVA ORDEM: Criar paciente PRIMEIRO, depois usuário - - // Etapa 1: Criar registro do paciente (SEM autenticação) - console.log("\n📝 NOVA ESTRATÉGIA: Criando paciente ANTES do usuário..."); - const patientResult = await createPatient(null); - if (!patientResult) { - console.log("\n⚠️ Não foi possível criar registro do paciente"); - console.log(" ℹ️ Tentando criar usuário mesmo assim..."); - } else { - console.log("\n✅ Paciente criado com sucesso!"); - } - - // Aguardar um pouco - console.log("\n⏳ Aguardando 2 segundos..."); - await new Promise((resolve) => setTimeout(resolve, 2000)); - - // Etapa 2: Signup (criar usuário de autenticação) - const signupResult = await signupPaciente(); - if (!signupResult || !signupResult.id) { - console.log("\n❌ TESTE FALHOU: Não foi possível criar o usuário"); - return; - } - - const userId = signupResult.id; - console.log("\n✅ Usuário criado após paciente!"); - - // Etapa 3: Login - const loginResult = await loginPaciente(); - if (!loginResult || !loginResult.access_token) { - console.log("\n❌ TESTE FALHOU: Não foi possível fazer login"); - return; - } - - const accessToken = loginResult.access_token; - - // Etapa 4: Buscar informações do usuário - const userInfo = await getUserInfo(accessToken); - if (!userInfo) { - console.log( - "\n⚠️ Login bem-sucedido, mas não foi possível buscar informações do usuário" - ); - } - - // Etapa 5: Verificar se aparece na lista de pacientes - const patients = await listPatients(accessToken); - - // Resumo final - console.log("\n" + "=".repeat(60)); - console.log("📊 RESUMO DO TESTE"); - console.log("=".repeat(60)); - console.log( - `✅ Usuário criado no Supabase Auth: ${signupResult ? "SIM" : "NÃO"}` - ); - console.log( - `✅ Registro criado na tabela patients: ${patientResult ? "SIM" : "NÃO"}` - ); - console.log(`✅ Login funciona: ${loginResult ? "SIM" : "NÃO"}`); - console.log(`✅ Dados do usuário recuperados: ${userInfo ? "SIM" : "NÃO"}`); - console.log( - `✅ Paciente aparece na lista: ${ - patients && patients.length > 0 ? "SIM" : "NÃO" - }` - ); - console.log("=".repeat(60)); - - if (signupResult && patientResult && loginResult && userInfo && patients) { - console.log("\n🎉 TESTE COMPLETO BEM-SUCEDIDO! 🎉"); - console.log("\nO paciente foi cadastrado corretamente e:"); - console.log(" 1. Usuário criado no Supabase Auth ✅"); - console.log(" 2. Registro na tabela patients ✅"); - console.log(" 3. Login funciona ✅"); - console.log(" 4. Dados acessíveis via API ✅"); - } else { - console.log("\n⚠️ TESTE PARCIALMENTE BEM-SUCEDIDO"); - console.log("Algumas etapas falharam. Verifique os logs acima."); - } - } catch (error) { - console.error("\n❌ ERRO GERAL NO TESTE:", error); - } -} - -// Executar teste -runTest(); diff --git a/MEDICONNECT 2/scripts/test-get-doctors.js b/MEDICONNECT 2/scripts/test-get-doctors.js deleted file mode 100644 index 475b2ad12..000000000 --- a/MEDICONNECT 2/scripts/test-get-doctors.js +++ /dev/null @@ -1,50 +0,0 @@ -import fetch from "node-fetch"; - -const myHeaders = { - apikey: - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ", - Authorization: - "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ", -}; - -console.log("🔍 Testando GET /doctors com token...\n"); - -fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/doctors", { - method: "GET", - headers: myHeaders, -}) - .then((response) => { - console.log(`Status: ${response.status} ${response.statusText}`); - return response.text(); - }) - .then((result) => { - console.log("\n📄 Resposta:"); - try { - const json = JSON.parse(result); - if (Array.isArray(json)) { - console.log(`✅ Array com ${json.length} registro(s)`); - if (json.length > 0) { - console.log("\n📋 Médicos encontrados:"); - json.forEach((medico, index) => { - console.log( - `\n${index + 1}. ${medico.full_name || medico.nome || "Sem nome"}` - ); - console.log(` ID: ${medico.id}`); - console.log(` CRM: ${medico.crm}`); - console.log( - ` Especialidade: ${medico.specialty || medico.especialidade}` - ); - console.log(` Email: ${medico.email}`); - console.log(` Ativo: ${medico.active}`); - }); - } else { - console.log("⚠️ Tabela vazia - sem médicos cadastrados"); - } - } else { - console.log(JSON.stringify(json, null, 2)); - } - } catch (e) { - console.log(result); - } - }) - .catch((error) => console.log("❌ Erro:", error)); diff --git a/MEDICONNECT 2/scripts/test-login.js b/MEDICONNECT 2/scripts/test-login.js deleted file mode 100644 index afbfaecbd..000000000 --- a/MEDICONNECT 2/scripts/test-login.js +++ /dev/null @@ -1,54 +0,0 @@ -import fetch from "node-fetch"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -async function testLogin() { - console.log("\n🔐 Testando login na API do Supabase...\n"); - - const email = "testefinal@gmail.com"; - const password = "Teste123!"; - - console.log(`Email: ${email}`); - console.log(`Password: ${password}\n`); - - try { - const response = await fetch( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - method: "POST", - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email: email, - password: password, - }), - } - ); - - const data = await response.json(); - - console.log(`Status: ${response.status}\n`); - - if (response.ok) { - console.log("✅ LOGIN SUCESSO!"); - console.log(`\nToken JWT: ${data.access_token?.substring(0, 50)}...`); - console.log(`User ID: ${data.user?.id}`); - console.log(`Email: ${data.user?.email}`); - console.log( - `Email confirmado: ${data.user?.email_confirmed_at ? "SIM" : "NÃO"}` - ); - } else { - console.log("❌ LOGIN FALHOU"); - console.log("\nResposta completa:"); - console.log(JSON.stringify(data, null, 2)); - } - } catch (error) { - console.error("❌ Erro ao fazer login:", error.message); - } -} - -testLogin(); diff --git a/MEDICONNECT 2/scripts/test-signup-simple.js b/MEDICONNECT 2/scripts/test-signup-simple.js deleted file mode 100644 index df24056e6..000000000 --- a/MEDICONNECT 2/scripts/test-signup-simple.js +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Teste simplificado de signup via Supabase - */ - -import fetch from "node-fetch"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -const timestamp = Date.now(); -const testEmail = `pacienteteste${timestamp}@gmail.com`; - -console.log("Testando signup com:", testEmail); - -async function testSignup() { - const url = `${SUPABASE_URL}/auth/v1/signup`; - - console.log("URL:", url); - - const body = { - email: testEmail, - password: "Senha123!@#", - options: { - data: { - role: "paciente", - full_name: "Teste Automático", - }, - }, - }; - - console.log("Body:", JSON.stringify(body, null, 2)); - - try { - const response = await fetch(url, { - method: "POST", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - }, - body: JSON.stringify(body), - }); - - console.log("Status:", response.status); - console.log("Headers:", Object.fromEntries(response.headers.entries())); - - const text = await response.text(); - console.log("Response (text):", text.substring(0, 500)); - - try { - const data = JSON.parse(text); - console.log("Response (JSON):", JSON.stringify(data, null, 2)); - } catch (e) { - console.log("Não é JSON válido"); - } - } catch (error) { - console.error("Erro:", error.message); - } -} - -testSignup(); diff --git a/MEDICONNECT 2/scripts/testar-atribuicoes-fernando.js b/MEDICONNECT 2/scripts/testar-atribuicoes-fernando.js deleted file mode 100644 index 744b60a67..000000000 --- a/MEDICONNECT 2/scripts/testar-atribuicoes-fernando.js +++ /dev/null @@ -1,178 +0,0 @@ -// Script para testar patient_assignments do Fernando -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -// Credenciais do Fernando -const FERNANDO_EMAIL = "fernando.pirichowski@souunit.com.br"; -const FERNANDO_PASSWORD = "fernando"; - -async function testarAtribuicoes() { - try { - console.log("\n🔐 === TESTE DE PATIENT_ASSIGNMENTS ===\n"); - - // 1. Login do Fernando - console.log("1️⃣ Fazendo login com Fernando..."); - const loginResponse = await fetch( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - }, - body: JSON.stringify({ - email: FERNANDO_EMAIL, - password: FERNANDO_PASSWORD, - }), - } - ); - - if (!loginResponse.ok) { - throw new Error( - `Erro no login: ${loginResponse.status} - ${await loginResponse.text()}` - ); - } - - const loginData = await loginResponse.json(); - const accessToken = loginData.access_token; - const fernandoUserId = loginData.user.id; - - console.log(`✅ Login realizado com sucesso!`); - console.log(` User ID: ${fernandoUserId}`); - console.log(` Email: ${loginData.user.email}`); - - // 2. Buscar perfil do Fernando - console.log("\n2️⃣ Buscando perfil no profiles..."); - const profileResponse = await fetch( - `${SUPABASE_URL}/rest/v1/profiles?id=eq.${fernandoUserId}&select=*`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${accessToken}`, - }, - } - ); - - if (!profileResponse.ok) { - throw new Error(`Erro ao buscar perfil: ${profileResponse.status}`); - } - - const profiles = await profileResponse.json(); - if (profiles.length > 0) { - console.log( - `✅ Perfil encontrado: ${ - profiles[0].full_name || profiles[0].name || "Sem nome" - }` - ); - } - - // 3. Buscar atribuições do Fernando - console.log("\n3️⃣ Buscando patient_assignments..."); - console.log(` Query: user_id=eq.${fernandoUserId}&role=eq.medico`); - - const assignmentsResponse = await fetch( - `${SUPABASE_URL}/rest/v1/patient_assignments?user_id=eq.${fernandoUserId}&role=eq.medico&select=*`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${accessToken}`, - }, - } - ); - - if (!assignmentsResponse.ok) { - const errorText = await assignmentsResponse.text(); - throw new Error( - `Erro ao buscar atribuições: ${assignmentsResponse.status} - ${errorText}` - ); - } - - const assignments = await assignmentsResponse.json(); - console.log(`✅ ${assignments.length} atribuições encontradas!`); - - if (assignments.length === 0) { - console.log( - "\n⚠️ Fernando NÃO tem atribuições na tabela patient_assignments!" - ); - console.log( - " Isso significa que ele não conseguirá ver pacientes no painel médico." - ); - console.log("\n💡 Solução:"); - console.log(" 1. Criar atribuições manualmente no Supabase"); - console.log(" 2. OU usar o script criar-atribuicao-fernando.js"); - } else { - console.log("\n📋 Atribuições encontradas:"); - assignments.forEach((a, i) => { - console.log(`\n ${i + 1}. Atribuição ID: ${a.id}`); - console.log(` Patient ID: ${a.patient_id}`); - console.log(` Role: ${a.role}`); - console.log(` Created At: ${a.created_at}`); - }); - - // 4. Buscar detalhes dos pacientes atribuídos - console.log("\n4️⃣ Buscando detalhes dos pacientes..."); - - for (let i = 0; i < assignments.length; i++) { - const assignment = assignments[i]; - const patientResponse = await fetch( - `${SUPABASE_URL}/rest/v1/patients?id=eq.${assignment.patient_id}&select=id,full_name,email,phone_mobile`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${accessToken}`, - }, - } - ); - - if (patientResponse.ok) { - const patients = await patientResponse.json(); - if (patients.length > 0) { - const p = patients[0]; - console.log(` ${i + 1}. ${p.full_name || "Sem nome"}`); - console.log(` Email: ${p.email || "N/A"}`); - console.log(` Tel: ${p.phone_mobile || "N/A"}`); - } else { - console.log( - ` ${i + 1}. ⚠️ Paciente ${ - assignment.patient_id - } não encontrado!` - ); - } - } - } - } - - // 5. Listar TODOS os pacientes (para referência) - console.log("\n5️⃣ Listando TODOS os pacientes (para referência)..."); - const allPatientsResponse = await fetch( - `${SUPABASE_URL}/rest/v1/patients?select=id,full_name&limit=10`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${accessToken}`, - }, - } - ); - - if (allPatientsResponse.ok) { - const allPatients = await allPatientsResponse.json(); - console.log( - `📊 Total de pacientes no sistema: ${allPatients.length} (primeiros 10)` - ); - allPatients.forEach((p, i) => { - console.log(` ${i + 1}. ${p.full_name} (${p.id})`); - }); - } - - console.log("\n✅ Teste concluído!"); - } catch (error) { - console.error("\n❌ Erro no teste:", error); - if (error instanceof Error) { - console.error(" Mensagem:", error.message); - } - } -} - -// Executar -testarAtribuicoes(); diff --git a/MEDICONNECT 2/scripts/testar-com-autenticacao.js b/MEDICONNECT 2/scripts/testar-com-autenticacao.js deleted file mode 100644 index b3acc69ca..000000000 --- a/MEDICONNECT 2/scripts/testar-com-autenticacao.js +++ /dev/null @@ -1,143 +0,0 @@ -import fetch from "node-fetch"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -console.log("\n🔐 TESTANDO COM AUTENTICAÇÃO\n"); -console.log("Precisamos de um usuário válido para fazer login."); -console.log("Digite o email e senha de um usuário que você sabe que existe:\n"); - -// Credenciais fornecidas pelo usuário -const EMAIL_TESTE = "riseup@popcode.com.br"; -const SENHA_TESTE = "riseup"; - -async function testarComAutenticacao() { - console.log(`📧 Tentando login com: ${EMAIL_TESTE}\n`); - - // PASSO 1: Fazer login - try { - const loginResponse = await fetch( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - method: "POST", - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email: EMAIL_TESTE, - password: SENHA_TESTE, - }), - } - ); - - if (!loginResponse.ok) { - console.log("❌ Login falhou:", loginResponse.status); - const error = await loginResponse.text(); - console.log(error); - console.log( - "\n💡 SOLUÇÃO: Use um email/senha de usuário que você já cadastrou!" - ); - return; - } - - const loginData = await loginResponse.json(); - const accessToken = loginData.access_token; - - console.log("✅ Login bem-sucedido!"); - console.log(`👤 User ID: ${loginData.user?.id}`); - console.log(`🔑 Token: ${accessToken.substring(0, 50)}...\n`); - - // PASSO 2: Buscar médicos COM o token - console.log("📋 Buscando médicos COM autenticação...\n"); - - const medicosResponse = await fetch( - `${SUPABASE_URL}/rest/v1/doctors?select=*`, - { - method: "GET", - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${accessToken}`, - "Content-Type": "application/json", - }, - } - ); - - if (medicosResponse.ok) { - const medicos = await medicosResponse.json(); - console.log(`✅ MÉDICOS ENCONTRADOS: ${medicos.length}\n`); - - if (medicos.length > 0) { - console.log("📋 Lista de médicos:\n"); - medicos.forEach((medico, index) => { - console.log( - `${index + 1}. ${medico.full_name || medico.nome || "Sem nome"}` - ); - console.log(` CRM: ${medico.crm}`); - console.log( - ` Especialidade: ${medico.specialty || medico.especialidade}` - ); - console.log(` Email: ${medico.email}`); - console.log(""); - }); - } - } else { - console.log("❌ Erro ao buscar médicos:", medicosResponse.status); - const error = await medicosResponse.text(); - console.log(error); - } - - // PASSO 3: Buscar pacientes COM o token - console.log("\n📋 Buscando pacientes COM autenticação...\n"); - - const pacientesResponse = await fetch( - `${SUPABASE_URL}/rest/v1/patients?select=*`, - { - method: "GET", - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${accessToken}`, - "Content-Type": "application/json", - }, - } - ); - - if (pacientesResponse.ok) { - const pacientes = await pacientesResponse.json(); - console.log(`✅ PACIENTES ENCONTRADOS: ${pacientes.length}\n`); - - if (pacientes.length > 0) { - console.log("📋 Lista de pacientes:\n"); - pacientes.slice(0, 5).forEach((paciente, index) => { - console.log( - `${index + 1}. ${paciente.full_name || paciente.nome || "Sem nome"}` - ); - console.log(` Email: ${paciente.email}`); - console.log(` CPF: ${paciente.cpf}`); - console.log(""); - }); - - if (pacientes.length > 5) { - console.log(`... e mais ${pacientes.length - 5} pacientes\n`); - } - } - } else { - console.log("❌ Erro ao buscar pacientes:", pacientesResponse.status); - const error = await pacientesResponse.text(); - console.log(error); - } - - console.log( - "\n✅ SUCESSO! Os dados ESTÃO no Supabase e são acessíveis com autenticação!\n" - ); - console.log("🎯 CONCLUSÃO:"); - console.log(" - RLS está configurado corretamente"); - console.log(" - Dados precisam de autenticação para serem lidos"); - console.log(" - A aplicação funciona porque o usuário está logado\n"); - } catch (error) { - console.error("❌ Erro:", error.message); - } -} - -testarComAutenticacao(); diff --git a/MEDICONNECT 2/scripts/testar-criacao-relatorio.js b/MEDICONNECT 2/scripts/testar-criacao-relatorio.js deleted file mode 100644 index d9ef62035..000000000 --- a/MEDICONNECT 2/scripts/testar-criacao-relatorio.js +++ /dev/null @@ -1,178 +0,0 @@ -/** - * Script para testar criação de relatório com estrutura correta - */ - -import axios from "axios"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -const FERNANDO_EMAIL = "fernando.pirichowski@souunit.com.br"; -const FERNANDO_PASSWORD = "fernando"; - -async function main() { - try { - console.log("🔐 Fazendo login como médico Fernando...\n"); - - const loginResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: FERNANDO_EMAIL, - password: FERNANDO_PASSWORD, - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - } - ); - - const token = loginResponse.data.access_token; - const userId = loginResponse.data.user.id; - - console.log("✅ Login realizado com sucesso!"); - console.log(` User ID: ${userId}\n`); - - // Buscar primeiro paciente disponível - console.log("🔍 Buscando pacientes...\n"); - const pacientesResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/patients?select=*&limit=1&order=created_at.desc`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${token}`, - }, - } - ); - - if (pacientesResponse.data.length === 0) { - console.log("❌ Nenhum paciente encontrado!"); - console.log("Execute primeiro o script cadastrar-guilherme.js\n"); - return; - } - - const guilherme = pacientesResponse.data[0]; - console.log("✅ Paciente encontrado:"); - console.log(` ID: ${guilherme.id}`); - console.log(` Nome: ${guilherme.full_name}\n`); - - // Criar relatório de teste - console.log("📝 Criando relatório médico...\n"); - - const relatorioData = { - patient_id: guilherme.id, - order_number: `REL-2025-10-TEST-${Math.random() - .toString(36) - .substr(2, 4) - .toUpperCase()}`, - exam: "Consulta Clínica Geral", - diagnosis: - "Paciente apresenta quadro de check-up de rotina sem alterações significativas.", - conclusion: - "Exame físico dentro dos padrões normais. Paciente orientado sobre hábitos saudáveis e prevenção de doenças.", - cid_code: "Z00.0", - content_html: `
-

Relatório Médico - Consulta Clínica

-

Paciente: ${guilherme.full_name}

-

Data: ${new Date().toLocaleDateString("pt-BR")}

-

Anamnese:

-

Paciente compareceu para consulta de check-up de rotina. Nega queixas específicas.

-

Exame Físico:

-

- - Estado geral: Bom
- - Pressão arterial: 120/80 mmHg
- - Frequência cardíaca: 72 bpm
- - Ausculta cardíaca e pulmonar: Sem alterações -

-

Diagnóstico:

-

Check-up de rotina sem alterações

-

Conduta:

-

- - Manter hábitos saudáveis
- - Retornar em 6 meses para novo check-up
- - Atividade física regular -

-
`, - content_json: { - blocks: [ - { - type: "heading", - level: 2, - text: "Relatório Médico - Consulta Clínica", - }, - { type: "paragraph", text: `Paciente: ${guilherme.full_name}` }, - { - type: "paragraph", - text: `Data: ${new Date().toLocaleDateString("pt-BR")}`, - }, - { type: "heading", level: 3, text: "Anamnese" }, - { - type: "paragraph", - text: "Paciente compareceu para consulta de check-up de rotina.", - }, - ], - }, - status: "final", - requested_by: "Dr. Fernando Pirichowski - Squad 18", - due_at: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(), - hide_date: false, - hide_signature: false, - }; - - const createResponse = await axios.post( - `${SUPABASE_URL}/rest/v1/reports`, - relatorioData, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${token}`, - "Content-Type": "application/json", - Prefer: "return=representation", - }, - } - ); - - const relatorio = Array.isArray(createResponse.data) - ? createResponse.data[0] - : createResponse.data; - - console.log("✅ RELATÓRIO CRIADO COM SUCESSO!\n"); - console.log("📋 Detalhes do relatório:"); - console.log(` ID: ${relatorio.id}`); - console.log(` Número do Pedido: ${relatorio.order_number}`); - console.log(` Paciente ID: ${relatorio.patient_id}`); - console.log(` Exame: ${relatorio.exam}`); - console.log(` Status: ${relatorio.status}`); - console.log(` Diagnóstico: ${relatorio.diagnosis.substring(0, 50)}...`); - console.log(` Conclusão: ${relatorio.conclusion.substring(0, 50)}...`); - console.log(` CID: ${relatorio.cid_code}`); - console.log(` Solicitado por: ${relatorio.requested_by}`); - console.log(` Vencimento: ${relatorio.due_at}`); - console.log(` Criado em: ${relatorio.created_at}\n`); - - console.log("🎉 TESTE COMPLETO!\n"); - console.log('✅ Botão "Novo Relatório" no painel médico está funcionando'); - console.log("✅ API de relatórios totalmente integrada"); - console.log( - "✅ Estrutura de dados correta (patient_id, exam, diagnosis, etc.)\n" - ); - - console.log("📝 Próximos passos:"); - console.log("1. Acesse http://localhost:5173/login-medico"); - console.log( - "2. Faça login com: fernando.pirichowski@souunit.com.br / fernando" - ); - console.log('3. Clique no botão "Novo Relatório" (verde)'); - console.log("4. Preencha o formulário e teste a criação!\n"); - } catch (error) { - console.error("❌ ERRO:", error.response?.data || error.message); - if (error.response) { - console.error("Status:", error.response.status); - console.error("Data:", JSON.stringify(error.response.data, null, 2)); - } - } -} - -main(); diff --git a/MEDICONNECT 2/scripts/testar-guilherme.js b/MEDICONNECT 2/scripts/testar-guilherme.js deleted file mode 100644 index f122ed0e8..000000000 --- a/MEDICONNECT 2/scripts/testar-guilherme.js +++ /dev/null @@ -1,156 +0,0 @@ -/** - * Script de teste completo para verificar se Guilherme pode acessar o sistema - */ - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -const GUILHERME_EMAIL = "guilhermesilvagomes1020@gmail.com"; -const GUILHERME_PASSWORD = "guilherme123"; - -async function testarGuilherme() { - try { - console.log("\n🧪 === TESTANDO ACESSO DO GUILHERME ===\n"); - - // 1. Testar login - console.log("1️⃣ Testando login do Guilherme..."); - console.log(` Email: ${GUILHERME_EMAIL}`); - console.log(` Senha: ${GUILHERME_PASSWORD}\n`); - - const loginResponse = await fetch( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - }, - body: JSON.stringify({ - email: GUILHERME_EMAIL, - password: GUILHERME_PASSWORD, - }), - } - ); - - if (!loginResponse.ok) { - const error = await loginResponse.text(); - console.error("❌ Erro no login:", error); - throw new Error("Login falhou"); - } - - const loginData = await loginResponse.json(); - const token = loginData.access_token; - const userId = loginData.user.id; - - console.log("✅ Login realizado com sucesso!"); - console.log(` User ID: ${userId}`); - console.log(` Email verificado: ${loginData.user.email}\n`); - - // 2. Verificar pacientes atribuídos - console.log("2️⃣ Verificando pacientes atribuídos..."); - const assignmentsResponse = await fetch( - `${SUPABASE_URL}/rest/v1/patient_assignments?user_id=eq.${userId}`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${token}`, - }, - } - ); - - const assignments = await assignmentsResponse.json(); - console.log(` ✅ ${assignments.length} paciente(s) atribuído(s)`); - - if (assignments.length > 0) { - for (const assignment of assignments) { - console.log(`\n 📋 Atribuição:`); - console.log(` Patient ID: ${assignment.patient_id}`); - console.log(` Role: ${assignment.role}`); - - // Buscar dados do paciente - const patientResponse = await fetch( - `${SUPABASE_URL}/rest/v1/patients?id=eq.${assignment.patient_id}`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${token}`, - }, - } - ); - - const patients = await patientResponse.json(); - if (patients && patients.length > 0) { - const patient = patients[0]; - console.log(` Nome: ${patient.full_name}`); - console.log(` Email: ${patient.email}`); - console.log(` Telefone: ${patient.phone_mobile}`); - } - } - } - - // 3. Verificar consultas (localStorage simulation) - console.log("\n3️⃣ Verificando consultas de demonstração..."); - const fs = await import("fs"); - const path = await import("path"); - const { fileURLToPath } = await import("url"); - const { dirname } = await import("path"); - - const __filename = fileURLToPath(import.meta.url); - const __dirname = dirname(__filename); - - const consultasPath = path.join( - __dirname, - "..", - "src", - "data", - "consultas-demo.json" - ); - - if (fs.existsSync(consultasPath)) { - const consultasData = fs.readFileSync(consultasPath, "utf-8"); - const consultas = JSON.parse(consultasData); - - console.log(` ✅ ${consultas.length} consultas encontradas\n`); - - consultas.forEach((consulta, index) => { - console.log(` 📅 Consulta ${index + 1}:`); - console.log(` Data/Hora: ${consulta.dataHora}`); - console.log(` Status: ${consulta.status}`); - console.log(` Tipo: ${consulta.tipo}`); - console.log(` Médico: ${consulta.medicoNome}`); - console.log(` Observações: ${consulta.observacoes}\n`); - }); - } else { - console.log(" ⚠️ Arquivo de consultas não encontrado"); - } - - // 4. Resumo final - console.log("\n✅ === TODOS OS TESTES PASSARAM! ===\n"); - console.log("📋 RESUMO:"); - console.log(` ✅ Login funcionando`); - console.log(` ✅ Paciente atribuído ao usuário`); - console.log(` ✅ Consultas de demonstração criadas`); - console.log(` ✅ Role: user (acesso ao painel paciente)\n`); - - console.log("🎯 PRÓXIMA AÇÃO:"); - console.log(" 1. Inicie o servidor de desenvolvimento: npm run dev"); - console.log(" 2. Acesse: http://localhost:5173/paciente"); - console.log(" 3. Faça login com:"); - console.log(` Email: ${GUILHERME_EMAIL}`); - console.log(` Senha: ${GUILHERME_PASSWORD}`); - console.log(" 4. Você verá as 3 consultas no painel!\n"); - - console.log("💡 DICA:"); - console.log(" As consultas são carregadas automaticamente do arquivo"); - console.log(" src/data/consultas-demo.json para o localStorage\n"); - } catch (error) { - console.error("\n❌ ERRO NO TESTE:", error.message); - if (error.stack) { - console.error(error.stack); - } - process.exit(1); - } -} - -testarGuilherme(); diff --git a/MEDICONNECT 2/scripts/testar-login-fernando.js b/MEDICONNECT 2/scripts/testar-login-fernando.js deleted file mode 100644 index 2fbb93ef9..000000000 --- a/MEDICONNECT 2/scripts/testar-login-fernando.js +++ /dev/null @@ -1,130 +0,0 @@ -/** - * Script para testar login do médico Fernando - * Verifica autenticação e se o usuário é identificado como médico - */ - -import axios from "axios"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -const FERNANDO_EMAIL = "fernando.pirichowski@souunit.com.br"; -const FERNANDO_PASSWORD = "fernando"; - -async function main() { - try { - console.log("🔐 TESTANDO LOGIN DO MÉDICO FERNANDO\n"); - console.log("Credenciais:"); - console.log(` Email: ${FERNANDO_EMAIL}`); - console.log(` Senha: ${FERNANDO_PASSWORD}\n`); - - // 1. Fazer login - console.log("1️⃣ Fazendo login...\n"); - const loginResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: FERNANDO_EMAIL, - password: FERNANDO_PASSWORD, - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - } - ); - - const token = loginResponse.data.access_token; - const userId = loginResponse.data.user.id; - - console.log("✅ Login realizado com sucesso!"); - console.log(` User ID: ${userId}`); - console.log(` Email: ${loginResponse.data.user.email}\n`); - - // 2. Verificar se é médico (consultar tabela doctors) - console.log("2️⃣ Verificando se usuário é médico...\n"); - const doctorResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/doctors?user_id=eq.${userId}&select=*`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${token}`, - }, - } - ); - - if (doctorResponse.data.length > 0) { - const doctor = doctorResponse.data[0]; - console.log("✅ USUÁRIO É MÉDICO!"); - console.log("\n📋 Dados do médico:"); - console.log(` ID: ${doctor.id}`); - console.log(` Nome: ${doctor.full_name}`); - console.log(` Email: ${doctor.email}`); - console.log(` CRM: ${doctor.crm}-${doctor.crm_uf}`); - console.log(` Especialidade: ${doctor.specialty}`); - console.log(` Ativo: ${doctor.active ? "Sim" : "Não"}`); - console.log(` User ID: ${doctor.user_id}\n`); - - console.log("✅ LOGIN VÁLIDO - Pode acessar painel médico!"); - console.log("🎯 Redirecionamento: /painel-medico\n"); - } else { - console.log("❌ USUÁRIO NÃO É MÉDICO"); - console.log(" Este usuário não tem registro na tabela doctors"); - console.log(" Acesso ao painel médico será negado.\n"); - } - - // 3. Buscar consultas do médico (se aplicável) - if (doctorResponse.data.length > 0) { - console.log("3️⃣ Buscando consultas do médico...\n"); - try { - const consultasResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/appointments?doctor_id=eq.${doctorResponse.data[0].id}&select=*`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${token}`, - }, - } - ); - console.log( - ` Total de consultas: ${consultasResponse.data.length}\n` - ); - } catch (error) { - console.log(" ⚠️ Tabela appointments não encontrada ou sem dados\n"); - } - } - - // 4. Resumo - console.log("📊 RESUMO DO TESTE:\n"); - console.log("✅ Autenticação funcionando corretamente"); - console.log("✅ Verificação de role médico implementada"); - console.log("✅ Token JWT válido gerado"); - console.log( - `✅ Médico: ${doctorResponse.data.length > 0 ? "SIM" : "NÃO"}\n` - ); - - if (doctorResponse.data.length > 0) { - console.log("🎉 TESTE BEM-SUCEDIDO!"); - console.log( - "O médico Fernando pode fazer login e acessar o painel médico.\n" - ); - } - } catch (error) { - console.error("❌ ERRO NO TESTE:", error.response?.data || error.message); - if (error.response) { - console.error("Status:", error.response.status); - - if (error.response.status === 400) { - console.error("\n💡 Possíveis causas:"); - console.error(" - Email ou senha incorretos"); - console.error(" - Usuário não existe"); - console.error( - " - Email não confirmado (verificar configurações Supabase)" - ); - } - } - } -} - -main(); diff --git a/MEDICONNECT 2/scripts/testar-relatorios.js b/MEDICONNECT 2/scripts/testar-relatorios.js deleted file mode 100644 index efdf3d0c7..000000000 --- a/MEDICONNECT 2/scripts/testar-relatorios.js +++ /dev/null @@ -1,195 +0,0 @@ -/** - * Script para testar a criação de relatórios na API - * Verifica se a tabela reports existe e testa criação de relatório - */ - -import axios from "axios"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -// Credenciais do médico Fernando -const FERNANDO_EMAIL = "fernando.pirichowski@souunit.com.br"; -const FERNANDO_PASSWORD = "fernando"; - -async function main() { - try { - console.log("🔐 Fazendo login como médico Fernando...\n"); - - // 1. Login do médico - const loginResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: FERNANDO_EMAIL, - password: FERNANDO_PASSWORD, - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - } - ); - - const token = loginResponse.data.access_token; - const userId = loginResponse.data.user.id; - - console.log("✅ Login realizado com sucesso!"); - console.log(` User ID: ${userId}\n`); - - // 2. Verificar se tabela reports existe - console.log("🔍 Verificando se tabela reports existe...\n"); - - try { - const checkTableResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/reports?select=id&limit=1`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${token}`, - }, - } - ); - - console.log("✅ Tabela reports existe!"); - console.log( - ` Registros encontrados: ${checkTableResponse.data.length}\n` - ); - } catch (error) { - if (error.response?.status === 404) { - console.log("❌ ERRO: Tabela reports NÃO existe no Supabase!\n"); - console.log( - "💡 SOLUÇÃO: Execute o SQL abaixo no Supabase SQL Editor:\n" - ); - console.log("```sql"); - console.log(`CREATE TABLE IF NOT EXISTS public.reports ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - titulo TEXT NOT NULL, - tipo TEXT CHECK (tipo IN ('consultas', 'pacientes', 'financeiro', 'medicos')) NOT NULL, - descricao TEXT, - data_inicio DATE NOT NULL, - data_fim DATE NOT NULL, - dados JSONB DEFAULT '{}'::jsonb, - gerado_por UUID REFERENCES auth.users(id), - created_at TIMESTAMPTZ DEFAULT NOW(), - updated_at TIMESTAMPTZ DEFAULT NOW() -); - --- Habilitar RLS -ALTER TABLE public.reports ENABLE ROW LEVEL SECURITY; - --- Políticas de acesso -CREATE POLICY "reports_select_authenticated" ON public.reports - FOR SELECT TO authenticated USING (true); - -CREATE POLICY "reports_insert_authenticated" ON public.reports - FOR INSERT TO authenticated WITH CHECK (true); - -CREATE POLICY "reports_update_own" ON public.reports - FOR UPDATE TO authenticated USING (gerado_por = auth.uid()); - -CREATE POLICY "reports_delete_own" ON public.reports - FOR DELETE TO authenticated USING (gerado_por = auth.uid()); -\`\`\`\n`); - return; - } - throw error; - } - - // 3. Criar relatório de teste - console.log("📝 Criando relatório de teste...\n"); - - const relatorioData = { - titulo: "Relatório de Teste - Consultas Outubro 2025", - tipo: "consultas", - descricao: - "Relatório gerado automaticamente para testar a funcionalidade", - data_inicio: "2025-10-01", - data_fim: "2025-10-31", - dados: { - medicoId: userId, - medicoNome: "Fernando Pirichowski - Squad 18", - totalConsultas: 0, - testScript: true, - }, - gerado_por: userId, - }; - - const createResponse = await axios.post( - `${SUPABASE_URL}/rest/v1/reports`, - relatorioData, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${token}`, - "Content-Type": "application/json", - Prefer: "return=representation", - }, - } - ); - - const relatorio = Array.isArray(createResponse.data) - ? createResponse.data[0] - : createResponse.data; - - console.log("✅ Relatório criado com sucesso!\n"); - console.log("📋 Detalhes do relatório:"); - console.log(` ID: ${relatorio.id}`); - console.log(` Título: ${relatorio.titulo}`); - console.log(` Tipo: ${relatorio.tipo}`); - console.log(` Período: ${relatorio.data_inicio} a ${relatorio.data_fim}`); - console.log(` Gerado por: ${relatorio.gerado_por}`); - console.log(` Criado em: ${relatorio.created_at}\n`); - - // 4. Listar todos os relatórios - console.log("📊 Listando todos os relatórios...\n"); - - const listResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/reports?select=*&order=created_at.desc`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${token}`, - }, - } - ); - - console.log(`Total de relatórios: ${listResponse.data.length}\n`); - listResponse.data.forEach((rel, index) => { - console.log(`${index + 1}. ${rel.titulo}`); - console.log( - ` Tipo: ${rel.tipo} | Período: ${rel.data_inicio} a ${rel.data_fim}` - ); - console.log(` Criado em: ${rel.created_at}\n`); - }); - - // 5. Resumo - console.log("✅ TESTE COMPLETO!\n"); - console.log("🎉 Sistema de relatórios funcionando corretamente!"); - console.log( - '✅ Botão "Novo Relatório" no painel médico está conectado à API\n' - ); - } catch (error) { - console.error("❌ ERRO:", error.response?.data || error.message); - if (error.response) { - console.error("Status:", error.response.status); - - if (error.response.status === 404) { - console.error("\n⚠️ Tabela reports não encontrada!"); - console.error("Execute o SQL de criação da tabela mostrado acima."); - } else if (error.response.status === 401) { - console.error("\n⚠️ Erro de autenticação"); - console.error("Verifique se o token JWT está válido"); - } else if (error.response.status === 400) { - console.error("\n⚠️ Erro de validação"); - console.error( - "Detalhes:", - JSON.stringify(error.response.data, null, 2) - ); - } - } - } -} - -main(); diff --git a/MEDICONNECT 2/scripts/verificar-estrutura-reports.js b/MEDICONNECT 2/scripts/verificar-estrutura-reports.js deleted file mode 100644 index 633e6ef00..000000000 --- a/MEDICONNECT 2/scripts/verificar-estrutura-reports.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Script para verificar estrutura da tabela reports - */ - -import axios from "axios"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -const ADMIN_EMAIL = "riseup@popcode.com.br"; -const ADMIN_PASSWORD = "riseup"; - -async function main() { - try { - console.log("🔐 Fazendo login...\n"); - - const loginResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: ADMIN_EMAIL, - password: ADMIN_PASSWORD, - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - } - ); - - const token = loginResponse.data.access_token; - console.log("✅ Login OK\n"); - - console.log("🔍 Listando relatórios existentes para ver estrutura...\n"); - - const listResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/reports?select=*&limit=1`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${token}`, - }, - } - ); - - if (listResponse.data.length > 0) { - console.log("✅ Estrutura encontrada:"); - console.log(JSON.stringify(listResponse.data[0], null, 2)); - console.log( - "\nCampos disponíveis:", - Object.keys(listResponse.data[0]).join(", ") - ); - return; - } - - console.log( - "⚠️ Nenhum relatório existente. Tentando criar com campos básicos...\n" - ); - - const relatorioMinimo = { - titulo: "Teste Estrutura", - tipo: "consultas", - }; - - const createResponse = await axios.post( - `${SUPABASE_URL}/rest/v1/reports`, - relatorioMinimo, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${token}`, - "Content-Type": "application/json", - Prefer: "return=representation", - }, - } - ); - - console.log("✅ Relatório criado com sucesso!\n"); - console.log("📋 Estrutura da tabela reports:"); - console.log(JSON.stringify(createResponse.data, null, 2)); - } catch (error) { - console.error("❌ ERRO:", error.response?.data || error.message); - if (error.response) { - console.error("Status:", error.response.status); - console.error("Data:", JSON.stringify(error.response.data, null, 2)); - } - } -} - -main(); diff --git a/MEDICONNECT 2/scripts/verificar-fernando.js b/MEDICONNECT 2/scripts/verificar-fernando.js deleted file mode 100644 index 0d6f664f8..000000000 --- a/MEDICONNECT 2/scripts/verificar-fernando.js +++ /dev/null @@ -1,187 +0,0 @@ -import axios from "axios"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -async function verificarPermissoesFernando() { - try { - console.log("═══════════════════════════════════════════════════"); - console.log("🔍 VERIFICANDO PERMISSÕES DE FERNANDO"); - console.log("═══════════════════════════════════════════════════\n"); - - // 1. Login como Fernando - console.log("🔑 Fazendo login como Fernando..."); - const loginResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: "fernando.pirichowski@souunit.com.br", - password: "fernando", - }, - { - headers: { - apikey: SUPABASE_ANON_KEY, - "Content-Type": "application/json", - }, - } - ); - - const token = loginResponse.data.access_token; - const userId = loginResponse.data.user.id; - const userEmail = loginResponse.data.user.email; - - console.log("✅ Login realizado com sucesso!"); - console.log(` User ID: ${userId}`); - console.log(` Email: ${userEmail}\n`); - - // 2. Buscar dados do usuário na tabela profiles - console.log("👤 Buscando dados na tabela profiles..."); - const userResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/profiles?id=eq.${userId}&select=*`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${token}`, - }, - } - ); - - if (userResponse.data.length === 0) { - console.log("❌ Usuário não encontrado na tabela profiles!\n"); - } else { - const user = userResponse.data[0]; - console.log("✅ Dados do usuário:"); - console.log(` Nome: ${user.full_name || "N/A"}`); - console.log(` Email: ${user.email}`); - console.log(` is_admin: ${user.is_admin}`); - console.log(` is_secretary: ${user.is_secretary}`); - console.log(` is_admin_or_manager: ${user.is_admin_or_manager}\n`); - } - - // 3. Buscar roles na tabela user_roles - console.log("🎭 Buscando roles na tabela user_roles..."); - const rolesResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/user_roles?user_id=eq.${userId}&select=*`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${token}`, - }, - } - ); - - if (rolesResponse.data.length === 0) { - console.log("❌ Nenhuma role encontrada!\n"); - } else { - console.log("✅ Roles encontradas:"); - rolesResponse.data.forEach((role) => { - console.log(` • ${role.role}`); - }); - console.log(""); - } - - // 4. Testar acesso aos pacientes - console.log("🏥 Testando acesso aos pacientes..."); - try { - const pacientesResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/patients?select=id,full_name,email&limit=5`, - { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${token}`, - }, - } - ); - - console.log( - `✅ ACESSO PERMITIDO! (${pacientesResponse.data.length} pacientes encontrados)` - ); - - if (pacientesResponse.data.length > 0) { - console.log("\n📋 Pacientes acessíveis:"); - pacientesResponse.data.forEach((p) => { - console.log( - ` • ${p.full_name || "Sem nome"} - ${p.email || "Sem email"}` - ); - }); - } - console.log(""); - } catch (error) { - console.log(`❌ ACESSO NEGADO!`); - console.log( - ` Erro: ${error.response?.data?.message || error.message}\n` - ); - } - - // 5. Testar criação de relatório - console.log("📝 Testando permissão para criar relatório..."); - try { - // Não vou criar de fato, só testar se tem permissão - const testReportData = { - patient_id: "00000000-0000-0000-0000-000000000000", // ID fake para teste - exam: "Teste de permissão", - diagnosis: "Teste", - conclusion: "Teste", - order_number: "TEST-001", - status: "draft", - }; - - await axios.post(`${SUPABASE_URL}/rest/v1/reports`, testReportData, { - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${token}`, - "Content-Type": "application/json", - Prefer: "return=representation", - }, - }); - - console.log("✅ PERMISSÃO PARA CRIAR RELATÓRIOS: SIM\n"); - } catch (error) { - if (error.response?.status === 403) { - console.log("❌ PERMISSÃO PARA CRIAR RELATÓRIOS: NEGADA"); - console.log( - ` Erro: ${error.response?.data?.message || "Acesso negado"}\n` - ); - } else { - console.log( - "⚠️ Erro ao testar (pode ser FK constraint, não necessariamente permissão)" - ); - console.log(` ${error.response?.data?.message || error.message}\n`); - } - } - - // 6. Resumo - console.log("═══════════════════════════════════════════════════"); - console.log("📊 RESUMO DAS PERMISSÕES DE FERNANDO"); - console.log("═══════════════════════════════════════════════════"); - - const userData = userResponse.data[0] || {}; - const roles = rolesResponse.data.map((r) => r.role); - - console.log("\n🎭 Roles:", roles.length > 0 ? roles.join(", ") : "Nenhuma"); - console.log("👑 Is Admin:", userData.is_admin || false); - console.log("👔 Is Secretary:", userData.is_secretary || false); - console.log("👨‍💼 Is Admin/Manager:", userData.is_admin_or_manager || false); - console.log(""); - - if (userData.is_admin || roles.includes("admin")) { - console.log("✅ Fernando TEM permissões de ADMIN"); - } else { - console.log("❌ Fernando NÃO TEM permissões de ADMIN"); - console.log("\n💡 Para adicionar permissões de admin:"); - console.log(" 1. Execute: node scripts/dar-admin-fernando.js"); - console.log(" 2. Ou use o painel do Supabase"); - } - console.log(""); - } catch (error) { - console.error("\n❌ ERRO:", error.response?.data || error.message); - - if (error.code === "ENOTFOUND") { - console.log("\n⚠️ Problema de conexão com Supabase"); - } else if (error.response?.status === 400) { - console.log("\n⚠️ Credenciais inválidas ou usuário não existe"); - } - } -} - -verificarPermissoesFernando(); diff --git a/MEDICONNECT 2/scripts/verificar-todas-tabelas.js b/MEDICONNECT 2/scripts/verificar-todas-tabelas.js deleted file mode 100644 index 5c23938ee..000000000 --- a/MEDICONNECT 2/scripts/verificar-todas-tabelas.js +++ /dev/null @@ -1,104 +0,0 @@ -import fetch from "node-fetch"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -console.log( - "🔍 DIAGNÓSTICO COMPLETO - Verificando todas as tabelas possíveis\n" -); - -async function testarVariacoes() { - const testes = [ - // Médicos - { nome: "doctors", url: `${SUPABASE_URL}/rest/v1/doctors?select=*` }, - { - nome: "doctors (count)", - url: `${SUPABASE_URL}/rest/v1/doctors?select=count`, - }, - { nome: "medicos", url: `${SUPABASE_URL}/rest/v1/medicos?select=*` }, - { - nome: "user_directory", - url: `${SUPABASE_URL}/rest/v1/user_directory?select=*`, - }, - - // Pacientes - { nome: "patients", url: `${SUPABASE_URL}/rest/v1/patients?select=*` }, - { - nome: "patients (count)", - url: `${SUPABASE_URL}/rest/v1/patients?select=count`, - }, - { nome: "pacientes", url: `${SUPABASE_URL}/rest/v1/pacientes?select=*` }, - - // Outras tabelas possíveis - { nome: "profiles", url: `${SUPABASE_URL}/rest/v1/profiles?select=*` }, - { nome: "users", url: `${SUPABASE_URL}/rest/v1/users?select=*` }, - { - nome: "appointments", - url: `${SUPABASE_URL}/rest/v1/appointments?select=*`, - }, - ]; - - for (const teste of testes) { - console.log(`\n📋 Testando: ${teste.nome}`); - console.log("─".repeat(60)); - - try { - const response = await fetch(teste.url, { - method: "GET", - headers: { - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${SUPABASE_ANON_KEY}`, - "Content-Type": "application/json", - }, - }); - - console.log(`Status: ${response.status}`); - - if (response.ok) { - const data = await response.json(); - - if (Array.isArray(data)) { - console.log(`✅ ENCONTRADO! ${data.length} registro(s)`); - - if (data.length > 0) { - console.log("\n📄 Primeiro registro:"); - const primeiro = data[0]; - const campos = Object.keys(primeiro); - console.log(`Campos disponíveis: ${campos.join(", ")}`); - console.log("\nDados:"); - console.log(JSON.stringify(primeiro, null, 2).substring(0, 500)); - } - } else if (data.count !== undefined) { - console.log(`✅ COUNT: ${data.count} registro(s)`); - } else { - console.log("✅ Resposta:", JSON.stringify(data).substring(0, 200)); - } - } else if (response.status === 404) { - console.log("❌ Tabela não existe"); - } else if (response.status === 401 || response.status === 403) { - console.log("🔒 Bloqueado por RLS (precisa autenticação)"); - } else { - const error = await response.text(); - console.log("❌ Erro:", error.substring(0, 200)); - } - } catch (error) { - console.log("❌ Erro de conexão:", error.message); - } - - // Pequeno delay entre requests - await new Promise((resolve) => setTimeout(resolve, 100)); - } - - console.log("\n\n" + "=".repeat(60)); - console.log("🎯 RESUMO"); - console.log("=".repeat(60)); - console.log("Se alguma tabela mostrou registros > 0, os dados EXISTEM!"); - console.log("Se todas mostraram 0, pode ser:"); - console.log(" 1. Dados realmente não existem"); - console.log(" 2. RLS está bloqueando a leitura"); - console.log(" 3. Tabelas têm nomes diferentes"); - console.log("\n"); -} - -testarVariacoes(); diff --git a/MEDICONNECT 2/scripts/verify-user-creation.js b/MEDICONNECT 2/scripts/verify-user-creation.js deleted file mode 100644 index 3f1aef01d..000000000 --- a/MEDICONNECT 2/scripts/verify-user-creation.js +++ /dev/null @@ -1,160 +0,0 @@ -/** - * Verificar se um usuário/paciente foi criado na API - */ - -import fetch from "node-fetch"; - -const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; -const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; - -// Pegar email da linha de comando ou usar um padrão -const emailToSearch = process.argv[2] || "paciente.teste"; - -console.log("\n🔍 VERIFICANDO CRIAÇÃO DE USUÁRIO\n"); -console.log("=".repeat(60)); -console.log(`Buscando por: ${emailToSearch}`); -console.log("=".repeat(60)); - -async function checkProfiles() { - console.log("\n📋 Verificando tabela profiles..."); - - try { - const response = await fetch( - `${SUPABASE_URL}/rest/v1/profiles?email=ilike.*${emailToSearch}*&select=*`, - { - method: "GET", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${SUPABASE_ANON_KEY}`, - }, - } - ); - - const data = await response.json(); - - if (!response.ok) { - console.log(" ⚠️ Erro ao acessar profiles:", data); - return []; - } - - console.log(` ✅ Encontrados ${data.length} registro(s) em profiles`); - data.forEach((profile, i) => { - console.log(`\n 👤 Usuário ${i + 1}:`); - console.log(` ID: ${profile.id}`); - console.log(` Nome: ${profile.full_name || profile.name}`); - console.log(` Email: ${profile.email}`); - console.log( - ` Telefone: ${profile.phone_mobile || profile.phone || "N/A"}` - ); - console.log(` Criado em: ${profile.created_at}`); - }); - - return data; - } catch (error) { - console.error(" ❌ Erro:", error.message); - return []; - } -} - -async function checkPatients() { - console.log("\n📋 Verificando tabela patients..."); - - try { - const response = await fetch( - `${SUPABASE_URL}/rest/v1/patients?email=ilike.*${emailToSearch}*&select=*`, - { - method: "GET", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${SUPABASE_ANON_KEY}`, - }, - } - ); - - const data = await response.json(); - - if (!response.ok) { - console.log(" ⚠️ Erro ao acessar patients:", data); - return []; - } - - console.log(` ✅ Encontrados ${data.length} registro(s) em patients`); - data.forEach((patient, i) => { - console.log(`\n 🏥 Paciente ${i + 1}:`); - console.log(` ID: ${patient.id}`); - console.log(` Nome: ${patient.full_name}`); - console.log(` Email: ${patient.email}`); - console.log(` CPF: ${patient.cpf || "N/A"}`); - console.log(` Telefone: ${patient.phone_mobile || "N/A"}`); - console.log(` Criado em: ${patient.created_at}`); - }); - - return data; - } catch (error) { - console.error(" ❌ Erro:", error.message); - return []; - } -} - -async function checkUsers() { - console.log( - "\n📋 Tentando verificar auth.users (pode falhar por permissões)..." - ); - - try { - const response = await fetch(`${SUPABASE_URL}/auth/v1/admin/users`, { - method: "GET", - headers: { - "Content-Type": "application/json", - apikey: SUPABASE_ANON_KEY, - Authorization: `Bearer ${SUPABASE_ANON_KEY}`, - }, - }); - - const data = await response.json(); - - if (!response.ok) { - console.log(" ⚠️ Sem permissão para acessar auth.users (normal)"); - return []; - } - - const filtered = - data.users?.filter((u) => u.email?.includes(emailToSearch)) || []; - console.log( - ` ✅ Encontrados ${filtered.length} usuário(s) em auth.users` - ); - - return filtered; - } catch (error) { - console.log(" ⚠️ Sem acesso a auth.users (normal para anon key)"); - return []; - } -} - -async function run() { - const profiles = await checkProfiles(); - const patients = await checkPatients(); - await checkUsers(); - - console.log("\n" + "=".repeat(60)); - console.log("📊 RESUMO"); - console.log("=".repeat(60)); - console.log(`Registros em profiles: ${profiles.length}`); - console.log(`Registros em patients: ${patients.length}`); - - if (profiles.length > 0 && patients.length > 0) { - console.log("\n✅ SUCESSO! Usuário criado em ambas as tabelas!"); - } else if (profiles.length > 0) { - console.log("\n⚠️ Usuário criado em profiles, mas não em patients"); - } else if (patients.length > 0) { - console.log("\n⚠️ Registro em patients, mas não em profiles"); - } else { - console.log("\n❌ Nenhum registro encontrado"); - } - console.log("=".repeat(60)); -} - -run(); diff --git a/MEDICONNECT 2/src/App.tsx b/MEDICONNECT 2/src/App.tsx index 8017ef03a..a94a1d055 100644 --- a/MEDICONNECT 2/src/App.tsx +++ b/MEDICONNECT 2/src/App.tsx @@ -24,13 +24,20 @@ import TokenInspector from "./pages/TokenInspector"; import AdminDiagnostico from "./pages/AdminDiagnostico"; import TesteCadastroSquad18 from "./pages/TesteCadastroSquad18"; import PainelAdmin from "./pages/PainelAdmin"; +import CentralAjudaRouter from "./pages/CentralAjudaRouter"; function App() { return ( -
+
+ + Pular para o conteúdo +
-
+
} /> } /> @@ -42,6 +49,7 @@ function App() { } /> } /> } /> + } /> }> } /> diff --git a/MEDICONNECT 2/src/__tests__/accessibility.test.tsx b/MEDICONNECT 2/src/__tests__/accessibility.test.tsx deleted file mode 100644 index 0b3951315..000000000 --- a/MEDICONNECT 2/src/__tests__/accessibility.test.tsx +++ /dev/null @@ -1,131 +0,0 @@ -// Ambiente jsdom para testar hooks que manipulam document.documentElement -import { describe, it, expect, beforeEach, vi } from "vitest"; -import { - STORAGE_KEY, - DEFAULT_ACCESSIBILITY_PREFS, - applyAccessibilityPrefsForTest, -} from "../hooks/useAccessibilityPrefs"; -import * as pacienteService from "../services/pacienteService"; - -// Pequeno mock de localStorage para ambiente de teste jsdom - -describe("useAccessibilityPrefs", () => { - beforeEach(() => { - // Limpa storage entre testes - for (let i = 0; i < global.localStorage.length; i++) { - const key = global.localStorage.key(i); - if (key) global.localStorage.removeItem(key); - } - document.documentElement.className = ""; - document.documentElement.style.fontSize = ""; - }); - - it("aplica classe dark ao ativar darkMode", () => { - const prefs = { ...DEFAULT_ACCESSIBILITY_PREFS, darkMode: true }; - applyAccessibilityPrefsForTest(prefs); - expect(document.documentElement.classList.contains("dark")).toBe(true); - }); - - it("aplica/remover classes para cada preferência boolean", () => { - const mapping: Array< - [keyof typeof DEFAULT_ACCESSIBILITY_PREFS, string | null] - > = [ - ["highContrast", "high-contrast"], - ["darkMode", "dark"], - ["dyslexicFont", "dyslexic-font"], - ["lineSpacing", "line-spacing"], - ["reducedMotion", "reduced-motion"], - ["lowBlueLight", "low-blue-light"], - ["focusMode", "focus-mode"], - ]; - for (const [key, className] of mapping) { - if (!className) continue; - const prefsOn = { - ...DEFAULT_ACCESSIBILITY_PREFS, - [key]: true, - } as typeof DEFAULT_ACCESSIBILITY_PREFS; - applyAccessibilityPrefsForTest(prefsOn); - expect(document.documentElement.classList.contains(className)).toBe(true); - const prefsOff = { - ...DEFAULT_ACCESSIBILITY_PREFS, - [key]: false, - } as typeof DEFAULT_ACCESSIBILITY_PREFS; - applyAccessibilityPrefsForTest(prefsOff); - expect(document.documentElement.classList.contains(className)).toBe( - false - ); - } - }); - - it("persiste alterações no localStorage", () => { - const updated = { - ...DEFAULT_ACCESSIBILITY_PREFS, - highContrast: true, - fontSize: 120, - }; - localStorage.setItem(STORAGE_KEY, JSON.stringify(updated)); - const raw = localStorage.getItem(STORAGE_KEY); - expect(raw).not.toBeNull(); - const parsed = JSON.parse(raw!); - expect(parsed.highContrast).toBe(true); - expect(parsed.fontSize).toBe(120); - }); - - it("reset volta ao estado padrão removendo classes e restaurando font-size", () => { - const modified = { - ...DEFAULT_ACCESSIBILITY_PREFS, - darkMode: true, - highContrast: true, - fontSize: 150, - }; - applyAccessibilityPrefsForTest(modified); - expect(document.documentElement.classList.contains("dark")).toBe(true); - expect(document.documentElement.style.fontSize).toBe("150%"); - // Aplica defaults - applyAccessibilityPrefsForTest(DEFAULT_ACCESSIBILITY_PREFS); - expect(document.documentElement.classList.contains("dark")).toBe(false); - expect(document.documentElement.classList.contains("high-contrast")).toBe( - false - ); - expect(document.documentElement.style.fontSize).toBe("100%"); - }); -}); - -describe("pacienteService normalização", () => { - it("remove formatação de cpf, telefone e cep em createPatient", async () => { - const originalPost = (await import("../services/http")).http.post; - const mockPost = vi - .fn() - .mockResolvedValue({ - success: true, - data: [ - { - id: "abc", - full_name: "Fulano", - cpf: "12345678909", - phone_mobile: "11988887777", - }, - ], - }); - // Monkey patch simples - // Type assertion específica para sobrescrever somente durante o teste - (await import("../services/http")).http.post = - mockPost as unknown as typeof originalPost; - - await pacienteService.createPatient({ - nome: "Fulano", - cpf: "123.456.789-09", - email: "fulano@example.com", - telefone: "(11) 98888-7777", - endereco: { cep: "01001-000" }, - }); - expect(mockPost).toHaveBeenCalledTimes(1); - const bodyArg = mockPost.mock.calls[0][1]; - expect(bodyArg.cpf).toBe("12345678909"); - expect(bodyArg.phone_mobile).toBe("11988887777"); - expect(bodyArg.cep).toBe("01001000"); - - // restore - (await import("../services/http")).http.post = originalPost; - }); -}); diff --git a/MEDICONNECT 2/src/__tests__/accessibilityMenu.axe.test.tsx b/MEDICONNECT 2/src/__tests__/accessibilityMenu.axe.test.tsx deleted file mode 100644 index 27317e131..000000000 --- a/MEDICONNECT 2/src/__tests__/accessibilityMenu.axe.test.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { describe, it, expect, beforeAll } from "vitest"; -import { render } from "@testing-library/react"; -import AccessibilityMenu from "../components/AccessibilityMenu"; -import { - DEFAULT_ACCESSIBILITY_PREFS, - applyAccessibilityPrefsForTest, -} from "../hooks/useAccessibilityPrefs"; -import axe from "axe-core"; -import * as React from "react"; -import * as ReactDOM from "react-dom"; -import axeReact from "@axe-core/react"; - -// Teste básico: montar o menu e verificar ausência de violações "serious" ou "critical" - -describe("AccessibilityMenu a11y", () => { - beforeAll(() => { - // Mock minimal de speechSynthesis para evitar erros em jsdom - // @ts-expect-error mocking - global.window.speechSynthesis = { - cancel: () => {}, - speak: () => {}, - paused: false, - pending: false, - speaking: false, - addEventListener: () => {}, - removeEventListener: () => {}, - dispatchEvent: () => true, - }; - axeReact(React, ReactDOM, 1000); - }); - - it("não possui violações sérias/criticas no estado inicial", async () => { - applyAccessibilityPrefsForTest(DEFAULT_ACCESSIBILITY_PREFS); - const { container } = render(); - // Espera para que listeners/efeitos terminem - await new Promise((r) => setTimeout(r, 20)); - const results = await axe.run(container, { - runOnly: ["wcag2a", "wcag2aa"], - }); - const serious = results.violations.filter((v) => - ["serious", "critical"].includes(v.impact || "") - ); - if (serious.length) { - console.error( - "A11y Violations:", - serious.map((v) => ({ - id: v.id, - impact: v.impact, - nodes: v.nodes.length, - })) - ); - } - expect(serious.length).toBe(0); - }); -}); diff --git a/MEDICONNECT 2/src/__tests__/accessibilityMenu.e2e.test.ts b/MEDICONNECT 2/src/__tests__/accessibilityMenu.e2e.test.ts deleted file mode 100644 index 1d7945510..000000000 --- a/MEDICONNECT 2/src/__tests__/accessibilityMenu.e2e.test.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { describe, it, expect, beforeAll, afterAll } from "vitest"; -import puppeteer, { Browser, Page } from "puppeteer"; -import * as net from "net"; -import { build, preview } from "vite"; - -// Porta padrão do Vite -const PORT = 5173; -const ORIGIN = `http://127.0.0.1:${PORT}`; - -function waitForPort(port: number, timeoutMs = 20000): Promise { - const start = Date.now(); - return new Promise((resolve, reject) => { - const tryOnce = () => { - const socket = net.connect(port, "127.0.0.1"); - socket.on("connect", () => { - socket.end(); - resolve(); - }); - socket.on("error", () => { - socket.destroy(); - if (Date.now() - start > timeoutMs) - reject(new Error("Timeout aguardando Vite dev server")); - else setTimeout(tryOnce, 300); - }); - }; - tryOnce(); - }); -} - -let browser: Browser; -let page: Page; -let previewServer: Awaited> | undefined; -let built = false; - -async function ensurePreviewServer() { - // Se já existe algo na porta (ex dev aberto manualmente), apenas usa - try { - await waitForPort(PORT, 800); - return; - } catch { - /* inicia preview */ - } - - if (!built) { - await build(); - built = true; - } - previewServer = await preview({ - preview: { port: PORT, host: "127.0.0.1" }, - server: { middlewareMode: false }, - } as unknown as Parameters[0]); - await waitForPort(PORT); -} - -describe("E2E Accessibility Menu", () => { - beforeAll(async () => { - await ensurePreviewServer(); - browser = await puppeteer.launch({ headless: true }); - page = await browser.newPage(); - await page.goto(ORIGIN, { waitUntil: "domcontentloaded" }); - }, 90000); - - afterAll(async () => { - if (browser) await browser.close(); - if (previewServer) { - // @ts-expect-error acesso interno não tipado - const httpServer = - previewServer.httpServer || previewServer.server?.httpServer; - if (httpServer) httpServer.close(); - } - }); - - it("abre e fecha o diálogo de acessibilidade", async () => { - // Botão flutuante - await page.waitForSelector('button[aria-label="Menu de Acessibilidade"]', { - timeout: 10000, - }); - await page.click('button[aria-label="Menu de Acessibilidade"]'); - await page.waitForSelector('div[role="dialog"][aria-modal="true"]', { - timeout: 5000, - }); - const exists = await page.$('div[role="dialog"][aria-modal="true"]'); - expect(exists).not.toBeNull(); - // Pressiona ESC para fechar - await page.keyboard.press("Escape"); - // Pequeno delay - await new Promise((r) => setTimeout(r, 150)); - const still = await page.$('div[role="dialog"][aria-modal="true"]'); - expect(still).toBeNull(); - }, 30000); - - it("ativa dark mode e alto contraste e persiste após reload", async () => { - // Abre menu (caso esteja fechado) - const trigger = await page.$('button[aria-label="Menu de Acessibilidade"]'); - if (trigger) { - await trigger.click(); - await page.waitForSelector('div[role="dialog"][aria-modal="true"]', { - timeout: 5000, - }); - } - - // Helper para clicar botão pelo texto visível interno - async function clickToggleByAria(label: string) { - const selector = `button[aria-label="${label}"]`; - await page.waitForSelector(selector, { timeout: 5000 }); - await page.click(selector); - } - - // Ativa Modo Escuro e Alto Contraste (aria-label fica igual ao label) - await clickToggleByAria("Modo Escuro"); - await clickToggleByAria("Alto Contraste"); - - // Verifica classes aplicadas - const classesBefore = await page.evaluate(() => - Array.from(document.documentElement.classList) - ); - expect(classesBefore).toContain("dark"); - expect(classesBefore).toContain("high-contrast"); - - // Recarrega página para validar persistência (localStorage -> rehidratação) - await page.reload({ waitUntil: "domcontentloaded" }); - - const classesAfter = await page.evaluate(() => - Array.from(document.documentElement.classList) - ); - expect(classesAfter).toContain("dark"); - expect(classesAfter).toContain("high-contrast"); - - // (Opcional) Reabre menu e desfaz para não impactar execuções subsequentes - const trigger2 = await page.$( - 'button[aria-label="Menu de Acessibilidade"]' - ); - if (trigger2) { - await trigger2.click(); - await page.waitForSelector('div[role="dialog"][aria-modal="true"]', { - timeout: 5000, - }); - await clickToggleByAria("Modo Escuro"); - await clickToggleByAria("Alto Contraste"); - await page.keyboard.press("Escape"); - } - }, 45000); -}); diff --git a/MEDICONNECT 2/src/__tests__/accessibilityMenu.semantic.test.tsx b/MEDICONNECT 2/src/__tests__/accessibilityMenu.semantic.test.tsx deleted file mode 100644 index 483adf856..000000000 --- a/MEDICONNECT 2/src/__tests__/accessibilityMenu.semantic.test.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { render, fireEvent, act } from "@testing-library/react"; -import AccessibilityMenu from "../components/AccessibilityMenu"; -// Diagnostics -console.log( - "AccessibilityMenu import type:", - typeof AccessibilityMenu, - AccessibilityMenu && Object.keys(AccessibilityMenu || {}) -); -import { - DEFAULT_ACCESSIBILITY_PREFS, - applyAccessibilityPrefsForTest, -} from "../hooks/useAccessibilityPrefs"; - -// Teste sem dependência de axe-core garantindo semântica mínima do diálogo - -describe.skip("AccessibilityMenu semântica (skip – aguardando correção de pipeline React)", () => { - it("abre e fecha mantendo atributos ARIA corretos", () => { - const Dummy = () => ; - const dummyRender = render(); - console.log("DUMMY_HTML", dummyRender.container.innerHTML); - dummyRender.unmount(); - applyAccessibilityPrefsForTest(DEFAULT_ACCESSIBILITY_PREFS); - const { getByTestId, queryByRole, container } = render( - - ); - expect(container).toBeTruthy(); - console.log("DEBUG_HTML", container.innerHTML); - const trigger = getByTestId("a11y-menu-trigger"); - act(() => { - fireEvent.click(trigger); - }); - const dialog = queryByRole("dialog"); - expect(dialog).not.toBeNull(); - expect(dialog?.getAttribute("aria-modal")).toBe("true"); - act(() => { - fireEvent.keyDown(document, { key: "Escape" }); - }); - expect(queryByRole("dialog")).toBeNull(); - }); - - it("aplica foco inicial ao abrir", () => { - const { getByTestId, queryByRole, container } = render( - - ); - expect(container).toBeTruthy(); - console.log("DEBUG_HTML", container.innerHTML); - act(() => { - fireEvent.click(getByTestId("a11y-menu-trigger")); - }); - const dialog = queryByRole("dialog") as HTMLElement; - expect(dialog).not.toBeNull(); - const active = document.activeElement as HTMLElement; - expect(dialog.contains(active)).toBe(true); - }); -}); diff --git a/MEDICONNECT 2/src/__tests__/manualRootRender.test.tsx b/MEDICONNECT 2/src/__tests__/manualRootRender.test.tsx deleted file mode 100644 index 94f27fbef..000000000 --- a/MEDICONNECT 2/src/__tests__/manualRootRender.test.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { describe, it, expect } from "vitest"; -import * as React from "react"; -import * as ReactDOMClient from "react-dom/client"; - -describe.skip("Manual root render (skip temporário – pipeline React em Vitest quebrado)", () => { - it("render via createRoot directly", async () => { - const host = document.createElement("div"); - document.body.appendChild(host); - const App = () => OK; - const root = ReactDOMClient.createRoot(host); - root.render(); - await Promise.resolve(); - console.log("HOST_HTML_AFTER", host.innerHTML); - expect(host.innerHTML).toContain("data-testid"); - }); -}); diff --git a/MEDICONNECT 2/src/__tests__/miniRender.test.tsx b/MEDICONNECT 2/src/__tests__/miniRender.test.tsx deleted file mode 100644 index cc293d8f7..000000000 --- a/MEDICONNECT 2/src/__tests__/miniRender.test.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { render } from "@testing-library/react"; -import * as React from "react"; -import * as ReactDOMClient from "react-dom/client"; - -const Mini = () => ; - -describe.skip("Mini sanity (skip temporário – pipeline React em Vitest quebrado)", () => { - it("renderiza componente simples", async () => { - console.log("React version:", React.version); - console.log("ReactDOMClient keys:", Object.keys(ReactDOMClient)); - const { getByTestId, container } = render(); - await Promise.resolve(); - console.log("MINI_HTML_AFTER_MT", container.innerHTML); - expect(container.innerHTML).toContain("button"); - expect(getByTestId("mini").textContent).toBe("Oi"); - }); -}); diff --git a/MEDICONNECT 2/src/__tests__/plainDom.test.ts b/MEDICONNECT 2/src/__tests__/plainDom.test.ts deleted file mode 100644 index dc71dcf2f..000000000 --- a/MEDICONNECT 2/src/__tests__/plainDom.test.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { describe, it, expect } from "vitest"; - -describe("Plain DOM sanity", () => { - it("manipula DOM sem React", () => { - const div = document.createElement("div"); - div.id = "x"; - div.textContent = "hello"; - document.body.appendChild(div); - expect(document.getElementById("x")?.textContent).toBe("hello"); - }); -}); diff --git a/MEDICONNECT 2/src/components/AccessibilityMenu.tsx b/MEDICONNECT 2/src/components/AccessibilityMenu.tsx index 84ca25fec..12bf4b94f 100644 --- a/MEDICONNECT 2/src/components/AccessibilityMenu.tsx +++ b/MEDICONNECT 2/src/components/AccessibilityMenu.tsx @@ -146,7 +146,7 @@ const AccessibilityMenu: React.FC = () => { <>
+
+ + + + {loading ? ( +
+
+
+ ) : list.length === 0 ? ( +
+ Nenhuma disponibilidade cadastrada. Use o formulário acima para + adicionar horários. +
+ ) : ( +
+ + + + + + + + + + + + + + {list.map((item) => ( + + + + + + + + + + ))} + +
+ Dia da Semana + + Horário Início + + Horário Fim + + Duração + + Tipo + + Status + + Ações +
+ {item.weekday + ? item.weekday.charAt(0).toUpperCase() + + item.weekday.slice(1) + : "-"} + + {item.start_time?.slice(0, 5)} + + {item.end_time?.slice(0, 5)} + + {item.slot_minutes || 30} min + + {item.appointment_type === "presencial" + ? "Presencial" + : "Telemedicina"} + + + + +
+
+ )} +
+ ); +}; + +export default AvailabilityManager; diff --git a/MEDICONNECT 2/src/components/agenda/AvailableSlotsPicker.tsx b/MEDICONNECT 2/src/components/agenda/AvailableSlotsPicker.tsx new file mode 100644 index 000000000..d3de6f638 --- /dev/null +++ b/MEDICONNECT 2/src/components/agenda/AvailableSlotsPicker.tsx @@ -0,0 +1,79 @@ +import React, { useEffect, useMemo, useState } from "react"; +import toast from "react-hot-toast"; +import { appointmentService } from "../../services"; + +interface Props { + doctorId: string; + date: string; // YYYY-MM-DD + onSelect: (time: string) => void; // HH:MM + appointment_type?: "presencial" | "telemedicina"; +} + +const AvailableSlotsPicker: React.FC = ({ + doctorId, + date, + onSelect, + appointment_type, +}) => { + const [slots, setSlots] = useState([]); + const [loading, setLoading] = useState(false); + + const range = useMemo(() => { + if (!date) return null; + const start = new Date(`${date}T00:00:00Z`).toISOString(); + const end = new Date(`${date}T23:59:59Z`).toISOString(); + return { start, end }; + }, [date]); + + useEffect(() => { + async function fetchSlots() { + if (!doctorId || !range) return; + setLoading(true); + const res = await appointmentService.getAvailableSlots({ + doctor_id: doctorId, + start_date: range.start, + end_date: range.end, + appointment_type, + }); + setLoading(false); + if (res.success && res.data) { + const times = res.data.slots + .filter((s) => s.available) + .map((s) => s.datetime.slice(11, 16)); + setSlots(times); + } else { + toast.error(res.error || "Erro ao buscar horários"); + } + } + void fetchSlots(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [doctorId, date, appointment_type]); + + if (!date || !doctorId) return null; + + if (loading) + return
Carregando horários...
; + + if (!slots.length) + return ( +
+ Nenhum horário disponível para a data selecionada. +
+ ); + + return ( +
+ {slots.map((t) => ( + + ))} +
+ ); +}; + +export default AvailableSlotsPicker; diff --git a/MEDICONNECT 2/src/components/agenda/DoctorCalendar.tsx b/MEDICONNECT 2/src/components/agenda/DoctorCalendar.tsx new file mode 100644 index 000000000..d9fd7f0f1 --- /dev/null +++ b/MEDICONNECT 2/src/components/agenda/DoctorCalendar.tsx @@ -0,0 +1,459 @@ +// UI/UX refresh: melhorias visuais e de acessibilidade sem alterar a lógica +import React, { useEffect, useState } from "react"; +import toast from "react-hot-toast"; +import { appointmentService } from "../../services"; +import pacienteService from "../../services/pacienteService"; +import type { Appointment } from "../../services/appointmentService"; +import { ChevronLeft, ChevronRight, X } from "lucide-react"; + +interface Props { + doctorId: string; +} + +interface CalendarDay { + date: Date; + dateStr: string; + isCurrentMonth: boolean; + isToday: boolean; + appointments: Appointment[]; +} + +const WEEKDAYS = ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"]; +const MONTHS = [ + "Janeiro", + "Fevereiro", + "Março", + "Abril", + "Maio", + "Junho", + "Julho", + "Agosto", + "Setembro", + "Outubro", + "Novembro", + "Dezembro", +]; + +const DoctorCalendar: React.FC = ({ doctorId }) => { + const [currentDate, setCurrentDate] = useState(new Date()); + const [appointments, setAppointments] = useState([]); + const [loading, setLoading] = useState(false); + const [selectedDay, setSelectedDay] = useState(null); + const [patientsById, setPatientsById] = useState>({}); + + useEffect(() => { + if (doctorId) { + loadAppointments(); + loadPatients(); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [doctorId, currentDate]); + + async function loadAppointments() { + setLoading(true); + try { + const response = await appointmentService.listAppointments(); + if (response.success && response.data) { + // Filtrar apenas do médico selecionado + const filtered = response.data.filter( + (apt) => apt.doctor_id === doctorId + ); + setAppointments(filtered); + } else { + toast.error(response.error || "Erro ao carregar agendamentos"); + } + } catch (error) { + console.error("Erro ao carregar agendamentos:", error); + toast.error("Erro ao carregar agendamentos"); + } finally { + setLoading(false); + } + } + + async function loadPatients() { + // Carrega pacientes para mapear nome pelo id (render amigável) + try { + const res = await pacienteService.listPatients(); + if (res && Array.isArray(res.data)) { + const map: Record = {}; + for (const p of res.data) { + if (p?.id) map[p.id] = p.nome || p.email || p.cpf || p.id; + } + setPatientsById(map); + } else if ( + res && + typeof (res as unknown) === "object" && + ( + res as { + data?: { + data?: Array<{ + id?: string; + nome?: string; + email?: string; + cpf?: string; + }>; + }; + } + ).data?.data + ) { + const list = + ( + res as { + data?: { + data?: Array<{ + id?: string; + nome?: string; + email?: string; + cpf?: string; + }>; + }; + } + ).data?.data || []; + const map: Record = {}; + for (const p of list) { + if (p?.id) map[p.id] = p.nome || p.email || p.cpf || p.id; + } + setPatientsById(map); + } + } catch { + // silencioso; não bloqueia calendário + } finally { + /* no-op */ + } + } + + function getPatientName(id?: string) { + if (!id) return ""; + return patientsById[id] || id; + } + + function getCalendarDays(): CalendarDay[] { + const year = currentDate.getFullYear(); + const month = currentDate.getMonth(); + + // Primeiro dia do mês + const firstDay = new Date(year, month, 1); + // Último dia do mês + const lastDay = new Date(year, month + 1, 0); + + // Dia da semana do primeiro dia (0 = domingo) + const startingDayOfWeek = firstDay.getDay(); + + const days: CalendarDay[] = []; + const today = new Date(); + today.setHours(0, 0, 0, 0); + + // Adicionar dias do mês anterior + const prevMonthLastDay = new Date(year, month, 0); + for (let i = startingDayOfWeek - 1; i >= 0; i--) { + const date = new Date(year, month - 1, prevMonthLastDay.getDate() - i); + const dateStr = formatDateISO(date); + days.push({ + date, + dateStr, + isCurrentMonth: false, + isToday: false, + appointments: getAppointmentsForDate(dateStr), + }); + } + + // Adicionar dias do mês atual + for (let day = 1; day <= lastDay.getDate(); day++) { + const date = new Date(year, month, day); + const dateStr = formatDateISO(date); + const isToday = date.getTime() === today.getTime(); + days.push({ + date, + dateStr, + isCurrentMonth: true, + isToday, + appointments: getAppointmentsForDate(dateStr), + }); + } + + // Adicionar dias do próximo mês para completar a grade + const remainingDays = 42 - days.length; // 6 semanas x 7 dias + for (let day = 1; day <= remainingDays; day++) { + const date = new Date(year, month + 1, day); + const dateStr = formatDateISO(date); + days.push({ + date, + dateStr, + isCurrentMonth: false, + isToday: false, + appointments: getAppointmentsForDate(dateStr), + }); + } + + return days; + } + + function formatDateISO(date: Date): string { + return date.toISOString().split("T")[0]; + } + + function getAppointmentsForDate(dateStr: string): Appointment[] { + return appointments.filter((apt) => { + if (!apt.scheduled_at) return false; + const aptDate = apt.scheduled_at.split("T")[0]; + return aptDate === dateStr; + }); + } + + function previousMonth() { + setCurrentDate( + new Date(currentDate.getFullYear(), currentDate.getMonth() - 1, 1) + ); + } + + function nextMonth() { + setCurrentDate( + new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 1) + ); + } + + function goToToday() { + setCurrentDate(new Date()); + } + + function getStatusColor(status?: string): string { + switch (status) { + case "confirmed": + return "bg-blue-500"; + case "completed": + return "bg-green-500"; + case "cancelled": + return "bg-red-500"; + case "no_show": + return "bg-gray-500"; + case "checked_in": + return "bg-purple-500"; + case "in_progress": + return "bg-yellow-500"; + default: + return "bg-orange-500"; // requested + } + } + + function getStatusLabel(status?: string): string { + const labels: Record = { + requested: "Solicitado", + confirmed: "Confirmado", + checked_in: "Check-in", + in_progress: "Em andamento", + completed: "Concluído", + cancelled: "Cancelado", + no_show: "Faltou", + }; + return labels[status || "requested"] || status || "Solicitado"; + } + + const calendarDays = getCalendarDays(); + + return ( +
+ {/* Cabeçalho modernizado: melhor contraste, foco e navegação */} +
+

+ Calendário de Consultas +

+
+ +
+ + + {MONTHS[currentDate.getMonth()]} {currentDate.getFullYear()} + + +
+
+
+ + {loading ? ( +
+
+
+ ) : ( + <> + {/* Cabeçalhos dos dias da semana */} +
+ {WEEKDAYS.map((day) => ( +
+ {day} +
+ ))} +
+ + {/* Grid do calendário com células interativas acessíveis */} +
+ {calendarDays.map((day, index) => ( +
0 + ? "cursor-pointer hover:bg-blue-50" + : "" + }`} + onClick={() => + day.appointments.length > 0 && setSelectedDay(day) + } + > + {/* Número do dia com destaque para hoje */} +
+ {day.date.getDate()} +
+ {/* Chips de horários com cores por status */} +
+ {day.appointments.slice(0, 3).map((apt, idx) => ( +
+ {apt.scheduled_at?.slice(11, 16)} +
+ ))} + {day.appointments.length > 3 && ( +
+ +{day.appointments.length - 3} mais +
+ )} +
+
+ ))} +
+ + )} + + {/* Modal de detalhes do dia - melhorado com acessibilidade e botão de fechar */} + {selectedDay && ( +
setSelectedDay(null)} + role="dialog" + aria-modal="true" + aria-label="Consultas do dia selecionado" + > +
e.stopPropagation()} + > +
+

+ Consultas de{" "} + {selectedDay.date.toLocaleDateString("pt-BR", { + weekday: "long", + day: "numeric", + month: "long", + year: "numeric", + })} +

+ +
+
+ {selectedDay.appointments.length === 0 ? ( +

+ Nenhuma consulta agendada para este dia. +

+ ) : ( + selectedDay.appointments.map((apt) => ( +
+
+
+
+ + {apt.scheduled_at?.slice(11, 16)} + + + {getStatusLabel(apt.status)} + +
+
+
+ Paciente:{" "} + {getPatientName(apt.patient_id)} +
+ {apt.appointment_type && ( +
+ Tipo:{" "} + {apt.appointment_type === "presencial" + ? "Presencial" + : "Telemedicina"} +
+ )} + {apt.chief_complaint && ( +
+ Queixa:{" "} + {apt.chief_complaint} +
+ )} +
+
+
+
+ )) + )} +
+
+ +
+
+
+ )} +
+ ); +}; + +export default DoctorCalendar; diff --git a/MEDICONNECT 2/src/components/agenda/ExceptionsManager.tsx b/MEDICONNECT 2/src/components/agenda/ExceptionsManager.tsx new file mode 100644 index 000000000..397ce3758 --- /dev/null +++ b/MEDICONNECT 2/src/components/agenda/ExceptionsManager.tsx @@ -0,0 +1,265 @@ +import React, { useEffect, useState } from "react"; +import toast from "react-hot-toast"; +import { exceptionService } from "../../services"; +import type { + DoctorException, + ExceptionKind, +} from "../../services/exceptionService"; + +interface Props { + doctorId: string; +} + +const ExceptionsManager: React.FC = ({ doctorId }) => { + const [list, setList] = useState([]); + const [loading, setLoading] = useState(false); + const [form, setForm] = useState({ + date: "", + start_time: "", + end_time: "", + kind: "bloqueio" as ExceptionKind, + reason: "", + }); + const [saving, setSaving] = useState(false); + + async function load() { + if (!doctorId) return; + setLoading(true); + const res = await exceptionService.listExceptions({ doctor_id: doctorId }); + if (res.success && res.data) setList(res.data); + else toast.error(res.error || "Erro ao carregar exceções"); + setLoading(false); + } + + useEffect(() => { + void load(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [doctorId]); + + async function addException(e: React.FormEvent) { + e.preventDefault(); + if (!doctorId || !form.date || !form.kind) { + toast.error("Preencha data e tipo"); + return; + } + setSaving(true); + const res = await exceptionService.createException({ + doctor_id: doctorId, + date: form.date, + start_time: form.start_time || undefined, + end_time: form.end_time || undefined, + kind: form.kind, + reason: form.reason || undefined, + }); + setSaving(false); + if (res.success) { + toast.success("Exceção criada"); + setForm({ + date: "", + start_time: "", + end_time: "", + kind: "bloqueio", + reason: "", + }); + void load(); + } else toast.error(res.error || "Falha ao criar"); + } + + async function remove(item: DoctorException) { + if (!item.id) return; + const ok = confirm("Remover exceção?"); + if (!ok) return; + const res = await exceptionService.deleteException(item.id); + if (res.success) { + toast.success("Removida"); + void load(); + } else toast.error(res.error || "Falha ao remover"); + } + + return ( +
+

+ Exceções (Bloqueios/Liberações) +

+
+
+
+ + setForm((f) => ({ ...f, date: e.target.value }))} + className="px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-600 focus:border-blue-600/40 transition-colors" + required + /> +
+
+ + + setForm((f) => ({ ...f, start_time: e.target.value })) + } + className="px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-600 focus:border-blue-600/40 transition-colors" + placeholder="Dia todo" + /> +
+
+ + + setForm((f) => ({ ...f, end_time: e.target.value })) + } + className="px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-600 focus:border-blue-600/40 transition-colors" + placeholder="Dia todo" + /> +
+
+ + +
+
+ + + setForm((f) => ({ ...f, reason: e.target.value })) + } + className="px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-600 focus:border-blue-600/40 transition-colors" + placeholder="Ex.: Férias, Reunião, etc." + /> +
+
+ +
+
+
+ + {loading ? ( +
+
+
+ ) : list.length === 0 ? ( +
+ Nenhuma exceção cadastrada. Use o formulário acima para + bloquear/liberar horários. +
+ ) : ( +
+ + + + + + + + + + + + + {list.map((item) => ( + + + + + + + + + ))} + +
+ Data + + Horário Início + + Horário Fim + + Tipo + + Motivo + + Ações +
+ {item.date + ? new Date(item.date + "T00:00:00").toLocaleDateString( + "pt-BR" + ) + : "—"} + + {item.start_time ? ( + item.start_time.slice(0, 5) + ) : ( + Dia todo + )} + + {item.end_time ? ( + item.end_time.slice(0, 5) + ) : ( + Dia todo + )} + + + {item.kind === "bloqueio" ? "Bloqueio" : "Liberação"} + + + {item.reason || } + + +
+
+ )} +
+ ); +}; + +export default ExceptionsManager; diff --git a/MEDICONNECT 2/src/components/agenda/ScheduleAppointmentModal.tsx b/MEDICONNECT 2/src/components/agenda/ScheduleAppointmentModal.tsx new file mode 100644 index 000000000..869d01c71 --- /dev/null +++ b/MEDICONNECT 2/src/components/agenda/ScheduleAppointmentModal.tsx @@ -0,0 +1,428 @@ +// UI/UX: adiciona refs e ícones para melhorar acessibilidade e feedback visual +import React, { useState, useEffect, useMemo, useRef } from "react"; +import { + Calendar as CalendarIcon, + Clock, + Loader2, + Stethoscope, + X, +} from "lucide-react"; +import toast from "react-hot-toast"; +import { appointmentService } from "../../services"; +import medicoService, { type Medico } from "../../services/medicoService"; +import pacienteService from "../../services/pacienteService"; +import type { Paciente as PacienteModel } from "../../services/pacienteService"; +import AvailableSlotsPicker from "./AvailableSlotsPicker"; + +interface Props { + isOpen: boolean; + onClose: () => void; + patientId?: string; // opcional: quando não informado, seleciona paciente no modal + patientName?: string; // opcional + onSuccess?: () => void; +} + +const ScheduleAppointmentModal: React.FC = ({ + isOpen, + onClose, + patientId, + patientName, + onSuccess, +}) => { + const [doctors, setDoctors] = useState([]); + const [loadingDoctors, setLoadingDoctors] = useState(false); + const [patients, setPatients] = useState([]); + const [loadingPatients, setLoadingPatients] = useState(false); + + const [selectedDoctorId, setSelectedDoctorId] = useState(""); + const [selectedDate, setSelectedDate] = useState(""); + const [selectedTime, setSelectedTime] = useState(""); + const [appointmentType, setAppointmentType] = useState< + "presencial" | "telemedicina" + >("presencial"); + const [reason, setReason] = useState(""); + const [loading, setLoading] = useState(false); + const [selectedPatientId, setSelectedPatientId] = useState(""); + const [selectedPatientName, setSelectedPatientName] = useState(""); + + // A11y & UX: refs para foco inicial e fechamento via overlay/ESC + const overlayRef = useRef(null); + const dialogRef = useRef(null); + const firstFieldRef = useRef(null); + const closeBtnRef = useRef(null); + + // A11y: IDs para aria-labelledby/aria-describedby + const titleId = useMemo( + () => `schedule-modal-title-${patientId ?? "novo"}`, + [patientId] + ); + const descId = useMemo( + () => `schedule-modal-desc-${patientId ?? "novo"}`, + [patientId] + ); + + useEffect(() => { + if (isOpen) { + loadDoctors(); + if (!patientId) { + loadPatients(); + } else { + // Garantir estados internos alinhados com props + setSelectedPatientId(patientId); + setSelectedPatientName(patientName || ""); + } + // UX: foco no primeiro campo quando abrir + setTimeout(() => firstFieldRef.current?.focus(), 0); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isOpen]); + + async function loadDoctors() { + setLoadingDoctors(true); + const res = await medicoService.listarMedicos(); + setLoadingDoctors(false); + if (res.success && res.data) { + setDoctors(res.data.data); // res.data é MedicoListResponse, res.data.data é Medico[] + } else { + toast.error("Erro ao carregar médicos"); + } + } + + async function loadPatients() { + setLoadingPatients(true); + try { + const res = await pacienteService.listPatients(); + setLoadingPatients(false); + if (res && Array.isArray(res.data)) { + setPatients(res.data); + } else if ( + res && + typeof (res as unknown) === "object" && + (res as { data?: { data?: PacienteModel[] } }).data?.data + ) { + // fallback caso formato mude (evita any explícito) + setPatients( + (res as { data?: { data?: PacienteModel[] } }).data?.data || [] + ); + } else { + toast.error("Erro ao carregar pacientes"); + } + } catch { + setLoadingPatients(false); + toast.error("Erro ao carregar pacientes"); + } + } + + async function handleSubmit(e: React.FormEvent) { + e.preventDefault(); + + const finalPatientId = patientId || selectedPatientId; + if ( + !selectedDoctorId || + !selectedDate || + !selectedTime || + !finalPatientId + ) { + toast.error("Preencha médico, data e horário"); + return; + } + + setLoading(true); + + const datetime = `${selectedDate}T${selectedTime}:00`; + + const res = await appointmentService.createAppointment({ + patient_id: finalPatientId, + doctor_id: selectedDoctorId, + scheduled_at: datetime, + appointment_type: appointmentType, + chief_complaint: reason || undefined, + }); + + setLoading(false); + + if (res.success) { + toast.success("Agendamento criado com sucesso!"); + onSuccess?.(); + handleClose(); + } else { + toast.error(res.error || "Erro ao criar agendamento"); + } + } + + function handleClose() { + setSelectedDoctorId(""); + setSelectedDate(""); + setSelectedTime(""); + setAppointmentType("presencial"); + setReason(""); + setSelectedPatientId(""); + setSelectedPatientName(""); + onClose(); + } + + if (!isOpen) return null; + + const selectedDoctor = doctors.find((d) => d.id === selectedDoctorId); + const patientPreselected = !!patientId; + const effectivePatientName = patientPreselected + ? patientName + : selectedPatientName || + (patients.find((p) => p.id === selectedPatientId)?.nome ?? ""); + + // UX: handlers para ESC e clique fora + function onKeyDown(e: React.KeyboardEvent) { + if (e.key === "Escape") { + e.stopPropagation(); + handleClose(); + } + } + function onOverlayClick(e: React.MouseEvent) { + if (e.target === overlayRef.current) handleClose(); + } + + return ( +
+
e.stopPropagation()} + > +
+
+
+ +
+ +

+ Selecione o médico, a data, o tipo de consulta e um horário disponível + para criar um novo agendamento. +

+ +
+ {/* Paciente (apenas quando não veio por props) */} + {!patientPreselected && ( +
+ + {loadingPatients ? ( + // Skeleton para carregamento de pacientes +
+ ) : ( + + )} +
+ )} + {/* Médico */} +
+ + {loadingDoctors ? ( +
+ ) : ( + + )} + {selectedDoctor && ( +
+ CRM: {selectedDoctor.crm} +
+ )} +
+ + {/* Data */} +
+ + { + setSelectedDate(e.target.value); + setSelectedTime(""); // Limpa o horário ao mudar a data + }} + min={new Date().toISOString().split("T")[0]} + className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-600 focus:border-blue-600/40 transition-colors" + required + /> +

+ Selecione uma data para + ver os horários disponíveis. +

+
+ + {/* Tipo de Consulta */} +
+ + +

+ O tipo de consulta pode alterar + a disponibilidade de horários. +

+
+ + {/* Horários Disponíveis */} + {selectedDoctorId && selectedDate && ( +
+ + setSelectedTime(time)} + /> + {selectedTime && ( +
+ Horário selecionado:{" "} + {selectedTime} +
+ )} +
+ )} + + {/* Motivo */} +
+ +