Files
dayMaker_lp/documentação/05_RECOMMENDATION_ENGINE.md
2026-05-13 15:59:02 +01:00

5.0 KiB

🎯 Motor de Recomendações

Filosofia

"Não precisas de IA para parecer inteligente. Precisas de regras bem pensadas."

O motor de recomendações evolui em 3 fases:

Fase Tecnologia Estado
1 — Regras estáticas Lógica JS simples MVP
2 — IA de linguagem OpenAI API 🔲 Fase 2
3 — Recomendação personalizada Histórico + ML 🔲 Fase 3

FASE 1 — Regras Estáticas (MVP)

Contextos disponíveis

O utilizador escolhe um dos seguintes contextos:

// constants/contexts.js

export const CONTEXTS = [
  {
    id: 'travel_short',
    label: 'Viagem curta (1-3 dias)',
    icon: '✈️',
    tags: ['travel'],
    priorityCategories: ['documents', 'clothing', 'electronics', 'footwear'],
    maxItems: 20,
  },
  {
    id: 'travel_long',
    label: 'Viagem longa (4+ dias)',
    icon: '🧳',
    tags: ['travel'],
    priorityCategories: ['documents', 'clothing', 'electronics', 'footwear', 'accessories'],
    maxItems: 40,
  },
  {
    id: 'work',
    label: 'Dia de trabalho',
    icon: '💼',
    tags: ['work'],
    priorityCategories: ['electronics', 'clothing', 'footwear', 'accessories'],
    maxItems: 15,
  },
  {
    id: 'casual',
    label: 'Fim de semana casual',
    icon: '😎',
    tags: ['casual'],
    priorityCategories: ['clothing', 'footwear', 'accessories'],
    maxItems: 10,
  },
  {
    id: 'sport',
    label: 'Treino / Desporto',
    icon: '🏃',
    tags: ['sport'],
    priorityCategories: ['clothing', 'footwear'],
    maxItems: 8,
  },
  {
    id: 'outdoor',
    label: 'Saída para o exterior',
    icon: '🌲',
    tags: ['outdoor', 'travel'],
    priorityCategories: ['clothing', 'footwear', 'accessories'],
    maxItems: 12,
  },
];

Lógica de filtragem

// services/suggestions.js

export function getSuggestionsForContext(items, contextId) {
  const context = CONTEXTS.find(c => c.id === contextId);
  if (!context) return [];

  // 1. Filtrar itens com pelo menos uma tag do contexto
  const relevantItems = items.filter(item =>
    item.contextTags.some(tag => context.tags.includes(tag))
  );

  // 2. Ordenar por prioridade de categoria
  const sorted = relevantItems.sort((a, b) => {
    const aIndex = context.priorityCategories.indexOf(a.category);
    const bIndex = context.priorityCategories.indexOf(b.category);
    const aPriority = aIndex === -1 ? 999 : aIndex;
    const bPriority = bIndex === -1 ? 999 : bIndex;
    return aPriority - bPriority;
  });

  // 3. Limitar ao máximo de itens
  return sorted.slice(0, context.maxItems);
}

Exemplos de output

Contexto: "Viagem curta"

✅ Passaporte           (documents.identity → travel)
✅ Portátil             (electronics.computers → travel, work)
✅ Carregador USB-C     (electronics.cables → travel)
✅ T-shirt preta        (clothing.casual → casual, travel)
✅ Jeans azul           (clothing.casual → casual, travel)
✅ Sapatilhas brancas   (footwear.casual → casual, travel)
❌ Fato de treino       (clothing.sportswear → sport) ← não aparece
❌ Consola PS5          (electronics.gaming → casual) ← não aparece

FASE 2 — IA de Linguagem (OpenAI API)

Não implementar no MVP. Esta secção é referência para a Fase 2.

Objetivo

Permitir ao utilizador escrever em linguagem natural:

  • "Vou viajar 4 horas de comboio"
  • "Tenho uma reunião importante amanhã de manhã"
  • "Fim de semana na praia"

Arquitetura proposta

Utilizador escreve frase
        ↓
OpenAI API (classificação de contexto)
        ↓
Retorna JSON estruturado:
{
  "context": "travel",
  "duration": "short",
  "environment": "transit",
  "weather": "unknown",
  "formality": "casual"
}
        ↓
Motor de regras Fase 1 (com parâmetros enriquecidos)
        ↓
Lista de itens sugeridos

Prompt base para OpenAI

System: És um assistente de inventário pessoal. 
Analisa a frase do utilizador e devolve APENAS um JSON com:
- context: "travel" | "work" | "casual" | "sport" | "outdoor" | "formal"
- duration: "short" | "medium" | "long" | null
- environment: "indoor" | "outdoor" | "transit" | null
- weather: "cold" | "hot" | "rainy" | null
- formality: "casual" | "formal" | null

User: {frase do utilizador}

FASE 3 — Recomendação Personalizada

Fase muito futura. Apenas visão.

  • Sistema aprende quais itens o utilizador seleciona/ignora das sugestões
  • Pontuação de relevância por item por contexto
  • Integração com API de clima para filtros automáticos
  • Histórico de viagens para sugestões baseadas em padrões

Notas para o agente IA

  • No MVP, usar APENAS a Fase 1. Não implementar OpenAI no MVP.
  • A lógica de getSuggestionsForContext deve ser pura (sem side effects)
  • Os contextos são fixos no MVP — não adicionar sem validar com o utilizador
  • A ordenação por priorityCategories é intencional e importante — respeitá-la
  • Quando a Fase 2 for implementada, o output do OpenAI deve mapear para os IDs de contexto da Fase 1