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.
|
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.
|
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').
|
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`.
|
- **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.
|
- **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" />
|
<DollarSign size={18} className="text-emerald-500" />
|
||||||
<div>
|
<div>
|
||||||
<p className="text-[10px] uppercase font-bold text-slate-400">Investimento Mensal</p>
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1130,9 +1130,9 @@ const Finance: React.FC<FinanceProps> = ({ data, updateData }) => {
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-6 py-5">
|
<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 && (
|
{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>
|
<div className="text-[10px] text-slate-500 font-medium">Total do Carnê</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
@ -1229,23 +1229,23 @@ const Finance: React.FC<FinanceProps> = ({ data, updateData }) => {
|
||||||
const displayValue = valorPago > 0 ? valorPago : (payment.amount - discount);
|
const displayValue = valorPago > 0 ? valorPago : (payment.amount - discount);
|
||||||
return (
|
return (
|
||||||
<div className="font-bold text-slate-700 text-sm">
|
<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>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="font-bold text-slate-700 text-sm">
|
<div className="font-bold text-slate-700 text-sm">
|
||||||
R$ {(payment.amount + additions).toLocaleString('pt-BR', { minimumFractionDigits: 2 })}
|
R$ {(payment.amount + additions).toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
|
||||||
</div>
|
</div>
|
||||||
{activeDiscount > 0 && (
|
{activeDiscount > 0 && (
|
||||||
<div className="text-[10px] text-emerald-600 font-bold">
|
<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>
|
</div>
|
||||||
)}
|
)}
|
||||||
{additions > 0 && (
|
{additions > 0 && (
|
||||||
<div className="text-[10px] text-red-500 font-bold">
|
<div className="text-[10px] text-red-500 font-bold">
|
||||||
+ R$ {additions.toLocaleString('pt-BR', { minimumFractionDigits: 2 })} (Juros/Multa)
|
+ R$ {additions.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} (Juros/Multa)
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|
@ -1368,23 +1368,23 @@ const Finance: React.FC<FinanceProps> = ({ data, updateData }) => {
|
||||||
const displayValue = valorPago > 0 ? valorPago : (payment.amount - discount);
|
const displayValue = valorPago > 0 ? valorPago : (payment.amount - discount);
|
||||||
return (
|
return (
|
||||||
<div className="font-black text-slate-900 text-sm">
|
<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>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="font-black text-slate-900 text-sm">
|
<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>
|
</div>
|
||||||
{activeDiscount > 0 && (
|
{activeDiscount > 0 && (
|
||||||
<div className="text-[10px] text-emerald-600 font-bold">
|
<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>
|
</div>
|
||||||
)}
|
)}
|
||||||
{additions > 0 && (
|
{additions > 0 && (
|
||||||
<div className="text-[10px] text-red-500 font-bold mt-0.5">
|
<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>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|
@ -1701,7 +1701,7 @@ const Finance: React.FC<FinanceProps> = ({ data, updateData }) => {
|
||||||
<div className="flex justify-between items-start">
|
<div className="flex justify-between items-start">
|
||||||
<div>
|
<div>
|
||||||
<div className="text-xs font-black text-indigo-500 uppercase tracking-wider">Parcela {parcela.numero}</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>
|
||||||
<div className="text-right">
|
<div className="text-right">
|
||||||
<div className="text-xs text-slate-400 font-medium">Vencimento</div>
|
<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 className="flex justify-between items-start">
|
||||||
<div>
|
<div>
|
||||||
<div className="text-xs font-black text-indigo-500 uppercase tracking-wider">Parcela {parcela.numero}</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>
|
||||||
<div className="text-right">
|
<div className="text-right">
|
||||||
<div className="text-xs text-slate-400 font-medium">Vencimento</div>
|
<div className="text-xs text-slate-400 font-medium">Vencimento</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue