Projeto Kanban Bluwe Cosméticos

Este projeto é um sistema Kanban de produção robusto, projetado para otimizar o controle de fabricação de cosméticos. Ele integra funcionalidades de gerenciamento de produtos, controle de estágios de produção, APIs REST, um banco de dados SQLite/PostgreSQL, e uma interface de usuário moderna baseada em Next.js. O diferencial é a inclusão de servidores MCP (Model Context Protocol) que permitem a integração com LLMs, oferecendo capacidades de orquestração de recursos, execução de ferramentas externas (como OpenAI, Slack, GitHub) e automações neurais avançadas.

Principais Funcionalidades

  • Gerenciamento de Produtos: CRUD completo para produtos, com controle de Ordem de Produção (OP), lotes e quantidades.
  • Kanban Visual: Acompanhamento de produtos em um fluxo de trabalho com estágios definidos (Produção 1kg, Análise C.Q., Produção Reator, Análise Final, Aprovado, Rejeitado).
  • Controle de Semi-Acabados e Envase: Gerenciamento de baldes de 18kg e registro detalhado de processos de envase.
  • Automações Inteligentes (Via MCP):
    • Análise de Qualidade: Em caso de falha em testes de qualidade, o sistema pode alertar equipes via Slack e criar issues no GitHub.
    • Monitoramento de Eficiência: Alertas automáticos para baixa eficiência no envase.
    • Auditoria Visual: Captura de screenshots de estados críticos do sistema para auditoria (via Playwright).
    • Assistente IA: Integração com OpenAI para análise de contexto e tomada de decisão.
  • Métricas e Relatórios: Acompanhamento de status de produção, eficiência e potenciais gargalos.
  • APIs REST: Conjunto abrangente de APIs para interação programática com o sistema.

Instalação

Para configurar e executar o sistema localmente:

  1. Clone o repositório:
    git clone https://github.com/CharlesAquino/kanban-bluwe-cosmeticos.git
    cd kanban-bluwe-cosmeticos
  2. Instale as dependências:
    npm install
  3. Configure o banco de dados (SQLite para desenvolvimento):
    # Gere o cliente Prisma
    npm run prisma:generate
    # Configure o banco SQLite
    npm run prisma:push
  4. Inicie o servidor de desenvolvimento do Next.js:
    npm run dev
    A aplicação estará disponível em: 'http://localhost:3000'

Configuração do Servidor MCP para Clientes LLM

Para que um cliente LLM possa se conectar e utilizar as capacidades do servidor MCP, ele precisará configurar os detalhes de conexão e as ferramentas expostas. Abaixo, um exemplo de configuração em formato JSON que um cliente MCP poderia usar. Esta configuração detalha como iniciar o servidor e quais recursos e ferramentas ele expõe:

{
  "server_name": "kanban-bluwe-cosmeticos-mcp",
  "description": "Servidor MCP para o sistema Kanban de produção de cosméticos Bluwe. Oferece ferramentas para gerenciamento de produção, controle de qualidade, e automações inteligentes, integrando-se com serviços como OpenAI, Slack, GitHub e Playwright.",
  "transport": {
    "protocol": "stdio",
    "command": "node",
    "args": ["./mcp-servers/server.js"],
    "environment": {
      "NODE_ENV": "development",
      "DATABASE_URL": "file:./dev.db",
      "OPENAI_API_KEY": "SUA_CHAVE_OPENAI",
      "SLACK_WEBHOOK": "SEU_SLACK_WEBHOOK_URL",
      "GITHUB_TOKEN": "SEU_GITHUB_TOKEN",
      "GITHUB_REPO": "bluwe/kanban-production",
      "NEXT_PUBLIC_BASE_URL": "http://localhost:3000",
      "PLAYWRIGHT_ENABLED": "true",
      "LLAMA_ENDPOINT": "SEU_ENDPOINT_LLAMA_LOCAL"
    }
  },
  "capabilities": {
    "resources": [
      {
        "name": "products",
        "description": "Gerenciamento de produtos, seus estágios, status e histórico de controle horário.",
        "schema": {
          "type": "object",
          "properties": {
            "id": { "type": "string", "description": "Identificador único do produto." },
            "name": { "type": "string", "description": "Nome do produto." },
            "op": { "type": "string", "description": "Ordem de Produção." },
            "batch": { "type": "string", "description": "Número do lote do produto." },
            "quantity": { "type": "number", "description": "Quantidade do produto em quilogramas (kg)." },
            "currentStage": { "type": "string", "enum": ["BACKLOG", "PRODUCAO_1KG", "AVALIACAO_COR", "PRODUCAO_5KG", "AVALIACAO_FINAL", "APROVADO", "REJEITADO"], "description": "Estágio atual de produção do produto." },
            "status": { "type": "string", "enum": ["ACTIVE", "PAUSED", "COMPLETED", "BLOCKED", "CANCELLED"], "description": "Status atual do produto (ativo, pausado, completo, bloqueado, cancelado)." },
            "manufacturingDate": { "type": "string", "format": "date-time", "description": "Data de fabricação." },
            "createdAt": { "type": "string", "format": "date-time", "description": "Timestamp de criação do registro." },
            "updatedAt": { "type": "string", "format": "date-time", "description": "Timestamp da última atualização do registro." },
            "hourlyControls": { "type": "array", "items": { "$ref": "#/definitions/HourlyControl" }, "description": "Histórico de controles horários associados ao produto." }
          },
          "definitions": {
            "HourlyControl": {
              "type": "object",
              "properties": {
                "id": { "type": "string" },
                "date": { "type": "string", "format": "date" },
                "shift": { "type": "string", "enum": ["morning", "afternoon", "night"] },
                "operator": { "type": "string" },
                "targetQuantity": { "type": "number" },
                "actualQuantity": { "type": "number" },
                "efficiency": { "type": "number" },
                "status": { "type": "string" },
                "notes": { "type": "string" },
                "stage": { "type": "string" },
                "createdAt": { "type": "string", "format": "date-time" },
                "updatedAt": { "type": "string", "format": "date-time" }
              }
            }
          }
        },
        "operations": [
          {"method": "getProducts", "description": "Lista todos os produtos no sistema."},
          {"method": "createProduct", "parameters": {"name": "string", "op": "string", "batch": "string", "quantity": "number", "createdById": "string"}, "description": "Cria um novo produto. Requer nome, ordem de produção, lote, quantidade e o ID do criador."},
          {"method": "getProductById", "parameters": {"id": "string"}, "description": "Obtém detalhes de um produto específico pelo ID."},
          {"method": "updateProduct", "parameters": {"id": "string", "data": "object"}, "description": "Atualiza informações de um produto existente, fornecendo o ID e os dados a serem atualizados."},
          {"method": "deleteProduct", "parameters": {"id": "string"}, "description": "Deleta um produto pelo ID."},
          {"method": "advanceProductStage", "parameters": {"id": "string", "nextStage": "string", "mod": "number"}, "description": "Avança um produto para o próximo estágio de produção, especificando o ID do produto, o próximo estágio e o fator de modificação."},
          {"method": "pauseProduct", "parameters": {"id": "string"}, "description": "Pausa a produção de um produto pelo ID."},
          {"method": "resumeProduct", "parameters": {"id": "string"}, "description": "Retoma a produção de um produto pausado pelo ID."},
          {"method": "blockProduct", "parameters": {"id": "string", "reason": "string"}, "description": "Bloqueia a produção de um produto pelo ID, requerendo um motivo."}
        ]
      },
      {
        "name": "semi_finished_items",
        "description": "Gerenciamento de itens semi-acabados, seus baldes e logs de envase.",
        "schema": {
          "type": "object",
          "properties": {
            "id": { "type": "string", "description": "Identificador único do item semi-acabado." },
            "productId": { "type": "string", "description": "ID do produto de origem (opcional)." },
            "name": { "type": "string", "description": "Nome do item semi-acabado." },
            "family": { "type": "string", "description": "Família do produto." },
            "op": { "type": "string", "description": "Ordem de Produção." },
            "batch": { "type": "string", "description": "Número do lote." },
            "quantityTotal": { "type": "number", "description": "Quantidade total em kg do item semi-acabado." },
            "quantityEnvasado": { "type": "number", "description": "Quantidade em kg já envasada." },
            "status": { "type": "string", "enum": ["AGUARDANDO", "ENVIASANDO", "QUARENTENA", "FINALIZADO"], "description": "Status do item semi-acabado (aguardando, envasando, quarentena, finalizado)." },
            "manufacturingDate": { "type": "string", "format": "date-time" },
            "createdAt": { "type": "string", "format": "date-time" },
            "updatedAt": { "type": "string", "format": "date-time" }
          }
        },
        "operations": [
          {"method": "getSemiFinishedItems", "description": "Lista todos os itens semi-acabados."},
          {"method": "createSemiFinishedItem", "parameters": {"name": "string", "family": "string", "op": "string", "batch": "string", "quantityTotal": "number", "createdById": "string"}, "description": "Cria um novo item semi-acabado, com nome, família, OP, lote, quantidade total e o ID do criador."},
          {"method": "sendBucketsToPackaging", "parameters": {"semiFinishedId": "string", "bucketIds": "array<string>"}, "description": "Envia um ou mais baldes de um semi-acabado para a área de envase."},
          {"method": "packageBucket", "parameters": {"bucketId": "string", "deltaKg": "number"}, "description": "Registra uma quantidade envasada de um balde específico, informando o ID do balde e a quantidade em kg."},
          {"method": "returnBucket", "parameters": {"bucketId": "string"}, "description": "Devolve um balde para o estoque de semi-acabados pelo ID."}
        ]
      },
      {
        "name": "quality_management",
        "description": "Recursos para registrar e consultar testes de qualidade e não conformidades.",
        "schema": {
          "type": "object",
          "properties": {
            "qualityTest": {
              "type": "object",
              "properties": {
                "id": { "type": "string" },
                "productId": { "type": "string" },
                "productName": { "type": "string" },
                "batch": { "type": "string" },
                "stage": { "type": "string" },
                "parameter": { "type": "string", "enum": ["pH", "viscosidade", "cor", "densidade", "estabilidade", "pureza"] },
                "targetValue": { "type": "number" },
                "tolMin": { "type": "number" },
                "tolMax": { "type": "number" },
                "measuredValue": { "type": "number" },
                "unit": { "type": "string" },
                "operator": { "type": "string" },
                "timestamp": { "type": "string", "format": "date-time" },
                "approved": { "type": "boolean" },
                "notes": { "type": "string" }
              },
              "required": ["productId", "productName", "batch", "stage", "parameter", "targetValue", "tolMin", "tolMax", "measuredValue", "unit", "operator", "approved", "timestamp"]
            },
            "nonConformity": {
              "type": "object",
              "properties": {
                "id": { "type": "string" },
                "productId": { "type": "string" },
                "productName": { "type": "string" },
                "batch": { "type": "string" },
                "stage": { "type": "string" },
                "type": { "type": "string", "enum": ["qualidade", "processo", "material", "equipamento"] },
                "severity": { "type": "string", "enum": ["critical", "major", "minor"] },
                "description": { "type": "string" },
                "status": { "type": "string", "enum": ["open", "investigating", "resolved", "closed"] },
                "createdAt": { "type": "string", "format": "date-time" },
                "responsible": { "type": "string" },
                "deadline": { "type": "string", "format": "date-time" }
              },
              "required": ["productId", "productName", "batch", "stage", "type", "severity", "description", "status", "createdAt"]
            }
          }
        },
        "operations": [
          {"method": "createQualityTest", "parameters": {"productId": "string", "productName": "string", "batch": "string", "stage": "string", "parameter": "string", "targetValue": "number", "tolMin": "number", "tolMax": "number", "measuredValue": "number", "unit": "string", "operator": "string", "notes": "string"}, "description": "Registra um novo teste de qualidade para um produto, com todos os detalhes do teste."},
          {"method": "getQualityTestsByProduct", "parameters": {"productId": "string"}, "description": "Busca todos os testes de qualidade para um produto específico pelo ID."},
          {"method": "createNonConformity", "parameters": {"productId": "string", "productName": "string", "batch": "string", "stage": "string", "type": "string", "severity": "string", "description": "string"}, "description": "Registra uma nova não conformidade, incluindo detalhes como tipo, severidade e descrição."},
          {"method": "getNonConformities", "description": "Lista todas as não conformidades registradas."}
        ]
      }
    ],
    "tools": [
      {
        "name": "OpenAIChatCompletion",
        "description": "Permite realizar chamadas de completação de chat com o modelo OpenAI para análise e geração de texto. Ideal para assistentes de IA e processamento de linguagem natural.",
        "parameters": {
          "type": "object",
          "properties": {
            "messages": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "role": { "type": "string", "enum": ["system", "user", "assistant"], "description": "Papel da mensagem (system, user, ou assistant)." },
                  "content": { "type": "string", "description": "Conteúdo da mensagem." }
                },
                "required": ["role", "content"]
              },
              "description": "Uma lista de mensagens que compõem o histórico da conversa."
            },
            "model": { "type": "string", "description": "O modelo OpenAI a ser usado, e.g., 'gpt-3.5-turbo'.", "default": "gpt-3.5-turbo" },
            "maxTokens": { "type": "number", "description": "O número máximo de tokens que a resposta deve conter.", "default": 1000 }
          },
          "required": ["messages"]
        },
        "invoke": {
          "method": "chatCompletion",
          "description": "Chamada do método 'chatCompletion' para interagir com o modelo de chat da OpenAI."
        }
      },
      {
        "name": "SlackNotification",
        "description": "Envia notificações para canais específicos no Slack. Útil para alertas automáticos e comunicação de eventos do sistema.",
        "parameters": {
          "type": "object",
          "properties": {
            "message": { "type": "string", "description": "O conteúdo da mensagem a ser enviada." },
            "channel": { "type": "string", "description": "O canal do Slack (e.g., '#geral', 'kanban-alerts') para onde a mensagem será enviada. Opcional." }
          },
          "required": ["message"]
        },
        "invoke": {
          "method": "sendNotification",
          "description": "Chamada do método 'sendNotification' para enviar uma mensagem para o Slack."
        }
      },
      {
        "name": "GitHubCreateIssue",
        "description": "Cria uma nova issue no GitHub para rastreamento de tarefas, bugs ou não conformidades. Permite automatizar a criação de tickets de acompanhamento.",
        "parameters": {
          "type": "object",
          "properties": {
            "title": { "type": "string", "description": "O título da issue." },
            "body": { "type": "string", "description": "O corpo detalhado da issue (Markdown suportado). Opcional." },
            "labels": { "type": "array", "items": { "type": "string" }, "description": "Uma lista de etiquetas para a issue (e.g., ['bug', 'urgent']). Opcional." }
          },
          "required": ["title"]
        },
        "invoke": {
          "method": "createGitHubIssue",
          "description": "Chamada do método 'createGitHubIssue' para criar uma issue no repositório GitHub configurado."
        }
      },
      {
        "name": "PlaywrightScreenshot",
        "description": "Captura uma screenshot de uma URL específica do sistema para auditoria visual ou documentação. Útil para registrar o estado da UI em momentos críticos.",
        "parameters": {
          "type": "object",
          "properties": {
            "url": { "type": "string", "description": "A URL da página a ser capturada. Se não fornecida, usa a URL base configurada do projeto. Opcional." },
            "name": { "type": "string", "description": "O nome do arquivo da screenshot. Um nome único será gerado se não fornecido. Opcional." }
          }
        },
        "invoke": {
          "method": "captureScreenshot",
          "description": "Chamada do método 'captureScreenshot' para gerar uma imagem da interface do usuário."
        }
      }
    ],
    "prompts": []
  }
}

Comentários para a configuração JSON:

  • 'transport.protocol': Define o protocolo de comunicação. 'stdio' é um padrão comum para comunicação entre processos.
  • 'transport.command': O comando executável para iniciar o servidor MCP. 'node' é usado para executar scripts JavaScript.
  • 'transport.args': Os argumentos para o comando. '['./mcp-servers/server.js']' indica o script principal do servidor MCP, que deve ser o ponto de entrada para todas as funcionalidades.
  • 'environment': Variáveis de ambiente que o servidor MCP pode precisar para funcionar corretamente. É fundamental substituir 'SUA_CHAVE_OPENAI', 'SEU_SLACK_WEBHOOK_URL', 'SEU_GITHUB_TOKEN', 'SEU_ENDPOINT_LLAMA_LOCAL' pelos seus valores reais. O 'PLAYWRIGHT_ENABLED' deve ser configurado como "true" para ativar a captura de screenshots.
  • 'capabilities': Lista as capacidades do servidor, divididas em 'resources' (recursos de dados) e 'tools' (ferramentas de ação).
    • 'resources': Descreve os tipos de dados que podem ser acessados ou manipulados (como 'products', 'semi_finished_items', 'quality_management'). Cada recurso tem um 'schema' que define sua estrutura e 'operations' que são os métodos JSON-RPC disponíveis para interagir com ele, com descrições claras dos parâmetros.
    • 'tools': Descreve as funções externas que o LLM pode invocar. Cada ferramenta especifica seu 'name', uma 'description' de sua funcionalidade, os 'parameters' esperados (com seus tipos e descrições), e o bloco 'invoke' que define o 'method' JSON-RPC a ser chamado no servidor MCP para executar essa ferramenta.
    • 'prompts': Atualmente vazio, mas pode ser usado para definir templates de prompts customizados para interações com LLMs.

Como Iniciar o Servidor MCP Separadamente (para uso por clientes LLM):

Para iniciar o servidor MCP principal, que orquestra as ferramentas mencionadas, você pode usar o comando:

npm run mcp:serve

Este comando iniciará o servidor principal que estará pronto para receber requisições JSON-RPC de clientes LLM. Certifique-se de que todas as variáveis de ambiente necessárias estejam configuradas corretamente no seu arquivo '.env' para que as integrações com OpenAI, Slack, GitHub e Playwright funcionem.

信息

分类

商业系统