mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 00:52:50 +00:00
Gates the previously open support-agent, procurement, compliance, facilities, list-users and trade-access controllers, separates customer from staff routes across bookings, contracts, companies, billing, warehouses, files and train scheduling, and moves billing, overview, reports and the settings controllers onto their own keys instead of the blanket admin key. Drops the demo-permissions module and the untested notification test route.
117 lines
3.4 KiB
TypeScript
117 lines
3.4 KiB
TypeScript
import { CurrentUser } from "@edr/api-common";
|
|
import {
|
|
SUPPORT_ATTACHMENT_MAX_PER_MESSAGE,
|
|
SupportAuthorRole,
|
|
} from "@edr/types";
|
|
import {
|
|
Body,
|
|
Controller,
|
|
Get,
|
|
Post,
|
|
Query,
|
|
UploadedFiles,
|
|
UseInterceptors,
|
|
} from "@nestjs/common";
|
|
import { FilesInterceptor } from "@nestjs/platform-express";
|
|
import { ApiBody, ApiConsumes, ApiOperation, ApiTags } from "@nestjs/swagger";
|
|
|
|
import {
|
|
AuthUserPayload,
|
|
resolveAuthUserId,
|
|
} from "../../common/resolve-auth-user-id";
|
|
import {
|
|
SUPPORT_ATTACHMENT_FIELD,
|
|
supportAttachmentMulterOptions,
|
|
} from "./attachment-upload.options";
|
|
import { PortalCustomer } from "../../common/booking-guards";
|
|
import { ListMessagesQueryDto } from "./dto/list-messages-query.dto";
|
|
import { SendMessageDto } from "./dto/send-message.dto";
|
|
import { SupportChatService } from "./support-chat.service";
|
|
|
|
/**
|
|
* Portal (customer) support-chat endpoints. The caller's company has exactly one
|
|
* thread, so these are addressed as a singleton — no conversation id on the wire,
|
|
* and nothing for a portal user to pick between.
|
|
*/
|
|
@ApiTags("support-chat")
|
|
@Controller("support")
|
|
@PortalCustomer()
|
|
export class SupportChatController {
|
|
constructor(private readonly service: SupportChatService) {}
|
|
|
|
@Get("conversation")
|
|
@ApiOperation({
|
|
summary: "My company's support thread (null until someone speaks)",
|
|
})
|
|
conversation(@CurrentUser() user: AuthUserPayload) {
|
|
return this.service.getCustomerConversation(resolveAuthUserId(user));
|
|
}
|
|
|
|
@Get("conversation/messages")
|
|
@ApiOperation({
|
|
summary: "Messages in my company's support thread (newest page first)",
|
|
description:
|
|
"Keyset-paginated backwards from the newest message. Omit `before` for " +
|
|
"the newest page, then pass the previous response's `nextCursor` to walk " +
|
|
"back through history. `nextCursor: null` means the thread's start.",
|
|
})
|
|
messages(
|
|
@CurrentUser() user: AuthUserPayload,
|
|
@Query() query: ListMessagesQueryDto,
|
|
) {
|
|
return this.service.getCustomerMessages(resolveAuthUserId(user), query);
|
|
}
|
|
|
|
@Post("conversation/messages")
|
|
@UseInterceptors(
|
|
FilesInterceptor(
|
|
SUPPORT_ATTACHMENT_FIELD,
|
|
SUPPORT_ATTACHMENT_MAX_PER_MESSAGE,
|
|
supportAttachmentMulterOptions,
|
|
),
|
|
)
|
|
@ApiConsumes("multipart/form-data", "application/json")
|
|
@ApiBody({
|
|
schema: {
|
|
type: "object",
|
|
properties: {
|
|
body: { type: "string" },
|
|
attachments: {
|
|
type: "array",
|
|
items: { type: "string", format: "binary" },
|
|
},
|
|
},
|
|
},
|
|
})
|
|
@ApiOperation({
|
|
summary:
|
|
"Send a message as the customer (optionally with attachments), opening the thread if needed",
|
|
})
|
|
send(
|
|
@CurrentUser() user: AuthUserPayload,
|
|
@Body() body: SendMessageDto,
|
|
@UploadedFiles() attachments?: Express.Multer.File[],
|
|
) {
|
|
return this.service.sendAsCustomer(
|
|
resolveAuthUserId(user),
|
|
body.body,
|
|
attachments ?? [],
|
|
);
|
|
}
|
|
|
|
@Post("conversation/read")
|
|
@ApiOperation({ summary: "Mark my company's thread read (customer side)" })
|
|
read(@CurrentUser() user: AuthUserPayload) {
|
|
return this.service.markCustomerRead(resolveAuthUserId(user));
|
|
}
|
|
|
|
@Get("unread-count")
|
|
@ApiOperation({ summary: "Count my unread support messages" })
|
|
unread(@CurrentUser() user: AuthUserPayload) {
|
|
return this.service.unreadCount(
|
|
SupportAuthorRole.CUSTOMER,
|
|
resolveAuthUserId(user),
|
|
);
|
|
}
|
|
}
|