@company-manager/docs
Support

Meilleures Pratiques

Guide des meilleures pratiques pour Company Manager.

Meilleures Pratiques

Guide complet des meilleures pratiques pour l'utilisation et le développement de Company Manager.

Architecture

Structure du Code

  • Organisation modulaire
  • Séparation des préoccupations
  • DRY (Don't Repeat Yourself)
  • SOLID principles

Gestion des Dépendances

// Utilisation des versions fixes
{
  "dependencies": {
    "next": "v15.4.0-canary.47",
    "react": "18.2.0",
    "typescript": "5.8"
  }
}

Développement

Standards de Code

// Bon exemple
const fetchUser = async (id: string): Promise<User> => {
  try {
    return await prisma.user.findUnique({ where: { id } });
  } catch (error) {
    logger.error("Erreur lors de la récupération de l'utilisateur", {
      id,
      error,
    });
    throw new UserNotFoundError(id);
  }
};

// À éviter
const getUser = async (id) => {
  const user = await prisma.user.findUnique({ where: { id } });
  return user;
};

Tests

// Tests complets
describe("UserService", () => {
  describe("createUser", () => {
    it("should create user with valid data", async () => {
      // Arrange
      const userData = {
        /* ... */
      };

      // Act
      const user = await userService.createUser(userData);

      // Assert
      expect(user).toBeDefined();
      expect(user.email).toBe(userData.email);
    });

    it("should handle validation errors", async () => {
      // ...
    });
  });
});

Performance

Optimisation des Requêtes

// Bon exemple - Requêtes optimisées
const getOrdersWithDetails = async () => {
  return prisma.order.findMany({
    include: {
      items: true,
      customer: {
        select: {
          id: true,
          name: true,
          email: true,
        },
      },
    },
  });
};

// À éviter - N+1 queries
const getOrders = async () => {
  const orders = await prisma.order.findMany();
  for (const order of orders) {
    order.items = await prisma.orderItem.findMany({
      where: { orderId: order.id },
    });
  }
  return orders;
};

Mise en Cache

// Configuration du cache
const cache = new LRUCache({
  max: 500,
  ttl: 1000 * 60 * 5, // 5 minutes
});

// Utilisation
const getCachedData = async (key: string) => {
  const cached = cache.get(key);
  if (cached) return cached;

  const data = await fetchData(key);
  cache.set(key, data);
  return data;
};

Sécurité

Validation des Données

// Schéma de validation
const userSchema = z.object({
  email: z.string().email(),
  password: z.string().min(8).regex(/[A-Z]/).regex(/[0-9]/),
  role: z.enum(["USER", "ADMIN"]),
});

// Utilisation
const validateUser = (data: unknown) => {
  return userSchema.parse(data);
};

Gestion des Sessions

// Configuration des sessions
const sessionConfig = {
  maxAge: 7 * 24 * 60 * 60, // 7 jours
  secure: process.env.NODE_ENV === "production",
  sameSite: "lax" as const,
};

Multi-tenant

Isolation des Données

// Middleware de tenant
const withTenant = async (
  req: NextApiRequest,
  res: NextApiResponse,
  next: NextHandler
) => {
  const tenant = await getTenantFromRequest(req);
  if (!tenant) {
    return res.status(401).json({ error: "Tenant non trouvé" });
  }

  req.tenant = tenant;
  return next();
};

Gestion des Ressources

// Utilisation efficace des ressources
const prisma = new PrismaClient({
  datasources: {
    db: {
      url: `${process.env.DATABASE_URL}?connection_limit=5`,
    },
  },
});

Monitoring

Logs

// Configuration des logs
const logger = winston.createLogger({
  level: "info",
  format: winston.format.json(),
  defaultMeta: { service: "company-manager" },
  transports: [
    new winston.transports.File({ filename: "error.log", level: "error" }),
    new winston.transports.File({ filename: "combined.log" }),
  ],
});

Métriques

// Collecte de métriques
const metrics = {
  requestCount: new Counter("http_requests_total"),
  requestDuration: new Histogram("http_request_duration_seconds"),
  activeUsers: new Gauge("active_users_total"),
};

Déploiement

CI/CD

# GitHub Actions
name: CI
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: bun install
      - run: bun test
      - run: bun lint

Environnements

# Configuration par environnement
NODE_ENV=production
DATABASE_URL=postgresql://user:pass@prod-db/company_manager
REDIS_URL=redis://prod-redis:6379

Maintenance

Backups

# Script de backup
#!/bin/bash
pg_dump company_manager > backup_$(date +%Y%m%d).sql

Mises à Jour

{
  "scripts": {
    "update": "bun update && bun prisma generate && bun build",
    "migrate": "bun prisma migrate deploy"
  }
}