WIP - fix AI suggestions during call progress

This commit is contained in:
Francisco Gaona
2026-02-05 03:02:02 +01:00
parent 9226442525
commit eb1619c56c
2 changed files with 52 additions and 29 deletions

View File

@@ -16,26 +16,45 @@ import { TenantId } from './tenant.decorator';
export class TenantController { export class TenantController {
constructor(private readonly tenantDbService: TenantDatabaseService) {} constructor(private readonly tenantDbService: TenantDatabaseService) {}
/**
* Helper to find tenant by ID or domain
*/
private async findTenant(identifier: string) {
const centralPrisma = getCentralPrisma();
// Check if identifier is a CUID (tenant ID) or a domain
const isCUID = /^c[a-z0-9]{24}$/i.test(identifier);
if (isCUID) {
// Look up by tenant ID directly
return centralPrisma.tenant.findUnique({
where: { id: identifier },
select: { id: true, integrationsConfig: true },
});
} else {
// Look up by domain
const domainRecord = await centralPrisma.domain.findUnique({
where: { domain: identifier },
include: { tenant: { select: { id: true, integrationsConfig: true } } },
});
return domainRecord?.tenant;
}
}
/** /**
* Get integrations configuration for the current tenant * Get integrations configuration for the current tenant
*/ */
@Get('integrations') @Get('integrations')
async getIntegrationsConfig(@TenantId() domain: string) { async getIntegrationsConfig(@TenantId() tenantIdentifier: string) {
const centralPrisma = getCentralPrisma(); const tenant = await this.findTenant(tenantIdentifier);
// Look up tenant by domain
const domainRecord = await centralPrisma.domain.findUnique({
where: { domain },
include: { tenant: { select: { id: true, integrationsConfig: true } } },
});
if (!domainRecord?.tenant || !domainRecord.tenant.integrationsConfig) { if (!tenant || !tenant.integrationsConfig) {
return { data: null }; return { data: null };
} }
// Decrypt the config // Decrypt the config
const config = this.tenantDbService.decryptIntegrationsConfig( const config = this.tenantDbService.decryptIntegrationsConfig(
domainRecord.tenant.integrationsConfig as any, tenant.integrationsConfig as any,
); );
// Return config with sensitive fields masked // Return config with sensitive fields masked
@@ -49,31 +68,26 @@ export class TenantController {
*/ */
@Put('integrations') @Put('integrations')
async updateIntegrationsConfig( async updateIntegrationsConfig(
@TenantId() domain: string, @TenantId() tenantIdentifier: string,
@Body() body: { integrationsConfig: any }, @Body() body: { integrationsConfig: any },
) { ) {
const { integrationsConfig } = body; const { integrationsConfig } = body;
if (!domain) { if (!tenantIdentifier) {
throw new Error('Domain is missing from request'); throw new Error('Tenant identifier is missing from request');
} }
// Look up tenant by domain const tenant = await this.findTenant(tenantIdentifier);
const centralPrisma = getCentralPrisma();
const domainRecord = await centralPrisma.domain.findUnique({
where: { domain },
include: { tenant: { select: { id: true, integrationsConfig: true } } },
});
if (!domainRecord?.tenant) { if (!tenant) {
throw new Error(`Tenant with domain ${domain} not found`); throw new Error(`Tenant with identifier ${tenantIdentifier} not found`);
} }
// Merge with existing config to preserve masked values // Merge with existing config to preserve masked values
let finalConfig = integrationsConfig; let finalConfig = integrationsConfig;
if (domainRecord.tenant.integrationsConfig) { if (tenant.integrationsConfig) {
const existingConfig = this.tenantDbService.decryptIntegrationsConfig( const existingConfig = this.tenantDbService.decryptIntegrationsConfig(
domainRecord.tenant.integrationsConfig as any, tenant.integrationsConfig as any,
); );
// Replace masked values with actual values from existing config // Replace masked values with actual values from existing config
@@ -86,8 +100,9 @@ export class TenantController {
); );
// Update in database // Update in database
const centralPrisma = getCentralPrisma();
await centralPrisma.tenant.update({ await centralPrisma.tenant.update({
where: { id: domainRecord.tenant.id }, where: { id: tenant.id },
data: { data: {
integrationsConfig: encryptedConfig as any, integrationsConfig: encryptedConfig as any,
}, },

View File

@@ -478,20 +478,28 @@ export class VoiceService {
const { callSid, tenantId, userId } = params; const { callSid, tenantId, userId } = params;
try { try {
// Get OpenAI config - tenantId might be a domain, so look it up // Get OpenAI config - tenantId might be a domain or a tenant ID (UUID or CUID)
const centralPrisma = getCentralPrisma(); const centralPrisma = getCentralPrisma();
// Try to find tenant by domain first (if tenantId is like "tenant1") // Detect if tenantId looks like an ID (UUID or CUID) or a domain name
// UUIDs: 8-4-4-4-12 hex format
// CUIDs: 25 character alphanumeric starting with 'c'
const isUUID = /^[0-9a-f]{8}-[0-9a-f]{4}-/i.test(tenantId);
const isCUID = /^c[a-z0-9]{24}$/i.test(tenantId);
const isId = isUUID || isCUID;
let tenant; let tenant;
if (!tenantId.match(/^[0-9a-f]{8}-[0-9a-f]{4}-/i)) { if (!isId) {
// Looks like a domain, not a UUID // Looks like a domain, not an ID
this.logger.log(`Looking up tenant by domain: ${tenantId}`);
const domainRecord = await centralPrisma.domain.findUnique({ const domainRecord = await centralPrisma.domain.findUnique({
where: { domain: tenantId }, where: { domain: tenantId },
include: { tenant: { select: { id: true, integrationsConfig: true } } }, include: { tenant: { select: { id: true, integrationsConfig: true } } },
}); });
tenant = domainRecord?.tenant; tenant = domainRecord?.tenant;
} else { } else {
// It's a UUID // It's an ID (UUID or CUID)
this.logger.log(`Looking up tenant by ID: ${tenantId}`);
tenant = await centralPrisma.tenant.findUnique({ tenant = await centralPrisma.tenant.findUnique({
where: { id: tenantId }, where: { id: tenantId },
select: { id: true, integrationsConfig: true }, select: { id: true, integrationsConfig: true },