import { Body, Controller, Get, HttpCode, Post, Query } from '@nestjs/common'; import { SalesExpertAppService } from './sales-expert-app.service'; import { CurrentCustomer, CustomerAuth } from '../customer-auth/customer.guards'; import type { AuthenticatedCustomer } from '../customer-auth/app-principal'; /** * The sales expert's own screens in the customer apps. * * POST expert/child-orders -> legacy POST /order/child (ApiMobileController:759) * POST expert/my-customers -> legacy POST /my-child (ApiMobileController:184) * GET expert/me -> the expert's profile strip * * Every route sits behind the app token and takes its scope from * `me.adminUserId`, which only a sales-expert token carries. An ordinary * customer's token has it undefined, so the service refuses with 403 — the * apps also hide the menu entries, but the server does not rely on that. * * No route accepts a customer id or an agent id from the client. */ @Controller('expert') export class SalesExpertAppController { constructor(private readonly expert: SalesExpertAppService) {} /** Legacy POST /order/child — POST because the reference posted its paging. */ @CustomerAuth() @Post('child-orders') @HttpCode(200) childOrders( @Body() body: { page?: number; limit?: number; search?: string | null }, @CurrentCustomer() me: AuthenticatedCustomer, ) { return this.expert.childOrders(me.adminUserId, body ?? {}); } /** Legacy POST /my-child. */ @CustomerAuth() @Post('my-customers') @HttpCode(200) myCustomers( @Body() body: { search?: string | null; text_search?: string | null }, @CurrentCustomer() me: AuthenticatedCustomer, ) { // The reference read `text_search` (ApiMobileController.php:186); the // ported screens send `search`. Both accepted. return this.expert.myCustomers(me.adminUserId, { search: body?.search ?? body?.text_search ?? null, }); } @CustomerAuth() @Get('me') me(@CurrentCustomer() me: AuthenticatedCustomer) { return this.expert.me(me.adminUserId); } /** * Whether the signed-in principal is a sales expert. The apps call this once * after login to decide whether to show the two expert entries; the answer * comes from the token, so a customer cannot make it say yes. * * `actingAsCustomerId` lets an app that was reloaded mid-impersonation render * its "viewing as …" bar from the server's view of the session rather than * trusting its own stored state. */ @CustomerAuth() @Get('whoami') whoami(@CurrentCustomer() me: AuthenticatedCustomer) { return { isSalesExpert: Boolean(me.adminUserId), type: me.type, actingAsCustomerId: me.actingAsCustomerId ?? null, }; } }