diff --git a/src/modules/auth/auth.controller.ts b/src/modules/auth/auth.controller.ts index 2735892..d0d50c0 100644 --- a/src/modules/auth/auth.controller.ts +++ b/src/modules/auth/auth.controller.ts @@ -1,3 +1,10 @@ +import { Controller, Get } from "@nestjs/common"; + +//todo +@Controller() export class AuthController{ - + @Get() + getHello(): string { + return 'Hello World!'; + } } \ No newline at end of file diff --git a/src/modules/notifications/services/notifications.service.ts b/src/modules/notifications/services/notifications.service.ts index 77a023c..4043202 100644 --- a/src/modules/notifications/services/notifications.service.ts +++ b/src/modules/notifications/services/notifications.service.ts @@ -84,10 +84,11 @@ export class NotificationsService { channel: dto.channel, recipient: recipient.contact, subject: dto.subject, - content: await this.templateService.render(dto.templateId, { - ...recipient.data, - ...dto.variables, - }), + content:'{}', + //content: await this.templateService.render(dto.templateId, { + // ...recipient.data, + // ...dto.variables, + //}), templateId: dto.templateId, status: 'PENDING', batchId: dto.batchId, @@ -138,16 +139,16 @@ export class NotificationsService { message: notification.content, userToken: notification.user?.userToken, userAlias: notification.user?.userAlias, - from: notification.metadata?.from, + //from: notification.metadata?.from, }); break; case 'EMAIL': result = await this.emailService.send({ to: notification.recipient, - subject: notification.subject, + // subject: notification.subject, content: notification.content, - template: notification.templateId, + //template: notification.templateId, message: '' }); break; @@ -244,8 +245,8 @@ export class NotificationsService { for (const user of users) { recipients.push({ userId: user.id, - contact: dto.channel === 'SMS' ? user.msisdn : user.email, - data: { name: user.name, msisdn: user.msisdn }, + contact: dto.channel === 'SMS' ? user.msisdn : user.msisdn, + data: { name: user.msisdn, msisdn: user.msisdn }, }); } } @@ -278,7 +279,7 @@ export class NotificationsService { users.push(...activeUsers.map(u => ({ userId: u.id, contact: u.msisdn, - data: { name: u.name, msisdn: u.msisdn }, + data: { name: u.msisdn, msisdn: u.msisdn }, }))); break; diff --git a/src/modules/notifications/services/webhook.service.ts b/src/modules/notifications/services/webhook.service.ts index 774f2d4..b6046d8 100644 --- a/src/modules/notifications/services/webhook.service.ts +++ b/src/modules/notifications/services/webhook.service.ts @@ -63,7 +63,7 @@ export class WebhookService { try { const signature = this.generateSignature( webhook.payload, - webhook.partner?.secretKey, + webhook.partner?.secretKey as string, ); const response = await firstValueFrom( @@ -84,8 +84,8 @@ export class WebhookService { data: { status: 'SUCCESS', response: response.data, - responseCode: response.status, - deliveredAt: new Date(), + //responseCode: response.status, + //deliveredAt: new Date(), attempts: attempt, }, }); @@ -96,7 +96,7 @@ export class WebhookService { where: { id: webhookId }, data: { status: attempt >= 3 ? 'FAILED' : 'RETRYING', - lastError: error.message, + //lastError: error.message, attempts: attempt, lastAttempt: new Date(), }, diff --git a/src/modules/operators/operators.controller.ts b/src/modules/operators/operators.controller.ts index 5d082f0..e940876 100644 --- a/src/modules/operators/operators.controller.ts +++ b/src/modules/operators/operators.controller.ts @@ -1,5 +1,11 @@ //todo +import { Controller, Get } from "@nestjs/common"; +@Controller() export class OperatorsController{ + @Get() + getHello(): string { + return 'Hello World!'; + } } \ No newline at end of file diff --git a/src/modules/partners/dto/partner.dto.ts b/src/modules/partners/dto/partner.dto.ts index 0a76c84..73dc1ce 100644 --- a/src/modules/partners/dto/partner.dto.ts +++ b/src/modules/partners/dto/partner.dto.ts @@ -4,6 +4,7 @@ import { IsOptional, IsObject, MinLength, + IsUrl, } from 'class-validator'; import { ApiProperty } from '@nestjs/swagger'; @@ -73,4 +74,16 @@ export class UpdateCallbacksDto { onSuccess?: string; onFailure?: string; }; + + @IsOptional() + @IsUrl() + success?: string; + + @IsOptional() + @IsUrl() + cancel?: string; + + @IsOptional() + @IsUrl() + webhook?: string; } diff --git a/src/modules/partners/partners.controller.ts b/src/modules/partners/partners.controller.ts index 057af66..0c7f554 100644 --- a/src/modules/partners/partners.controller.ts +++ b/src/modules/partners/partners.controller.ts @@ -1,4 +1,9 @@ -//todoe +//todo +import { Controller, Get } from "@nestjs/common"; +@Controller() export class PartnersController{ - + @Get() + getHello(): string { + return 'Hello World!'; + } } \ No newline at end of file diff --git a/src/modules/partners/partners.service.ts b/src/modules/partners/partners.service.ts index 8ac12b2..8cec1e1 100644 --- a/src/modules/partners/partners.service.ts +++ b/src/modules/partners/partners.service.ts @@ -7,6 +7,7 @@ import { PrismaService } from '../../shared/services/prisma.service'; import * as bcrypt from 'bcrypt'; import * as crypto from 'crypto'; import { CreatePartnerDto, UpdateCallbacksDto } from './dto/partner.dto'; +import { Prisma } from 'generated/prisma'; @Injectable() export class PartnersService { @@ -65,8 +66,10 @@ export class PartnersService { const updatedPartner = await this.prisma.partner.update({ where: { id: partnerId }, data: { - callbacks: dto, - }, + //callbacks: dto as unknown as Prisma.JsonValue, + // ou + callbacks: JSON.parse(JSON.stringify(dto)), + }, }); return { diff --git a/src/modules/payments/payments.service.ts b/src/modules/payments/payments.service.ts index 21a237a..4c5b48d 100644 --- a/src/modules/payments/payments.service.ts +++ b/src/modules/payments/payments.service.ts @@ -45,9 +45,11 @@ export class PaymentsService { // Créer la transaction dans la base const payment = await this.prisma.payment.create({ + data: { + partnerId:"", userId: user.id, - amount: chargeDto.amount, + amount: chargeDto.amount, currency: chargeDto.currency, description: chargeDto.description, reference: chargeDto.reference || this.generateReference(), diff --git a/src/modules/subscriptions/schedulers/subscription.scheduler.ts b/src/modules/subscriptions/schedulers/subscription.scheduler.ts index 09cbca8..4e749f9 100644 --- a/src/modules/subscriptions/schedulers/subscription.scheduler.ts +++ b/src/modules/subscriptions/schedulers/subscription.scheduler.ts @@ -73,7 +73,7 @@ export class SubscriptionScheduler { }, data: { status: 'EXPIRED', - expiredAt: new Date(), + //expiredAt: new Date(), }, }); diff --git a/src/modules/subscriptions/services/plan.service.ts b/src/modules/subscriptions/services/plan.service.ts index 72e56c7..5bff4d5 100644 --- a/src/modules/subscriptions/services/plan.service.ts +++ b/src/modules/subscriptions/services/plan.service.ts @@ -2,7 +2,6 @@ import { Injectable, BadRequestException, NotFoundException } from '@nestjs/comm import { PrismaService } from '../../../shared/services/prisma.service'; import { CreatePlanDto, UpdatePlanDto } from '../dto/plan.dto'; import { Prisma } from 'generated/prisma'; - @Injectable() export class PlanService { @@ -248,9 +247,9 @@ export class PlanService { interval: plan.interval, intervalCount: plan.intervalCount, trialDays: plan.trialDays, - features: plan.features, - limits: plan.limits, - metadata: { ...plan.metadata, duplicatedFrom: plan.id }, + //features: plan.features, + //limits: plan.limits, + metadata: {metadata:plan.metadata, duplicatedFrom: plan.id }, active: false, // Désactivé par défaut }, }); @@ -321,14 +320,14 @@ export class PlanService { select: { createdAt: true, cancelledAt: true, - expiredAt: true, + suspendedAt: true, }, }); if (subscriptions.length === 0) return 0; const lifetimes = subscriptions.map(sub => { - const endDate = sub.cancelledAt || sub.expiredAt || new Date(); + const endDate = sub.cancelledAt || sub.suspendedAt || new Date(); return endDate.getTime() - sub.createdAt.getTime(); }); diff --git a/src/modules/subscriptions/subscriptions.module.ts b/src/modules/subscriptions/subscriptions.module.ts index ad1f132..24261b6 100644 --- a/src/modules/subscriptions/subscriptions.module.ts +++ b/src/modules/subscriptions/subscriptions.module.ts @@ -9,9 +9,11 @@ import { BillingService } from './services/billing.service'; import { PrismaService } from '../../shared/services/prisma.service'; import { PaymentsModule } from '../payments/payments.module'; import { NotificationsModule } from '../notifications/notifications.module'; +import { HttpModule } from '@nestjs/axios'; @Module({ imports: [ + HttpModule, BullModule.registerQueue({ name: 'subscriptions', }), diff --git a/src/modules/subscriptions/subscriptions.service.ts b/src/modules/subscriptions/subscriptions.service.ts index 08327f5..0b8f0d9 100644 --- a/src/modules/subscriptions/subscriptions.service.ts +++ b/src/modules/subscriptions/subscriptions.service.ts @@ -85,9 +85,7 @@ export class SubscriptionsService { currentPeriodStart, currentPeriodEnd, nextBillingDate, - trialEndsAt, - amount: plan.amount, - currency: plan.currency, + trialEndsAt, metadata: { ...dto.metadata, userAlias: user.userAlias, @@ -234,6 +232,18 @@ export class SubscriptionsService { where: { id: partnerId }, }); + interface PartnerCallbacks { + subscription?: { + onCancel?: string; + onRenew?: string; + onExpire?: string; + }; + payment?: { + onSuccess?: string; + onFailure?: string; + }; + } + /* if (partner?.callbacks?subscription?.onCancel) { await this.subscriptionQueue.add('webhook-notification', { url: partner.callbacks.subscription.onCancel, @@ -241,6 +251,7 @@ export class SubscriptionsService { subscription: updatedSubscription, }); } + */ return updatedSubscription; } @@ -293,29 +304,32 @@ export class SubscriptionsService { currentPeriodEnd: this.calculatePeriodEnd(subscription.plan, subscription.currentPeriodEnd), nextBillingDate: this.calculatePeriodEnd(subscription.plan, subscription.currentPeriodEnd), lastPaymentId: payment.id, - lastPaymentDate: new Date(), + // lastPaymentDate: new Date(), renewalCount: { increment: 1 }, failureCount: 0, // Reset failure count on success }, }); // Programmer le prochain renouvellement + /* todo const delay = subscription.nextBillingDate.getTime() - Date.now(); await this.billingQueue.add( 'process-renewal', { subscriptionId }, { delay }, ); + */ // Notifier le succès - if (subscription.partner?.callbacks?.subscription?.onRenew) { + + /* if (subscription.partner?.callbacks?.subscription?.onRenew) { await this.subscriptionQueue.add('webhook-notification', { url: subscription.partner.callbacks.subscription.onRenew, event: 'SUBSCRIPTION_RENEWED', subscription: subscription, payment: payment, }); - } + }*/ } else { await this.handleRenewalFailure(subscription); } @@ -342,13 +356,14 @@ export class SubscriptionsService { }); if (payment.status === 'SUCCESS') { + //todo await this.prisma.subscription.update({ where: { id: subscription.id }, data: { status: 'ACTIVE', - activatedAt: new Date(), + createdAt: new Date(), lastPaymentId: payment.id, - lastPaymentDate: new Date(), + //lastPaymentDate: new Date(), }, }); @@ -364,7 +379,7 @@ export class SubscriptionsService { where: { id: subscription.id }, data: { status: 'FAILED', - failureReason: payment.failureReason, + //todo failureReason: payment.failureReason, }, }); } @@ -373,7 +388,7 @@ export class SubscriptionsService { where: { id: subscription.id }, data: { status: 'FAILED', - failureReason: error.message, + //failureReason: error.message, }, }); throw error; @@ -392,7 +407,7 @@ export class SubscriptionsService { status: 'SUSPENDED', failureCount, suspendedAt: new Date(), - suspensionReason: `Payment failed ${maxRetries} times`, + //suspensionReason: `Payment failed ${maxRetries} times`, }, });