Files
domain-wall/packages/logic/domains/customerinfo/repository.ts

301 lines
9.1 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 getCustomerInfoByOrderId(
orderId: number,
): Promise<Result<CustomerInfoModel[]>> {
try {
const results = await this.db.query.customerInfo.findMany({
where: eq(customerInfo.orderId, orderId),
});
const out = [] as CustomerInfoModel[];
for (const result of results) {
const parsed = customerInfoModel.safeParse(result);
if (!parsed.success) {
Logger.error("Failed to parse customer info", result);
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 for the order",
userHint: "Please try again",
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,
orderId: payload.orderId || 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;
if (payload.orderId !== undefined) updateValues.orderId = payload.orderId;
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,
),
};
}
}
}