// === ENUMS COHÉRENTS === export enum UserType { HUB = 'HUB', MERCHANT_PARTNER = 'MERCHANT' } export enum UserRole { // Rôles Hub (sans merchantPartnerId) DCB_ADMIN = 'dcb-admin', DCB_SUPPORT = 'dcb-support', DCB_PARTNER = 'dcb-partner', // Rôles Merchant Partner (avec merchantPartnerId obligatoire) DCB_PARTNER_ADMIN = 'dcb-partner-admin', DCB_PARTNER_MANAGER = 'dcb-partner-manager', DCB_PARTNER_SUPPORT = 'dcb-partner-support' } export enum MerchantStatus { ACTIVE = 'ACTIVE', INACTIVE = 'INACTIVE', PENDING = 'PENDING', SUSPENDED = 'SUSPENDED' } export enum ConfigType { API_KEY = 'API_KEY', SECRET_KEY = 'SECRET_KEY', WEBHOOK_URL = 'WEBHOOK_URL', CALLBACK_URL = 'CALLBACK_URL', TIMEOUT = 'TIMEOUT', RETRY_COUNT = 'RETRY_COUNT', CUSTOM = 'CUSTOM' } export enum Operator { ORANGE_CI = 1, MTN_CI = 2, MOOV_CI = 3, WAVE = 4 } // === MODÈLES PRINCIPAUX === export interface MerchantConfig { id?: number; name: ConfigType | string; value: string; operatorId: Operator; merchantId?: number; createdAt?: string; updatedAt?: string; } export interface TechnicalContact { id?: number; firstName: string; lastName: string; phone: string; email: string; merchantId?: number; createdAt?: string; updatedAt?: string; } export interface MerchantUser { userId: string; role: UserRole; // Utilisation de vos rôles existants username?: string; email?: string; firstName?: string; lastName?: string; merchantPartnerId?: number; } export interface Merchant { id?: number; name: string; logo?: string; description?: string; adresse: string; phone: string; status?: MerchantStatus; configs: MerchantConfig[]; users: MerchantUser[]; technicalContacts: TechnicalContact[]; createdAt?: string; updatedAt?: string; createdBy?: string; createdByUsername?: string; } // === DTOs CRUD === export interface CreateMerchantDto { name: string; logo?: string; description?: string; adresse: string; phone: string; configs: Omit[]; technicalContacts: Omit[]; } export interface UpdateMerchantDto extends Partial { status?: MerchantStatus; } export interface AddUserToMerchantDto { userId: string; role: UserRole; // Utilisation de vos rôles existants merchantPartnerId: number; } export interface UpdateUserRoleDto { role: UserRole; // Utilisation de vos rôles existants } // === RÉPONSES API === export interface ApiResponse { success: boolean; data?: T; error?: string; message?: string; } export interface PaginatedResponse { items: T[]; total: number; page: number; limit: number; totalPages: number; } export interface MerchantStatsResponse { totalMerchants: number; activeMerchants: number; inactiveMerchants: number; pendingMerchants: number; totalConfigs: number; totalTechnicalContacts: number; } // === SEARCH === export interface SearchMerchantsParams { query?: string; status?: MerchantStatus; page?: number; limit?: number; } // === UTILITAIRES === export class MerchantUtils { static getStatusDisplayName(status: MerchantStatus): string { const statusNames = { [MerchantStatus.ACTIVE]: 'Actif', [MerchantStatus.INACTIVE]: 'Inactif', [MerchantStatus.PENDING]: 'En attente', [MerchantStatus.SUSPENDED]: 'Suspendu' }; return statusNames[status] || status; } static getStatusBadgeClass(status: MerchantStatus): string { const statusClasses = { [MerchantStatus.ACTIVE]: 'badge bg-success', [MerchantStatus.INACTIVE]: 'badge bg-secondary', [MerchantStatus.PENDING]: 'badge bg-warning', [MerchantStatus.SUSPENDED]: 'badge bg-danger' }; return statusClasses[status] || 'badge bg-secondary'; } static getOperatorName(operatorId: Operator): string { const operatorNames = { [Operator.ORANGE_CI]: 'Orange CI', [Operator.MTN_CI]: 'MTN CI', [Operator.MOOV_CI]: 'Moov CI', [Operator.WAVE]: 'Wave' }; return operatorNames[operatorId] || 'Inconnu'; } static getConfigTypeName(configName: ConfigType | string): string { const configTypeNames = { [ConfigType.API_KEY]: 'Clé API', [ConfigType.SECRET_KEY]: 'Clé Secrète', [ConfigType.WEBHOOK_URL]: 'URL Webhook', [ConfigType.CALLBACK_URL]: 'URL Callback', [ConfigType.TIMEOUT]: 'Timeout (ms)', [ConfigType.RETRY_COUNT]: 'Nombre de tentatives', [ConfigType.CUSTOM]: 'Personnalisé' }; return configTypeNames[configName as ConfigType] || configName; } static validateMerchantCreation(merchant: CreateMerchantDto): string[] { const errors: string[] = []; if (!merchant.name?.trim()) { errors.push('Le nom du merchant est requis'); } if (!merchant.adresse?.trim()) { errors.push('L\'adresse est requise'); } if (!merchant.phone?.trim()) { errors.push('Le téléphone est requis'); } if (!merchant.technicalContacts || merchant.technicalContacts.length === 0) { errors.push('Au moins un contact technique est requis'); } if (!merchant.configs || merchant.configs.length === 0) { errors.push('Au moins une configuration est requise'); } return errors; } // Méthode pour obtenir les rôles disponibles pour les merchants static getAvailableMerchantRoles(): UserRole[] { return [ UserRole.DCB_PARTNER_ADMIN, UserRole.DCB_PARTNER_MANAGER, UserRole.DCB_PARTNER_SUPPORT ]; } // Vérifier si un rôle est valide pour un merchant static isValidMerchantRole(role: UserRole): boolean { const merchantRoles = [ UserRole.DCB_PARTNER_ADMIN, UserRole.DCB_PARTNER_MANAGER, UserRole.DCB_PARTNER_SUPPORT ]; return merchantRoles.includes(role); } }