fix(students): apply biometrics mapping in getAlunos, persist face_descriptor in postgres and document status in GEMINI.md

This commit is contained in:
Sidney 2026-05-25 09:35:07 -03:00
parent c5d2979b60
commit 6cdf609f62
2 changed files with 11 additions and 6 deletions

View File

@ -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. 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). 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. 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.

View File

@ -651,7 +651,8 @@ export async function getAlunos() {
cpf: r.cpf, cpf: r.cpf,
phone: r.telefone, phone: r.telefone,
registrationDate: r.data_matricula, 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, nome_responsavel, telefone_responsavel, cpf_responsavel, data_nascimento_responsavel,
turma_id, status, data_matricula, foto_url, cep, rua, numero, bairro, cidade, estado, turma_id, status, data_matricula, foto_url, cep, rua, numero, bairro, cidade, estado,
desconto, tem_responsavel, modelo_contrato_id, numero_matricula, senha_portal, desconto, tem_responsavel, modelo_contrato_id, numero_matricula, senha_portal,
motivo_cancelamento motivo_cancelamento, face_descriptor
) VALUES ( ) 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 *`, ) RETURNING *`,
[ [
a.id, a.nome || a.name, a.email || '', a.telefone || a.phone || '', a.data_nascimento || a.birthDate || null, 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.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.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.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]; 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, 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, 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, desconto=$22, tem_responsavel=$23, modelo_contrato_id=$24, numero_matricula=$25, senha_portal=$26,
motivo_cancelamento=$27 motivo_cancelamento=$27, face_descriptor=COALESCE($28, face_descriptor)
WHERE id = $28 RETURNING *`, WHERE id = $29 RETURNING *`,
[ [
a.nome || a.name, a.email || '', a.telefone || a.phone || '', a.data_nascimento || a.birthDate || null, 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, 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.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.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,
id id
] ]
); );