Repository navigation
Estado Atual
Referências: backend #77 e app #16. Este levantamento distingue comportamento implementado de objetivos e registros históricos.
O app SwiftUI consulta diretamente ofertas no projeto Firebase veja-o-preco, via FirebaseFirestore. get_ofertas_do_dia existe, mas não monta a vitrine atual. O bundle iOS é com.joaosilva.VejaOpreco.
Há 11 Cloud Functions de segunda geração, Python 3.12, em us-central1. O código usa Vertex AI (gemini-3.1-flash-lite). Firestore Native Standard contém ofertas, produtos, supermercados, historico_precos, sinonimos e duplicatas_ignoradas. A leitura de clientes é pública apenas para ofertas e produtos; escritas de clientes são negadas. Imagens são publicadas pelo Admin SDK no Storage.
A atualização agendada no código ocorre às 10h e 14h (America/Belem); a limpeza de ofertas expiradas, às 23h. A captura de Instagram e parte dos encartes usa Playwright local, seguida de OCR, envio para extração, auditoria de categorias, deduplicação e curadoria.
produto_nome, preco, unidade e categoria alimentam o card. Campos opcionais incluem produto_id, imagem_url, loja, supermercado_id, validade e expira_em (Timestamp → Date). O ID vem de @DocumentID.
A consulta exige expira_em >= agora no servidor e aplica estaValida novamente no cliente. Documentos sem expira_em não entram nessa consulta, embora o modelo isoladamente considere nil válido. validade é texto de apresentação, sem interpretação de data pelo app.
Há nove categorias principais e OUTROS; categorias desconhecidas são decodificadas como ALIMENTOS. Documentos que falham no decode são descartados por try?/compactMap. A consulta é pontual, sem listener em tempo real.
O helper central normaliza nomes/unidades, resolve sinônimos, registra histórico diário e evita ofertas repetidas. Preço novo expira ofertas anteriores do mesmo produto e loja. Ofertas de lojas irmãs podem compartilhar um documento com supermercado_ids; supermercado_id permanece como loja principal.
A extração PDF tem gravação própria em batch e não usa o helper central. Portanto, normalização, campos e histórico não são equivalentes em todos os caminhos.
A ingestão automática usa imagens 200×200. A curadoria posterior usa 400×400, normalmente com fundo branco e cache-buster. Resolução, correspondência com marca/variante e margem de 20px não são garantidas para todo o catálogo. As ondas anteriores são entregas históricas, não uma certificação permanente da vitrine.
- A expiração atual é sete dias após captura/renovação, mesmo quando há validade textual. Não há conversão dessa validade em expiração no helper examinado.
- O app ainda não usa
supermercado_idsno filtro; ofertas compartilhadas podem faltar na loja secundária. - O fluxo PDF não registra o mesmo histórico diário do helper central.
- Fusões de produtos não remapeiam automaticamente o histórico de preços.
- Existem IDs legados de lojas e diferenças entre cadastro e ofertas; o app deriva o carrossel das ofertas.
- O app ainda não apresenta histórico de preços nem notificações. Erros de carregamento ficam no console; o gesto de atualização não aguarda a Task interna.
- Curadoria contínua e revisão dos cards permanecem nas issues #11, #12 e #13 do app. Esta sincronização não encerra essas tarefas.
O diretório functions/venv atende Firebase/IA; venv_triagem atende Playwright/OCR. Logs atuais são scripts/cron_hoje.log e cron_AAAA-MM-DD_10h|14h.log, com poda de logs de janela antigos.
Scripts de seed, integração, curadoria, fusão e limpeza podem alterar produção. Iniciar apenas o emulador de Functions não garante Firestore emulado: conferir FIRESTORE_EMULATOR_HOST e o destino do Admin SDK antes de executar. seed_firestore.py apaga coleções; não é uma consulta.
Validação realizada: py_compile de functions/main.py, build iOS Simulator com CODE_SIGNING_ALLOWED=NO e revisão do diff. Não houve teste funcional no simulador, execução de crawlers, alterações de dados nem deploy. A versão do código implantado nas Functions não foi confrontada com a fonte local.
A sincronização integra registros das sessões 86–102 do backend e o filtro de expiradas do app; atualiza os Markdown e as duas Wikis, com commits rastreáveis, merge --no-ff e retorno a develop.
109 produtos e 115 ofertas ativas receberam as fotos selecionadas pelo usuário no preview. A opção Coxão Mole / Chã de Dentro Bovino Resfriado permaneceu desmarcada e não foi alterada. A seleção exportada foi confrontada com os 109 checkboxes marcados.
As imagens foram publicadas em produtos/{produto_id}.jpg, JPEG RGB de 400 × 400, proporção preservada e transparências compostas sobre branco. O cadastro mestre recebeu imagem_origem=curadoria_manual e atualizado_em; as ofertas vinculadas receberam a mesma URL com ?t=<timestamp>. No app, OfertaDetalheView reconhece ?t= e mostra o selo verde e o texto “400 × 400 px (Curadoria HD)”. O selo pertence à interface e não foi desenhado nas fotos.
Verificação posterior: 109 URLs públicas responderam com bytes iguais aos arquivos preparados, JPEG 400 × 400; os 109 produtos e 115 ofertas foram relidos e conferidos. Não houve alteração de preços, validade, código Swift ou Functions, nem deploy. A exibição do selo foi conferida pela condição implementada no código, sem teste funcional no simulador. O app usa consulta pontual; é necessário atualizar a vitrine para receber as novas URLs.
65 fotos selecionadas tinham ressalvas de variante/tamanho ou representação genérica no preview. A aprovação permite aplicar essas escolhas, mas não comprova correspondência exata de todos os rótulos. As observações e fontes foram preservadas no relatório individual. Das 202 entradas sinalizadas na auditoria, 93 ficaram fora deste lote (92 sem candidata confiável e uma candidata desmarcada).
Antes da gravação foram preservados os documentos Firestore com tipos originais, JSON legível, arquivos anteriores do Storage, gerações e seleção aprovada. Uma tentativa inicial recebeu HTTP 403, restaurou o arquivo original e não alterou Firestore; a aplicação concluída incluiu a publicação pública utilizada pelo fluxo existente. A atualização dos 224 documentos ocorreu em batch com pré-condições de versão.
Rastreabilidade: issue backend #78; relatório docs/CURADORIA_2026-10-02.md. Backup local e evidências: curadoria-2026-10-02/aplicacao no diretório de visualizações da sessão Codex; não versionar o backup binário.