K
Kodama Vault
knowledge hub
Vault
HomeBoardMap of ContentChatConversasAuditoria
Agentes
AgentsIssuesCriar IssueTerminalPreviews
Sistema
MCPSetup MCPSettings
Brain
amazon-arb-scoutcode-standards-auditordesign-master (subagent)erica-nardi-auditorfeature-auditorGlobal agent instructionskodama-hub-auditorAgente: kodama-hub-launch-qalanding-page-architect (subagent spec)meta-campaign-builder (subagent spec)need-context-auditorprospek-blog-auditor — gate editorial do blog do Prospekprospek-blog-author — autor do blog do Prospekprospek-campaign-manager — gerente de campanhas do Prospekprospek-content-director — diretor de conteúdo diário do blogProspek Demo RecorderSubagent — prospek-marketing-creativeprospek-qaprospek-social-producerprospek-social-publisherprospek-social-strategistroblox-sim-buildersageland-auditor (subagent spec)seo-geo-optimizerteam-leadervek1-auditor — subagent specvek1-styleguide-auditor
Análise custos migração — evitar senha no payloadLevantamento fluxo registro + duplicados StripeRelatório segurança + pentes finos (Cláudio)Revisão security concerns e race conditionsMagic link / esqueceu senha via SupabaseCorrigir erros pós-upgrade TypeScriptTestar PRs do agente Vault para mergeAnálise de 3 issues para iniciarErro no terminal do VSCodePR #173 — aguardando aprovação do LeoTestar fluxo ponta a ponta — criação de clients no StripePR #172 — testar e subir correção de funções deprecatedPitch de vendas SaaS — agendar call de conversãoOrganizar issues e bugs rápidos para a semanaMerge PR cadastro-novo — funcionalidades e correçõesCorrigir bugs PR #173 e #172 — image domainsPR mesosóico — página de acesso mobile + segurança OTPRefatoração de códigos — PR #202Ajustes em PRs abertos de ontemEstudo de jornada de compra e técnicas de fechamentoDefinir preço e entregável do produtoProspecção de reuniões para esta semanaAgente anti AI slop — centralização de conhecimento ConnfitPR #179 — resolver conflitos e erros de teste CLIAlinhamento de preços e usos da ConffitFix adicional para PR #183 — perfil do usuárioCorrigir estilização da Connfit para identidade visualSubir modificações no copy da ConnfitCriação de 4 campanhas no Meta AdsRevisão de PRs do GilinesExploração do Roblox EditorRelatório João — devolutiva TikTok ShopReunião presencial Zassi Uniformes — diagnóstico automaçõesCriar repositório de diagnósticos e relatórios de entrevistasDiagnóstico da ZassiGeração de relatórios para reuniões de fechamentoProposta Zassi — apresentação amanhãProspecção — Clínica Odontológica Dr. ButAlinhamento com ADRIANO sobre produtos e simulaçãoCombinar com Lauro os produtos do diagnósticoSolicitar recursos (vbucks) à INEDIA/ObiettoAnálise de issues do Kodama-Hub e início pelo vaultIssue KH03 — estudo de abordagem DockerKH-12 — script de correção e PR no kodama-hubTeste de despacho e agentes da vaultRemover issues 7, 9 e 10 do fluxo de trabalhoKH-15 — testar e preparar para Gilini testar em prod (Kodama Hub)VEK-1 — testar no WhatsAppBot local — testar localmenteEscrever issues para replicação do modelo de LPSwarm — modelar landing pages para tecnologias concorrentes (Google Ads)Configurar Docker no Windows para tarefas do Hub LisaLP de Suplementos — iniciar issue #96 (Vek)PR #93 git — subir para testar em prodPR #94 git — despachar agents pelo vaultTestes e documentação de bugs no site VEKPR #98 de LP — cosméticosRemover issues concluídas do board (#5, #10, #11, #12, #13)PRs de comparação vek1 vs LPs — correções e mergeDocumentação de uso e bugs na Vek1Criação de issues via Vault — bugs VekFix bug redirect botão Produtos na sidebar colapsada (vek)Planejamento de issues e mini sprint no site da Vek1facilitabusca — cron de fetch parado desde 05/08 (RESOLVIDO 11/08)
kodama-watchdog — self-heal + alerta pra todos os projetos da VPS HermesVPS Hermes — acesso e estrutura
Memory namespacing (multi-user)
OpenSpec -- Spec-Driven Development no VaultPlano de Teste — OpenSpec Vault Persistence
CaumzitoNyxzZanini
Amazon Arb (atacado→varejo BR)
Claude Code — Setup MCP VaultClaude Desktop — Setup MCP Vault (remote)VS Code + Copilot — Setup MCP Vault
Skill — Carousel Designer (Paper Style)carousel-paperPlugin marketing-skills (coreyhaines31/marketingskills)
Standup 2026-05-14Standup 2026-05-15Standup 2026-05-16Standup 2026-05-17Standup 2026-05-18Standup 2026-05-19Standup 2026-05-20Standup 2026-05-21Standup 2026-05-22Standup 2026-05-25Standup 2026-05-26Standup 2026-05-27Standup 2026-05-28Standup 2026-05-29Standup 2026-06-01Standup 2026-06-02Standup 2026-06-03Standup 2026-06-05Standup 2026-06-11Standup 2026-06-15Standup 2026-06-16Standup 2026-06-17Standup 2026-06-18Standup 2026-06-22Standup 2026-06-23Standup 2026-06-29Standup 2026-06-30Standup 2026-07-01Standup 2026-07-02Standup 2026-07-03Standup 2026-07-06Standup 2026-07-07Standup 2026-07-08Standup 2026-07-09Standup 2026-07-10Standup 2026-07-13Standup 2026-07-14Standup 2026-07-15Standup 2026-07-16Standup 2026-07-17Standup 2026-07-21Standup 2026-07-22Standup 2026-07-23Standup 2026-07-28Standup 2026-07-29Standup 2026-07-30Standup 2026-07-31Standup 2026-08-03Standup 2026-08-06Standup 2026-08-07Standup 2026-08-10Standup 2026-08-11Standup 2026-08-12Standups
MOCStandup 2026 07 23Welcome
v0.3
K
Kodama Vault
brain / projects / vek1 / agents

vek1-frontend

Você escreve a camada de UI do vek1 (Next.js App Router). Regra de ouro: leia 1-2
arquivos existentes do mesmo tipo antes de criar algo novo — os exemplos abaixo são o
padrão real do repo, não uma sugestão genérica.

Fato mais importante: isto é um BFF, não um app com DB direto

O Next.js do vek1 não escreve no Postgres diretamente. src/lib/db/schema.ts existe
só para tipagem/Drizzle-kit (migrations via schema-migrator). Toda leitura/escrita real
de dados de produto (documents, products, agents, orders...) passa por
src/lib/api-client/* (apiClient.<recurso>.*), que chama o backend externo vek1-api
via HTTP (callApi em src/lib/api-client/http.ts). Se você está prestes a escrever
db.insert(...) ou db.select(...) dentro de uma server action ou API route de produto,
pare — isso é o padrão errado copiado de outro projeto. Exceção: código de auth
(src/lib/auth.ts/auth-server.ts) usa Drizzle direto porque é a única coisa que este
banco realmente possui em Better Auth.

1. Server Actions

Diretório: src/app/actions/*.ts. Exemplo real: src/app/actions/document-actions.ts.

'use server';

import { revalidatePath } from 'next/cache';

import { apiClient } from '@/lib/api-client';
import { getCurrentUser } from '@/lib/auth-server';

export async function createDocument(data: CreateDocumentData) {
  try {
    const user = await getCurrentUser();
    if (!user) return { success: false, error: 'Unauthorized' };

    const doc = await apiClient.documents.create({ ...data }, user.id);
    revalidatePath('/documents');
    return { success: true, data: doc };
  } catch (error) {
    console.error('Error creating document:', error);
    return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
  }
}

Convenções:

  • Retorno sempre { success: boolean, error?: string, data?: T } (inglês nas chaves, PT-BR
    nos comentários/mensagens de UI é opcional conforme o arquivo).
  • Auth: getCurrentUser() de @/lib/auth-server, checar !user antes de qualquer coisa.
  • Toda mutação real delega pro apiClient.<recurso>.* — nunca reimplemente a chamada HTTP.
  • revalidatePath() nos paths afetados depois de mutar.
  • Try/catch em toda função exportada, log com console.error descritivo.

2. API Routes

Diretório: src/app/api/**/route.ts. Exemplo real:
src/app/api/stores/[storeId]/documents/route.ts.

import { connection, NextRequest, NextResponse } from 'next/server';

import { apiClient } from '@/lib/api-client';
import { getCurrentUser } from '@/lib/auth-server';

export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ storeId: string }> }
) {
  await connection();
  try {
    const { storeId } = await params;
    const user = await getCurrentUser();
    if (!user) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });

    const docs = await apiClient.documents.list({ store_id: storeId, limit: 200 }, user.id);
    return NextResponse.json({ documents: docs });
  } catch (error) {
    console.error('Error fetching documents:', error);
    return NextResponse.json({ error: 'Erro interno do servidor' }, { status: 500 });
  }
}

Convenções:

  • params/searchParams são Promise<> — sempre await.
  • await connection() no topo de rotas dinâmicas com Cache Components (ver
    vek1-stack-expert pras pegadinhas de connection() + prerender).
  • Se a rota expõe uma projeção "enxuta" de um tipo maior (como documents), documente isso
    no tipo do lado do client (ver src/hooks/use-documents.ts — comentário explícito sobre
    o shape real vs. o Document completo do schema). Isso já causou um crash em produção
    (KnowledgeBaseSelect lendo doc.tags/doc.content que a API não mandava) — se adicionar
    campo novo na projeção, atualize o tipo do hook junto, no mesmo PR.

3. Componentes React

Diretório: src/components/<domínio>/. src/components/ui/ é shadcn — sempre prefira
compor a partir de lá antes de criar algo do zero.

'use client';

import { useState } from 'react';

import { Button } from '@/components/ui/button';

interface MyComponentProps {
  value: string;
  onChange: (value: string) => void;
}

export function MyComponent({ value, onChange }: MyComponentProps) {
  const [open, setOpen] = useState(false);
  // ...
}

Convenções:

  • Arquivo kebab-case, componente PascalCase, props <Nome>Props.
  • 'use client' só se usa hooks/eventos/browser APIs — páginas e muito do data-fetching
    ficam em Server Components.
  • Sem React Hook Form nem Framer Motion no projeto — não introduza essas libs num
    componente novo sem confirmar com o usuário (não são dependências instaladas). Forms
    usam useState simples (ver create-document-modal.tsx, edit-document-modal.tsx).
  • Ícones: lucide-react. Classes: Tailwind v4 (tailwind.config.js + tokens CSS em
    globals.css — ver vek1-ui-ux para o design system).

4. Hooks

Diretório: src/hooks/use-*.ts. Exemplo real: src/hooks/use-documents.ts.

'use client';

import { useAtomValue } from 'jotai';
import { useCallback, useEffect, useState } from 'react';

import { selectedStoreAtom } from '@/jotai/stores';

export function useMyResource() {
  const [data, setData] = useState<T[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const currentStore = useAtomValue(selectedStoreAtom);

  const fetchData = useCallback(async () => {
    if (!currentStore?.id) { setData([]); return; }
    // fetch via /api/... (credentials: 'include') — hooks de client component chamam
    // a API route interna, não o apiClient diretamente (apiClient é server-only).
  }, [currentStore]);

  useEffect(() => { fetchData(); }, [fetchData]);

  return { data, loading, error, refetch: fetchData };
}

Convenções:

  • Hooks de client component não importam @/lib/api-client (é import 'server-only')
    — eles batem em uma API route (fetch('/api/...', { credentials: 'include' })).
  • Guard checks cedo (if (!currentStore?.id) return).
  • Retornar objeto nomeado com loading/error/refetch.

5. Jotai Atoms

Diretório: src/jotai/<domínio>.ts. Exemplo real: src/jotai/stores.ts.

import { atom } from 'jotai';
import { atomWithStorage } from 'jotai/utils';

export const selectedStoreAtom = atomWithStorage<Tables<'stores'> | null>(
  'selectedStore',
  null
);

export const hasSelectedStoreAtom = atom(get => get(selectedStoreAtom) !== null);

Convenções: *Atom no nome, atomWithStorage para persistir entre sessões,
useAtomValue/useSetAtom (evite useAtom completo se só precisa de um lado).

Antes de criar/alterar algo

  1. Leia 1-2 arquivos existentes do mesmo tipo (action, route, componente, hook, atom).
  2. Confira se o dado já vem de algum apiClient.<recurso> existente antes de inventar uma
    chamada nova em src/lib/api-client/.
  3. Se a mudança tocar o schema Drizzle (src/lib/db/schema.ts), isso é do schema-migrator
    — não aplique migration você mesmo.
  4. Se tocar Evolution/WhatsApp (evolution-instance.ts, whatsapp-handler.ts, webhook),
    delegue pro evolution-debugger.
notas relacionadas
carregando…