4.3.2. Build functions

Pre-setup

Before implementing the feature, first we will create a new folder named functions inside the modules/pcustomer-management directory. In the functions folder, we will sequentially create the files: add-customer.ts, delete-customer.ts, get-pcustomer.ts, get-pcustomers.ts, and update-customer.ts.

4.3.2.1

Add potential customer function

First, we will build the function to add a user. First, import some things as follows:

import { AppError, isStandardError } from "../../../error";
import { PCustomerDAO } from "../data-model/dao";
import { initializeInternalContext } from "../../../context/internal-context";

// Import types
import type { RuntimeContext } from "../../../context/runtime-context";
import type { InternalContext } from "../../../context/internal-context";
import type { TPCustomer } from "../data-model/type";

Next is the add user function.

/**
 * Thêm thông tin của một khách hàng vào trong danh sách.
 *
 * @param ctx - runtime context.
 *
 * @returns
 */
export async function addCustomer(ctx: RuntimeContext) {
  try {
    const body = await ctx.getBody<Partial<TPCustomer>>();

    const pcustomerDao = new PCustomerDAO();
    const internalCtx = initializeInternalContext() as InternalContext<
      Partial<TPCustomer>
    >;

    internalCtx.params = body;
    internalCtx.options!.canCatchError = true;

    const result = await pcustomerDao.insertPCustomer(internalCtx);

    return result;
  } catch (error: any) {
    if (isStandardError(error)) return error;

    const err = new AppError("Cannot add new potential customer");
    err.asHTTPError("InternalServerError");
    return err;
  }
}

In this function, you can see that we get the user information with ctx.getBody() (Runtime Context) and create another context (Internal Context). Then we update the information in the internal context and call the pcustomerDao.insertPCustomer() function. The following functions will also have a similar flow to this one.

4.3.2.2

We can still unit test this function, provided that we fully create the context for it.

Delete potential customer function

Next is the function to delete a customer. Import some things first.

import { AppError, isStandardError } from "../../../error";
import { PCustomerDAO } from "../data-model/dao";
import { initializeInternalContext } from "../../../context/internal-context";

// Import types
import type { RuntimeContext } from "../../../context/runtime-context";
import type { InternalContext } from "../../../context/internal-context";
import type { TDeletePCustomerParams } from "../data-model/type";

Add the function code.

/**
 * Xoá thông tin của một khách hàng ra khỏi danh sách.
 *
 * @param ctx - runtime context.
 *
 * @returns
 */
export async function deleteCustomer(ctx: RuntimeContext) {
  try {
    const params = await ctx.getParams<{ id: string }>();

    const pcustomerDao = new PCustomerDAO();
    const internalCtx =
      initializeInternalContext() as InternalContext<TDeletePCustomerParams>;

    internalCtx.params = {
      query: {
        id: params.id,
      },
    };
    internalCtx.options!.canCatchError = true;

    const result = await pcustomerDao.deletePCustomer(internalCtx);

    return result;
  } catch (error: any) {
    if (isStandardError(error)) return error;

    const err = new AppError("Cannot delete potential customer");
    err.asHTTPError("InternalServerError");
    return err;
  }
}

4.3.2.3

Get potential customer function

Next is the function to get the information of a customer. Import some things first.

import { AppError, isStandardError } from "../../../error";
import { PCustomerDAO } from "../data-model/dao";
import { initializeInternalContext } from "../../../context/internal-context";

// Import types
import type { RuntimeContext } from "../../../context/runtime-context";
import type { InternalContext } from "../../../context/internal-context";
import type { TFindPCustomerParams } from "../data-model/type";

Add the function code.

/**
 * Lấy một người dùng ở trong cơ sở dữ liệu, theo một số điều kiện.
 *
 * @param ctx - runtime context
 */
export async function getCustomer(ctx: RuntimeContext) {
  try {
    const params = await ctx.getParams<{ id: string }>();

    const pcustomerDao = new PCustomerDAO();
    const internalCtx =
      initializeInternalContext() as InternalContext<TFindPCustomerParams>;

    internalCtx.params = {
      query: { id: params.id },
    };
    internalCtx.options!.canCatchError = true;

    const result = await pcustomerDao.getPCustomer(internalCtx);

    return result;
  } catch (error) {
    if (isStandardError(error)) return error;

    const err = new AppError("Cannot get a potential customer");
    err.asHTTPError("InternalServerError");
    return err;
  }
}

4.3.2.4

Get potential customers function

Next is the function to get the list of customer information. Import some things first.

import { AppError, isStandardError } from "../../../error";
import { PCustomerDAO } from "../data-model/dao";
import { initializeInternalContext } from "../../../context/internal-context";

// Import types
import type { RuntimeContext } from "../../../context/runtime-context";
import type { InternalContext } from "../../../context/internal-context";
import type { TFindPCustomerParams } from "../data-model/type";

Add the function code.

/**
 * Lấy danh sách các khác hàng ở trong cơ sở dữ liệu.
 *
 * @param ctx - runtime context.
 *
 * @returns
 */
export async function getCustomers(ctx: RuntimeContext) {
  try {
    const query = await ctx.getQuery<{ limit: string; startKey: string }>();

    const pcustomerDao = new PCustomerDAO();
    const internalCtx =
      initializeInternalContext() as InternalContext<TFindPCustomerParams>;

    internalCtx.params = {
      limit: query.limit,
      staryKey: query.startKey,
    };
    internalCtx.options!.canCatchError = true;

    const result = await pcustomerDao.listPCustomers(internalCtx);

    return result;
  } catch (error) {
    if (isStandardError(error)) return error;

    const err = new AppError("Cannot found list of potential customers");
    err.asHTTPError("InternalServerError");
    return err;
  }
}

4.3.2.5

Update potential customer function

Next is the function to update the customer information. Import some things first.

import { AppError, isStandardError } from "../../../error";
import { PCustomerDAO } from "../data-model/dao";
import { initializeInternalContext } from "../../../context/internal-context";

// Import types
import type { RuntimeContext } from "../../../context/runtime-context";
import type { InternalContext } from "../../../context/internal-context";
import type { TPCustomer } from "../data-model/type";

Add the function code.

/**
 * Cập nhật thông tin của một khách hàng trong hệ thống.
 *
 * @param ctx - runtime context.
 *
 * @returns
 */
export async function updateCustomer(ctx: RuntimeContext) {
  try {
    const body = await ctx.getBody<Partial<TPCustomer>>();
    const params = await ctx.getParams<{ id: string }>();

    const pcustomerDao = new PCustomerDAO();
    const internalCtx = initializeInternalContext() as InternalContext<
      Partial<TPCustomer>
    >;

    internalCtx.params = { id: params.id, ...body };
    internalCtx.options!.canCatchError = true;

    const result = await pcustomerDao.updatePCustomer(internalCtx);

    return result;
  } catch (error) {
    if (isStandardError(error)) return error;

    const err = new AppError("Cannot update existing potential customer");
    err.asHTTPError("InternalServerError");
    return err;
  }
}

4.3.2.6

Ok, so we have completed building the functions to perform customer management tasks.