From f7d36d03f89d1eaf95f49e16d5beda5625d56c3d Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sat, 18 Apr 2026 12:08:37 +0000 Subject: [PATCH] Changes Co-authored-by: domfelipe <53182096+domfelipe@users.noreply.github.com> --- README.md | 76 ++++++++++++++ .../mika/cronjobs/AutoPausedBanner.tsx | 45 +++++++++ .../mika/cronjobs/CronjobsDashboardWidget.tsx | 99 +++++++++++++++++++ .../IntegrationsDashboardWidget.tsx | 96 ++++++++++++++++++ src/routes/painel.index.tsx | 14 ++- 5 files changed, 329 insertions(+), 1 deletion(-) create mode 100644 src/components/mika/cronjobs/AutoPausedBanner.tsx create mode 100644 src/components/mika/cronjobs/CronjobsDashboardWidget.tsx create mode 100644 src/components/mika/integrations/IntegrationsDashboardWidget.tsx diff --git a/README.md b/README.md index 2875dcb..b1df2ad 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,82 @@ A Edge Function `telegram-webhook` hoje responde com um placeholder. O `TODO Fas --- +## Fase 4 — Integrações OAuth + Automações (✅ entregue) + +### O que foi entregue + +- **5 providers OAuth** cadastrados em `available_mcps`: Google Workspace, Notion, Todoist, Cal.com, Microsoft 365 +- **Edge Functions**: + - `oauth-start` — gera state token + URL de autorização (PKCE quando aplicável) + - `oauth-callback` (público, `verify_jwt = false`) — troca code por tokens, persiste no Vault + - `refresh-integration-token` — renova access_token via refresh_token + - `disconnect-integration` — revoga no provider + apaga do Vault + auto-pausa cronjobs dependentes + - `test-integration` — verifica conectividade sem consumir refresh + - `parse-cronjob-natural-language` — Lovable AI Gateway (gemini-2.5-flash) → cron + prompt +- **Frontend `/painel/integracoes`** — grid com 4 estados (available, locked, connected, error), página de detalhe com `DisconnectMCPDialog` que lista cronjobs dependentes +- **Frontend `/painel/cronjobs`** — wizard 3 passos (NL → revisão obrigatória → checagem de dependências MCP), gestão de status (active/paused/auto_paused) +- **Dashboard** — widgets de Skills, Automações e Integrações + banner de auto-pausa +- **Enforcement via banco** — views `user_jobs_limits` e `user_integration_limits` aplicam limites por plano +- **Cleanup oauth_states** — trigger `FOR EACH STATEMENT` (não FOR EACH ROW) limpa tokens expirados + +### Etapas pós-deploy (uma única vez) + +#### 1. Configurar OAuth apps em cada provider + +Para cada provider abaixo, crie um OAuth app e configure a **Redirect URI**: + +``` +https://smsarmgoirlcedmqvdgc.supabase.co/functions/v1/oauth-callback +``` + +| Provider | Console | Scopes mínimos | +|----------|---------|----------------| +| **Google Workspace** | [console.cloud.google.com](https://console.cloud.google.com) → APIs & Services → Credentials → OAuth 2.0 Client ID (Web app) | `openid email profile https://www.googleapis.com/auth/gmail.readonly https://www.googleapis.com/auth/calendar` | +| **Microsoft 365** | [Azure Portal](https://portal.azure.com) → App registrations → New registration → Web | `openid email profile offline_access Mail.Read Calendars.ReadWrite` | +| **Notion** | [notion.so/my-integrations](https://www.notion.so/my-integrations) → New integration (Public) | (definidos na integração) | +| **Todoist** | [developer.todoist.com](https://developer.todoist.com/appconsole.html) → App management → Create app | `data:read_write` | +| **Cal.com** | [app.cal.com/settings/developer](https://app.cal.com/settings/developer/oauth-clients) → New OAuth Client | `READ_BOOKING WRITE_BOOKING READ_PROFILE` | + +#### 2. Adicionar os 10 secrets no Lovable Cloud + +Pelo menu **Connectors → Lovable Cloud → Secrets**, adicione: + +``` +GOOGLE_OAUTH_CLIENT_ID +GOOGLE_OAUTH_CLIENT_SECRET +MICROSOFT_OAUTH_CLIENT_ID +MICROSOFT_OAUTH_CLIENT_SECRET +NOTION_OAUTH_CLIENT_ID +NOTION_OAUTH_CLIENT_SECRET +TODOIST_OAUTH_CLIENT_ID +TODOIST_OAUTH_CLIENT_SECRET +CALCOM_OAUTH_CLIENT_ID +CALCOM_OAUTH_CLIENT_SECRET +``` + +#### 3. Verificar publicação Realtime + +A view `user_integration_limits` e `user_jobs_limits` usam dados de `user_integrations` e `scheduled_jobs`. Não precisam estar em realtime, mas confirme que os RPCs Vault permanecem restritos ao `service_role`. + +#### 4. Teste end-to-end + +1. Acesse `/painel/integracoes` → conecte uma integração (ex: Notion) +2. Acesse `/painel/cronjobs/nova` → descreva "todo dia útil às 9h, criar uma página no Notion com resumo do dia" +3. Confirme a revisão (cron + prompt) +4. A automação deve aparecer ativa em `/painel/cronjobs` +5. Desconecte a integração Notion → a automação deve aparecer **auto-pausada** com banner no dashboard + +### O que **não** está nesta fase + +- ❌ Execução real de cronjobs (Fase 5 — scheduler + Hermes) +- ❌ Sync Mika ↔ Container (Fase 5) +- ❌ MCPs corporativos privados / BYOA +- ❌ Histórico de execuções de cronjobs +- ❌ Dashboard de uso de API calls +- ❌ Providers além dos 5 listados + +--- + ## Comandos úteis ```bash diff --git a/src/components/mika/cronjobs/AutoPausedBanner.tsx b/src/components/mika/cronjobs/AutoPausedBanner.tsx new file mode 100644 index 0000000..1019836 --- /dev/null +++ b/src/components/mika/cronjobs/AutoPausedBanner.tsx @@ -0,0 +1,45 @@ +"use client"; + +import { Link } from "@tanstack/react-router"; +import { AlertTriangle } from "lucide-react"; +import { useCronjobs } from "@/hooks/use-cronjobs"; +import { Button } from "@/components/ui/button"; + +export function AutoPausedBanner() { + const { data: jobs } = useCronjobs(); + const autoPaused = (jobs ?? []).filter((j) => j.status === "auto_paused"); + + if (autoPaused.length === 0) return null; + + return ( +
+ {autoPaused.length === 1 + ? "1 automação foi pausada automaticamente" + : `${autoPaused.length} automações foram pausadas automaticamente`} +
++ Geralmente isso acontece quando uma integração necessária foi desconectada ou expirou. + Reconecte a integração ou revise a automação para reativá-la. +
++ {activeCount} ativa{activeCount === 1 ? "" : "s"} + {limits?.max_jobs ? ` de ${limits.max_jobs} disponíveis` : ""} + {autoPausedCount > 0 && ( + <> + {" · "} + + {autoPausedCount} auto-pausada{autoPausedCount === 1 ? "" : "s"} + + > + )} +
++ Seu plano atual não inclui automações.{" "} + + Fazer upgrade + +
++ Crie sua primeira automação descrevendo em português. +
+ +{job.name}
+{job.human_readable}
++ {connected.length} conectada{connected.length === 1 ? "" : "s"} + {limit?.max_integrations ? ` de ${limit.max_integrations} disponíveis` : ""} + {errored.length > 0 && ( + <> + {" · "} + + {errored.length} com erro + + > + )} +
++ Conecte serviços como Gmail, Notion e Cal.com para ampliar seu Mika. +
+ +{mcp.name}
+ {card.kind === "connected" && card.integration.connected_account_email && ( ++ {card.integration.connected_account_email} +
+ )} +