Skip to content

Ajouter un module

Un module est un dossier autonome dans src/modules/ qui regroupe tout le code lie a une fonctionnalite.

Structure d'un module

src/modules/<nom>/
  commands/          # Commandes slash Discord
    my.command.ts
  handlers/          # Event handlers
    my.handler.ts
  jobs/              # Taches cron
    my.job.ts
  services/          # Logique metier
    my.service.ts
  repositories/      # Acces DB (Prisma)
    my.repository.ts
  types/             # Interfaces et DTOs
    my.dto.ts
  utils/             # Fonctions utilitaires
    my.parser.ts

Tous les sous-dossiers sont optionnels. Un module simple peut n'avoir qu'une commande et un service.

Checklist de creation

1. Schema Prisma (si besoin de DB)

Ajouter les modeles dans prisma/schema.prisma :

prisma
model MyModel {
  id        String   @id @default(cuid())
  guildId   String
  // ... champs ...
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@index([guildId])
}

Puis generer et migrer :

bash
npx prisma migrate dev --name add-my-model
npx prisma generate

2. Variables d'environnement (si besoin)

Ajouter dans src/config/env.ts (schema Zod) :

typescript
MY_API_KEY: z.string().trim().min(1).optional(),

Et dans .env.example :

MY_API_KEY=

3. Repository (acces DB)

typescript
// src/modules/<nom>/repositories/my.repository.ts
import { prisma } from '../../../shared/db/prisma.js';

export const myRepository = {
  async findByGuild(guildId: string) {
    return prisma.myModel.findMany({ where: { guildId } });
  },

  async upsert(params: { guildId: string; /* ... */ }) {
    return prisma.myModel.upsert({
      where: { /* unique constraint */ },
      create: params,
      update: params,
    });
  },
};

4. Service (logique metier)

typescript
// src/modules/<nom>/services/my.service.ts
import { myRepository } from '../repositories/my.repository.js';
import { logger } from '../../../config/logger.js';

const log = logger.child({ module: 'my-module' });

export const myService = {
  async doSomething(guildId: string) {
    const data = await myRepository.findByGuild(guildId);
    log.info({ count: data.length }, 'Data fetched');
    return data;
  },
};

5. Commande

Voir Ajouter une commande.

6. Handler (si evenement Discord)

Voir Ajouter un handler.

7. Job cron (si tache planifiee)

Voir Ajouter un cron.

8. Help embed (optionnel)

Ajouter la documentation de la commande dans src/modules/help/help-embeds.ts :

typescript
// Dans buildPublicHelpEmbeds() ou buildStaffHelpEmbeds()
embed.addFields(
  { name: '`/mycommand`', value: 'Description de la commande.', inline: false },
);

9. Enregistrement dans bootstrap

Dans src/app/bootstrap.ts, ajouter les imports et appels necessaires :

  • Commande : dans register-commands.ts
  • Handler : dans la section handlers de bootstrap.ts
  • Job : dans le handler clientReady de bootstrap.ts

10. Tests (optionnel)

Creer les tests dans tests/unit/modules/<nom>/ :

tests/unit/modules/<nom>/
  my.service.test.ts

Voir Tests pour les patterns de test.