Structure du projet
Un projet de démarrage Rebase comporte trois packages interconnectés :
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.tstsc --noEmit à la racine vérifie scripts/ ; dans config/, backend/ ou
frontend/, il vérifie ce workspace. Depuis 0.25
En 0.24, la racine n’a pas de tsconfig.json, et tsc y affiche son aide et
ne vérifie rien.
Frontend (frontend/)
Section intitulée « Frontend (frontend/) »Le frontend est une application standard Vite + React + TypeScript. Le fichier clé est App.tsx, qui relie tous les contrôleurs Rebase ensemble :
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> );}main.tsx le monte sous un basename de react-router récupéré depuis
import.meta.env.BASE_URL, que rebase build définit à partir du path déclaré
par cette application dans rebase.json — ainsi, les assets, le routeur et le serveur s’accordent sur
une seule et même valeur sans avoir à l’écrire trois fois.
Concepts clés
Section intitulée « Concepts clés »createRebaseClient— Crée le client SDK qui gère les requêtes HTTP, les connexions WebSocket et la gestion des jetons d’authentificationvirtual:rebase-collections— Un plugin Vite qui importe automatiquement vos collections partagées au moment du builduseRebaseAuthController— Conserve l’utilisateur connecté et le cycle de vie des jetons, et constitue ce que<Rebase>distribue à tous les éléments en dessous de lui
Backend (backend/)
Section intitulée « Backend (backend/) »Il n’y a aucun fichier serveur à consulter, et c’est voulu : un projet échafaudé
déclare runtime: "managed", de sorte que l’image publiée rebasepro/server démarre
votre projet. Ce que contient backend/, c’est le code pris en compte par le runtime :
| Chemin | Description |
|---|---|
backend/functions/ |
Routes personnalisées, montées automatiquement sur /api/functions/<filename> |
backend/crons/ |
Tâches planifiées, découvertes de la même manière (à créer selon vos besoins) |
backend/src/schema.generated.ts |
Le schéma Drizzle de vos collections : écrit par rebase init, et régénéré à chaque rebase dev et rebase build |
Le runtime met en place :
- API REST à
/api/data/*— CRUD généré pour chaque collection - Authentification à
/api/auth/*— inscription, connexion, rafraîchissement, OAuth - Stockage à
/api/storage/*— téléversement et téléchargement - WebSocket — synchronisation en temps réel via LISTEN/NOTIFY de Postgres
- Vos fonctions et crons, issus des répertoires ci-dessus
La configuration provient de rebase.json, du répertoire config/ et des variables
d’environnement. Voir Environnement et configuration.
rebase build transforme l’ensemble en un bundle — les collections,
fonctions et crons compilés, accompagnés d’un manifeste — que le runtime managé démarre. Rien
dans le bundle n’est écrit à la main ; si vous souhaitez voir à quoi il ressemble,
consultez Runtime et bundles.
Le panneau servi par le frontend comporte deux volets. Le Studio est celui destiné aux développeurs — l’éditeur de schéma, la console SQL, l’explorateur de politiques RLS — et il est accessible via le bouton de bascule dans le menu latéral, sans nécessiter de déploiement séparé. Voir Studio.
Pour reprendre plutôt le contrôle du processus — vos propres middlewares, routes et
configuration d’authentification —, exécutez rebase eject. Tout ce qui suit ce paragraphe s’applique uniquement après un eject :
un projet échafaudé ne contient aucun de ces fichiers, et rien n’y appelle
initializeRebaseBackend. Cette commande génère un point d’entrée qui appelle
directement initializeRebaseBackend, ainsi qu’un Dockerfile et un fichier compose pour le
compiler ; à partir de ce moment, vous maintenez le serveur et les mises à niveau du runtime de la plateforme
ne s’appliquent plus au projet. Cet aspect est documenté dans
Intégration d’un serveur personnalisé.
Collections (config/collections/)
Section intitulée « Collections (config/collections/) »Les collections constituent la source unique de vérité de votre modèle de données. Elles sont définies en TypeScript et consommées à la fois par le frontend (pour la génération de l’interface utilisateur) et par le backend (pour la génération du schéma et le routage de l’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;Le slug devient le chemin d’URL dans l’interface d’administration ainsi que le point de terminaison de l’API REST (/api/data/products), et le nom de table PostgreSQL correspond par défaut à ce slug. N’ajoutez table que s’ils diffèrent.
Comment ils sont reliés
Section intitulée « Comment ils sont reliés »- Vous définissez les collections dans
config/collections/ - Le backend les lit pour générer les schémas Drizzle et monter les routes REST
- Le frontend les lit (via le plugin Vite) pour afficher les tables, les formulaires et la navigation
- La CLI les lit pour générer le schéma Drizzle (
rebase schema generate), les types du SDK (rebase generate-sdk) et, à partir de ce schéma, les fichiers de migration (rebase db generate)
Pendant l’exécution de rebase dev, enregistrer un fichier dans config/collections/
régénère backend/src/schema.generated.ts et les types du SDK dans
generated/sdk/, redémarre le backend, et le démarrage crée les tables et les
colonnes manquantes. En dehors de rebase dev, les mêmes étapes s’effectuent via
rebase schema generate et rebase generate-sdk.
Sur la 0.23, rebase dev ne régénère que le schéma, et rebase generate-sdk
est une étape à part.
Étapes suivantes
Section intitulée « Étapes suivantes »- Démarrage rapide — Lancez-vous avec un nouveau projet Rebase
- Configuration — Toutes les variables d’environnement et options