264 lines
8.0 KiB
TypeScript
264 lines
8.0 KiB
TypeScript
import { desc, eq, type Database } from "@pkg/db";
|
|
import { customerInfo } from "@pkg/db/schema";
|
|
import { getError, Logger } from "@pkg/logger";
|
|
import { ERROR_CODES, type Result } from "@pkg/result";
|
|
import {
|
|
customerInfoModel,
|
|
type CreateCustomerInfoPayload,
|
|
type CustomerInfoModel,
|
|
type UpdateCustomerInfoPayload,
|
|
} from "./data";
|
|
|
|
export class CustomerInfoRepository {
|
|
private db: Database;
|
|
|
|
constructor(db: Database) {
|
|
this.db = db;
|
|
}
|
|
|
|
async getAllCustomerInfo(): Promise<Result<CustomerInfoModel[]>> {
|
|
try {
|
|
const results = await this.db.query.customerInfo.findMany({
|
|
orderBy: [desc(customerInfo.createdAt)],
|
|
});
|
|
const out = [] as CustomerInfoModel[];
|
|
for (const result of results) {
|
|
const parsed = customerInfoModel.safeParse(result);
|
|
if (!parsed.success) {
|
|
Logger.error("Failed to parse customer info");
|
|
Logger.error(parsed.error);
|
|
continue;
|
|
}
|
|
out.push(parsed.data);
|
|
}
|
|
return { data: out };
|
|
} catch (e) {
|
|
return {
|
|
error: getError(
|
|
{
|
|
code: ERROR_CODES.DATABASE_ERROR,
|
|
message: "Failed to fetch customer information",
|
|
detail:
|
|
"An error occurred while retrieving customer information from the database",
|
|
userHint: "Please try refreshing the page",
|
|
actionable: false,
|
|
},
|
|
e,
|
|
),
|
|
};
|
|
}
|
|
}
|
|
|
|
async getCustomerInfoById(id: number): Promise<Result<CustomerInfoModel>> {
|
|
try {
|
|
const result = await this.db.query.customerInfo.findFirst({
|
|
where: eq(customerInfo.id, id),
|
|
});
|
|
|
|
if (!result) {
|
|
return {
|
|
error: getError({
|
|
code: ERROR_CODES.NOT_FOUND_ERROR,
|
|
message: "Customer information not found",
|
|
detail: "No customer information exists with the provided ID",
|
|
userHint: "Please check the customer ID and try again",
|
|
actionable: true,
|
|
}),
|
|
};
|
|
}
|
|
|
|
const parsed = customerInfoModel.safeParse(result);
|
|
if (!parsed.success) {
|
|
Logger.error("Failed to parse customer info", result);
|
|
return {
|
|
error: getError({
|
|
code: ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
message: "Failed to parse customer information",
|
|
userHint: "Please try again",
|
|
detail: "Failed to parse customer information",
|
|
}),
|
|
};
|
|
}
|
|
return { data: parsed.data };
|
|
} catch (e) {
|
|
return {
|
|
error: getError(
|
|
{
|
|
code: ERROR_CODES.DATABASE_ERROR,
|
|
message: "Failed to fetch customer information",
|
|
detail:
|
|
"An error occurred while retrieving the customer information from the database",
|
|
userHint: "Please try refreshing the page",
|
|
actionable: false,
|
|
},
|
|
e,
|
|
),
|
|
};
|
|
}
|
|
}
|
|
|
|
async createCustomerInfo(
|
|
payload: CreateCustomerInfoPayload,
|
|
): Promise<Result<number>> {
|
|
try {
|
|
const result = await this.db
|
|
.insert(customerInfo)
|
|
.values({
|
|
firstName: payload.firstName,
|
|
middleName: payload.middleName || "",
|
|
lastName: payload.lastName,
|
|
email: payload.email,
|
|
phoneCountryCode: payload.phoneCountryCode,
|
|
phoneNumber: payload.phoneNumber,
|
|
country: payload.country,
|
|
state: payload.state,
|
|
city: payload.city,
|
|
zipCode: payload.zipCode,
|
|
address: payload.address,
|
|
address2: payload.address2 || null,
|
|
})
|
|
.returning({ id: customerInfo.id })
|
|
.execute();
|
|
|
|
if (!result || result.length === 0) {
|
|
throw new Error("Failed to create customer info record");
|
|
}
|
|
|
|
return { data: result[0].id };
|
|
} catch (e) {
|
|
return {
|
|
error: getError(
|
|
{
|
|
code: ERROR_CODES.DATABASE_ERROR,
|
|
message: "Failed to create customer information",
|
|
detail: "An error occurred while creating the customer information",
|
|
userHint: "Please try again",
|
|
actionable: false,
|
|
},
|
|
e,
|
|
),
|
|
};
|
|
}
|
|
}
|
|
|
|
async updateCustomerInfo(
|
|
payload: UpdateCustomerInfoPayload,
|
|
): Promise<Result<boolean>> {
|
|
try {
|
|
if (!payload.id) {
|
|
return {
|
|
error: getError({
|
|
code: ERROR_CODES.VALIDATION_ERROR,
|
|
message: "Invalid customer ID",
|
|
detail: "No customer ID was provided for the update operation",
|
|
userHint: "Please provide a valid customer ID",
|
|
actionable: true,
|
|
}),
|
|
};
|
|
}
|
|
|
|
// Check if customer info exists
|
|
const existing = await this.db.query.customerInfo.findFirst({
|
|
where: eq(customerInfo.id, payload.id),
|
|
});
|
|
|
|
if (!existing) {
|
|
return {
|
|
error: getError({
|
|
code: ERROR_CODES.NOT_FOUND_ERROR,
|
|
message: "Customer information not found",
|
|
detail: "No customer information exists with the provided ID",
|
|
userHint: "Please check the customer ID and try again",
|
|
actionable: true,
|
|
}),
|
|
};
|
|
}
|
|
|
|
// Build the update object with only the fields that are provided
|
|
const updateValues: Record<string, any> = {};
|
|
|
|
if (payload.firstName !== undefined)
|
|
updateValues.firstName = payload.firstName;
|
|
if (payload.middleName !== undefined)
|
|
updateValues.middleName = payload.middleName;
|
|
if (payload.lastName !== undefined)
|
|
updateValues.lastName = payload.lastName;
|
|
if (payload.email !== undefined) updateValues.email = payload.email;
|
|
if (payload.phoneCountryCode !== undefined)
|
|
updateValues.phoneCountryCode = payload.phoneCountryCode;
|
|
if (payload.phoneNumber !== undefined)
|
|
updateValues.phoneNumber = payload.phoneNumber;
|
|
if (payload.country !== undefined) updateValues.country = payload.country;
|
|
if (payload.state !== undefined) updateValues.state = payload.state;
|
|
if (payload.city !== undefined) updateValues.city = payload.city;
|
|
if (payload.zipCode !== undefined) updateValues.zipCode = payload.zipCode;
|
|
if (payload.address !== undefined) updateValues.address = payload.address;
|
|
if (payload.address2 !== undefined)
|
|
updateValues.address2 = payload.address2;
|
|
updateValues.updatedAt = new Date();
|
|
|
|
await this.db
|
|
.update(customerInfo)
|
|
.set(updateValues)
|
|
.where(eq(customerInfo.id, payload.id))
|
|
.execute();
|
|
|
|
return { data: true };
|
|
} catch (e) {
|
|
return {
|
|
error: getError(
|
|
{
|
|
code: ERROR_CODES.DATABASE_ERROR,
|
|
message: "Failed to update customer information",
|
|
detail: "An error occurred while updating the customer information",
|
|
userHint: "Please try again",
|
|
actionable: false,
|
|
},
|
|
e,
|
|
),
|
|
};
|
|
}
|
|
}
|
|
|
|
async deleteCustomerInfo(id: number): Promise<Result<boolean>> {
|
|
try {
|
|
// Check if customer info exists
|
|
const existing = await this.db.query.customerInfo.findFirst({
|
|
where: eq(customerInfo.id, id),
|
|
});
|
|
|
|
if (!existing) {
|
|
return {
|
|
error: getError({
|
|
code: ERROR_CODES.NOT_FOUND_ERROR,
|
|
message: "Customer information not found",
|
|
detail: "No customer information exists with the provided ID",
|
|
userHint: "Please check the customer ID and try again",
|
|
actionable: true,
|
|
}),
|
|
};
|
|
}
|
|
|
|
await this.db
|
|
.delete(customerInfo)
|
|
.where(eq(customerInfo.id, id))
|
|
.execute();
|
|
|
|
return { data: true };
|
|
} catch (e) {
|
|
return {
|
|
error: getError(
|
|
{
|
|
code: ERROR_CODES.DATABASE_ERROR,
|
|
message: "Failed to delete customer information",
|
|
detail: "An error occurred while deleting the customer information",
|
|
userHint: "Please try again",
|
|
actionable: false,
|
|
},
|
|
e,
|
|
),
|
|
};
|
|
}
|
|
}
|
|
}
|