"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