feat(wip): up the settings onboaridng flow

This commit is contained in:
Nathnael
2026-06-18 14:45:14 +00:00
parent e9149242b2
commit c6179c046c
11 changed files with 339 additions and 7 deletions

View File

@@ -23,7 +23,11 @@ import { CreateCompanyDto } from "./dto/create-company.dto";
import { UpdateCompanyDto } from "./dto/update-company.dto";
import { CreateExternalProfileDto } from "./dto/create-external-profile.dto";
import { CreateCompanyWithProfileDto } from "./dto/create-company-with-profile.dto";
import { ResponseCompanyDto } from "./dto/response-company.dto";
import { AddCompanyProfilesDto } from "./dto/add-company-profiles.dto";
import {
ResponseCompanyDto,
ResponseCompanyProfileDto,
} from "./dto/response-company.dto";
import { ResponseExternalProfileDto } from "./dto/response-external-profile.dto";
import { CompanyInfoResponseDto } from "./dto/company-info-response.dto";
import { UpdateProfileDto } from "./dto/update-profile.dto";
@@ -85,6 +89,22 @@ export class CompaniesController {
return this.companiesService.updateProfile(user.id, dto);
}
@Post("company-profiles")
@ApiOperation({
summary:
"Add operational profile(s) (importer/exporter/forwarder) to the current user's company",
})
async addCompanyProfiles(
@CurrentUser() user: CurrentIamUser,
@Body() dto: AddCompanyProfilesDto,
): Promise<ResponseCompanyProfileDto[]> {
const profiles = await this.companiesService.addCompanyProfilesForUser(
user.id,
dto.types,
);
return profiles.map((p) => new ResponseCompanyProfileDto(p));
}
// Used by portal
@Post("create")
@ApiOperation({

View File

@@ -434,4 +434,47 @@ export class CompaniesService {
return profiles;
}
/**
* Add operational profile(s) to the current user's company (portal settings).
* Add-only and idempotent: each requested type must be allowed for the
* company's type, profiles that already exist are skipped (not re-created or
* rejected), and the full updated list is returned.
*/
async addCompanyProfilesForUser(
userId: string,
types: ProfileType[],
): Promise<CompanyProfile[]> {
const profile = await this.profilesRepo.findByUserId(userId);
if (!profile)
throw new NotFoundException(`Profile for user ${userId} not found`);
const companyId = profile.company?.id ?? profile.companyId;
const company = await this.findCompanyById(companyId);
const allowedTypes = this.getProfileTypeForCompanyType(company.type);
for (const type of types) {
if (!allowedTypes.includes(type)) {
throw new BadRequestException(
`Profile type "${type}" is not allowed for company type "${company.type}"`,
);
}
const existing = await this.companyProfilesRepo.findByType(
companyId,
type,
);
if (existing) continue;
const reference = await this.companyProfilesRepo.generateReference(type);
await this.companyProfilesRepo.create({
companyId,
type,
reference,
status: ProfileStatus.Active,
});
}
return this.companyProfilesRepo.findByCompanyId(companyId);
}
}

View File

@@ -0,0 +1,9 @@
import { IsArray, IsEnum, ArrayMinSize } from "class-validator";
import { ProfileType } from "../entities/company-profile.entity";
export class AddCompanyProfilesDto {
@IsArray()
@ArrayMinSize(1)
@IsEnum(ProfileType, { each: true })
types!: ProfileType[];
}

View File

@@ -1,9 +1,11 @@
import { Company } from '../entities/company.entity';
import { ExternalProfile } from '../entities/external-profile.entity';
import { ResponseCompanyProfileDto } from './response-company.dto';
export class ProfileResponseDto {
companyId: string;
companyName: string;
companyType: string;
companyEmail: string | null;
companyPhone: string | null;
companyLocation: string;
@@ -12,6 +14,8 @@ export class ProfileResponseDto {
vatNumber: string | null;
fanNumber: string | null;
companyProfiles: ResponseCompanyProfileDto[];
contactPersonName: string | null;
contactPersonPhone: string | null;
generalManagerName: string | null;
@@ -29,6 +33,10 @@ export class ProfileResponseDto {
constructor(profile: ExternalProfile, company: Company) {
this.companyId = company.id;
this.companyName = company.name;
this.companyType = company.type;
this.companyProfiles =
company.companyProfiles?.map((p) => new ResponseCompanyProfileDto(p)) ??
[];
this.companyEmail = company.email ?? null;
this.companyPhone = company.phone ?? null;
this.companyLocation = company.country;