From 6cdf609f62c150e5acdd048e6d0d075f0d60657d Mon Sep 17 00:00:00 2001 From: Sidney Date: Mon, 25 May 2026 09:35:07 -0300 Subject: [PATCH] fix(students): apply biometrics mapping in getAlunos, persist face_descriptor in postgres and document status in GEMINI.md --- GEMINI.md | 2 ++ manager/services/database.js | 15 +++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/GEMINI.md b/GEMINI.md index 098a8cb..7220c46 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -70,3 +70,5 @@ 41. **Database Schema Sync**: Sempre garanta que as tabelas de destino possuam colunas como `is_deleted` e demais modificadores antes de habilitar rotas PUT/DELETE, pois a ausência do schema falhará silenciosamente no Express 5. 42. **Cronological Display Standard**: Consultas a cadastros secundários (como Disciplinas e Categorias) DEVEM utilizar `ORDER BY created_at ASC` no SQL para manter a mesma ordem de listagem original do sistema (evitando reordenação alfabética não-intencional). 43. **Mass Contracts Update**: A edição de um "Modelo de Contrato" dispara atualizações em massa (PUT `/api/contratos/:id`) recalcularizando as variáveis de todos os contratos já emitidos para os alunos vinculados àquele modelo, garantindo atualização em tempo real no Portal do Aluno via SQL. +44. **Biometria SQL-First Parcial**: A biometria (faceDescriptor) já está preparada para persistência nativa na coluna jsonb 'face_descriptor' do PostgreSQL (com mapeamento camelCase na API). Contudo, o cadastro de alunos via Manager ainda não utiliza a API SQL em sua plenitude no handleSave. Até a refatoração do Students.tsx, os alunos novos continuarão dependendo do fallback do school_data.json. + \ No newline at end of file diff --git a/manager/services/database.js b/manager/services/database.js index ba8efaf..86fd13b 100644 --- a/manager/services/database.js +++ b/manager/services/database.js @@ -651,7 +651,8 @@ export async function getAlunos() { cpf: r.cpf, phone: r.telefone, registrationDate: r.data_matricula, - contractTemplateId: r.modelo_contrato_id + contractTemplateId: r.modelo_contrato_id, + faceDescriptor: r.face_descriptor })); } @@ -662,9 +663,9 @@ export async function insertAluno(a) { nome_responsavel, telefone_responsavel, cpf_responsavel, data_nascimento_responsavel, turma_id, status, data_matricula, foto_url, cep, rua, numero, bairro, cidade, estado, desconto, tem_responsavel, modelo_contrato_id, numero_matricula, senha_portal, - motivo_cancelamento + motivo_cancelamento, face_descriptor ) VALUES ( - $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28 + $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29 ) RETURNING *`, [ a.id, a.nome || a.name, a.email || '', a.telefone || a.phone || '', a.data_nascimento || a.birthDate || null, @@ -676,7 +677,8 @@ export async function insertAluno(a) { a.numero || a.addressNumber || '', a.bairro || a.addressNeighborhood || '', a.cidade || a.addressCity || '', a.estado || a.addressState || '', a.desconto || a.discount || 0, a.tem_responsavel !== undefined ? a.tem_responsavel : (a.hasGuardian || false), a.modelo_contrato_id || a.contractTemplateId || null, a.numero_matricula || a.enrollmentNumber || null, - a.senha_portal || a.portalPassword || null, a.motivo_cancelamento || a.cancellationReason || null + a.senha_portal || a.portalPassword || null, a.motivo_cancelamento || a.cancellationReason || null, + a.faceDescriptor ? JSON.stringify(a.faceDescriptor) : null ] ); return result.rows[0]; @@ -689,8 +691,8 @@ export async function updateAluno(id, a) { nome_responsavel=$8, telefone_responsavel=$9, cpf_responsavel=$10, data_nascimento_responsavel=$11, turma_id=$12, status=$13, data_matricula=$14, foto_url=$15, cep=$16, rua=$17, numero=$18, bairro=$19, cidade=$20, estado=$21, desconto=$22, tem_responsavel=$23, modelo_contrato_id=$24, numero_matricula=$25, senha_portal=$26, - motivo_cancelamento=$27 - WHERE id = $28 RETURNING *`, + motivo_cancelamento=$27, face_descriptor=COALESCE($28, face_descriptor) + WHERE id = $29 RETURNING *`, [ a.nome || a.name, a.email || '', a.telefone || a.phone || '', a.data_nascimento || a.birthDate || null, a.cpf || '', a.rg || '', a.rg_data_emissao || a.rgIssueDate || null, @@ -702,6 +704,7 @@ export async function updateAluno(id, a) { a.estado || a.addressState || '', a.desconto || a.discount || 0, a.tem_responsavel !== undefined ? a.tem_responsavel : (a.hasGuardian || false), a.modelo_contrato_id || a.contractTemplateId || null, a.numero_matricula || a.enrollmentNumber || null, a.senha_portal || a.portalPassword || null, a.motivo_cancelamento || a.cancellationReason || null, + a.faceDescriptor ? JSON.stringify(a.faceDescriptor) : null, id ] );