Rebrand the product to Montact and point local UI at production API.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -11,7 +11,7 @@ import {
|
||||
noteAccessWhere,
|
||||
ownerWhere,
|
||||
} from '../common/record-scope';
|
||||
import { BUSINESS_FIELD_LABELS, isBusinessField } from '@mento/shared';
|
||||
import { BUSINESS_FIELD_LABELS, brand, brandSuggestionFa, isBusinessField } from '@mento/shared';
|
||||
import { AiService } from './ai.service';
|
||||
|
||||
type CatalogItem = AskMentoSourceDto;
|
||||
@@ -39,7 +39,7 @@ export class AiAskService {
|
||||
answer?: string;
|
||||
sources?: Array<{ type?: string; id?: string; label?: string }>;
|
||||
}>(
|
||||
`You are Mento, a Persian CRM sales assistant.
|
||||
`You are ${brand.name}, a Persian CRM sales assistant.
|
||||
Answer ONLY from the CRM context. If the context is insufficient, say so in Persian.
|
||||
Do not invent customers, amounts, dates, or promises.
|
||||
Return JSON: { "answer": string, "sources": [{ "type": "person"|"note"|"activity"|"deal"|"memory", "id": string, "label": string }] }
|
||||
@@ -73,7 +73,7 @@ Return JSON: { "text": string, "cta": string, "ctaKind": "call"|"activity" }
|
||||
Rules:
|
||||
- 2 to 4 short sentences from the context only.
|
||||
- Mention durable memory, last contact, open deals, or next follow-up when present.
|
||||
- cta is one concrete next step, starting with «پیشنهاد منتو:».
|
||||
- cta is one concrete next step, starting with «${brand.suggestionPrefixFa}».
|
||||
- ctaKind is "call" if a phone follow-up is best, otherwise "activity".
|
||||
- Do not invent facts.`,
|
||||
`Customer briefing context:\n${context}`,
|
||||
@@ -84,7 +84,7 @@ Rules:
|
||||
const ctaKind = raw.ctaKind === 'activity' ? 'activity' : 'call';
|
||||
return {
|
||||
text: text || 'هنوز دادهٔ کافی برای خلاصه هوشمند این مشتری نیست.',
|
||||
cta: cta || 'پیشنهاد منتو: امروز با مشتری تماس بگیر',
|
||||
cta: cta || brandSuggestionFa('امروز با مشتری تماس بگیر'),
|
||||
ctaKind,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { brand } from '@mento/shared';
|
||||
|
||||
/** پنل ترِز / رایگان — همان الگوی montime */
|
||||
const SMS_TREZ_DEFAULT_BASE_URL = 'http://smspanel.Trez.ir';
|
||||
@@ -44,7 +45,7 @@ export class SmsService {
|
||||
async sendOtpSms(mobile: string, code: string): Promise<boolean> {
|
||||
const template =
|
||||
this.config.get<string>('SMS_OTP_TEMPLATE') ??
|
||||
'کد ورود پرتال منتو: {code}';
|
||||
`کد ورود پرتال ${brand.nameFa}: {code}`;
|
||||
const text = template.replace('{code}', code);
|
||||
const result = await this.sendSmsDetailed(mobile, text);
|
||||
return result.ok;
|
||||
|
||||
@@ -21,6 +21,7 @@ import type { Actor } from '../common/record-scope';
|
||||
import { CompaniesService } from './companies.service';
|
||||
import { CreateCompanyDto, ListQueryDto, UpdateCompanyDto } from './dto';
|
||||
import { ContactsExcelService } from './contacts-excel.service';
|
||||
import { brand } from '@mento/shared';
|
||||
|
||||
@Controller('companies')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@@ -50,7 +51,7 @@ export class CompaniesController {
|
||||
res.set({
|
||||
'Content-Type':
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'Content-Disposition': 'attachment; filename="mento-companies.xlsx"',
|
||||
'Content-Disposition': `attachment; filename="${brand.filePrefix}-companies.xlsx"`,
|
||||
});
|
||||
return new StreamableFile(buffer);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import type { Actor } from '../common/record-scope';
|
||||
import { CreatePersonDto, ListQueryDto, UpdatePersonDto } from './dto';
|
||||
import { PeopleService } from './people.service';
|
||||
import { ContactsExcelService } from './contacts-excel.service';
|
||||
import { brand } from '@mento/shared';
|
||||
|
||||
@Controller('people')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@@ -51,7 +52,7 @@ export class PeopleController {
|
||||
res.set({
|
||||
'Content-Type':
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'Content-Disposition': 'attachment; filename="mento-people.xlsx"',
|
||||
'Content-Disposition': `attachment; filename="${brand.filePrefix}-people.xlsx"`,
|
||||
});
|
||||
return new StreamableFile(buffer);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Controller, Get } from '@nestjs/common';
|
||||
import type { HealthResponse } from '@mento/shared';
|
||||
import { brand } from '@mento/shared';
|
||||
|
||||
@Controller('health')
|
||||
export class HealthController {
|
||||
@@ -7,7 +8,7 @@ export class HealthController {
|
||||
getHealth(): HealthResponse {
|
||||
return {
|
||||
status: 'ok',
|
||||
service: 'mento-api',
|
||||
service: `${brand.id}-api`,
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
UpdateLoyaltyTierDto,
|
||||
} from './dto';
|
||||
import { LoyaltyService } from './loyalty.service';
|
||||
import { brand } from '@mento/shared';
|
||||
|
||||
@Controller('loyalty')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
@@ -96,7 +97,7 @@ export class LoyaltyController {
|
||||
res.set({
|
||||
'Content-Type':
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'Content-Disposition': 'attachment; filename="mento-loyalty-members.xlsx"',
|
||||
'Content-Disposition': `attachment; filename="${brand.filePrefix}-loyalty-members.xlsx"`,
|
||||
});
|
||||
return new StreamableFile(buffer);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import { ValidationPipe } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { brand } from '@mento/shared';
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
async function bootstrap() {
|
||||
@@ -24,7 +25,7 @@ async function bootstrap() {
|
||||
const port = Number(config.get<string>('PORT') ?? 3000);
|
||||
await app.listen(port);
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Mento API listening on http://localhost:${port}/api`);
|
||||
console.log(`${brand.name} API listening on http://localhost:${port}/api`);
|
||||
}
|
||||
|
||||
bootstrap();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { brand } from '@mento/shared';
|
||||
import type { NotificationDto, NotificationsListDto } from '@mento/shared';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { SmsService } from '../common/sms.service';
|
||||
@@ -228,7 +229,7 @@ export class NotificationsService {
|
||||
this.logger.warn('Activity reminder SMS skipped: SMS not configured');
|
||||
return;
|
||||
}
|
||||
const text = `یادآوری منتو: ${title}`.slice(0, 160);
|
||||
const text = `${brand.reminderPrefixFa} ${title}`.slice(0, 160);
|
||||
const result = await this.sms.sendSmsDetailed(mobile, text);
|
||||
if (!result.ok) {
|
||||
this.logger.warn(`Activity reminder SMS failed: ${result.reason ?? 'unknown'}`);
|
||||
|
||||
Reference in New Issue
Block a user