import { Injectable, Logger } from '@nestjs/common'; import { DataSource } from 'typeorm'; const REQUIRED_STEPS = ['profile', 'workspace', 'invite_member', 'first_workflow']; @Injectable() export class OnboardingService { private readonly logger = new Logger(OnboardingService.name); constructor(private dataSource: DataSource) {} async getProgress(orgId: string) { const rows = await this.dataSource.query( `SELECT completed_steps, completed_at, updated_at FROM shared.onboarding_progress WHERE organization_id = $1`, [orgId], ); if (rows.length === 0) { // Create a fresh record await this.dataSource.query( `INSERT INTO shared.onboarding_progress (organization_id) VALUES ($1) ON CONFLICT DO NOTHING`, [orgId], ); return { completedSteps: [], completedAt: null, requiredSteps: REQUIRED_STEPS }; } return { completedSteps: rows[0].completed_steps || [], completedAt: rows[0].completed_at, requiredSteps: REQUIRED_STEPS, }; } async markStepComplete(orgId: string, step: string) { // Add step to array (using array_append with dedup) await this.dataSource.query( `INSERT INTO shared.onboarding_progress (organization_id, completed_steps, updated_at) VALUES ($1, ARRAY[$2::text], NOW()) ON CONFLICT (organization_id) DO UPDATE SET completed_steps = CASE WHEN $2 = ANY(onboarding_progress.completed_steps) THEN onboarding_progress.completed_steps ELSE array_append(onboarding_progress.completed_steps, $2::text) END, updated_at = NOW()`, [orgId, step], ); // Check if all required steps are done const rows = await this.dataSource.query( `SELECT completed_steps FROM shared.onboarding_progress WHERE organization_id = $1`, [orgId], ); const completedSteps = rows[0]?.completed_steps || []; const allDone = REQUIRED_STEPS.every((s) => completedSteps.includes(s)); if (allDone) { await this.dataSource.query( `UPDATE shared.onboarding_progress SET completed_at = NOW() WHERE organization_id = $1 AND completed_at IS NULL`, [orgId], ); } return this.getProgress(orgId); } async resetProgress(orgId: string) { await this.dataSource.query( `UPDATE shared.onboarding_progress SET completed_steps = '{}', completed_at = NULL, updated_at = NOW() WHERE organization_id = $1`, [orgId], ); return this.getProgress(orgId); } }