# ๐Ÿ›๏ธ ALETHEIA โ€” Arquitetura Tรฉcnica > **Aletheia** (แผ€ฮปฮฎฮธฮตฮนฮฑ) โ€” "verdade" em grego. Scanner de rรณtulos alimentares com IA que revela a verdade sobre o que vocรช come. --- ## ๐Ÿ“‹ รndice 1. [Visรฃo Geral](#visรฃo-geral) 2. [Stack Tecnolรณgica](#stack-tecnolรณgica) 3. [Arquitetura de Sistema](#arquitetura-de-sistema) 4. [Mรณdulos](#mรณdulos) 5. [Modelo de Dados](#modelo-de-dados) 6. [Fluxo Principal](#fluxo-principal) 7. [APIs Externas](#apis-externas) 8. [PWA & Cรขmera](#pwa--cรขmera) 9. [Monetizaรงรฃo Tรฉcnica](#monetizaรงรฃo-tรฉcnica) 10. [Performance](#performance) 11. [Design & UX](#design--ux) 12. [Roadmap](#roadmap) 13. [Estrutura de Diretรณrios](#estrutura-de-diretรณrios) --- ## Visรฃo Geral O usuรกrio aponta a cรขmera do celular para o cรณdigo de barras de um alimento. Em menos de 5 segundos, recebe: - **Explicaรงรฃo simples** de cada ingrediente ("como se tivesse 10 anos") - **Score de saรบde** de 0 a 100 (com breakdown visual) - **Alertas** sobre ingredientes problemรกticos (corantes, conservantes, excesso de sรณdio) - **Alternativas** mais saudรกveis disponรญveis na mesma categoria - **Compatibilidade** com seu perfil alimentar (alergias, dietas, restriรงรตes) --- ## Stack Tecnolรณgica ### Backend | Componente | Tecnologia | Justificativa | |---|---|---| | **Framework** | FastAPI (Python 3.12) | Async nativo, tipagem forte, docs automรกticas | | **ORM** | SQLAlchemy 2.0 + Alembic | Migrations versionadas, async support | | **Banco principal** | PostgreSQL 16 | JSONB para dados flexรญveis, full-text search | | **Cache** | Redis 7 | Cache de produtos, rate limiting, sessรตes | | **Task queue** | Celery + Redis broker | Anรกlises IA em background | | **Auth** | JWT (access + refresh tokens) | Stateless, rotaรงรฃo de tokens | | **Servidor** | Uvicorn + Gunicorn | Workers async para alta concorrรชncia | ### Frontend | Componente | Tecnologia | Justificativa | |---|---|---| | **Framework** | Next.js 14 (App Router) | SSR, RSC, PWA-ready | | **UI** | Tailwind CSS + Radix UI | Design system consistente, acessรญvel | | **Estado** | Zustand | Leve, simples, sem boilerplate | | **Cรขmera/Barcode** | `navigator.mediaDevices` + ZXing-js | Scan direto no browser, sem SDK nativo | | **HTTP** | Axios + React Query (TanStack) | Cache client-side, retry, optimistic updates | | **PWA** | next-pwa (Workbox) | Offline support, install prompt | | **Animaรงรตes** | Framer Motion | Score gauge, transiรงรตes suaves | ### Infra | Componente | Tecnologia | |---|---| | **Deploy backend** | Railway / Fly.io (ou VPS com Docker) | | **Deploy frontend** | Vercel | | **CI/CD** | GitHub Actions | | **Monitoramento** | Sentry (erros) + Uptime Kuma (status) | | **Logs** | Estruturados com structlog โ†’ stdout | | **Storage** | S3-compatible (imagens de produtos) | --- ## Arquitetura de Sistema ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ CLIENTE (PWA) โ”‚ โ”‚ Next.js 14 ยท Tailwind ยท ZXing-js ยท Service Worker โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ HTTPS โ–ผ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ API GATEWAY โ”‚ โ”‚ FastAPI ยท Uvicorn ยท JWT โ”‚ โ”‚ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ Auth โ”‚ โ”‚ Scanner โ”‚ โ”‚ Produtos โ”‚ โ”‚ โ”‚ โ”‚ Module โ”‚ โ”‚ Module โ”‚ โ”‚ Module โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ Anรกlise โ”‚ โ”‚ Score โ”‚ โ”‚Alternativ.โ”‚ โ”‚ โ”‚ โ”‚ IA โ”‚ โ”‚ Saรบde โ”‚ โ”‚ Module โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚Histรณrico โ”‚ โ”‚ Perfil โ”‚ โ”‚Gamificaรงรฃoโ”‚ โ”‚ โ”‚ โ”‚ Module โ”‚ โ”‚Alimentar โ”‚ โ”‚ Module โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚Postgresโ”‚ โ”‚ Redis โ”‚ โ”‚ Celery โ”‚ โ”‚ 16 โ”‚ โ”‚ 7 โ”‚ โ”‚ Workers โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ APIs Externas โ”‚ โ”‚ โ€ข Open Food Facts โ”‚ โ”‚ โ€ข OpenAI GPT-4o-mini โ”‚ โ”‚ โ€ข Stripe โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` --- ## Mรณdulos ### 1. Auth Module **Responsabilidade:** Registro, login, gerenciamento de sessรฃo. ``` POST /auth/register โ†’ Cria conta (email + senha ou OAuth) POST /auth/login โ†’ Retorna access_token + refresh_token POST /auth/refresh โ†’ Renova access_token POST /auth/forgot-password โ†’ Envia email de reset POST /auth/reset-password โ†’ Aplica nova senha GET /auth/me โ†’ Retorna perfil do usuรกrio logado DELETE /auth/me โ†’ Deleta conta (LGPD) ``` - **Senhas:** bcrypt (cost factor 12) - **Tokens:** JWT RS256, access_token (15min), refresh_token (30 dias) - **OAuth:** Google e Apple Sign-In (futuro) - **Rate limit:** 5 tentativas de login por minuto por IP ### 2. Scanner Module **Responsabilidade:** Decodificaรงรฃo de barcode e orquestraรงรฃo do fluxo de scan. ``` POST /scan โ†’ Recebe barcode, orquestra busca + anรกlise GET /scan/{scan_id} โ†’ Retorna resultado completo de um scan ``` **Fluxo interno:** 1. Recebe barcode (EAN-13/UPC-A) do frontend 2. Verifica rate limit do usuรกrio (crรฉditos) 3. Busca produto no cache Redis โ†’ DB local โ†’ Open Food Facts 4. Se produto novo, persiste no DB 5. Dispara anรกlise IA (sync se cache hit, async se primeira vez) 6. Retorna resultado consolidado **Barcode no frontend:** - ZXing-js para decodificaรงรฃo client-side - Fallback: envio de imagem para Google Cloud Vision API (barcode detection) - Suporte: EAN-13, EAN-8, UPC-A, UPC-E ### 3. Produtos Module **Responsabilidade:** CRUD de produtos, cache e sincronizaรงรฃo com Open Food Facts. ``` GET /products/{barcode} โ†’ Busca produto por barcode GET /products/{barcode}/nutrition โ†’ Dados nutricionais detalhados POST /products/report โ†’ Usuรกrio reporta dados incorretos ``` **Estratรฉgia de cache (3 camadas):** | Camada | TTL | Detalhes | |---|---|---| | **Redis** | 24h | Hot cache, produtos escaneados recentemente | | **PostgreSQL** | 30 dias | Cache persistente, atualizado via cron | | **Open Food Facts** | Sob demanda | Source of truth, fallback | **Dados armazenados do produto:** - Nome, marca, categoria - Lista de ingredientes (texto original) - Tabela nutricional (por 100g e por porรงรฃo) - Nutri-Score (A-E) quando disponรญvel - NOVA group (1-4, grau de processamento) - Imagens (frente, ingredientes, nutricional) - Alรฉrgenos declarados ### 4. Anรกlise IA Module **Responsabilidade:** Anรกlise inteligente de ingredientes via GPT-4o-mini. ``` POST /analysis/ingredients โ†’ Analisa lista de ingredientes GET /analysis/{analysis_id} โ†’ Retorna anรกlise completa ``` **Prompt Engineering:** ```python SYSTEM_PROMPT = """ Vocรช รฉ um nutricionista especialista que explica ingredientes alimentares de forma simples, como se falasse com alguรฉm sem formaรงรฃo tรฉcnica. Para cada ingrediente, forneรงa: 1. Nome popular (se diferente do tรฉcnico) 2. O que รฉ e para que serve no produto (1-2 frases) 3. Classificaรงรฃo: โœ… Natural | โš ๏ธ Atenรงรฃo | ๐Ÿšซ Evitar 4. Motivo da classificaรงรฃo (1 frase) Ao final, gere: - Score de saรบde (0-100) com justificativa - Top 3 ingredientes problemรกticos (se houver) - Resumo em 1 parรกgrafo para leigo """ USER_PROMPT_TEMPLATE = """ Produto: {product_name} Marca: {brand} Categoria: {category} Ingredientes: {ingredients_text} Tabela nutricional (por 100g): {nutrition_table} Perfil do usuรกrio: {user_profile} # alergias, restriรงรตes Analise este produto. """ ``` **Otimizaรงรตes:** - Cache de anรกlises por hash(ingredientes + perfil_usuario) - GPT-4o-mini para custo baixo (~$0.15/1M input tokens) - Structured output (JSON mode) para parsing confiรกvel - Timeout: 10s, retry com exponential backoff - Fallback: anรกlise baseada em regras se IA falhar **Response format (JSON):** ```json { "ingredients": [ { "name": "Aรงรบcar invertido", "popular_name": "Aรงรบcar lรญquido", "explanation": "ร‰ aรงรบcar comum dissolvido e processado para ficar lรญquido. Usado para adoรงar e dar textura.", "classification": "warning", "reason": "Alto รญndice glicรชmico, contribui para picos de aรงรบcar no sangue." } ], "health_score": 35, "score_breakdown": { "naturalness": 20, "nutrition": 40, "processing": 30, "additives": 50 }, "problematic_top3": ["Aรงรบcar invertido", "Gordura vegetal hidrogenada", "Corante caramelo IV"], "summary": "Este produto รฉ ultraprocessado com alto teor de aรงรบcar...", "alerts": [ {"type": "allergen", "message": "Contรฉm glรบten (incompatรญvel com seu perfil)"} ] } ``` ### 5. Score de Saรบde Module **Responsabilidade:** Cรกlculo do score 0-100, combinando dados nutricionais + anรกlise IA. **Algoritmo de Score:** ```python def calculate_health_score(product, ai_analysis): score = 100 # 1. Nutri-Score (peso: 25%) nutri_penalty = {"a": 0, "b": 5, "c": 15, "d": 25, "e": 35} score -= nutri_penalty.get(product.nutri_score, 20) * 0.25 # 2. NOVA Group - Processamento (peso: 25%) nova_penalty = {1: 0, 2: 10, 3: 25, 4: 40} score -= nova_penalty.get(product.nova_group, 30) * 0.25 # 3. Ingredientes problemรกticos (peso: 25%) problematic_count = len(ai_analysis.problematic_ingredients) score -= min(problematic_count * 8, 40) * 0.25 # 4. Perfil nutricional (peso: 25%) # Penaliza excesso de: sรณdio, aรงรบcar, gordura saturada, gordura trans # Bonifica presenรงa de: fibra, proteรญna, vitaminas nutrition_score = calculate_nutrition_subscore(product.nutrition) score -= (100 - nutrition_score) * 0.25 return max(0, min(100, round(score))) ``` **Visualizaรงรฃo:** - Gauge circular animado (0-100) - Cores: ๐Ÿ”ด 0-30 | ๐ŸŸ  31-50 | ๐ŸŸก 51-70 | ๐ŸŸข 71-100 - Breakdown em 4 categorias com barras horizontais ### 6. Histรณrico Module **Responsabilidade:** Timeline de scans do usuรกrio, estatรญsticas e tendรชncias. ``` GET /history โ†’ Lista scans do usuรกrio (paginado) GET /history/stats โ†’ Estatรญsticas gerais (score mรฉdio, total scans) GET /history/trends โ†’ Evoluรงรฃo do score ao longo do tempo DELETE /history/{scan_id} โ†’ Remove scan do histรณrico ``` **Funcionalidades:** - Filtro por perรญodo, score range, categoria - Score mรฉdio dos รบltimos 7/30/90 dias - Grรกfico de tendรชncia (melhoria ao longo do tempo) - "Seus piores hรกbitos" (categorias com menor score mรฉdio) - Export CSV/PDF (premium) ### 7. Alternativas Module **Responsabilidade:** Sugerir produtos mais saudรกveis na mesma categoria. ``` GET /alternatives/{barcode} โ†’ Alternativas para um produto ``` **Lรณgica:** 1. Identifica categoria do produto (ex: "biscoito recheado") 2. Busca produtos da mesma categoria no DB com score > produto atual 3. Ordena por: score DESC, popularidade (nยบ de scans) DESC 4. Retorna top 5 alternativas com comparativo **Response:** ```json { "current_product": {"name": "Biscoito X", "score": 25}, "alternatives": [ { "name": "Biscoito Integral Y", "brand": "Marca Y", "score": 72, "score_diff": "+47", "highlights": ["Sem gordura trans", "Rico em fibras", "Menos aรงรบcar"], "barcode": "7891234567890" } ] } ``` ### 8. Perfil Alimentar Module **Responsabilidade:** Preferรชncias, alergias e restriรงรตes do usuรกrio. ``` GET /profile/dietary โ†’ Retorna perfil alimentar PUT /profile/dietary โ†’ Atualiza perfil GET /profile/dietary/check/{barcode} โ†’ Verifica compatibilidade ``` **Dados do perfil:** ```json { "allergies": ["glรบten", "lactose", "amendoim"], "intolerances": ["frutose"], "diet": "vegetariano", // null, vegetariano, vegano, low-carb, keto, etc "avoid": ["corantes artificiais", "glutamato monossรณdico"], "goals": ["reduzir aรงรบcar", "mais fibra"], "conditions": ["diabetes tipo 2", "hipertensรฃo"] // premium } ``` **Impacto no fluxo:** - Anรกlise IA recebe perfil como contexto - Alertas personalizados ("โš ๏ธ Contรฉm glรบten โ€” vocรช รฉ celรญaco") - Score ajustado por relevรขncia pessoal - Alternativas filtradas por compatibilidade ### 9. Gamificaรงรฃo Module **Responsabilidade:** Engajamento via conquistas, streaks e nรญveis. ``` GET /gamification/profile โ†’ XP, nรญvel, conquistas GET /gamification/achievements โ†’ Lista todas as conquistas GET /gamification/leaderboard โ†’ Ranking semanal (premium) ``` **Sistema de XP:** | Aรงรฃo | XP | |---|---| | Scan de produto | +10 | | Primeiro scan do dia | +20 (bรดnus streak) | | Escolher alternativa saudรกvel | +30 | | Completar perfil alimentar | +50 | | Streak de 7 dias | +100 | | Compartilhar resultado | +15 | **Conquistas (badges):** - ๐ŸŒฑ Primeiro Scan - ๐Ÿ” Detetive (10 scans) - ๐Ÿ† Expert (100 scans) - ๐Ÿฅ— Escolha Saudรกvel (5 alternativas escolhidas) - ๐Ÿ”ฅ Streak Master (30 dias seguidos) - ๐Ÿ“Š Analista (score mรฉdio > 70 no mรชs) --- ## Modelo de Dados ### Diagrama ER Simplificado ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ users โ”‚ โ”‚ plans โ”‚ โ”‚dietary_profilesโ”‚ โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚ โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚ โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚ โ”‚ id (PK) โ”‚โ”€โ”€โ”€โ”€โ–ถโ”‚ id (PK) โ”‚ โ”‚ id (PK) โ”‚ โ”‚ email โ”‚ โ”‚ name โ”‚ โ”‚ user_id (FK) โ”‚ โ”‚ password_hashโ”‚ โ”‚ price โ”‚ โ”‚ allergies[] โ”‚ โ”‚ name โ”‚ โ”‚ scan_limit โ”‚ โ”‚ diet โ”‚ โ”‚ plan_id (FK) โ”‚ โ”‚ features{} โ”‚ โ”‚ avoid[] โ”‚ โ”‚ xp โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ goals[] โ”‚ โ”‚ level โ”‚ โ”‚ conditions[] โ”‚ โ”‚ streak_days โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ created_at โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ 1:N โ–ผ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ scans โ”‚โ”€โ”€โ”€โ”€โ–ถโ”‚ products โ”‚ โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚ โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚ โ”‚ id (PK) โ”‚ โ”‚ id (PK) โ”‚ โ”‚ user_id (FK) โ”‚ โ”‚ barcode (UQ) โ”‚ โ”‚ product_id โ”‚ โ”‚ name โ”‚ โ”‚ analysis_id โ”‚ โ”‚ brand โ”‚ โ”‚ score โ”‚ โ”‚ category โ”‚ โ”‚ scanned_at โ”‚ โ”‚ ingredients โ”‚ โ”‚ source โ”‚ โ”‚ nutrition {} โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ nutri_score โ”‚ โ”‚ nova_group โ”‚ โ”‚ images {} โ”‚ โ”‚ allergens[] โ”‚ โ”‚ off_data {} โ”‚ โ”‚ updated_at โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ 1:N โ–ผ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ ingredients โ”‚ โ”‚ analyses โ”‚ โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚ โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚ โ”‚ id (PK) โ”‚ โ”‚ id (PK) โ”‚ โ”‚ product_id โ”‚ โ”‚ product_id โ”‚ โ”‚ name โ”‚ โ”‚ profile_hash โ”‚ โ”‚ popular_name โ”‚ โ”‚ ingredients[]โ”‚ โ”‚ classificationโ”‚ โ”‚ score โ”‚ โ”‚ explanation โ”‚ โ”‚ breakdown {} โ”‚ โ”‚ risk_level โ”‚ โ”‚ summary โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ alerts[] โ”‚ โ”‚ model_versionโ”‚ โ”‚ created_at โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ alternatives โ”‚ โ”‚ achievements โ”‚ โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚ โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚ โ”‚ id (PK) โ”‚ โ”‚ id (PK) โ”‚ โ”‚ product_id โ”‚ โ”‚ user_id (FK) โ”‚ โ”‚ alt_product_idโ”‚ โ”‚ badge_type โ”‚ โ”‚ score_diff โ”‚ โ”‚ unlocked_at โ”‚ โ”‚ highlights[] โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ scan_credits โ”‚ โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚ โ”‚ id (PK) โ”‚ โ”‚ user_id (FK) โ”‚ โ”‚ date โ”‚ โ”‚ used โ”‚ โ”‚ limit โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` ### DDL Principais Tabelas ```sql -- Usuรกrios CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), email VARCHAR(255) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, name VARCHAR(100) NOT NULL, plan_id INTEGER REFERENCES plans(id) DEFAULT 1, xp INTEGER DEFAULT 0, level INTEGER DEFAULT 1, streak_days INTEGER DEFAULT 0, last_scan_date DATE, stripe_customer_id VARCHAR(255), created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); -- Planos CREATE TABLE plans ( id SERIAL PRIMARY KEY, name VARCHAR(50) NOT NULL, -- 'free', 'premium' price_cents INTEGER NOT NULL, -- 0, 1490 (R$14.90) scan_limit_daily INTEGER NOT NULL, -- 3, -1 (unlimited) features JSONB DEFAULT '{}' -- {"export": true, "history_full": true} ); -- Produtos CREATE TABLE products ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), barcode VARCHAR(20) UNIQUE NOT NULL, name VARCHAR(500), brand VARCHAR(200), category VARCHAR(200), ingredients_text TEXT, nutrition JSONB, -- {"energy_kcal": 250, "fat": 12, ...} nutri_score CHAR(1), -- A-E nova_group SMALLINT, -- 1-4 images JSONB, -- {"front": "url", "ingredients": "url"} allergens TEXT[], off_data JSONB, -- Raw Open Food Facts response scan_count INTEGER DEFAULT 0, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX idx_products_barcode ON products(barcode); CREATE INDEX idx_products_category ON products(category); -- Scans CREATE TABLE scans ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES users(id) ON DELETE CASCADE, product_id UUID REFERENCES products(id), analysis_id UUID REFERENCES analyses(id), health_score SMALLINT, scanned_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX idx_scans_user_date ON scans(user_id, scanned_at DESC); -- Anรกlises IA CREATE TABLE analyses ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), product_id UUID REFERENCES products(id), profile_hash VARCHAR(64), -- SHA-256 do perfil alimentar (para cache) ingredients_analysis JSONB, -- Array de anรกlises por ingrediente health_score SMALLINT, score_breakdown JSONB, -- {"naturalness": 20, "nutrition": 40, ...} problematic_top3 TEXT[], summary TEXT, alerts JSONB, model_version VARCHAR(50), -- "gpt-4o-mini-2024-07-18" tokens_used INTEGER, created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX idx_analyses_product_profile ON analyses(product_id, profile_hash); -- Perfis Alimentares CREATE TABLE dietary_profiles ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID UNIQUE REFERENCES users(id) ON DELETE CASCADE, allergies TEXT[] DEFAULT '{}', intolerances TEXT[] DEFAULT '{}', diet VARCHAR(50), avoid TEXT[] DEFAULT '{}', goals TEXT[] DEFAULT '{}', conditions TEXT[] DEFAULT '{}', updated_at TIMESTAMPTZ DEFAULT NOW() ); ``` --- ## Fluxo Principal ``` Usuรกrio abre app (PWA) โ”‚ โ–ผ โ”Œโ”€ Tela de Scan โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ navigator.mediaDevices.getUserMedia({video: { โ”‚ โ”‚ facingMode: "environment" โ”‚ โ”‚ }}) โ”‚ โ”‚ ZXing-js detecta barcode em tempo real โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ barcode detectado (ex: "7891000100103") โ–ผ POST /api/v1/scan { "barcode": "7891000100103" } โ”‚ โ–ผ โ”Œโ”€ Backend โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ 1. RATE LIMIT CHECK โ”‚ โ”‚ Redis: INCR user:{id}:scans:{date} โ”‚ โ”‚ Se >= limite โ†’ 402 (upgrade para premium) โ”‚ โ”‚ โ”‚ โ”‚ 2. BUSCA PRODUTO (3 camadas) โ”‚ โ”‚ a) Redis GET product:{barcode} โ”‚ โ”‚ โ†’ HIT? Retorna cached (< 5ms) โ”‚ โ”‚ b) PostgreSQL SELECT * FROM products WHERE barcode= โ”‚ โ”‚ โ†’ HIT? Retorna + atualiza Redis โ”‚ โ”‚ c) Open Food Facts API GET /api/v2/product/{barcode}โ”‚ โ”‚ โ†’ HIT? Persiste no DB + Redis โ”‚ โ”‚ โ†’ MISS? Retorna "Produto nรฃo encontrado" โ”‚ โ”‚ โ”‚ โ”‚ 3. BUSCA ANรLISE (cache por produto + perfil) โ”‚ โ”‚ profile_hash = SHA256(user.dietary_profile) โ”‚ โ”‚ SELECT * FROM analyses โ”‚ โ”‚ WHERE product_id = X AND profile_hash = Y โ”‚ โ”‚ โ†’ HIT? Retorna cached โ”‚ โ”‚ โ†’ MISS? Chama GPT-4o-mini โ”‚ โ”‚ โ”‚ โ”‚ 4. ANรLISE IA (se cache miss) โ”‚ โ”‚ OpenAI Chat Completion: โ”‚ โ”‚ model: "gpt-4o-mini" โ”‚ โ”‚ response_format: { type: "json_object" } โ”‚ โ”‚ messages: [system_prompt, user_prompt] โ”‚ โ”‚ Parse JSON โ†’ Persiste em analyses โ”‚ โ”‚ โ”‚ โ”‚ 5. CALCULA SCORE (se nรฃo veio da anรกlise) โ”‚ โ”‚ Combina: Nutri-Score + NOVA + IA + Nutriรงรฃo โ”‚ โ”‚ โ”‚ โ”‚ 6. BUSCA ALTERNATIVAS โ”‚ โ”‚ SELECT FROM products WHERE category = X โ”‚ โ”‚ AND health_score > current_score โ”‚ โ”‚ ORDER BY health_score DESC, scan_count DESC โ”‚ โ”‚ LIMIT 5 โ”‚ โ”‚ โ”‚ โ”‚ 7. REGISTRA SCAN โ”‚ โ”‚ INSERT INTO scans (...) โ”‚ โ”‚ UPDATE users SET xp = xp + 10 โ”‚ โ”‚ Verifica achievements โ”‚ โ”‚ โ”‚ โ”‚ 8. RETORNA RESPONSE โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ–ผ โ”Œโ”€ Frontend โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ โ”Œโ”€ Resultado โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ ๐Ÿซ Chocolate ao Leite XYZ โ”‚ โ”‚ โ”‚ โ”‚ Marca ABC โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ SCORE: 32 โ”‚ ๐Ÿ”ด Evitar โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ–ˆโ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–‘โ–‘โ–‘โ–‘ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โš ๏ธ ALERTAS โ”‚ โ”‚ โ”‚ โ”‚ โ€ข Contรฉm GLรšTEN (incompatรญvel com seu perfil) โ”‚ โ”‚ โ”‚ โ”‚ โ€ข Alto teor de aรงรบcar (52g/100g) โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ ๐Ÿ“‹ INGREDIENTES โ”‚ โ”‚ โ”‚ โ”‚ โ€ข Aรงรบcar โ† ๐Ÿšซ Primeiro ingrediente = base โ”‚ โ”‚ โ”‚ โ”‚ โ€ข Gordura vegetal hidrogenada โ† ๐Ÿšซ Trans โ”‚ โ”‚ โ”‚ โ”‚ โ€ข Cacau โ† โœ… Natural โ”‚ โ”‚ โ”‚ โ”‚ โ€ข Lecitina de soja โ† โš ๏ธ Emulsificante โ”‚ โ”‚ โ”‚ โ”‚ [ver todos โ†’] โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ ๐Ÿ”„ ALTERNATIVAS MAIS SAUDรVEIS โ”‚ โ”‚ โ”‚ โ”‚ โ€ข Chocolate 70% Marca Y โ€” Score: 68 (+36) โ”‚ โ”‚ โ”‚ โ”‚ โ€ข Chocolate Orgรขnico Z โ€” Score: 74 (+42) โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` ### Sequรชncia temporal (target < 5s) | Etapa | Tempo (cache hit) | Tempo (cache miss) | |---|---|---| | Decodificaรงรฃo barcode (client) | ~200ms | ~200ms | | Request โ†’ Backend | ~100ms | ~100ms | | Rate limit check (Redis) | ~5ms | ~5ms | | Busca produto | ~5ms (Redis) | ~800ms (OFF API) | | Busca/gera anรกlise IA | ~5ms (cache) | ~2500ms (GPT) | | Calcula score | ~10ms | ~10ms | | Busca alternativas | ~50ms | ~50ms | | Registra scan + XP | ~20ms | ~20ms | | Response โ†’ Frontend | ~100ms | ~100ms | | Render resultado | ~200ms | ~200ms | | **TOTAL** | **~700ms** โœ… | **~4000ms** โœ… | --- ## APIs Externas ### Open Food Facts - **URL:** `https://world.openfoodfacts.org/api/v2/product/{barcode}.json` - **Custo:** Gratuita, open source - **Rate limit:** 100 req/min (ser gentil) - **Cobertura:** ~3M produtos, boa cobertura Brasil - **User-Agent obrigatรณrio:** `Aletheia/1.0 (contato@aletheia.app)` - **Fallback:** Se produto nรฃo encontrado, permitir cadastro manual (v2.0) ### OpenAI GPT-4o-mini - **Endpoint:** `POST https://api.openai.com/v1/chat/completions` - **Modelo:** `gpt-4o-mini` - **Custo estimado:** - Input: ~500 tokens/scan ร— $0.15/1M = $0.000075/scan - Output: ~800 tokens/scan ร— $0.60/1M = $0.00048/scan - **Total: ~$0.00055/scan โ‰ˆ R$0.003/scan** - 10K scans/dia = ~R$30/dia - **Timeout:** 10 segundos - **Retry:** 3x com exponential backoff (1s, 2s, 4s) - **Fallback:** Anรกlise baseada em regras (lista de ingredientes conhecidos) ### Stripe - **Uso:** Assinaturas (Checkout + Customer Portal) - **Webhooks:** `invoice.paid`, `customer.subscription.updated`, `customer.subscription.deleted` - **Planos:** - Free: R$0 (3 scans/dia) - Premium: R$14,90/mรชs (ilimitado + features extras) ### Google Cloud Vision (fallback barcode) - **Uso:** Apenas quando ZXing-js falha na decodificaรงรฃo client-side - **Endpoint:** `POST https://vision.googleapis.com/v1/images:annotate` - **Custo:** $1.50/1K imagens (primeiras 1K/mรชs grรกtis) - **Alternativa free:** QuaggaJS como segundo decoder client-side --- ## PWA & Cรขmera ### Service Worker (next-pwa) ```javascript // next.config.js const withPWA = require('next-pwa')({ dest: 'public', register: true, skipWaiting: true, runtimeCaching: [ { urlPattern: /^https:\/\/api\.aletheia\.app\/api\/v1\/products\/.*/, handler: 'StaleWhileRevalidate', options: { cacheName: 'product-cache', expiration: { maxEntries: 200, maxAgeSeconds: 86400 } } } ] }); ``` ### Cรขmera & Barcode Scanner ```typescript // hooks/useBarcodeScan.ts import { BrowserMultiFormatReader } from '@zxing/library'; export function useBarcodeScan() { const videoRef = useRef(null); const readerRef = useRef(new BrowserMultiFormatReader()); const startScan = async () => { const stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment', // cรขmera traseira width: { ideal: 1280 }, height: { ideal: 720 }, } }); videoRef.current!.srcObject = stream; readerRef.current.decodeFromVideoDevice( undefined, // usa device padrรฃo videoRef.current!, (result, error) => { if (result) { // Vibra para feedback navigator.vibrate?.(200); // Envia barcode para API onBarcodeDetected(result.getText()); } } ); }; return { videoRef, startScan, stopScan }; } ``` ### Manifest (PWA) ```json { "name": "Aletheia - Scanner de Rรณtulos", "short_name": "Aletheia", "description": "Descubra a verdade sobre o que vocรช come", "start_url": "/", "display": "standalone", "orientation": "portrait", "theme_color": "#16A34A", "background_color": "#FFFFFF", "icons": [ { "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png" }, { "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png" } ] } ``` --- ## Monetizaรงรฃo Tรฉcnica ### Planos | Feature | Free | Premium (R$14,90/mรชs) | |---|---|---| | Scans por dia | 3 | Ilimitado | | Histรณrico | รšltimos 7 dias | Completo | | Anรกlise IA | Bรกsica | Detalhada + perfil | | Alternativas | Top 2 | Top 5 + comparativo | | Perfil alimentar | Alergias apenas | Completo (condiรงรตes) | | Export (CSV/PDF) | โŒ | โœ… | | Leaderboard | โŒ | โœ… | | Sem anรบncios | โŒ | โœ… | ### Fluxo Stripe ``` Usuรกrio clica "Upgrade Premium" โ”‚ โ–ผ POST /billing/checkout-session โ†’ Stripe Checkout Session (mode: subscription) โ†’ Redirect para Stripe hosted page โ”‚ โ–ผ Stripe processa pagamento โ”‚ โ–ผ Webhook: invoice.paid โ†’ Backend atualiza user.plan_id = 2 โ†’ Redis: SET user:{id}:plan premium โ”‚ โ–ผ Usuรกrio retorna ao app โ†’ plano ativo ``` ### Sistema de Crรฉditos ```python async def check_scan_credits(user_id: str) -> bool: today = date.today().isoformat() key = f"credits:{user_id}:{today}" # Usuรกrio premium โ†’ sempre permitido if await is_premium(user_id): return True used = await redis.get(key) if used and int(used) >= DAILY_FREE_LIMIT: # 3 return False await redis.incr(key) await redis.expire(key, 86400) # expira em 24h return True ``` --- ## Performance ### Metas | Mรฉtrica | Target | Estratรฉgia | |---|---|---| | Scan โ†’ resultado | < 5s (cold) / < 1s (cached) | Cache 3 camadas | | TTFB (first byte) | < 200ms | Edge deploy (Vercel) | | LCP | < 2.5s | SSR + lazy load imagens | | Bundle size | < 150KB (gzipped) | Tree shaking, dynamic imports | | Lighthouse PWA | > 90 | Service worker, manifest, HTTPS | | API p95 latency | < 500ms (cached) | Redis, connection pooling | | Uptime | 99.9% | Health checks, auto-restart | ### Estratรฉgias de Cache ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Cache Architecture โ”‚ โ”‚ โ”‚ โ”‚ Client (React Query) โ”‚ โ”‚ โ””โ”€ staleTime: 5min โ”‚ โ”‚ โ””โ”€ Produtos escaneados ficam em memรณria โ”‚ โ”‚ โ”‚ โ”‚ Service Worker (Workbox) โ”‚ โ”‚ โ””โ”€ StaleWhileRevalidate para /products โ”‚ โ”‚ โ””โ”€ CacheFirst para imagens estรกticas โ”‚ โ”‚ โ”‚ โ”‚ Redis (Server) โ”‚ โ”‚ โ””โ”€ product:{barcode} โ†’ TTL 24h โ”‚ โ”‚ โ””โ”€ analysis:{product_id}:{hash} โ†’ TTL 7d โ”‚ โ”‚ โ””โ”€ user:{id}:credits:{date} โ†’ TTL 24h โ”‚ โ”‚ โ”‚ โ”‚ PostgreSQL โ”‚ โ”‚ โ””โ”€ Source of truth, updated via cron โ”‚ โ”‚ โ””โ”€ Produtos atualizados a cada 30 dias โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` ### Otimizaรงรตes Backend - **Connection pooling:** SQLAlchemy async pool (min=5, max=20) - **Bulk operations:** Batch insert para alternativas - **รndices:** barcode (B-tree), category (B-tree), scans por user+date - **Async everywhere:** FastAPI + httpx (Open Food Facts) + asyncpg - **Streaming response:** Para anรกlises longas, usar SSE (Server-Sent Events) --- ## Design & UX ### Identidade Visual | Elemento | Especificaรงรฃo | |---|---| | **Nome** | Aletheia (แผ€ฮปฮฎฮธฮตฮนฮฑ = verdade) | | **Logo** | Olho grego estilizado (Nazar/Mati) com รญris em forma de barcode | | **Cores primรกrias** | Verde `#16A34A` (saรบde) + Branco `#FFFFFF` (clean) | | **Cores secundรกrias** | Cinza `#6B7280` (texto) + Verde claro `#DCFCE7` (backgrounds) | | **Cores de score** | ๐Ÿ”ด `#EF4444` ยท ๐ŸŸ  `#F97316` ยท ๐ŸŸก `#EAB308` ยท ๐ŸŸข `#22C55E` | | **Tipografia** | Inter (UI) + Plus Jakarta Sans (headings) | | **รcones** | Lucide Icons (consistente, leve) | | **Bordas** | `rounded-xl` (16px), sombras suaves | | **Espaรงamento** | Grid 8px, padding generoso | ### Telas Principais ``` 1. SPLASH / ONBOARDING - Logo Aletheia (olho grego animado) - "Descubra a verdade sobre o que vocรช come" - 3 slides: Scan โ†’ Entenda โ†’ Escolha melhor - CTA: "Comeรงar" โ†’ setup perfil alimentar 2. HOME - Header: logo + streak ๐Ÿ”ฅ + XP bar - Botรฃo central grande: "๐Ÿ“ท Escanear" - รšltimos scans (horizontal scroll) - Score mรฉdio da semana (mini gauge) - Tip do dia (IA) 3. SCANNER - Cรขmera fullscreen com overlay - Guia visual: "Aponte para o cรณdigo de barras" - Auto-detect + vibraรงรฃo - Loading: animaรงรฃo do olho "analisando" 4. RESULTADO - Score gauge animado (destaque principal) - Alertas personalizados (cards vermelhos/amarelos) - Lista de ingredientes (expandรญvel, com รญcones) - Alternativas (cards horizontais) - Botรตes: Salvar | Compartilhar | Escanear outro 5. HISTร“RICO - Timeline vertical com mini scores - Filtros: perรญodo, categoria, score - Grรกfico de tendรชncia (line chart) 6. PERFIL - Dados pessoais - Perfil alimentar (alergias, dieta, goals) - Plano (free/premium) - Gamificaรงรฃo (nรญvel, badges, streak) - Configuraรงรตes ``` ### Micro-interaรงรตes - **Scan detectado:** Vibraรงรฃo + flash verde + som sutil - **Score reveal:** Animaรงรฃo circular de 0 atรฉ valor final (1.5s) - **Ingrediente tap:** Expande com animaรงรฃo suave (Framer Motion) - **Achievement unlocked:** Toast animado com confetti - **Pull to refresh:** Animaรงรฃo do olho grego piscando --- ## Roadmap ### MVP โ€” Semanas 1-3 **Semana 1: Infraestrutura + Scanner** - [ ] Setup monorepo (turborepo ou pasta separada) - [ ] Backend: FastAPI boilerplate, auth JWT, migrations - [ ] Frontend: Next.js 14, PWA setup, layout base - [ ] Scanner: cรขmera + ZXing-js funcionando - [ ] Integraรงรฃo Open Food Facts (busca bรกsica) **Semana 2: IA + Core Features** - [ ] Anรกlise IA com GPT-4o-mini - [ ] Score de saรบde (algoritmo v1) - [ ] Tela de resultado completa - [ ] Cache Redis para produtos + anรกlises - [ ] Histรณrico bรกsico (lista de scans) **Semana 3: Polish + Deploy** - [ ] Design system (cores, tipografia, componentes) - [ ] Rate limiting (3 scans/dia free) - [ ] Alternativas bรกsicas - [ ] Error handling e loading states - [ ] Deploy: Vercel (front) + Railway (back) - [ ] Testes E2E dos fluxos principais **Entregรกveis MVP:** - PWA funcional no celular - Scan โ†’ resultado com score + ingredientes explicados - 3 scans grรกtis por dia - Histรณrico dos รบltimos 7 dias ### v1.0 โ€” Semanas 4-6 - [ ] Perfil alimentar completo - [ ] Alertas personalizados baseados no perfil - [ ] Stripe integration (premium) - [ ] Gamificaรงรฃo (XP, streaks, badges) - [ ] Onboarding flow - [ ] Push notifications (Web Push API) - [ ] Offline mode (scans salvos localmente) ### v2.0 โ€” Semanas 7-10 - [ ] Compartilhar resultado (social cards) - [ ] Comparar 2 produtos lado a lado - [ ] Leaderboard semanal - [ ] OCR de ingredientes (foto da lista quando sem barcode) - [ ] Cadastro de produtos por usuรกrios - [ ] API pรบblica para desenvolvedores - [ ] Internacionalizaรงรฃo (PT-BR, EN, ES) ### v3.0 โ€” Futuro - [ ] App nativo (React Native ou Capacitor) - [ ] Integraรงรฃo com supermercados (preรงos) - [ ] Scan de cardรกpios de restaurantes - [ ] Diรกrio alimentar com score diรกrio - [ ] Recomendaรงรตes de receitas saudรกveis - [ ] Integraรงรฃo com Apple Health / Google Fit --- ## Estrutura de Diretรณrios ``` aletheia/ โ”œโ”€โ”€ backend/ โ”‚ โ”œโ”€โ”€ app/ โ”‚ โ”‚ โ”œโ”€โ”€ __init__.py โ”‚ โ”‚ โ”œโ”€โ”€ main.py # FastAPI app factory โ”‚ โ”‚ โ”œโ”€โ”€ config.py # Settings (pydantic-settings) โ”‚ โ”‚ โ”œโ”€โ”€ database.py # SQLAlchemy async engine โ”‚ โ”‚ โ”œโ”€โ”€ dependencies.py # Shared deps (get_db, get_current_user) โ”‚ โ”‚ โ”œโ”€โ”€ models/ # SQLAlchemy models โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ user.py โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ product.py โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ scan.py โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ analysis.py โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ dietary_profile.py โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ plan.py โ”‚ โ”‚ โ”œโ”€โ”€ schemas/ # Pydantic schemas โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ user.py โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ product.py โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ scan.py โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ analysis.py โ”‚ โ”‚ โ”œโ”€โ”€ routers/ # API routes โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ auth.py โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ scan.py โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ products.py โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ analysis.py โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ history.py โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ alternatives.py โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ profile.py โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ gamification.py โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ billing.py โ”‚ โ”‚ โ”œโ”€โ”€ services/ # Business logic โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ auth_service.py โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ scan_service.py โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ product_service.py โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ ai_service.py โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ score_service.py โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ alternatives_service.py โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ credits_service.py โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ gamification_service.py โ”‚ โ”‚ โ”œโ”€โ”€ integrations/ # External APIs โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ open_food_facts.py โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ openai_client.py โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ stripe_client.py โ”‚ โ”‚ โ””โ”€โ”€ utils/ โ”‚ โ”‚ โ”œโ”€โ”€ cache.py โ”‚ โ”‚ โ”œโ”€โ”€ security.py โ”‚ โ”‚ โ””โ”€โ”€ prompts.py โ”‚ โ”œโ”€โ”€ alembic/ # Migrations โ”‚ โ”œโ”€โ”€ tests/ โ”‚ โ”œโ”€โ”€ Dockerfile โ”‚ โ”œโ”€โ”€ requirements.txt โ”‚ โ””โ”€โ”€ pyproject.toml โ”‚ โ”œโ”€โ”€ frontend/ โ”‚ โ”œโ”€โ”€ src/ โ”‚ โ”‚ โ”œโ”€โ”€ app/ # Next.js App Router โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ layout.tsx โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ page.tsx # Home โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ scan/page.tsx # Scanner โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ result/[id]/page.tsx โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ history/page.tsx โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ profile/page.tsx โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ premium/page.tsx โ”‚ โ”‚ โ”œโ”€โ”€ components/ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ ui/ # Design system โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ scanner/ โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ CameraView.tsx โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ BarcodeOverlay.tsx โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ result/ โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ ScoreGauge.tsx โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ IngredientList.tsx โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ AlertCards.tsx โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ AlternativeCards.tsx โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ gamification/ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ XPBar.tsx โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ BadgeGrid.tsx โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ useBarcodeScan.ts โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ useAuth.ts โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ useScan.ts โ”‚ โ”‚ โ”œโ”€โ”€ lib/ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ api.ts # Axios instance โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ utils.ts โ”‚ โ”‚ โ””โ”€โ”€ stores/ โ”‚ โ”‚ โ”œโ”€โ”€ authStore.ts # Zustand โ”‚ โ”‚ โ””โ”€โ”€ scanStore.ts โ”‚ โ”œโ”€โ”€ public/ โ”‚ โ”‚ โ”œโ”€โ”€ manifest.json โ”‚ โ”‚ โ”œโ”€โ”€ sw.js โ”‚ โ”‚ โ””โ”€โ”€ icons/ โ”‚ โ”œโ”€โ”€ next.config.js โ”‚ โ”œโ”€โ”€ tailwind.config.ts โ”‚ โ””โ”€โ”€ package.json โ”‚ โ”œโ”€โ”€ docs/ โ”‚ โ”œโ”€โ”€ ARQUITETURA-TECNICA.md # Este arquivo โ”‚ โ”œโ”€โ”€ API.md # Documentaรงรฃo da API โ”‚ โ””โ”€โ”€ DEPLOY.md # Guia de deploy โ”‚ โ”œโ”€โ”€ docker-compose.yml # PostgreSQL + Redis + Backend โ”œโ”€โ”€ .env.example โ””โ”€โ”€ README.md ``` --- ## Estimativa de Custos (10K usuรกrios ativos) | Serviรงo | Custo/mรชs | |---|---| | Vercel (frontend) | Free (hobby) ou $20 (pro) | | Railway (backend + DB + Redis) | ~$20-40 | | OpenAI GPT-4o-mini (~30K scans/mรชs) | ~R$90 (~$17) | | Stripe (2.5% + fees) | Variรกvel | | Domรญnio | ~R$40/ano | | **Total estimado** | **~R$250-400/mรชs** | **Break-even:** ~25-30 assinantes premium (R$14,90 ร— 30 = R$447) --- > *"Aletheia โ€” porque vocรช merece saber a verdade sobre o que come."* ๐Ÿ‘๏ธ