2025-08-22 17:02:49 +09:00
|
|
|
import {
|
|
|
|
|
Controller,
|
|
|
|
|
Get,
|
|
|
|
|
Patch,
|
|
|
|
|
Body,
|
|
|
|
|
Req,
|
|
|
|
|
UseInterceptors,
|
|
|
|
|
ClassSerializerInterceptor,
|
2025-09-24 18:00:49 +09:00
|
|
|
UsePipes,
|
2025-08-22 17:02:49 +09:00
|
|
|
} from "@nestjs/common";
|
2025-11-04 13:28:36 +09:00
|
|
|
import { UsersFacade } from "./application/users.facade";
|
|
|
|
|
import { ZodValidationPipe } from "@customer-portal/validation/nestjs";
|
2025-09-25 11:44:10 +09:00
|
|
|
import {
|
2025-10-07 17:38:39 +09:00
|
|
|
updateCustomerProfileRequestSchema,
|
|
|
|
|
type UpdateCustomerProfileRequest,
|
2025-10-03 17:33:39 +09:00
|
|
|
} from "@customer-portal/domain/auth";
|
2025-10-20 14:54:04 +09:00
|
|
|
import { addressSchema, type Address } from "@customer-portal/domain/customer";
|
2025-09-17 18:43:43 +09:00
|
|
|
import type { RequestWithUser } from "@bff/modules/auth/auth.types";
|
2025-08-20 18:02:50 +09:00
|
|
|
|
2025-08-21 15:24:40 +09:00
|
|
|
@Controller("me")
|
2025-08-22 17:02:49 +09:00
|
|
|
@UseInterceptors(ClassSerializerInterceptor)
|
2025-08-20 18:02:50 +09:00
|
|
|
export class UsersController {
|
2025-11-04 13:28:36 +09:00
|
|
|
constructor(private usersFacade: UsersFacade) {}
|
2025-08-20 18:02:50 +09:00
|
|
|
|
2025-10-07 17:38:39 +09:00
|
|
|
/**
|
|
|
|
|
* GET /me - Get complete customer profile (includes address)
|
|
|
|
|
* Profile data fetched from WHMCS (single source of truth)
|
|
|
|
|
*/
|
2025-08-20 18:02:50 +09:00
|
|
|
@Get()
|
2025-08-23 17:24:37 +09:00
|
|
|
async getProfile(@Req() req: RequestWithUser) {
|
2025-11-04 13:28:36 +09:00
|
|
|
return this.usersFacade.findById(req.user.id);
|
2025-08-20 18:02:50 +09:00
|
|
|
}
|
|
|
|
|
|
2025-10-07 17:38:39 +09:00
|
|
|
/**
|
|
|
|
|
* GET /me/summary - Get dashboard summary
|
|
|
|
|
*/
|
2025-08-21 15:24:40 +09:00
|
|
|
@Get("summary")
|
2025-08-23 17:24:37 +09:00
|
|
|
async getSummary(@Req() req: RequestWithUser) {
|
2025-11-04 13:28:36 +09:00
|
|
|
return this.usersFacade.getUserSummary(req.user.id);
|
2025-08-20 18:02:50 +09:00
|
|
|
}
|
|
|
|
|
|
2025-10-20 14:54:04 +09:00
|
|
|
/**
|
|
|
|
|
* GET /me/address - Get customer address only
|
|
|
|
|
*/
|
|
|
|
|
@Get("address")
|
|
|
|
|
async getAddress(@Req() req: RequestWithUser): Promise<Address | null> {
|
2025-11-04 13:28:36 +09:00
|
|
|
return this.usersFacade.getAddress(req.user.id);
|
2025-10-20 14:54:04 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* PATCH /me/address - Update address fields
|
|
|
|
|
*/
|
|
|
|
|
@Patch("address")
|
|
|
|
|
@UsePipes(new ZodValidationPipe(addressSchema.partial()))
|
|
|
|
|
async updateAddress(
|
|
|
|
|
@Req() req: RequestWithUser,
|
|
|
|
|
@Body() address: Partial<Address>
|
|
|
|
|
): Promise<Address> {
|
2025-11-04 13:28:36 +09:00
|
|
|
return this.usersFacade.updateAddress(req.user.id, address);
|
2025-10-20 14:54:04 +09:00
|
|
|
}
|
|
|
|
|
|
2025-10-07 17:38:39 +09:00
|
|
|
/**
|
|
|
|
|
* PATCH /me - Update customer profile (can update profile fields and/or address)
|
|
|
|
|
* All fields optional - only send what needs to be updated
|
|
|
|
|
* Updates stored in WHMCS (single source of truth)
|
2025-10-22 10:58:16 +09:00
|
|
|
*
|
2025-10-07 17:38:39 +09:00
|
|
|
* Examples:
|
|
|
|
|
* - Update name only: { firstname: "John", lastname: "Doe" }
|
|
|
|
|
* - Update address only: { address1: "123 Main St", city: "Tokyo" }
|
|
|
|
|
* - Update both: { firstname: "John", address1: "123 Main St" }
|
|
|
|
|
*/
|
2025-08-20 18:02:50 +09:00
|
|
|
@Patch()
|
2025-10-07 17:38:39 +09:00
|
|
|
@UsePipes(new ZodValidationPipe(updateCustomerProfileRequestSchema))
|
2025-10-22 10:58:16 +09:00
|
|
|
async updateProfile(
|
|
|
|
|
@Req() req: RequestWithUser,
|
|
|
|
|
@Body() updateData: UpdateCustomerProfileRequest
|
|
|
|
|
) {
|
2025-11-04 13:28:36 +09:00
|
|
|
return this.usersFacade.updateProfile(req.user.id, updateData);
|
2025-08-20 18:02:50 +09:00
|
|
|
}
|
|
|
|
|
}
|