docs: update GEMINI.md and MEMORY.md and fix decimal places formatting in finance
Build and Deploy (Gitea) / build-and-deploy (push) Successful in 2m3s
Details
Build and Deploy (Gitea) / build-and-deploy (push) Successful in 2m3s
Details
This commit is contained in:
parent
eefcbcc671
commit
3277f81ce7
|
|
@ -89,4 +89,6 @@
|
|||
55. **Migração Automática de Chaves de IA**: O sistema deve migrar automaticamente as configurações e chaves de IA legadas salvas no arquivo JSON para a tabela relacional `configuracoes_ia` do PostgreSQL para centralizar as credenciais.
|
||||
56. **Geração Híbrida de Imagens Gemini/Imagen**: O backend deve suportar chamadas de imagem nativas (endpoint `:generateImages` do Imagen 3) para modelos `imagen-` e chamadas multimodais para modelos Gemini (`responseModalities`), aplicando fallbacks automáticos em cascata caso o modelo primário selecionado falhe.
|
||||
57. **Correção de Autofill no Chrome**: Modais de IA devem desativar ou evitar elementos de formulário que induzam o Chrome a preencher incorretamente campos de texto irrelevantes (como busca de provas) com dados armazenados de login (ex: 'admin').
|
||||
58. **Limitação de Decimais em Formatação Financeira**: Todos os valores financeiros renderizados na tela (especialmente parcelas, multas e juros de atraso) devem ser limitados a exatamente duas casas decimais utilizando `toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })` para garantir conformidade visual e evitar o arredondamento incorreto do navegador com 3 ou mais dígitos.
|
||||
59. **Resiliência do Modelo de IA**: O backend em `server.selfhosted.js` implementa um filtro ativo contra modelos descontinuados da API Gemini (como `gemini-1.5-flash` e `gemini-2.5-flash-lite`) salvos no banco. O fallback forçado sob o capô deve ser sempre `gemini-2.0-flash`.
|
||||
|
||||
|
|
|
|||
|
|
@ -107,3 +107,7 @@ Nesta sessão de trabalho, realizamos o "core" da transição do sistema EduMana
|
|||
- **Migração de Chaves de IA para o PostgreSQL**: Adicionada rotina de migração transparente que move as credenciais e configurações de IA do antigo cache JSON de configurações para a tabela relacional `configuracoes_ia`.
|
||||
- **Correção de Autofill no Chrome**: Corrigido bug onde o recurso de preenchimento automático do Chrome inseria o usuário 'admin' na barra de busca de provas ao carregar o modal de configuração de IA.
|
||||
|
||||
### Fase 14: Correção de Precisão Financeira e Fallback do Módulo de IA (Julho de 2026)
|
||||
- **Exibição Estrita de Duas Casas Decimais**: Adicionado o parâmetro `maximumFractionDigits: 2` em todos os locais onde valores financeiros são formatados no painel Manager (arquivos `Finance.tsx`, `Students.tsx` e `Courses.tsx`). Isso corrige de forma definitiva a exibição de parcelas vencidas com 3 casas decimais (ex: R$ 175,871), aplicando o formato monetário padrão brasileiro de exatamente 2 casas decimais.
|
||||
- **Fallback e Filtro de Modelos Gemini Descontinuados**: Atualizado o modelo padrão de IA nas camadas de banco (`database.js`), backend (`server.selfhosted.js`) e frontend (`Exams.tsx`) de `gemini-1.5-flash` para `gemini-2.0-flash`. Além disso, foi adicionado um filtro que intercepta modelos inexistentes ou inválidos configurados no banco (como `gemini-2.5-flash-lite`) e faz o redirecionamento automático sob o capô para o modelo estável `gemini-2.0-flash`, evitando erros 404.
|
||||
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ const Courses: React.FC<CoursesProps> = ({ data, updateData }) => {
|
|||
<DollarSign size={18} className="text-emerald-500" />
|
||||
<div>
|
||||
<p className="text-[10px] uppercase font-bold text-slate-400">Investimento Mensal</p>
|
||||
<p className="font-semibold text-slate-800">R$ {course.monthlyFee.toLocaleString('pt-BR', { minimumFractionDigits: 2 })}</p>
|
||||
<p className="font-semibold text-slate-800">R$ {course.monthlyFee.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1130,9 +1130,9 @@ const Finance: React.FC<FinanceProps> = ({ data, updateData }) => {
|
|||
)}
|
||||
</td>
|
||||
<td className="px-6 py-5">
|
||||
<div className="font-black text-slate-900">R$ {group.totalAmount.toLocaleString('pt-BR', { minimumFractionDigits: 2 })}</div>
|
||||
<div className="font-black text-slate-900">R$ {group.totalAmount.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</div>
|
||||
{group.totalReceived > 0 && (
|
||||
<div className="text-[10px] text-blue-600 font-black">PAGO: R$ {group.totalReceived.toLocaleString('pt-BR', { minimumFractionDigits: 2 })}</div>
|
||||
<div className="text-[10px] text-blue-600 font-black">PAGO: R$ {group.totalReceived.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</div>
|
||||
)}
|
||||
<div className="text-[10px] text-slate-500 font-medium">Total do Carnê</div>
|
||||
</td>
|
||||
|
|
@ -1229,28 +1229,28 @@ const Finance: React.FC<FinanceProps> = ({ data, updateData }) => {
|
|||
const displayValue = valorPago > 0 ? valorPago : (payment.amount - discount);
|
||||
return (
|
||||
<div className="font-bold text-slate-700 text-sm">
|
||||
R$ {displayValue.toLocaleString('pt-BR', { minimumFractionDigits: 2 })}
|
||||
R$ {displayValue.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<>
|
||||
<div className="font-bold text-slate-700 text-sm">
|
||||
R$ {(payment.amount + additions).toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
|
||||
</div>
|
||||
{activeDiscount > 0 && (
|
||||
<div className="text-[10px] text-emerald-600 font-bold">
|
||||
- R$ {activeDiscount.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<>
|
||||
<div className="font-bold text-slate-700 text-sm">
|
||||
R$ {(payment.amount + additions).toLocaleString('pt-BR', { minimumFractionDigits: 2 })}
|
||||
</div>
|
||||
{activeDiscount > 0 && (
|
||||
<div className="text-[10px] text-emerald-600 font-bold">
|
||||
- R$ {activeDiscount.toLocaleString('pt-BR', { minimumFractionDigits: 2 })}
|
||||
</div>
|
||||
)}
|
||||
{additions > 0 && (
|
||||
<div className="text-[10px] text-red-500 font-bold">
|
||||
+ R$ {additions.toLocaleString('pt-BR', { minimumFractionDigits: 2 })} (Juros/Multa)
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
)}
|
||||
{additions > 0 && (
|
||||
<div className="text-[10px] text-red-500 font-bold">
|
||||
+ R$ {additions.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} (Juros/Multa)
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
})()}
|
||||
</td>
|
||||
<td className="px-4 py-4">{getStatusBadge(payment)}</td>
|
||||
|
|
@ -1368,23 +1368,23 @@ const Finance: React.FC<FinanceProps> = ({ data, updateData }) => {
|
|||
const displayValue = valorPago > 0 ? valorPago : (payment.amount - discount);
|
||||
return (
|
||||
<div className="font-black text-slate-900 text-sm">
|
||||
R$ {displayValue.toLocaleString('pt-BR', { minimumFractionDigits: 2 })}
|
||||
R$ {displayValue.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<>
|
||||
<div className="font-black text-slate-900 text-sm">
|
||||
R$ {(payment.amount + additions).toLocaleString('pt-BR', { minimumFractionDigits: 2 })}
|
||||
R$ {(payment.amount + additions).toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
|
||||
</div>
|
||||
{activeDiscount > 0 && (
|
||||
<div className="text-[10px] text-emerald-600 font-bold">
|
||||
- R$ {activeDiscount.toLocaleString('pt-BR', { minimumFractionDigits: 2 })}
|
||||
- R$ {activeDiscount.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
|
||||
</div>
|
||||
)}
|
||||
{additions > 0 && (
|
||||
<div className="text-[10px] text-red-500 font-bold mt-0.5">
|
||||
+ R$ {additions.toLocaleString('pt-BR', { minimumFractionDigits: 2 })} (Multa/Juros)
|
||||
+ R$ {additions.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} (Multa/Juros)
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
|
|
@ -1701,7 +1701,7 @@ const Finance: React.FC<FinanceProps> = ({ data, updateData }) => {
|
|||
<div className="flex justify-between items-start">
|
||||
<div>
|
||||
<div className="text-xs font-black text-indigo-500 uppercase tracking-wider">Parcela {parcela.numero}</div>
|
||||
<div className="text-lg font-bold text-slate-800 mt-0.5">R$ {parcela.valor.toLocaleString('pt-BR', { minimumFractionDigits: 2 })}</div>
|
||||
<div className="text-lg font-bold text-slate-800 mt-0.5">R$ {parcela.valor.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</div>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-xs text-slate-400 font-medium">Vencimento</div>
|
||||
|
|
|
|||
|
|
@ -2540,7 +2540,7 @@ const Students: React.FC<StudentsProps> = ({ data, updateData, deepLinkStudentId
|
|||
<div className="flex justify-between items-start">
|
||||
<div>
|
||||
<div className="text-xs font-black text-indigo-500 uppercase tracking-wider">Parcela {parcela.numero}</div>
|
||||
<div className="text-lg font-bold text-slate-800 mt-0.5">R$ {parcela.valor.toLocaleString('pt-BR', { minimumFractionDigits: 2 })}</div>
|
||||
<div className="text-lg font-bold text-slate-800 mt-0.5">R$ {parcela.valor.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</div>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-xs text-slate-400 font-medium">Vencimento</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue