저장을 습관화

TypeScript 연습 - 카페 관리 프로그램 만들기 본문

공부/TypeScript

TypeScript 연습 - 카페 관리 프로그램 만들기

ctrs 2023. 8. 1. 00:45

작업 환경: Windows 10, VSC

 

작업 목표: 카페 관리 프로그램 만들기

주요 기능 - 권한:

음료 등록 기능 - 어드민

음료 삭제 기능 - 어드민

음료 조회 기능 - 어드민, 고객

음료 주문 기능 - 고객

음료 준비 완료 기능 - 어드민

음료 수령 기능 - 고객

 

작업 기록

1. 환경 구축

$ npm init -y

$ tsc --init --rootDir ./src --outDir ./dist --esModuleInterop --module commonjs --strict true --allowJS true --checkJS true

--rootDir: 소스 파일이 들어가는 경로를 명시적으로 지정함
이번에는 ./src 디렉토리에 넣겠다고 하였음

-- outDir: 컴파일된 파일이 tsc로 되면 TS파일이 JS 파일로 나올것임
여기서는 ./dist 디렉토리에 들어가게끔 하였음

--esModuleInterop: require 구문을 사용해서 가져오던 CommonJS 방식의 모듈을 es모듈 방식의 import 구문으로 가져올 수 있게 함

package.json, tsconfig.json 파일 생성 확인

 

package.json 파일 내용 수정

{
...(생략)...
"scripts": {
    "start": "tsc && node ./dist/index.js",
    "build": "tsc --build",
    "clean": "tsc --build --clean"
  },
...(생략)...
}

 

 

2. /src/index.ts 폴더 생성

 

- /src/index.tx

interface User {
  id: number;
  name: string;
  role: "admin" | "customer"; // union 타입
}

interface Beverage {
  name: string;
  price: number;
}

interface Order {
  orderId: number;
  customerId: number;
  customerName: string;
  beverageName: string;
  status: "placed" | "completed" | "picked-up"; // union 타입
}

let beverages: Beverage[] = [];
let orders: Order[] = [];

function isAdmin(user: User): boolean {
  return user.role === "admin";
}

function isCustomer(user: User): boolean {
  return user.role === "customer";
}

// 음료 등록 API - 어드민
function addBeverage(user: User, name: string, price: number): void {
  if (!isAdmin(user)) {
    console.log("권한이 없습니다.");
    return;
  }

  const newBeverage: Beverage = { name, price };
  beverages.push(newBeverage);
}

// 음료 삭제 API - 어드민
function removeBeverage(user: User, beverageName: string): void {
  if (!isAdmin(user)) {
    console.log("권한이 없습니다.");
    return;
  }

  beverages = beverages.filter((beverage) => beverage.name !== beverageName);
}

// 음료 조회 API - 어드민, 고객
function getBeverages(user: User): Beverage[] {
  if (!user) {
    return [];
  }
  return beverages;
}

// 음료 찾기 API - 고객, 음료 주문할 때 판매하지 않는 음료를 사는 것을 방지
function findBeverage(beverageName: string): Beverage | undefined {
  return beverages.find((beverage) => beverage.name === beverageName);
}

// find 메소드의 조건 함수는 beverage라는 매개변수를 받습니다. 이 매개변수는 배열의 각 요소인 Beverage 타입의 객체를 나타냅니다. 조건 함수는 beverage.name과 beverageName을 비교하여 두 값이 일치하는지 확인합니다.

// 일치하는 음료를 찾으면 해당 음료 객체를 반환합니다. 일치하는 음료가 없으면 undefined를 반환합니다.

// 음료 주문 API - 고객
function placeOrder(user: User, beverageName: string): number {
  if (!isCustomer(user)) {
    console.log("권한이 없습니다.");
    return -1;
  }

  const beverage = findBeverage(beverageName);
  if (!beverage) {
    console.log("해당 음료를 찾을 수 없습니다.");
    return -1;
  }

  const newOrder: Order = {
    orderId: orders.length + 1,
    customerId: user.id,
    customerName: user.name,
    beverageName,
    status: "placed",
  };
  orders.push(newOrder);
  return newOrder.orderId;
}

// 음료 준비 완료 API - 어드민
function completeOrder(user: User, orderId: number): void {
  if (!isAdmin(user)) {
    console.log("권한이 없습니다.");
    return;
  }

  const order = orders.find((order) => order.orderId === orderId);
  if (order) {
    order.status = "completed"; // 단순히 주문의 상태만 바꾸고 끝!
    console.log(
      `[고객 메시지] ${order.customerName}님~ 주문하신 ${order.beverageName} 1잔 나왔습니다~`
    );
  }
}

// 음료 수령 API - 고객
function pickUpOrder(user: User, orderId: number): void {
  if (!isCustomer(user)) {
    console.log("권한이 없습니다.");
    return;
  }

  const order = orders.find(
    (order) => order.orderId === orderId && order.customerId === user.id
  );
  if (order && order.status === "completed") {
    order.status = "picked-up";
    console.log(
      `[어드민 메시지] 고객 ID[${order.customerId}]님이 주문 ID[${orderId}]을 수령했습니다.`
    );
  }
}

// 테스트
function main() {
  const admin: User = {
    id: 1,
    name: "바리스타",
    role: "admin",
  };

  // 유저 생성
  const member1: User = {
    id: 2,
    name: "ctrs",
    role: "customer",
  };

  const member2: User = {
    id: 3,
    name: "testCust",
    role: "customer",
  };

  // 음료 등록
  addBeverage(admin, "아메리카노", 4000);
  addBeverage(admin, "카페라떼", 4500);
  addBeverage(admin, "에스프레소", 3000);

  // 음료 삭제
  removeBeverage(admin, "에스프레소");

  console.log(
    `안녕하세요~ ${
      member1.name
    } 고객님! 카페에 오신 것을 환영합니다. 저희는 ${JSON.stringify(
      getBeverages(member1)
    )}를 판매하고 있습니다.`
  );
  // 음료 주문
  const orderId1 = placeOrder(member1, "아메리카노");
  if (orderId1 > 0) {
    setTimeout(() => {
      // 음료 제작 완료
      completeOrder(admin, orderId1);
      // 음료 수령
      pickUpOrder(member1, orderId1);
    }, 1000);
  }

  console.log(
    `안녕하세요~ ${
      member2.name
    } 고객님! 카페에 오신 것을 환영합니다. 저희는 ${JSON.stringify(
      getBeverages(member2)
    )}를 판매하고 있습니다.`
  );
  // 음료 주문
  const orderId2 = placeOrder(member2, "카페라떼");
  if (orderId2 > 0) {
    setTimeout(() => {
      // 음료 제작 완료
      completeOrder(admin, orderId2);
      // 음료 수령
      pickUpOrder(member2, orderId2);
    }, 3000);
  }
}

// 테스트 코드 실행
main();

 

4. 컴파일

$ npm run build

 

5. /dist/index.js 파일 생성 확인

"use strict";
let beverages = [];
let orders = [];
function isAdmin(user) {
  return user.role === "admin";
}
function isCustomer(user) {
  return user.role === "customer";
}
// 음료 등록 API - 어드민
function addBeverage(user, name, price) {
  if (!isAdmin(user)) {
    console.log("권한이 없습니다.");
    return;
  }
  const newBeverage = { name, price };
  beverages.push(newBeverage);
}
// 음료 삭제 API - 어드민
function removeBeverage(user, beverageName) {
  if (!isAdmin(user)) {
    console.log("권한이 없습니다.");
    return;
  }
  beverages = beverages.filter((beverage) => beverage.name !== beverageName);
}
// 음료 조회 API - 어드민, 고객
function getBeverages(user) {
  if (!user) {
    return [];
  }
  return beverages;
}
// 음료 찾기 API - 고객, 음료 주문할 때 판매하지 않는 음료를 사는 것을 방지
function findBeverage(beverageName) {
  return beverages.find((beverage) => beverage.name === beverageName);
}
// find 메소드의 조건 함수는 beverage라는 매개변수를 받습니다. 이 매개변수는 배열의 각 요소인 Beverage 타입의 객체를 나타냅니다. 조건 함수는 beverage.name과 beverageName을 비교하여 두 값이 일치하는지 확인합니다.
// 일치하는 음료를 찾으면 해당 음료 객체를 반환합니다. 일치하는 음료가 없으면 undefined를 반환합니다.
// 음료 주문 API - 고객
function placeOrder(user, beverageName) {
  if (!isCustomer(user)) {
    console.log("권한이 없습니다.");
    return -1;
  }
  const beverage = findBeverage(beverageName);
  if (!beverage) {
    console.log("해당 음료를 찾을 수 없습니다.");
    return -1;
  }
  const newOrder = {
    orderId: orders.length + 1,
    customerId: user.id,
    customerName: user.name,
    beverageName,
    status: "placed",
  };
  orders.push(newOrder);
  return newOrder.orderId;
}
// 음료 준비 완료 API - 어드민
function completeOrder(user, orderId) {
  if (!isAdmin(user)) {
    console.log("권한이 없습니다.");
    return;
  }
  const order = orders.find((order) => order.orderId === orderId);
  if (order) {
    order.status = "completed"; // 단순히 주문의 상태만 바꾸고 끝!
    console.log(
      `[고객 메시지] ${order.customerName}님~ 주문하신 ${order.beverageName} 1잔 나왔습니다~`
    );
  }
}
// 음료 수령 API - 고객
function pickUpOrder(user, orderId) {
  if (!isCustomer(user)) {
    console.log("권한이 없습니다.");
    return;
  }
  const order = orders.find(
    (order) => order.orderId === orderId && order.customerId === user.id
  );
  if (order && order.status === "completed") {
    order.status = "picked-up";
    console.log(
      `[어드민 메시지] 고객 ID[${order.customerId}]님이 주문 ID[${orderId}]을 수령했습니다.`
    );
  }
}
// 테스트
function main() {
  const admin = {
    id: 1,
    name: "바리스타",
    role: "admin",
  };
  // 유저 생성
  const member1 = {
    id: 2,
    name: "ctrs",
    role: "customer",
  };
  const member2 = {
    id: 3,
    name: "testCust",
    role: "customer",
  };
  // 음료 등록
  addBeverage(admin, "아메리카노", 4000);
  addBeverage(admin, "카페라떼", 4500);
  addBeverage(admin, "에스프레소", 3000);
  // 음료 삭제
  removeBeverage(admin, "에스프레소");
  console.log(
    `안녕하세요~ ${
      member1.name
    } 고객님! 카페에 오신 것을 환영합니다. 저희는 ${JSON.stringify(
      getBeverages(member1)
    )}를 판매하고 있습니다.`
  );
  // 음료 주문
  const orderId1 = placeOrder(member1, "아메리카노");
  if (orderId1 > 0) {
    setTimeout(() => {
      // 음료 제작 완료
      completeOrder(admin, orderId1);
      // 음료 수령
      pickUpOrder(member1, orderId1);
    }, 1000);
  }
  console.log(
    `안녕하세요~ ${
      member2.name
    } 고객님! 카페에 오신 것을 환영합니다. 저희는 ${JSON.stringify(
      getBeverages(member2)
    )}를 판매하고 있습니다.`
  );
  // 음료 주문
  const orderId2 = placeOrder(member2, "카페라떼");
  if (orderId2 > 0) {
    setTimeout(() => {
      // 음료 제작 완료
      completeOrder(admin, orderId2);
      // 음료 수령
      pickUpOrder(member2, orderId2);
    }, 3000);
  }
}
// 테스트 코드 실행
main();

 

6. /dist/index.js 파일 실행

$ npm run start

> 03.-starbucks@1.0.0 start
> tsc && node ./dist/index.js

안녕하세요~ ctrs 고객님! 카페에 오신 것을 환영합니다. 저희는 [{"name":"아메리카노","price":4000},{"name":"카페라떼","price":4500}]를 판매하고 있습니다.
안녕하세요~ testCust 고객님! 카페에 오신 것을 환영합니다. 저희는 [{"name":"아메리카노","price":4000},{"name":"카페라떼","price":4500}]를 판매하고 있습니다.
[고객 메시지] ctrs님~ 주문하신 아메리카노 1잔 나왔습니다~
[어드민 메시지] 고객 ID[2]님이 주문 ID[1]을 수령했습니다.
[고객 메시지] testCust님~ 주문하신 카페라떼 1잔 나왔습니다~
[어드민 메시지] 고객 ID[3]님이 주문 ID[2]을 수령했습니다.