import { Inject, Injectable, Logger, OnModuleInit } from "@nestjs/common"; import { usersRepo } from "@eden/database"; import type { EdenEnv } from "@eden/config"; import { EDEN_ENV } from "../config/config.constants.js"; import { PasswordService } from "../auth/password.service.js"; import { SUPER_ADMIN_ROLE } from "../auth/permissions.js"; /** * Mirrors the legacy's seedAdmin() (eden.md §5.7): runs once at boot, * only acts if `users` is empty, creates the first super_admin from env * vars — never hardcoded, never auto-generated-and-logged. If the env * vars aren't set, boot proceeds without seeding (useful for CI/tests * that don't need a real login) rather than crashing. */ @Injectable() export class SeedService implements OnModuleInit { private readonly logger = new Logger(SeedService.name); constructor( @Inject(EDEN_ENV) private readonly env: EdenEnv, private readonly passwords: PasswordService, ) {} async onModuleInit() { const existing = await usersRepo.countUsers(); if (existing > 0) return; if (!this.env.EDEN_SUPERADMIN_EMAIL || !this.env.EDEN_SUPERADMIN_PASSWORD) { this.logger.warn( "users está vazia e EDEN_SUPERADMIN_EMAIL/EDEN_SUPERADMIN_PASSWORD não estão definidos — pulando seed do super_admin.", ); return; } const { hash, algoVersion } = await this.passwords.hash(this.env.EDEN_SUPERADMIN_PASSWORD); const user = await usersRepo.createUser({ email: this.env.EDEN_SUPERADMIN_EMAIL, passwordHash: hash, passwordAlgoVersion: algoVersion, roleKey: SUPER_ADMIN_ROLE, fullName: "Super Administrador", }); await usersRepo.grantUserApplication(user.id, "core"); await usersRepo.grantUserApplication(user.id, "reseller"); await usersRepo.grantUserApplication(user.id, "subscriber"); this.logger.log(`super_admin inicial criado (${user.email}) a partir de EDEN_SUPERADMIN_EMAIL.`); } }