VendeeDocs
Contribuicao

Adicionando Features

End-to-end — da migration ate a navegacao

Guia passo a passo para adicionar uma feature completa ao Vendee.

Crie a migration no Supabase

Adicione as tabelas/colunas necessarias no banco:

CREATE TABLE my_entity (
  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  workspace_id uuid NOT NULL REFERENCES workspaces(id),
  name text NOT NULL,
  created_at timestamptz DEFAULT now()
);

ALTER TABLE my_entity ENABLE ROW LEVEL SECURITY;

CREATE POLICY "workspace_isolation" ON my_entity
  FOR ALL USING (workspace_id IN (SELECT get_user_workspace_ids()));

Regenere os tipos

bunx supabase gen types typescript --project-id <id> > packages/supabase/src/types.ts

Crie o hook

Em src/hooks/use-my-entity.ts:

import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { supabase } from "@/lib/supabase";
import { useWorkspaceStore } from "@/stores/workspace-store";

export function useMyEntities() {
  const workspace = useWorkspaceStore((s) => s.workspace);
  return useQuery({
    queryKey: ["my-entities", workspace?.id],
    queryFn: async () => {
      const { data, error } = await supabase
        .from("my_entity")
        .select("*")
        .eq("workspace_id", workspace!.id);
      if (error) throw error;
      return data;
    },
    enabled: !!workspace,
  });
}

Crie a feature

Em src/features/my-entity/:

src/features/my-entity/
├── MyEntityPage.tsx       # Pagina principal
└── components/
    └── MyEntityForm.tsx   # Formulario de criacao/edicao

Adicione a rota

Em src/routes/router.tsx:

const MyEntityPage = lazy(() => import("@/features/my-entity/MyEntityPage"));

// Dentro de AppLayout children:
{
  path: "my-entity",
  element: <SuspenseWrapper><MyEntityPage /></SuspenseWrapper>,
}

Adicione a navegacao

Em src/lib/navigation.ts:

import { MyIcon } from "lucide-react";

export const mainNavItems: NavItem[] = [
  // ... items existentes
  { title: "Minha Entidade", url: "/my-entity", icon: MyIcon },
];

Verifique

bun run check-types
bun run lint
bun run build --filter=app

Sempre siga o padrao existente: hook por tabela, feature-based structure, e lazy loading nas rotas.

On this page