ScaleRocket/Web

Packages

Packages partagés pour les composants UI, la configuration, les types TypeScript et les templates d'e-mails.

Vue d'ensemble

ScaleRocket utilise quatre packages partagés dans packages/ qui sont consommés par les trois applications. Ils sont liés via le pnpm workspace -- aucune publication ou gestion de version nécessaire.

@saas/ui

Emplacement : packages/ui/

La bibliothèque de composants partagés construite avec Tailwind CSS. Basée sur les patterns shadcn/ui.

packages/ui/
├── src/
│   ├── components/
│   │   ├── button.tsx
│   │   ├── card.tsx
│   │   ├── input.tsx
│   │   ├── toast.tsx
│   │   ├── theme-provider.tsx
│   │   └── theme-toggle.tsx
│   ├── hooks/
│   │   ├── use-toast.ts
│   │   └── use-theme.ts
│   ├── lib/
│   │   └── utils.ts          # cn() utility
│   ├── globals.css            # CSS variables, theme
│   └── index.ts               # Public exports
├── package.json
└── tsconfig.json

Utilisation :

import { Button, Card, Input, useToast, ThemeProvider } from "@saas/ui";

Utilitaire cn() :

// packages/ui/src/lib/utils.ts
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

@saas/config

Emplacement : packages/config/

Configuration centralisée partagée entre toutes les applications.

packages/config/
├── src/
│   ├── site.ts        # Site name, URLs, SEO defaults
│   ├── pricing.ts     # Plans, prices, Stripe IDs
│   ├── credits.ts     # Credit costs per feature
│   └── index.ts       # Public exports
├── package.json
└── tsconfig.json

site.ts

export const siteConfig = {
  name: "ScaleRocket",
  description: "Ship your SaaS in days, not months",
  url: "https://scalerocket.dev",
  appUrl: "https://app.scalerocket.dev",
  opsUrl: "https://admin.scalerocket.dev",
  ogImage: "https://scalerocket.dev/og.png",
  links: {
    twitter: "https://twitter.com/scalerocket",
    github: "https://github.com/scalerocket",
  },
  support: {
    email: "support@scalerocket.dev",
  },
};

pricing.ts

export const plans = [
  {
    id: "starter",
    name: "Starter",
    price: { monthly: 9, yearly: 90 },
    stripePriceId: {
      monthly: "price_xxx",
      yearly: "price_xxx",
    },
    credits: 100,
    features: ["100 credits/month", "Email support"],
  },
  // ...more plans
];

Utilisation :

import { siteConfig, plans } from "@saas/config";

@saas/types

Emplacement : packages/types/

Types TypeScript partagés générés à partir du schéma de la base de données et types d'API maintenus manuellement.

packages/types/
├── src/
│   ├── database.ts    # Auto-generated from Supabase
│   ├── api.ts         # API request/response types
│   ├── auth.ts        # User, session types
│   └── index.ts       # Public exports
├── package.json
└── tsconfig.json

database.ts

Généré automatiquement avec :

pnpm supabase gen types typescript --local > packages/types/src/database.ts

Cela vous donne des requêtes typées :

import type { Database } from "@saas/types";

type Profile = Database["public"]["Tables"]["profiles"]["Row"];
type Subscription = Database["public"]["Tables"]["subscriptions"]["Row"];

api.ts

Types maintenus manuellement pour les formes de requête/réponse des Edge Functions :

export interface CheckoutRequest {
  priceId: string;
  mode: "subscription" | "payment";
}

export interface CheckoutResponse {
  url: string;
}

export interface CreditBalance {
  balance: number;
  monthly_allowance: number;
  last_reset_at: string;
}

Utilisation :

import type { Database, Profile, CheckoutRequest } from "@saas/types";

@saas/emails

Emplacement : packages/emails/

Templates React Email et utilitaire d'envoi utilisant Resend.

packages/emails/
├── src/
│   ├── templates/
│   │   ├── welcome.tsx
│   │   ├── password-reset.tsx
│   │   ├── subscription-created.tsx
│   │   └── ...13 templates
│   ├── components/
│   │   └── layout.tsx         # Shared email layout
│   ├── send.ts                # Resend send utility
│   └── index.ts               # Public exports
├── package.json
└── tsconfig.json

Utilisation :

import { sendEmail, WelcomeEmail } from "@saas/emails";

await sendEmail({
  to: "user@example.com",
  subject: "Welcome!",
  react: WelcomeEmail({ name: "John", loginUrl: "https://..." }),
});

Comment modifier un package

  1. Modifiez les fichiers dans packages/<name>/src/.
  2. Exportez les nouveaux éléments depuis packages/<name>/src/index.ts.
  3. Utilisez-les dans n'importe quelle application -- le pnpm workspace résout le lien automatiquement.
  4. Exécutez pnpm type-check pour vérifier que rien n'est cassé.

Aucune étape de build n'est nécessaire pour le développement. Turborepo gère les builds pour la production.

Comment ajouter un nouveau package

# Create the package
mkdir -p packages/analytics/src
cd packages/analytics

# Initialize
pnpm init

Modifiez package.json :

{
  "name": "@saas/analytics",
  "version": "0.0.0",
  "main": "./src/index.ts",
  "types": "./src/index.ts",
  "scripts": {
    "type-check": "tsc --noEmit"
  }
}

Ajoutez-le à une application :

pnpm --filter app add @saas/analytics --workspace

Importez et utilisez :

import { trackEvent } from "@saas/analytics";

Fini ? Marquez cette page comme terminée.

On this page