K
Kodama Vault
knowledge hub
Vault
HomeBoardMap of ContentChatConversasAuditoria
Agentes
AgentsIssuesTerminalPreviews
Sistema
MCPSetup MCPSettings
Brain
Global agent instructions
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. But
VPS Hermes — acesso e estrutura
Always Commit Push DeployHermes Voice GeminiHermes VPSKodama Prospects TrackerMEMORYObsidian VaultRoblox Mining Sim
OpenSpec -- Spec-Driven Development no VaultPlano de Teste — OpenSpec Vault Persistence
CaumzitoNyxzZanini
vek1 — arquiteturavek1 — autenticaçãovek1 — contextovek1 — regras de copy e marketingvek1 — modelo de dadosvek1 — decisões técnicasvek1 — domínio e modelo de negóciovek1 — featuresvek1 — gaps e riscosvek1 — gotchasvek1 — integrações externasvek1 — pricing design (Stripe sub + topup)vek1 — atividade recentevek1 — roteiro de vendas (SDR → fechamento)vek1 — estado e maturidadevek1 — Migração Evolution API → WhatsApp Cloud API (Meta oficial)
Claude Code — Setup MCP VaultClaude Desktop — Setup MCP Vault (remote)VS Code + Copilot — Setup MCP Vault
Skill — Carousel Designer (Paper Style)
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-17Standups
MOCWelcome
v0.3
K
Kodama Vault
brain / projects / vek1

vek1 — decisões técnicas

Decisões técnicas notáveis

Arquitetura: api-first (PR #65–#70)

Decisão central: vek1 (Next 16) virou camada thin de UI + auth orchestration. Toda escrita em DB passa pelo vek1-api via HTTP interno. Drizzle schema permanece source-of-truth, mas mutations e maioria dos reads vão por apiClient.

Razões:

  • Single point pra auditoria (audit_log no vek1-api), rate limiting, retry, idempotência
  • Ownership check centralizado (assert_owns_store/order/lead/product) — bug aí está em 1 lugar
  • vek1-api já é dono dos modelos (chat, embeddings, file processing); spread Drizzle direto duplicava lógica
  • Permite eventualmente outras frontends (mobile, ops dashboard) sem reescrever access layer

Tradeoffs:

  • 2 hops (Vercel → VPS → Postgres) em cada mutation vs 1 hop direto
  • Latência adicional ~30-80ms por call (TLS + network)
  • Acoplamento: vek1-api down = vek1 read-only

Mitigação: Cache Components mantém UI rápida pra reads; mutations toleram latência extra.

Token scope segregation

3 tokens isolados (INTERNAL_API_TOKEN, INTERNAL_AUTH_TOKEN, INTERNAL_WEBHOOK_TOKEN). Razão: comprometimento de um escopo (ex: token leakado num client log) não dá acesso aos outros (ex: app token não cria sessions). Fallback pro app token cobre transição.

Cache Components (Next 16)

  • cacheComponents: true em next.config.ts
  • API routes com cookies/auth fazem await connection() no topo (force dynamic)
  • Pages auth-gated: refactor pra cookies em Suspense child, não no topo
  • lib/queries/* removeu wrappers React cache() (incompatível com cacheComponents prerender)
  • revalidatePath em vez de revalidateTag (sig mudou)

Drizzle sem migrations versionadas

  • bun run db:push --force direto contra Postgres prod
  • Risco: drops indexes não-Drizzle (hnsw vector, unique custom)
  • Mitigação: scripts/recreate-indexes.ts + init/01-init.sql re-aplicados após push
  • Tem agent dedicado: schema-migrator (cuidados especiais com hnsw)

Não usa drizzle-kit generate/migrate: pareceu overhead pra um schema com 1 owner. Pode mudar se schema crescer e equipe expandir.

Better Auth com HTTP adapter custom

  • createAdapterFactory em src/lib/auth-http-adapter.ts
  • Per-model dispatcher (não CRUD genérico)
  • Razão: keys camelCase vs snake_case + parse timestamps + endpoints purpose-built pro vek1-api
  • consumeOne(verification) resolve race PKCE: DELETE..RETURNING atomic no Postgres (vs find + delete que tem janela de race)

Storage: single bucket + key prefix

  • Antes (Supabase): 1 bucket por company (company-{slug}-files)
  • Agora (MinIO): bucket único vek1, key prefix companies/{user.id}/...
  • Razão: simpler, sem permissões bucket-create, anonymous download policy global, public URL via CDN

TypeScript / Lint / Format

  • TS strict
  • ESLint estrito: no-explicit-any error, import ordering com newlines-between
  • Prettier: singleQuote, trailingComma es5, arrowParens=avoid, printWidth=80
  • Path alias: @/* → src/*

Testes

  • Vitest 4 + Testing Library + jsdom (migração Jest → Vitest concluída em PR #40)
  • vitest.config.ts + setup file
  • Tests reais: orders-*.test.ts (5 arquivos, e2e + state machine + calc + stock), abacate-pay.test.ts, stock-sync-actions.test.ts, agents/documents/products/utils/redirect/badge/store-actions/check-duplicates
  • UI components mostly uncovered (gap conhecido)

CI/CD

3 jobs (Bun frozen-lockfile): lint → test → build. Envs CI = placeholders (PR #44, sem Supabase).

Server Actions

  • Todas thin wrappers sobre apiClient — auth/ownership check + chamada
  • revalidatePath aplicado consistentemente
  • Validação Zod parcial (alguns actions); maioria delega validação pro Pydantic strict no vek1-api

Padrão SSR Cache Components

Pages tipo /leads/page.tsx:

export default async function LeadsPage() {
  const user = await requireUser();
  return (
    <Suspense fallback={<LeadsListSkeleton />}>
      <LeadsList userId={user.id} />
    </Suspense>
  );
}

async function LeadsList({ userId }: { userId: string }) {
  'use cache';
  cacheTag(`leads-${userId}`);
  const data = await apiClient.leads.list({ ... });
  return <LeadsTable data={data} />;
}

Mas auth-gated pages que dependem de cookies dinâmicos usam await connection() em vez de 'use cache'.

Convenções de pastas

  • Server Components default; 'use client' só interativo
  • Mutações só via apiClient
  • Storage centralizado em lib/storage.ts
  • Sem any; interfaces explícitas
  • Estilo só Tailwind + cn()
  • Componentes em components/[feature]/ (alguns arquivos soltos em components/ raiz — gotcha histórico)

Scripts

  • bun run db:push — drizzle-kit push schema
  • bun run db:studio — drizzle studio
  • bun run test — vitest
  • Sem generate:types (não usa mais Supabase CLI)
notas relacionadas
carregando…