### Initial Project Setup with Docker Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/PROJETO_STATUS.md Clone the repository, set up environment variables, and start the development environment using Docker Compose. ```bash git clone https://github.com/RAFAELUFT22/kreativ_bot_v2.git cd kreativ_bot_v2 cp .env.example .env # editar com credenciais reais docker compose up -d ``` -------------------------------- ### Query Modules and Courses Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-handover-roadmap.md Example SQL query to join modules with their respective courses using the course_int_id foreign key. ```sql SELECT m.title, m.module_number, c.title FROM modules m JOIN courses c ON m.course_int_id = c.id; ``` -------------------------------- ### Verify Environment Variables Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-cleanup-and-fase1.md Check the project's .env file for required API keys and URLs before starting tasks. ```bash cat /root/ideias_app/.env | grep -E "N8N_API_KEY|EVOLUTION_API_KEY|N8N_URL" | head -5 ``` -------------------------------- ### Kreativ Bot WPP Implementation Order Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-tooljet-metabase-design.md A step-by-step guide for implementing the Kreativ Bot WPP project, including database migrations, Metabase card creation, and ToolJet/N8N configurations. ```text 1. Migration: criar ai_usage_log (1 comando docker exec) 2. Metabase: criar os 5 cards + organizar dashboard (UI, ~20 min) 3. ToolJet: criar app "Kreativ Admin" + data source + 7 queries (UI, ~45 min) 4. ToolJet: construir layouts Aba Conteúdo (drag & drop, ~30 min) 5. ToolJet: construir layouts Aba Alunos (drag & drop, ~20 min) 6. ToolJet: criar grupos RBAC (admin, tutor, conteudo) + convidar usuários 7. N8N: adicionar nó "AI Tutor: Log Usage" no ULTIMATE (após Task 3 do plano async) 8. Testar end-to-end: editar módulo no ToolJet → verificar no PostgreSQL 9. Testar: abrir dashboard Metabase → confirmar dados aparecem ``` -------------------------------- ### Check Environment Variables Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-tooljet-metabase-impl.md Use this bash command to confirm that the necessary environment variables (POSTGRES_PASSWORD, N8N_API_KEY, EVOLUTION_API_KEY) are present in the .env file. This is crucial for verifying credential setup. ```bash grep -E 'POSTGRES_PASSWORD|N8N_API_KEY|EVOLUTION_API_KEY' /root/ideias_app/.env ``` -------------------------------- ### Kreativ Ingest Dockerfile Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-content-pipeline-design.md Dockerfile for building the `kreativ_ingest` service. It sets up the Python environment, installs dependencies including PDF and DOCX parsers, and defines the command to run the application. ```dockerfile FROM python:3.11-slim WORKDIR /app RUN apt-get update && apt-get install -y --no-install-recommends \ libpoppler-cpp-dev curl && rm -rf /var/lib/apt/lists/* COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY main.py . CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] ``` -------------------------------- ### Get Module Workflow Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-n8n-async-redesign.md This workflow retrieves module data and generates a quiz. It fetches data from PostgreSQL, responds synchronously with title and content, and then asynchronously generates and sends a quiz using an OpenAI Chat Model and Evolution API. ```N8N Switch (get_module) ↓ [Nó 1] Module: Buscar Dados ← existente, manter type: PostgreSQL ↓ [Nó 2] Module: Responder 200 type: Respond to Webhook → { "ok": true, "title": "{{ $json.title }}", "content": "{{ $json.content_text }}", "module_number": {{ $json.module_number }}, "response": "Quiz sendo gerado... 📚" } ← Typebot recebe title + content IMEDIATAMENTE ↓ (continua em background) [Nó 3] Module: Chat Model type: OpenAI Chat Model → Credential: "OpenRouter" → Model: deepseek/deepseek-chat [Nó 4] Module: AI Gerar Quiz type: Basic LLM Chain → LLM: [Nó 3] → Prompt: reutilizar "Module: Prompt AI Quiz" (Code node existente) → Output: texto formatado com as perguntas do quiz ↓ [Nó 5] Module: Enviar Quiz type: HTTP Request → Evolution API sendText → "📝 *Quiz do {title}*\n\n{perguntas geradas}" ``` -------------------------------- ### Test Typebot Chat Start Endpoint Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/PROJETO_STATUS.md Initiate a chat session with the Typebot by sending a POST request to the startChat API endpoint. Ensure the 'remoteJid' and 'pushName' are correctly formatted. ```bash curl -s -X POST "https://bot.extensionista.site/api/v1/typebots/kreativ-education/startChat" -H "Content-Type: application/json" -d '{"prefilledVariables":{"remoteJid":"556399374165@s.whatsapp.net","pushName":"Rafael"}}' ``` -------------------------------- ### Session Sequence Checklist Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-handover-roadmap.md Recommended steps for initializing a development or maintenance session. ```text 1. Ler este doc (30s) 2. Rodar smoke test (comandos da seção 4) — confirmar tudo verde 3. git log --oneline -5 4. VERIFICAR Fase 2: existe nó 'Redis Rate Limit' no ULTIMATE? Existe validação auth no Normalizar Input? 5. Testar submit_quiz end-to-end (Fase 3B) 6. Popular embeddings dos módulos principais via scripts/ingest_embeddings.py (Fase 3C) 7. Atualizar este doc ao finalizar cada fase ``` -------------------------------- ### GET /health Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-content-pipeline-design.md Performs a health check on the service. ```APIDOC ## GET /health ### Description Used by Docker healthcheck to verify the service is running. ### Method GET ### Endpoint /health ``` -------------------------------- ### Get Student Progress Source: https://context7.com/rafaeluft22/kreativ_bot_wpp/llms.txt Retrieve comprehensive student statistics, including completed modules, completion percentage, and enrollment date. ```bash curl -X POST "https://n8n.extensionista.site/webhook/kreativ-unified-api" \ -H "Content-Type: application/json" \ -d '{ "action": "get_progress", "phone": "556399374165" }' ``` -------------------------------- ### Test Welcome Flow via Webhook Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/test-plan-rafael.md Simulate a new user sending an initial message to trigger the welcome flow. This tests the bot's response to first contact. ```bash docker exec kreativ_n8n wget -qO- --post-data='{ "event": "messages.upsert", "data": { "key": {"remoteJid": "556399374165@s.whatsapp.net", "fromMe": false}, "pushName": "Rafael Luciano", "message": {"conversation": "oi"} } }' --header="Content-Type: application/json" http://localhost:5678/webhook/whatsapp ``` -------------------------------- ### Get Current Workflow Definition Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-tooljet-metabase-impl.md Fetches the current N8N workflow definition and saves it to a temporary JSON file for modification. Ensure you are in the '/root/ideias_app' directory. ```bash cd /root/ideias_app N8N_KEY=$(grep N8N_API_KEY .env | cut -d= -f2) curl -s https://n8n.extensionista.site/api/v1/workflows/SoB5evP9aOmj6hLA \ -H "X-N8N-API-KEY: $N8N_KEY" > /tmp/ultimate_current.json echo "Nodes: $(python3 -c "import json; wf=json.load(open('/tmp/ultimate_current.json')); print(len(wf['nodes']))")" ``` -------------------------------- ### Configure Course Selector Dropdown Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-tooljet-metabase-impl.md Set up a 'Select' component for choosing a course. Ensure data is bound to '{{listCursos.data}}' and configure 'onChange' to trigger the 'listModulos' query. ```javascript { "name": "courseSelector", "label": "Curso", "data": "{{listCursos.data}}", "displayKey": "name", "valueKey": "id", "onChange": "query:listModulos" } ``` -------------------------------- ### Smoke Test: Get Progress Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-cleanup-and-fase1.md Performs a POST request to the Kreativ Unified API webhook to retrieve student progress. Requires the N8N_API_KEY to be sourced. ```bash source /root/ideias_app/.env # 3. get_progress curl -s -X POST -H "Content-Type: application/json" \ -d '{"phone":"556399374165","action":"get_progress"}' \ "https://n8n.extensionista.site/webhook/kreativ-unified-api" | python3 -m json.tool ``` -------------------------------- ### SQL Migration: Create `ai_usage_log` Table Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-tooljet-metabase-design.md SQL script to create the `ai_usage_log` table in the `kreativ_edu` database. This table is a prerequisite for tracking AI Tutor usage. ```sql -- Executar em kreativ_edu CREATE TABLE IF NOT EXISTS ai_usage_log ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), phone VARCHAR(20), event_type VARCHAR(50), -- 'ai_tutor', 'quiz_eval', 'quiz_gen' model VARCHAR(100), prompt_tokens INTEGER, completion_tokens INTEGER, duration_ms INTEGER, created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX idx_ai_usage_log_created ON ai_usage_log (created_at DESC); CREATE INDEX idx_ai_usage_log_event ON ai_usage_log (event_type, created_at DESC); ``` -------------------------------- ### Smoke Test: Get Module Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-cleanup-and-fase1.md Performs a POST request to the Kreativ Unified API webhook to retrieve module information. Requires the N8N_API_KEY to be sourced. ```bash source /root/ideias_app/.env # 2. get_module curl -s -X POST -H "Content-Type: application/json" \ -d '{"phone":"556399374165","action":"get_module","module_id":1}' \ "https://n8n.extensionista.site/webhook/kreativ-unified-api" | python3 -m json.tool ``` -------------------------------- ### Get Module Detail SQL Query Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-23-comet-briefing.md Retrieves the full details for a specific module based on its ID. Assumes the module ID is selected from a table. ```sql SELECT * FROM modules WHERE id = {{modules_table.selectedRow.id}} ``` -------------------------------- ### Kreativ Bot WPP Project References Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-tooljet-metabase-design.md Key file paths and URLs for the Kreativ Bot WPP project, including blueprints, SQL schemas, docker configurations, environment variables, and service endpoints. ```text /root/ideias_app/docs/TOOLJET_DASHBOARD_BLUEPRINT.md ← blueprint detalhado original /root/ideias_app/init-scripts/01-init-dbs.sql ← schema do kreativ_edu /root/ideias_app/docker-compose.yml ← tooljet (linha ~334), metabase (~380) /root/ideias_app/.env ← POSTGRES_PASSWORD, TOOLJET_SECRET_KEY ToolJet: https://admin.extensionista.site Metabase: https://dash.extensionista.site PostgreSQL host interno: kreativ_postgres:5432 Database: kreativ_edu Tabela-chave: modules (course_int_id INTEGER FK, não course_id VARCHAR) ``` -------------------------------- ### Configure Search Input for Students Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-tooljet-metabase-impl.md Set up a 'Text Input' component for searching students. The 'onChange' event should trigger the 'listAlunos' query. ```javascript { "name": "searchInput", "placeholder": "Buscar por nome ou telefone...", "onChange": "query:listAlunos" } ``` -------------------------------- ### Export N8N Workflow Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-n8n-async-impl.md Exports an N8N workflow to a JSON file using a cURL GET request and pipes the output to 'python3 -m json.tool' for pretty-printing. ```bash curl -s -H "X-N8N-API-KEY: $N8N_API_KEY" \ "https://n8n.extensionista.site/api/v1/workflows/SoB5evP9aOmj6hLA" | \ python3 -m json.tool > /root/ideias_app/n8n-workflows/60-kreativ-api-ultimate.json ``` -------------------------------- ### Verify script results in /scripts/ Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-cleanup-and-fase1.md Lists the contents of the scripts directory to verify expected files are present after a build process. ```bash ls /root/ideias_app/scripts/ ``` -------------------------------- ### Reset Stuck Typebot Sessions Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/PROJETO_STATUS.md Clear stuck chat sessions in Typebot by executing a PostgreSQL DELETE command. This targets sessions where the 'currentBlockId' starts with 'b_g'. ```bash docker exec kreativ_postgres psql -U kreativ_user -d typebot_db -c "DELETE FROM "ChatSession" WHERE state->>'currentBlockId' LIKE 'b_g%';" ``` -------------------------------- ### Get n8n Workflow ID Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-cleanup-and-fase1.md Retrieves the ID of a specific n8n workflow by name using a curl command and Python parsing. Ensure the N8N_API_KEY is set in your environment. ```bash WF_ID=$(curl -s -H "X-N8N-API-KEY: $N8N_API_KEY" \ "https://n8n.extensionista.site/api/v1/workflows" | \ python3 -c " import json,sys wfs=json.load(sys.stdin) for w in wfs.get('data',[]): if 'router' in w.get('name','').lower() or '01' in w.get('name',''): print(w['id']); break ") ``` -------------------------------- ### List Modules Query (SQL) Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/TOOLJET_DASHBOARD_BLUEPRINT.md SQL query to fetch modules for a specific course from the Kreativ DB. It requires the course ID to filter the modules. ```sql SELECT m.id, m.module_number, m.title, m.description, m.content_text, m.is_published, m.passing_score FROM modules m WHERE m.course_int_id = {{components.courseTable.selectedRow.id}} ORDER BY m.module_number ``` -------------------------------- ### Execute Migration in PostgreSQL Container Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-tooljet-metabase-impl.md Copies the migration file into the Docker container and executes it against the kreativ_edu database. ```bash docker cp /tmp/migration_ai_usage_log.sql kreativ_postgres:/tmp/migration_ai_usage_log.sql docker exec kreativ_postgres psql -U kreativ_user -d kreativ_edu \ -f /tmp/migration_ai_usage_log.sql ``` -------------------------------- ### Evolution API List Messages Syntax Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/PROJETO_STATUS.md Use this syntax for larger menus or lists in Evolution API. This example shows a main menu with options for modules and progress. ```text [list] [title]Menu Principal[/title] [description]O que deseja fazer?[/description] [buttonText]Selecionar[/buttonText] [menu] [section] title: Opções [row]title: 📚 Módulo, rowId: mod[/row] [row]title: 📊 Progresso, rowId: prog[/row] [/section] [/menu] [/list] ``` -------------------------------- ### Configure Students Table Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-tooljet-metabase-impl.md Set up a 'Table' component to display student data. Bind data to '{{listAlunos.data}}' and configure columns. 'onRowClicked' should trigger 'histQuiz' query and open the student modal. ```javascript { "name": "studentsTable", "data": "{{listAlunos.data}}", "columns": [ {"key": "name", "title": "Nome"}, {"key": "phone", "title": "Telefone"}, {"key": "course_name", "title": "Curso"}, {"key": "current_module", "title": "Módulo"}, {"key": "ultimo_score", "title": "Score"}, {"key": "ultimo_quiz", "title": "Último Quiz"} ], "onRowClicked": "query:histQuiz;openModal:studentModal" } ``` -------------------------------- ### Docker Compose Configuration for Kreativ Bot WPP Source: https://context7.com/rafaeluft22/kreativ_bot_wpp/llms.txt Sets up the main services for the Kreativ Bot WPP stack, including PostgreSQL with pgvector, Redis, Evolution API, N8N, Typebot Viewer, Chatwoot, and the Portal application. Requires environment variables for passwords and database URIs. ```yaml # docker-compose.yml (serviços principais) services: kreativ_postgres: image: pgvector/pgvector:pg16 environment: POSTGRES_USER: kreativ_user POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: kreativ_edu volumes: - ./init-scripts:/docker-entrypoint-initdb.d kreativ_redis: image: redis:7-alpine kreativ_evolution: image: atendai/evolution-api:v2.2.3 environment: DATABASE_CONNECTION_URI: postgresql://kreativ_postgres:5432/evolution_db TYPEBOT_ENABLED: "true" TYPEBOT_API_VERSION: latest TYPEBOT_URL: http://kreativ_typebot_viewer:3000 kreativ_n8n: image: n8nio/n8n:latest environment: DB_TYPE: postgresdb DB_POSTGRESDB_HOST: kreativ_postgres kreativ_typebot_viewer: image: typebot/viewer:latest environment: DATABASE_URL: postgresql://kreativ_postgres:5432/typebot_db kreativ_chatwoot: image: chatwoot/chatwoot:v3.15.0 environment: DATABASE_URL: postgresql://kreativ_postgres:5432/chatwoot_db kreativ_portal: build: ./apps/portal environment: DB_HOST: kreativ_postgres DB_NAME: kreativ_edu # Comandos úteis: # docker compose up -d # Iniciar stack # docker compose logs -f kreativ_n8n # Ver logs do N8N # docker exec kreativ_postgres psql -U kreativ_user -d kreativ_edu # Acessar DB ``` -------------------------------- ### Interagir com Tutor IA via API N8N Source: https://context7.com/rafaeluft22/kreativ_bot_wpp/llms.txt Permite que alunos façam perguntas livres sobre o conteúdo do curso. O sistema utiliza busca vetorial e histórico de conversas para fornecer respostas personalizadas via DeepSeek. ```bash curl -X POST "https://n8n.extensionista.site/webhook/kreativ-unified-api" \ -H "Content-Type: application/json" \ -d '{ "action": "ai_tutor", "phone": "556399374165", "message": "Pode me explicar melhor como funciona uma rede neural?" }' ``` ```text "Uma rede neural é inspirada no cérebro humano! Ela tem camadas de ``` -------------------------------- ### Check Available LangChain Nodes in N8N Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-n8n-async-impl.md Lists all available LangChain-related node types in N8N via its API. This helps verify if the required nodes for asynchronous operations are installed. ```bash export N8N_API_KEY=$(grep '^N8N_API_KEY=' /root/ideias_app/.env | cut -d'=' -f2 | tr -d '"') curl -s -H "X-N8N-API-KEY: $N8N_API_KEY" \ "https://n8n.extensionista.site/api/v1/node-types" | \ python3 -c " import json, sys types = json.load(sys.stdin) langchain = [t['name'] for t in types.get('data', []) if 'langchain' in t.get('name','').lower()] print('LangChain nodes disponíveis:') for t in sorted(langchain): print(f' {t}') " ``` -------------------------------- ### POST /webhook/kreativ-unified-api (ai_tutor) Source: https://context7.com/rafaeluft22/kreativ_bot_wpp/llms.txt Sends a query to the AI tutor, which uses RAG to provide context-aware answers. ```APIDOC ## POST /webhook/kreativ-unified-api ### Description Allows students to ask questions about the course content, answered by the AI tutor. ### Method POST ### Endpoint /webhook/kreativ-unified-api ### Request Body - **action** (string) - Required - Must be "ai_tutor" - **phone** (string) - Required - Student phone number - **message** (string) - Required - The student's question ### Request Example { "action": "ai_tutor", "phone": "556399374165", "message": "Pode me explicar melhor como funciona uma rede neural?" } ``` -------------------------------- ### List Modules SQL Query Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-23-comet-briefing.md Retrieves a list of all modules, including their ID, title, module number, publication status, video URL, and the count of media files. Ordered by module number. ```sql SELECT id, title, module_number, is_published, video_url, array_length(media_urls,1) as media_count FROM modules ORDER BY module_number ``` -------------------------------- ### Get Student Quiz History from PostgreSQL Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/SONAR_PLANO_2_TOOLJET.md Retrieves the historical quiz progress for a specific student from the 'enrollment_progress' table. Displays module number, status, score, AI feedback, and completion date/time. ```sql SELECT ep.module_number AS "Módulo", ep.status AS "Status", ep.score AS "Score", COALESCE(ep.ai_feedback, 'Sem feedback registrado') AS "Feedback IA", TO_CHAR(ep.completed_at AT TIME ZONE 'America/Sao_Paulo', 'DD/MM/YYYY HH24:MI') AS "Data" FROM enrollment_progress ep WHERE ep.student_id = '{{studentsTable.selectedRow.data.id}}' ORDER BY ep.completed_at DESC NULLS LAST ``` -------------------------------- ### List Courses Query Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-tooljet-metabase-design.md Retrieves all courses ordered by name to populate the course selector. ```sql SELECT id, name, description, created_at FROM courses ORDER BY name ASC ``` -------------------------------- ### Configure Modules Table Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-tooljet-metabase-impl.md Set up a 'Table' component to display modules. Bind data to '{{listModulos.data}}' and configure columns including a 'Badge' type for 'is_published'. Set 'onRowClicked' to trigger 'loadModulo' and open an edit modal. ```javascript { "name": "modulesTable", "data": "{{listModulos.data}}", "columns": [ {"key": "module_number", "title": "N°"}, {"key": "title", "title": "Título"}, {"key": "is_published", "title": "Publicado", "type": "badge"} ], "onRowClicked": "query:loadModulo;openModal:editModuloModal" } ``` -------------------------------- ### Get Module ID and Test Current submit_quiz Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-n8n-async-impl.md This snippet shows how to retrieve a valid module ID from the PostgreSQL database and then test the current submit_quiz functionality using cURL. Replace UUID_DO_MODULO_AQUI with the actual ID obtained. ```bash # Obter um module_id válido docker exec kreativ_postgres psql -U kreativ_user -d kreativ_edu \ -c "SELECT id, title FROM modules WHERE module_number=2 LIMIT 1;" -t # Testar submit_quiz atual curl -s -X POST -H "Content-Type: application/json" \ -d '{ "phone": "556399374165", "action": "submit_quiz", "module_id": "UUID_DO_MODULO_AQUI", "answers": ["A documentação rural é importante para registro da propriedade"] }' \ "https://n8n.extensionista.site/webhook/kreativ-unified-api" --max-time 40 ``` -------------------------------- ### Reset Student Database State Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/test-plan-rafael.md Use these commands to reset a student's progress in the database before starting a new test scenario. The full reset simulates a new student, while the partial reset only changes the attendance status. ```bash docker exec kreativ_postgres psql -U kreativ_user -d kreativ_edu -c " UPDATE students SET attendance_status='bot', current_module=1, completed_modules='{}', scores='{}', lead_score=0, lead_tags=NULL WHERE phone='556399374165';" ``` ```bash docker exec kreativ_postgres psql -U kreativ_user -d kreativ_edu -c " UPDATE students SET attendance_status='bot' WHERE phone='556399374165';" ``` -------------------------------- ### Kreativ Ingest Requirements.txt Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-content-pipeline-design.md Lists the Python dependencies required for the `kreativ_ingest` microservice, including FastAPI, Uvicorn, PDF/DOCX parsers, Boto3 for MinIO, and libraries for database and HTTP requests. ```python fastapi==0.111.0 uvicorn==0.29.0 pdfplumber==0.11.0 python-docx==1.1.0 boto3==1.34.0 psycopg2-binary==2.9.9 httpx==0.27.0 ``` -------------------------------- ### Generate Conversion Funnel Data Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/SONAR_PLANO_1_METABASE.md Provides data for a conversion funnel, showing counts for pre-inscriptions, registered students, students who started modules, and certificates issued. It uses subqueries to count from 'pre_inscriptions', 'students', and 'certificates' tables. ```sql SELECT unnest(ARRAY['Pré-inscrições','Alunos cadastrados','Iniciaram','Certificados']) AS etapa, unnest(ARRAY[ (SELECT COUNT(*) FROM pre_inscriptions)::int, (SELECT COUNT(*) FROM students)::int, (SELECT COUNT(*) FROM students WHERE current_module > 0)::int, (SELECT COUNT(*) FROM certificates)::int ]) AS total ``` -------------------------------- ### Student Learning Funnel Distribution (SQL) Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/SONAR_PLANO_1_METABASE.md This SQL query categorizes students by their current module progress, including those who haven't started. It's useful for visualizing the learning funnel. Requires the 'students' table with a 'current_module' column. ```sql SELECT CASE WHEN current_module = 0 THEN 'Não iniciado' ELSE CONCAT('Módulo ', current_module) END AS modulo, COUNT(*) AS alunos FROM students GROUP BY current_module ORDER BY current_module ``` -------------------------------- ### POST /webhook/kreativ-unified-api (get_module) Source: https://context7.com/rafaeluft22/kreativ_bot_wpp/llms.txt Fetches the content for a specific module and triggers the background generation of quiz questions. ```APIDOC ## POST /webhook/kreativ-unified-api ### Description Retrieves module content and dynamically generates quiz questions using DeepSeek. ### Method POST ### Endpoint /webhook/kreativ-unified-api ### Request Body - **action** (string) - Required - Must be "get_module" - **phone** (string) - Required - Student phone number - **module_number** (number) - Required - The module index to retrieve ### Request Example { "action": "get_module", "phone": "556399374165", "module_number": 1 } ### Response #### Success Response (200) - **title** (string) - Module title - **content_text** (string) - Educational content - **quiz_questions** (array) - List of generated questions #### Response Example { "title": "Introdução à Inteligência Artificial", "content_text": "A Inteligência Artificial (IA) é um campo da ciência...", "quiz_questions": [{"question": "O que é aprendizado de máquina?"}] } ``` -------------------------------- ### Simulate AI Tutor via Webhook Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-cleanup-and-fase1.md Sends a POST request to the AI tutor webhook to test message processing. ```bash source /root/ideias_app/.env curl -s -X POST \ -H "Content-Type: application/json" \ -d '{ "phone": "556399374165", "action": "ai_tutor", "message": "Explique o que é aprendizado ativo em 2 frases." }' \ "https://n8n.extensionista.site/webhook/kreativ-unified-api" | python3 -m json.tool ``` -------------------------------- ### SQL Query for Students Inactive for Over 7 Days Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/SONAR_PLANO_1_METABASE.md This SQL query identifies students who have been inactive for more than 7 days. It filters for students with 'bot' attendance status, who have passed module 0 (started the course), and whose last update was more than 7 days ago. ```sql SELECT COUNT(*) AS parados FROM students WHERE updated_at < NOW() - INTERVAL '7 days' AND attendance_status = 'bot' AND current_module > 0 ``` -------------------------------- ### Metabase Database Configuration Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-tooljet-metabase-design.md Details for connecting Metabase to the kreativ_edu PostgreSQL database. Ensure the .env file contains the POSTGRES_PASSWORD. ```text https://dash.extensionista.site → Admin → Databases Database: kreativ_edu (PostgreSQL, kreativ_postgres:5432) ``` ```text Type | PostgreSQL Name | kreativ_edu Host | `kreativ_postgres` Port | `5432` Database | `kreativ_edu` User | `kreativ_user` Password | Ver `.env → POSTGRES_PASSWORD` ``` -------------------------------- ### Configuração do Nó ai_tutor Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-n8n-async-redesign.md Estrutura de nós para o fluxo ai_tutor, incluindo extração de dados, resposta ao webhook, busca de contexto, configuração de memória e envio via WhatsApp. ```text Switch (ai_tutor) ↓ [Nó 1] AI Tutor: Extrair Input type: Edit Fields (Set) → phone: {{ $json.phone }} → message: {{ $json.message || $json.body || 'Olá' }} ↓ [Nó 2] AI Tutor: Responder 200 type: Respond to Webhook → { "ok": true, "response": "Seu tutor está analisando... 🤔" } ↓ [Nó 3] AI Tutor: Buscar Contexto type: PostgreSQL → Combined Context Query (reutilizar SQL do sub-workflow existente): - module_data: title, content_text as syllabus, evaluation_rubric - fewshot_data: training_memory (últimos 3 exemplos) - rag_chunks: document_chunks JOIN modules (top 5 por chunk_index) ↓ [Nó 4] AI Tutor: Preparar Sistema type: Edit Fields (Set) → systemMessage: string composta com curso, módulo, syllabus, rag_context, rubric ↓ [Nó 5] AI Tutor: Chat Model [sub-nó conectado ao Agent] type: OpenAI Chat Model (n8n-nodes-langchain.lmChatOpenAi) → Credential: "OpenRouter" (tipo OpenAI, base URL: https://openrouter.ai/api/v1) → Model: deepseek/deepseek-chat → Temperature: 0.7 [Nó 6] AI Tutor: Memória [sub-nó conectado ao Agent] type: Window Buffer Memory (n8n-nodes-langchain.memoryBufferWindow) → Session Key: {{ $('AI Tutor: Extrair Input').first().json.phone }} → Context Window Length: 10 (5 trocas) → Backend: Redis (credencial existente kreativ_redis) ↓ [Nó 7] AI Tutor: Agent type: AI Agent (n8n-nodes-langchain.agent) → Chat Model: [Nó 5] → Memory: [Nó 6] → System Message: {{ $('AI Tutor: Preparar Sistema').first().json.systemMessage }} → Human Message: {{ $('AI Tutor: Extrair Input').first().json.message }} → continueOnFail: true ↓ ↓ (erro) [normal] [Nó 7b] AI Tutor: Fallback type: Edit Fields (Set) → output: "Desculpe, o tutor está indisponível. Tente em instantes! 🔧" ↓ [Nó 8] AI Tutor: Enviar WhatsApp type: HTTP Request → POST https://evolution.extensionista.site/message/sendText/europs → Headers: { "apikey": "{{ $env.EVOLUTION_API_KEY }}" } → Body: { "number": "{{ $('AI Tutor: Extrair Input').first().json.phone }}@s.whatsapp.net", "textMessage": { "text": "{{ $json.output }}" } } ``` -------------------------------- ### List Modules for Selected Course Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-tooljet-metabase-design.md Fetches modules associated with the selected course ID, triggered when the course selector changes. ```sql SELECT m.id, m.module_number, m.title, m.is_published, LENGTH(m.content_text) AS chars_content, m.course_int_id FROM modules m WHERE m.course_int_id = {{courseSelector.value}} ORDER BY m.module_number ASC ``` -------------------------------- ### Metabase Query: AI Tutor Usage (14 days) Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-tooljet-metabase-design.md SQL query for Metabase to track AI Tutor usage, including calls, tokens, and average duration, over the last 14 days. Requires the `ai_usage_log` table. ```sql SELECT DATE(created_at) AS dia, COUNT(*) AS chamadas, SUM(prompt_tokens) AS tokens_prompt, SUM(completion_tokens) AS tokens_resposta, ROUND(AVG(duration_ms)::numeric / 1000, 1) AS tempo_medio_s FROM ai_usage_log WHERE event_type = 'ai_tutor' AND created_at >= NOW() - INTERVAL '14 days' GROUP BY DATE(created_at) ORDER BY dia DESC ``` -------------------------------- ### Retrieve Module Content Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-handover-roadmap.md Fetch the content of all modules for processing or review. ```bash docker exec kreativ_postgres psql -U kreativ_user -d kreativ_edu -c " SELECT m.id, m.title, m.content FROM modules m ORDER BY m.module_number;" ``` -------------------------------- ### Create ai_usage_log Migration SQL Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-tooljet-metabase-impl.md Defines the SQL schema for the ai_usage_log table and associated indexes to track AI usage metrics. ```bash cat > /tmp/migration_ai_usage_log.sql << 'EOF' -- Executar em kreativ_edu CREATE TABLE IF NOT EXISTS ai_usage_log ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), phone VARCHAR(20), event_type VARCHAR(50), -- 'ai_tutor', 'quiz_eval', 'quiz_gen' model VARCHAR(100), prompt_tokens INTEGER, completion_tokens INTEGER, duration_ms INTEGER, created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_ai_usage_log_created ON ai_usage_log (created_at DESC); CREATE INDEX IF NOT EXISTS idx_ai_usage_log_event ON ai_usage_log (event_type, created_at DESC); EOF ``` -------------------------------- ### Executar teste de baseline via cURL Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-n8n-async-impl.md Realiza uma requisição POST para o webhook do n8n e formata a resposta JSON para verificação rápida. ```bash echo "=== BASELINE antes da mudança ===" curl -s -X POST -H "Content-Type: application/json" \ -d '{"phone":"556399374165","action":"ai_tutor","message":"Teste baseline"}' \ "https://n8n.extensionista.site/webhook/kreativ-unified-api" --max-time 40 | \ python3 -c "import json,sys; r=json.load(sys.stdin); print(f'ok={r.get(\"ok\")} resp={str(r.get(\"response\",\"\"))[:50]}')" ``` -------------------------------- ### Verificar conexões do nó AI Tutor Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-n8n-async-impl.md Analisa o arquivo JSON do workflow para identificar as conexões existentes relacionadas ao nó AI Tutor. ```python python3 -c " import json wf = json.load(open('/tmp/ultimate_before_async.json')) conns = wf['connections'] # Encontrar o que conecta ao AI Tutor: Proxy Request for src, targets in conns.items(): for conn_type, lists in targets.items(): for tlist in lists: for t in tlist: if 'AI Tutor' in t.get('node','') or 'AI Tutor' in src: print(f'{src} --[{conn_type}]--> {t[\"node\"]}') " ``` -------------------------------- ### ToolJet Data Source Configuration Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-tooljet-metabase-impl.md Configuration details for setting up a PostgreSQL data source in ToolJet. Ensure the hostname is correctly set to the Docker container name (`kreativ_postgres`) and not `localhost` or `postgres` to avoid IPv6 connection issues. ```text Name: Kreativ PostgreSQL Host: kreativ_postgres Port: 5432 Database: kreativ_edu Username: kreativ_user Password: value from .env ``` -------------------------------- ### Backup do workflow n8n Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-n8n-async-impl.md Exporta o workflow atual via API e conta o número de nós existentes para verificação de integridade. ```bash export N8N_API_KEY=$(grep '^N8N_API_KEY=' /root/ideias_app/.env | cut -d'=' -f2 | tr -d '"') curl -s -H "X-N8N-API-KEY: $N8N_API_KEY" \ "https://n8n.extensionista.site/api/v1/workflows/SoB5evP9aOmj6hLA" > /tmp/ultimate_before_async.json echo "Backup salvo. Nodes: $(python3 -c "import json; w=json.load(open('/tmp/ultimate_before_async.json')); print(len(w['nodes']))")" ``` -------------------------------- ### POST /webhook/kreativ-unified-api (emit_certificate) Source: https://context7.com/rafaeluft22/kreativ_bot_wpp/llms.txt Generates a digital certificate for completed modules and saves it to the database. ```APIDOC ## POST /webhook/kreativ-unified-api ### Description Generates a digital certificate for completed modules. The certificate is saved in PostgreSQL with a unique verification code and made available on the student portal. ### Method POST ### Endpoint https://n8n.extensionista.site/webhook/kreativ-unified-api ### Request Body - **action** (string) - Required - Must be "emit_certificate" - **phone** (string) - Required - Student phone number - **module_number** (integer) - Required - Module number to certify ### Request Example { "action": "emit_certificate", "phone": "556399374165", "module_number": 1 } ### Response #### Success Response (200) - **success** (boolean) - Status of the operation - **cert_id** (string) - Unique certificate ID - **cert_url** (string) - URL to access the certificate - **verification_code** (string) - Code for verification - **module_name** (string) - Name of the certified module #### Response Example { "success": true, "cert_id": "uuid-certificado", "cert_url": "https://portal.extensionista.site/certificado/a1b2c3d4e5f6", "verification_code": "a1b2c3d4e5f6", "module_name": "Introdução à Inteligência Artificial" } ``` -------------------------------- ### Load Module for Editing Source: https://github.com/rafaeluft22/kreativ_bot_wpp/blob/main/docs/plans/2026-02-22-tooljet-metabase-design.md Retrieves specific module details based on the selected row in the modules table. ```sql SELECT id, module_number, title, content_text, evaluation_rubric, is_published, course_int_id FROM modules WHERE id = {{modulesTable.selectedRow.id}} LIMIT 1 ```