Ask for organization business field at signup, including jewelry.

Store Didar-style industry on the org so registration, settings, and Ask Mento share the same catalog.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-03 16:45:59 +03:30
co-authored by Cursor
parent ce94658fcd
commit d2f66d11fc
14 changed files with 286 additions and 8 deletions
+14
View File
@@ -1,6 +1,7 @@
import {
ArrayMinSize,
IsArray,
IsIn,
IsNumber,
IsOptional,
IsString,
@@ -10,6 +11,7 @@ import {
ValidateNested,
} from 'class-validator';
import { Type } from 'class-transformer';
import { BUSINESS_FIELDS } from '@mento/shared';
export class ExchangeRateInputDto {
@IsString()
@@ -42,3 +44,15 @@ export class UpdateOrgCurrenciesDto {
@Type(() => ExchangeRateInputDto)
rates?: ExchangeRateInputDto[];
}
export class UpdateOrganizationDto {
@IsOptional()
@IsString()
@MinLength(2)
@MaxLength(120)
name?: string;
@IsOptional()
@IsIn([...BUSINESS_FIELDS])
businessField?: (typeof BUSINESS_FIELDS)[number];
}
@@ -3,7 +3,7 @@ import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { RolesGuard } from '../auth/roles.guard';
import { Roles } from '../auth/roles.decorator';
import { CurrentUser } from '../auth/current-user.decorator';
import { UpdateOrgCurrenciesDto } from './dto';
import { UpdateOrgCurrenciesDto, UpdateOrganizationDto } from './dto';
import { OrganizationsService } from './organizations.service';
@Controller('organizations')
@@ -21,6 +21,15 @@ export class OrganizationsController {
return this.organizationsService.catalog();
}
@Patch('current')
@Roles('owner', 'admin')
updateCurrent(
@CurrentUser() user: { organizationId: string },
@Body() dto: UpdateOrganizationDto,
) {
return this.organizationsService.updateProfile(user.organizationId, dto);
}
@Patch('current/currencies')
@Roles('owner', 'admin')
updateCurrencies(
@@ -7,7 +7,7 @@ import type {
OrganizationDto,
UpdateOrgCurrenciesRequest,
} from '@mento/shared';
import { CURRENCY_CATALOG } from '@mento/shared';
import { CURRENCY_CATALOG, isBusinessField } from '@mento/shared';
import { Prisma } from '@prisma/client';
import { PrismaService } from '../prisma/prisma.service';
import { isKnownCurrency } from '../common/currency';
@@ -29,6 +29,27 @@ export class OrganizationsService {
return this.toDto(org);
}
async updateProfile(
organizationId: string,
dto: { name?: string; businessField?: string },
): Promise<OrganizationDto> {
if (dto.businessField && !isBusinessField(dto.businessField)) {
throw new BadRequestException('زمینه فعالیت معتبر نیست');
}
const name = dto.name?.trim();
if (dto.name !== undefined && (!name || name.length < 2)) {
throw new BadRequestException('نام سازمان معتبر نیست');
}
await this.prisma.organization.update({
where: { id: organizationId },
data: {
...(name ? { name } : {}),
...(dto.businessField ? { businessField: dto.businessField } : {}),
},
});
return this.getCurrent(organizationId);
}
async updateCurrencies(
organizationId: string,
dto: UpdateOrgCurrenciesRequest,
@@ -130,6 +151,7 @@ export class OrganizationsService {
id: string;
name: string;
slug: string;
businessField: string | null;
baseCurrency: string;
enabledCurrencies: string[];
exchangeRates: Array<{
@@ -142,6 +164,10 @@ export class OrganizationsService {
id: org.id,
name: org.name,
slug: org.slug,
businessField:
org.businessField && isBusinessField(org.businessField)
? org.businessField
: null,
baseCurrency: org.baseCurrency,
enabledCurrencies: org.enabledCurrencies,
exchangeRates: org.exchangeRates.map((r) => ({