fix: remove defaultAgentId fallback — require agentId from caller

agent-state, dispose, dial, performance, force-ready, unlock-agent
all required agentId from the request body now. No silent fallback
to OZONETEL_AGENT_ID env var which caused cross-tenant operations
in multi-agent setups (Ramaiah operations hitting Global's agent).

OZONETEL_AGENT_ID removed from telephony env seed list. Hardcoded
fallbacks (agent3, Test123$, 521814) deleted.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-11 12:10:31 +05:30
parent 0248c4cad1
commit 4bd08a9b02
3 changed files with 28 additions and 28 deletions

View File

@@ -20,15 +20,9 @@ export class OzonetelAgentController {
private readonly supervisor: SupervisorService,
) {}
// Read-through accessors so admin updates take effect immediately.
private get defaultAgentId(): string {
return this.telephony.getConfig().ozonetel.agentId || 'agent3';
}
private get defaultAgentPassword(): string {
return this.telephony.getConfig().ozonetel.agentPassword;
}
private get defaultSipId(): string {
return this.telephony.getConfig().ozonetel.sipId || '521814';
private requireAgentId(agentId: string | undefined | null): string {
if (!agentId) throw new HttpException('agentId required', 400);
return agentId;
}
@Post('agent-login')
@@ -67,17 +61,18 @@ export class OzonetelAgentController {
@Post('agent-state')
async agentState(
@Body() body: { state: 'Ready' | 'Pause'; pauseReason?: string },
@Body() body: { agentId: string; state: 'Ready' | 'Pause'; pauseReason?: string },
) {
if (!body.state) {
throw new HttpException('state required', 400);
}
const agentId = this.requireAgentId(body.agentId);
this.logger.log(`[AGENT-STATE] ${this.defaultAgentId}${body.state} (${body.pauseReason ?? 'none'})`);
this.logger.log(`[AGENT-STATE] ${agentId}${body.state} (${body.pauseReason ?? 'none'})`);
try {
const result = await this.ozonetelAgent.changeAgentState({
agentId: this.defaultAgentId,
agentId,
state: body.state,
pauseReason: body.pauseReason,
});
@@ -86,7 +81,7 @@ export class OzonetelAgentController {
// Auto-assign missed call when agent goes Ready
if (body.state === 'Ready') {
try {
const assigned = await this.missedQueue.assignNext(this.defaultAgentId);
const assigned = await this.missedQueue.assignNext(agentId);
if (assigned) {
this.logger.log(`[AGENT-STATE] Auto-assigned missed call ${assigned.id}`);
return { ...result, assignedCall: assigned };
@@ -112,7 +107,7 @@ export class OzonetelAgentController {
@Body() body: {
ucid: string;
disposition: string;
agentId?: string;
agentId: string;
callerPhone?: string;
direction?: string;
durationSec?: number;
@@ -125,7 +120,7 @@ export class OzonetelAgentController {
throw new HttpException('ucid and disposition required', 400);
}
const agentId = body.agentId ?? this.defaultAgentId;
const agentId = this.requireAgentId(body.agentId);
const ozonetelDisposition = this.mapToOzonetelDisposition(body.disposition);
// Cancel the ACW auto-dispose timer — the frontend submitted disposition
@@ -200,7 +195,7 @@ export class OzonetelAgentController {
// Auto-assign next missed call to this agent
try {
await this.missedQueue.assignNext(this.defaultAgentId);
await this.missedQueue.assignNext(agentId);
} catch (err) {
this.logger.warn(`Auto-assignment after dispose failed: ${err}`);
}
@@ -209,7 +204,7 @@ export class OzonetelAgentController {
this.eventBus.emit(Topics.CALL_COMPLETED, {
callId: null,
ucid: body.ucid,
agentId: this.defaultAgentId,
agentId,
callerPhone: body.callerPhone ?? '',
direction: body.direction ?? 'INBOUND',
durationSec: body.durationSec ?? 0,
@@ -224,13 +219,13 @@ export class OzonetelAgentController {
@Post('dial')
async dial(
@Body() body: { phoneNumber: string; agentId?: string; campaignName?: string; leadId?: string },
@Body() body: { phoneNumber: string; agentId: string; campaignName?: string; leadId?: string },
) {
if (!body.phoneNumber) {
throw new HttpException('phoneNumber required', 400);
}
const agentId = body.agentId ?? this.defaultAgentId;
const agentId = this.requireAgentId(body.agentId);
const did = this.telephony.getConfig().ozonetel.did;
const campaignName = body.campaignName
|| this.telephony.getConfig().ozonetel.campaignName
@@ -323,7 +318,7 @@ export class OzonetelAgentController {
@Get('performance')
async performance(@Query('date') date?: string, @Query('agentId') agentId?: string) {
const agent = agentId ?? this.defaultAgentId;
const agent = this.requireAgentId(agentId);
const targetDate = date ?? new Date().toISOString().split('T')[0];
this.logger.log(`Performance: date=${targetDate} agent=${agent}`);