Add Recebimento e Conferência web UI, Supabase schema and TeraBox backend (MVP) - #2
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 54e633af9e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| await dbUpdate('usuarios', { matricula, telefone }, { senha: novaSenha }); | ||
| if (state.mode === 'supabase') { | ||
| const { error } = await supabase.functions.invoke('send-sms', { body: { to: telefone, message: `Nova senha: ${novaSenha}` } }); | ||
| if (error) throw error; |
There was a problem hiding this comment.
Avoid persisting new password before delivery succeeds
In recoverBySms the password is written to usuarios before the SMS edge function is called. If send-sms fails (missing function, provider error, transient outage), the catch path reports failure but the account password has already changed and the user never receives the new value, which can lock them out. The same ordering is repeated in recoverByEmail.
Useful? React with 👍 / 👎.
| try { | ||
| await dbUpdate('usuarios', { matricula }, { senha: novaSenha }); | ||
| if (state.mode === 'supabase') { | ||
| const { error } = await supabase.functions.invoke('send-email', { body: { to: 'leseliv487@fengnu.com', subject: 'Nova senha', text: `Nova senha: ${novaSenha}` } }); |
There was a problem hiding this comment.
Use the user's email instead of a hard-coded recipient
The email recovery flow sends the reset message to a fixed address (leseliv487@fengnu.com) rather than the target user's registered email. In production this leaks credentials to an unrelated mailbox and prevents the intended account owner from receiving the reset notification.
Useful? React with 👍 / 👎.
| async function login(evt) { | ||
| evt.preventDefault(); | ||
| const f = new FormData(loginForm); | ||
| const data = await dbSelect('usuarios', { eq: { matricula: f.get('matricula'), senha: f.get('senha') }, single: true }); |
There was a problem hiding this comment.
Handle missing login rows without throwing
Login requests single: true, which maps to Supabase .single(). When credentials are invalid and zero rows match, .single() returns an error, dbSelect throws, and login never reaches the intended Matrícula ou senha inválida alert path. This makes normal failed-login attempts surface as runtime errors instead of a controlled auth response.
Useful? React with 👍 / 👎.
| (nota.itens_json || []).forEach((item) => { | ||
| const code = normalizeProductCode(item.codigo); | ||
| const fardosPorPalete = getFardosPorPalete(code); | ||
| conferenciaForm.insertAdjacentHTML('beforeend', `<div class="item"><p><strong>${code}</strong> - ${item.descricao}</p><p class="hint">NF: ${item.quantidadeFardo} fardos | ${fardosPorPalete} fardos por palete</p><label>Quantidade conferida<input type="number" step="0.01" min="0" required name="${code}" /></label></div>`); |
There was a problem hiding this comment.
Give conference inputs unique field names per item row
Each conference quantity input uses name="${code}", so repeated SKU codes in the same NF generate duplicate field names. During submit, form.get(code) returns one value for all duplicated rows, causing incorrect per-item divergences and wrong NQ/log records whenever the XML has multiple det entries with the same product code.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ba0d2a66ab
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const minhasConferencias = await dbSelect('conferencias', { eq: { conferente_matricula: state.user.matricula } }) || []; | ||
| const conferidasPorMim = new Set(minhasConferencias.map((c) => String(c.nota_id))); | ||
| visibleInvoices = allInvoices.filter((n) => !conferidasPorMim.has(String(n.id))); |
There was a problem hiding this comment.
Prevent duplicate conferências across operators
loadInvoices only hides notes already reviewed by the current matrícula, so the same NF stays available to other operators and each submission creates additional conferencias/nq_reports rows. In practice, if operator A and B both process the same note, divergence totals and NQ exports are duplicated and no longer represent a single physical conference for that carga.
Useful? React with 👍 / 👎.
| (nota.itens_json || []).forEach((item) => { | ||
| const code = normalizeProductCode(item.codigo); | ||
| const fardosPorPalete = getFardosPorPalete(code); | ||
| conferenciaForm.insertAdjacentHTML('beforeend', `<div class="item"><p><strong>${code}</strong> - ${item.descricao}</p><p class="hint">NF: ${item.quantidadeFardo} fardos | ${fardosPorPalete} fardos por palete</p><label>Quantidade conferida<input type="number" step="0.01" min="0" required name="${code}" /></label></div>`); |
There was a problem hiding this comment.
Escape XML fields before injecting conference item HTML
This HTML is built with insertAdjacentHTML using item.descricao/code derived from uploaded XML. A crafted NF-e payload containing HTML/JS in product text can execute script when the conference form is rendered, which allows browser-side takeover of the session context. Build nodes with textContent (or sanitize) instead of interpolating raw values into HTML.
Useful? React with 👍 / 👎.
| const { error } = await supabase.functions.invoke('send-email', { body: { to: 'leseliv487@fengnu.com', subject: 'Nova senha', text: `Nova senha: ${novaSenha}` } }); | ||
| if (error) throw error; | ||
| } | ||
| alert(`Senha resetada. Nova senha: ${novaSenha}`); |
There was a problem hiding this comment.
Do not disclose reset password in recovery success alert
The recovery flow displays the newly generated credential directly in the browser alert. Because recoverByEmail starts from matrícula input, this exposes account takeover risk: anyone who can trigger recovery can immediately read the new password from the UI instead of proving mailbox ownership. Recovery should send a one-time token/link and never reveal plaintext passwords client-side.
Useful? React with 👍 / 👎.
Motivation
admandoperacaoworkflows and Supabase persistence.Description
index.html,styles.css, andmain.jsimplementing login/register, role-based Admin/Operação UI, XML parsing, PDF generation (NFe + etiquetas), chat, logs view, NQ export lines and localStorage fallback when Supabase schema is absent.main.jswith helper DB wrappersdbSelect,dbInsert,dbUpdate,dbDeleteAllthat automatically switch to local mode on schema errors.server.jswith routesGET /auth/terabox,GET /auth/terabox/callback, andPOST /exportar-txt-teraboxto handle TeraBox OAuth and TXT upload (usesaxios,form-data), pluspackage.jsonand.env.examplefor configuration.supabase-schema.sqlto create the required tables (usuarios,notas,conferencias,logs,chats,nq_reports) andREADME.mdwith setup and run instructions.Testing
Codex Task