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:
@@ -11,6 +11,7 @@ import {
|
||||
noteAccessWhere,
|
||||
ownerWhere,
|
||||
} from '../common/record-scope';
|
||||
import { BUSINESS_FIELD_LABELS, isBusinessField } from '@mento/shared';
|
||||
import { AiService } from './ai.service';
|
||||
|
||||
type CatalogItem = AskMentoSourceDto;
|
||||
@@ -101,7 +102,11 @@ Rules:
|
||||
if (!person) throw new NotFoundException('شخص پیدا نشد');
|
||||
}
|
||||
|
||||
const [notes, activities, deals, memories] = await Promise.all([
|
||||
const [org, notes, activities, deals, memories] = await Promise.all([
|
||||
this.prisma.organization.findUnique({
|
||||
where: { id: actor.organizationId },
|
||||
select: { name: true, businessField: true },
|
||||
}),
|
||||
this.prisma.note.findMany({
|
||||
where: {
|
||||
organizationId: actor.organizationId,
|
||||
@@ -167,8 +172,13 @@ Rules:
|
||||
]);
|
||||
|
||||
const catalog: CatalogItem[] = [];
|
||||
const field =
|
||||
org?.businessField && isBusinessField(org.businessField)
|
||||
? BUSINESS_FIELD_LABELS[org.businessField]
|
||||
: 'نامشخص';
|
||||
const lines: string[] = [
|
||||
`Today: ${new Date().toISOString()}`,
|
||||
`Organization: ${org?.name ?? '—'} | business field: ${field}`,
|
||||
personId ? `Focus personId: ${personId}` : 'Scope: current user records',
|
||||
];
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ export class AuthService {
|
||||
data: {
|
||||
name: dto.organizationName,
|
||||
slug,
|
||||
businessField: dto.businessField,
|
||||
users: {
|
||||
create: {
|
||||
email: dto.email.toLowerCase(),
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import { IsEmail, IsString, MinLength } from 'class-validator';
|
||||
import {
|
||||
IsEmail,
|
||||
IsIn,
|
||||
IsString,
|
||||
MinLength,
|
||||
} from 'class-validator';
|
||||
import { BUSINESS_FIELDS } from '@mento/shared';
|
||||
|
||||
export class LoginDto {
|
||||
@IsEmail()
|
||||
@@ -24,4 +30,7 @@ export class RegisterOrganizationDto {
|
||||
@IsString()
|
||||
@MinLength(6)
|
||||
password!: string;
|
||||
|
||||
@IsIn([...BUSINESS_FIELDS])
|
||||
businessField!: (typeof BUSINESS_FIELDS)[number];
|
||||
}
|
||||
|
||||
@@ -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) => ({
|
||||
|
||||
Reference in New Issue
Block a user