Estrutura do Projeto
Um projeto inicial do Rebase possui três pacotes interconectados:
my-app/├── .env # Generated for you: JWT_SECRET, a database password, a free port├── rebase.json # Which apps this repository contains, and how each is built├── package.json # Root workspace config├── tsconfig.json # Typechecks scripts/; each workspace typechecks on its own├── docker-compose.yml # Self-hosting: Postgres + the published runtime image├── scripts/│ └── example.ts # The SDK end to end against the running backend: `pnpm example`│├── config/ # Shared by the backend and the admin panel│ ├── index.ts # Re-exports `collections`; the runtime reads `storageAuthorize` from here│ ├── collections/ # Your data model│ │ ├── index.ts # Sort order (`collections`) and `defaultSecurityRules` — not a registry│ │ ├── posts.ts # Example collections│ │ └── users.ts # The auth collection│ ├── resources.ts # What this project needs from wherever it runs│ ├── storage.ts # Who may read, write and list files│ └── cms.d.ts # One line that makes the `admin` block legal here│├── backend/│ ├── functions/ # Custom API routes, auto-mounted at /api/functions/<name>│ │ └── hello.ts│ └── src/│ └── schema.generated.ts # Drizzle schema, regenerated from your collections│└── frontend/ # The admin panel (React + Vite) ├── src/App.tsx ├── src/main.tsx └── vite.config.tsO tsc --noEmit na raiz verifica scripts/; em config/, backend/ ou
frontend/ ele verifica aquele workspace. Desde 0.25
Na 0.24 a raiz não tem tsconfig.json, e o tsc ali imprime a sua ajuda e não
verifica nada.
Frontend (frontend/)
Seção intitulada “Frontend (frontend/)”O frontend é uma aplicação padrão Vite + React + TypeScript. O arquivo principal é o App.tsx, que conecta todos os controladores do Rebase:
import React from "react";
import "@fontsource/jetbrains-mono";import "@fontsource-variable/inter";import "@fontsource-variable/instrument-sans";
import { Rebase, RebaseAuth, useRebaseAuthController } from "@rebasepro/app";import { RebaseCMS, RebaseShell } from "@rebasepro/cms";import { ErrorBoundary } from "@rebasepro/ui";import { RebaseStudio } from "@rebasepro/studio";import { createRebaseClient } from "@rebasepro/client";import { collections } from "virtual:rebase-collections";
// `rebase dev` injects VITE_API_URL with the port it actually bound, and that// port is derived from this project's path rather than fixed — so a// `http://localhost:3001` fallback here names a port nothing is listening on.// A deployed build serves the admin from the same origin as the API, where an// empty value is exactly what you want.const API_URL = import.meta.env.VITE_API_URL;const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID;
export function App() { const rebaseClient = React.useMemo(() => createRebaseClient({ baseUrl: API_URL, // Store the refresh token in an httpOnly cookie (XSS-safe) rather than // localStorage. The backend issues it via `auth.cookieAuth`. auth: { authFlowMode: "cookie" } }), []);
const authController = useRebaseAuthController({ client: rebaseClient, googleClientId: GOOGLE_CLIENT_ID });
return ( <ErrorBoundary fullPage> <Rebase client={rebaseClient} authController={authController} > {/* The sign-in screen. On its own this changes nothing — it is where you pass `loginView` to replace it. */} <RebaseAuth /> <RebaseCMS collections={collections} /> <RebaseStudio/> <RebaseShell title="Rebase"/> </Rebase> </ErrorBoundary> );}O main.tsx o monta sob um basename do react-router obtido a partir de import.meta.env.BASE_URL, que o rebase build define a partir do path declarado por este aplicativo no rebase.json — para que os assets, o roteador e o servidor concordem em um único valor sem que ele precise ser escrito três vezes.
Conceitos Principais
Seção intitulada “Conceitos Principais”createRebaseClient— Cria o cliente SDK que lida com requisições HTTP, conexões WebSocket e gerenciamento de tokens de autenticaçãovirtual:rebase-collections— Um plugin do Vite que importa automaticamente suas coleções compartilhadas em tempo de builduseRebaseAuthController— Mantém o usuário autenticado e o ciclo de vida do token, sendo o que o<Rebase>distribui para tudo abaixo dele
Backend (backend/)
Seção intitulada “Backend (backend/)”Não há nenhum arquivo de servidor para ler, e esse é o design pretendido: um projeto gerado declara runtime: "managed", portanto a imagem publicada de rebasepro/server inicializa seu projeto. O que a pasta backend/ contém é o código que o runtime utiliza:
| Caminho | O que é |
|---|---|
backend/functions/ |
Rotas personalizadas, montadas automaticamente em /api/functions/<filename> |
backend/crons/ |
Tarefas agendadas, descobertas da mesma forma (crie quando precisar de uma) |
backend/src/schema.generated.ts |
O schema do Drizzle das suas coleções: escrito pelo rebase init e regenerado a cada rebase dev e rebase build |
O runtime configura:
- API REST em
/api/data/*— CRUD gerado para cada coleção - Autenticação em
/api/auth/*— cadastro, login, atualização de token (refresh), OAuth - Armazenamento (Storage) em
/api/storage/*— upload e download - WebSocket — sincronização em tempo real via Postgres LISTEN/NOTIFY
- Suas funções e crons, a partir dos diretórios acima
A configuração vem de rebase.json, do diretório config/ e de variáveis de ambiente. Consulte Ambiente e Configuração.
O rebase build transforma tudo isso em um bundle — as coleções, funções e crons compilados, além de um manifesto — que o runtime gerenciado inicializa. Nada no bundle é escrito manualmente; se você quiser ver um, Runtime e Bundles mostra o que há nele.
O painel fornecido pelo frontend tem duas metades. O Studio é a parte voltada ao desenvolvedor — o editor de schema, o console SQL, o navegador de políticas de RLS — e está localizado atrás do toggle na gaveta lateral (drawer), não sendo uma implantação separada. Consulte Studio.
Para assumir o controle do processo — seus próprios middlewares, rotas e estrutura de autenticação —, execute rebase eject. Tudo abaixo deste parágrafo aplica-se apenas a projetos ejetados (ejected-only): um projeto recém-gerado não possui nenhum desses arquivos, e nada nele chama initializeRebaseBackend. O comando cria um ponto de entrada que chama initializeRebaseBackend diretamente, além de um Dockerfile e um arquivo compose que o compila; a partir de então, você mantém o servidor e as atualizações do runtime da plataforma não afetam mais o projeto. Essa interface está documentada em Integração de Servidor Personalizado.
Coleções (config/collections/)
Seção intitulada “Coleções (config/collections/)”As coleções são a única fonte da verdade para o seu modelo de dados. Elas são definidas em TypeScript e consumidas tanto pelo frontend (para geração da UI) quanto pelo backend (para geração do schema e roteamento da API).
import { defineCollection } from "@rebasepro/cms-types";
const productsCollection = defineCollection({ slug: "products", name: "Products", properties: { name: { type: "string", name: "Name" }, price: { type: "number", name: "Price" } }});
// The default export is what the loader picks up — every file in this directory// is loaded, listed in index.ts or not, and every collection in the scaffold is// written this way.export default productsCollection;O slug torna-se o caminho da URL na interface administrativa e o endpoint da API REST (/api/data/products), e o nome da tabela do PostgreSQL é definido com ele por padrão. Adicione table apenas quando forem diferentes.
Como Eles se Conectam
Seção intitulada “Como Eles se Conectam”- Você define as coleções em
config/collections/ - O backend as lê para gerar schemas do Drizzle e montar rotas REST
- O frontend as lê (via plugin do Vite) para renderizar tabelas, formulários e navegação
- A CLI as lê para gerar o schema do Drizzle (
rebase schema generate), os tipos do SDK (rebase generate-sdk) e, a partir desse schema, arquivos de migração (rebase db generate)
Enquanto o rebase dev estiver em execução, salvar um arquivo em config/collections/ regenera backend/src/schema.generated.ts e os tipos do SDK em generated/sdk/, reinicia o backend, e a inicialização cria as tabelas e colunas que estiverem faltando. Fora do rebase dev, essas mesmas etapas são realizadas com rebase schema generate e rebase generate-sdk.
Na versão 0.23, o rebase dev regenera apenas o schema, e o rebase generate-sdk
é uma etapa própria.
Próximos Passos
Seção intitulada “Próximos Passos”- Início Rápido — Comece a usar um novo projeto Rebase
- Configuração — Todas as variáveis de ambiente e opções