template-saas/apps/backend/dist/modules/onboarding/onboarding.service.js
rckrdmrd 50a821a415
Some checks failed
CI / Backend CI (push) Has been cancelled
CI / Frontend CI (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / CI Summary (push) Has been cancelled
[SIMCO-V38] feat: Actualizar a SIMCO v3.8.0
- HERENCIA-SIMCO.md actualizado con directivas v3.7 y v3.8
- Actualizaciones de configuracion

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 08:53:08 -06:00

188 lines
7.4 KiB
JavaScript

"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var OnboardingService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.OnboardingService = void 0;
const common_1 = require("@nestjs/common");
const typeorm_1 = require("@nestjs/typeorm");
const typeorm_2 = require("typeorm");
const tenant_entity_1 = require("../tenants/entities/tenant.entity");
const user_entity_1 = require("../auth/entities/user.entity");
const token_entity_1 = require("../auth/entities/token.entity");
const subscription_entity_1 = require("../billing/entities/subscription.entity");
const email_service_1 = require("../email/services/email.service");
const audit_service_1 = require("../audit/services/audit.service");
const audit_log_entity_1 = require("../audit/entities/audit-log.entity");
let OnboardingService = OnboardingService_1 = class OnboardingService {
constructor(tenantRepository, userRepository, tokenRepository, subscriptionRepository, emailService, auditService) {
this.tenantRepository = tenantRepository;
this.userRepository = userRepository;
this.tokenRepository = tokenRepository;
this.subscriptionRepository = subscriptionRepository;
this.emailService = emailService;
this.auditService = auditService;
this.logger = new common_1.Logger(OnboardingService_1.name);
}
async getStatus(tenantId) {
const tenant = await this.tenantRepository.findOne({
where: { id: tenantId },
});
if (!tenant) {
throw new common_1.BadRequestException('Tenant not found');
}
const teamData = await this.getTeamData(tenantId);
const planData = await this.getPlanData(tenantId);
const companyData = this.getCompanyData(tenant);
const step = this.calculateStep(companyData, teamData, planData, tenant);
const completed = tenant.status === 'active';
return {
step,
completed,
data: {
company: companyData,
team: teamData,
plan: planData,
},
};
}
async completeOnboarding(tenantId, userId) {
const tenant = await this.tenantRepository.findOne({
where: { id: tenantId },
});
if (!tenant) {
throw new common_1.BadRequestException('Tenant not found');
}
if (tenant.status === 'active') {
return {
success: true,
redirectUrl: '/dashboard',
};
}
if (tenant.status !== 'trial' && tenant.status !== 'suspended' && tenant.status !== 'canceled') {
throw new common_1.BadRequestException('Tenant is not in a valid state for onboarding completion');
}
const user = await this.userRepository.findOne({
where: { id: userId, tenant_id: tenantId },
});
if (!user) {
throw new common_1.BadRequestException('User not found');
}
const oldStatus = tenant.status;
tenant.status = 'active';
await this.tenantRepository.save(tenant);
await this.auditService.createAuditLog({
tenant_id: tenantId,
user_id: userId,
action: audit_log_entity_1.AuditAction.UPDATE,
entity_type: 'tenant',
entity_id: tenantId,
old_values: { status: oldStatus },
new_values: { status: 'active' },
description: 'Onboarding completed',
});
await this.sendWelcomeEmail(user, tenant);
this.logger.log(`Onboarding completed for tenant ${tenantId}`);
return {
success: true,
redirectUrl: '/dashboard',
};
}
getCompanyData(tenant) {
if (!tenant.name || !tenant.slug) {
return null;
}
return {
name: tenant.name,
slug: tenant.slug,
logo_url: tenant.logo_url,
settings: tenant.settings,
};
}
async getTeamData(tenantId) {
const invitesSent = await this.tokenRepository.count({
where: {
tenant_id: tenantId,
token_type: 'invitation',
},
});
const membersJoined = await this.userRepository.count({
where: {
tenant_id: tenantId,
status: 'active',
},
});
const actualMembersJoined = membersJoined > 1 ? membersJoined - 1 : 0;
return {
invitesSent,
membersJoined: actualMembersJoined,
};
}
async getPlanData(tenantId) {
const subscription = await this.subscriptionRepository.findOne({
where: { tenant_id: tenantId },
order: { created_at: 'DESC' },
});
return {
selected: !!subscription,
planId: subscription?.plan_id || null,
};
}
calculateStep(companyData, teamData, planData, tenant) {
if (tenant.status === 'active') {
return 4;
}
if (!companyData) {
return 1;
}
if (!planData.selected) {
return 3;
}
return 4;
}
async sendWelcomeEmail(user, tenant) {
try {
await this.emailService.sendTemplateEmail({
to: {
email: user.email,
name: user.first_name || undefined,
},
templateKey: 'welcome',
variables: {
userName: user.first_name || user.email,
appName: 'Template SaaS',
tenantName: tenant.name,
},
});
this.logger.log(`Welcome email sent to ${user.email}`);
}
catch (error) {
this.logger.error(`Failed to send welcome email to ${user.email}`, error.stack);
}
}
};
exports.OnboardingService = OnboardingService;
exports.OnboardingService = OnboardingService = OnboardingService_1 = __decorate([
(0, common_1.Injectable)(),
__param(0, (0, typeorm_1.InjectRepository)(tenant_entity_1.Tenant)),
__param(1, (0, typeorm_1.InjectRepository)(user_entity_1.User)),
__param(2, (0, typeorm_1.InjectRepository)(token_entity_1.Token)),
__param(3, (0, typeorm_1.InjectRepository)(subscription_entity_1.Subscription)),
__metadata("design:paramtypes", [typeorm_2.Repository,
typeorm_2.Repository,
typeorm_2.Repository,
typeorm_2.Repository,
email_service_1.EmailService,
audit_service_1.AuditService])
], OnboardingService);
//# sourceMappingURL=onboarding.service.js.map